A minizinc function that checks the neighbors for every element in an n*n matrix - minizinc

I am trying to search for every neighbor of an element of a n*n matrix in minizinc. So far i use very in efficient way where i have if-else for the whole matrix and separate conditions to handle the boundary variables. I am kinda new to minizinc and I was hoping if there is a n efficient way to do this. maybe with a function or something.
int: size; % Enter the size lads
set of int: board = 0..size-1;
array[board,board] of var 0..1: grid;
var int: z = sum(r in board, c in board) (grid[r,c]);
% solve maximize z;
solve :: int_search(
[grid[i,j] | i,j in board],
smallest,
indomain_max,
complete)
maximize z;
constraint
forall(r in board,c in board,x in board) (
if (r==0/\c==0) then %corner 1
(
if ( (grid[r,c+1] + grid[r+1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif(
(grid[r,c+1] + grid[r+1,c+1]+grid[r,c+1]) ==2)then(grid[r,c] = grid[r,c])
else grid[r,c]=0 endif
)
elseif (r==size-1/\c==size-1) then %corner2
( if ((grid[r-1,c]+grid[r,c-1]+grid[r-1,c-1])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r,c-1]+grid[r-1,c-1]) ==2) then (grid[r,c] = grid[r,c])
else (grid[r,c] = 0) endif
)
elseif (r==0/\c==size-1) then %corner3
( if( (grid[r,c-1]+grid[r+1,c]+grid[r+1,c-1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r+1,c]+grid[r+1,c-1]) ==2)then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==size-1/\c==0) then %corner4
( if((grid[r-1,c]+grid[r,c+1]+grid[r-1,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r,c+1]+grid[r-1,c+1]) ==2) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==0/\c==x/\c!=0/\c!=size-1) then %top row
( if((grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]+grid[r+1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]+grid[r+1,c+1]+grid[r,c+1])==2 ) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==size-1/\c==x/\c!=0/\c!=size-1) then %last row
( if((grid[r,c-1]+grid[r-1,c-1]+grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1])==3) then (grid[r,c] = 1)
elseif((grid[r,c-1]+grid[r-1,c-1]+grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]) ==2 ) then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r==x/\c==0/\r!=0/\r!=size-1) then %first col
( if ((grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]+grid[r+1,c+1]+grid[r+1,c])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r-1,c+1]+grid[r,c+1]+grid[r+1,c+1]+grid[r+1,c]) ==2) then (grid[r,c] = grid[r,c])
else (grid[r,c] = 0) endif
)
elseif (r==x/\c==0/\r!=0/\r!=size-1) then %last col
( if((grid[r-1,c]+grid[r-1,c-1]+grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c])==3) then (grid[r,c] = 1)
elseif((grid[r-1,c]+grid[r-1,c-1]+grid[r,c-1]+grid[r+1,c-1]+grid[r+1,c]) ==2)then(grid[r,c] = grid[r,c])
else(grid[r,c] = 0) endif
)
elseif (r!=0 /\ c!=x) /\ (r!=size-1/\c!=x)/\(r!=x/\c!=0)/\(r!=x/\c!=size-1) then %rest
(if(( grid[r-1,c-1] + grid[r-1,c] + grid[r-1,c+1] +
grid[r,c-1] + grid[r,c+1] +
grid[r+1,c-1] + grid[r+1,c] + grid[r+1,c+1]
)==3)then(grid[r,c] = 1)
elseif (( grid[r-1,c-1] + grid[r-1,c] + grid[r-1,c+1] +
grid[r,c-1] + grid[r,c+1] +
grid[r+1,c-1] + grid[r+1,c] + grid[r+1,c+1]
)==2 )then (grid[r,c] = grid[r,c])
else(grid[r,c] = 0)
endif
) /\ %endif
if (grid[r,0]==1 /\ grid[r+1,0]==1) then grid[r+2,0]=0 endif /\
if (grid[0,c]==1 /\ grid[0,c+1]==1) then grid[0,c+2]=0 endif /\
if (grid[size-1,c]==1 /\ grid[size-1,c+1]==1) then grid[size-1,c+2]=0 endif /\
if (grid[r,size-1]==1 /\ grid[r+1,size-1]==1) then grid[r+2,size-1]=0 endif
else r=r/\c=c
endif
)
/\
forall(r in board,c in board)(
if (grid[r,0]==1 /\ grid[r+1,0]==1) then grid[r+2,0]=0 endif /\
if (grid[0,c]==1 /\ grid[0,c+1]==1) then grid[0,c+2]=0 endif /\
if (grid[size,c]==1 /\ grid[size,c+1]==1/\ c<size-2/\c>1) then grid[size-1,c+2]=0 endif /\
if (grid[r,size]==1 /\ grid[r+1,size]==1 /\ r<size-2/\r>1) then grid[r+2,size-1]=0 endif
)
;
output [
if j = 0 then "\n" else " " endif ++
show(grid[i,j])
| i,j in board
]
;

Here is a general approach of summing the neighbors of the cells (and not including "this" cell). For each cell it defines a temporary variable (t) which sums the values of the neighbor cells. You then have to add the logic for different values of t.
int: r = 4; % rows
int: c = 4; % column
array[1..r, 1..c] of var 0..1: x;
constraint
forall(i in 1..r, j in 1..c) (
let {
var 0..r*c: t
}
in
t = sum(a,b in {-1,0,1} where
i+a in 1..r /\ j+b in 1..c % ensure we are in the matrix
/\ (a != 0 \/ b != 0) % don't include "this" cell
) (x[i+a,j+b])
)
;
solve satisfy;
Update: Here's the same model with a function sum_neighbors which calculates the number of neighbors of the specific cells.
int: r = 4; % rows
int: c = 4; % column
array[1..r, 1..c] of var 0..1: x;
function var int: sum_neighbors(int: i,int: j) =
sum(a,b in {-1,0,1} where
i+a in 1..r /\ j+b in 1..c /\ (a != 0 \/ b != 0)
) (x[i+a,j+b])
;
constraint
forall(i in 1..r, j in 1..c) (
let {
var 0..r*c: t
}
in
t = sum_neighbors(r,c)
)
;
solve satisfy;
You don't have to use the temporary t variable, I added it just to be able to test the model. You can now write stuff like
constraint
forall(i in 1..r, j in 1..c) (
if sum_neighbors(r,c) == 2 then
% ...
else
% ...
endif
)
;

Related

Merge sort in scilab

I implemented merge sort in scilab with the following code:
function x = mergesortre (x)
n = length (x);
if ( n > 1 ) then
m = floor (n/2);
p = n-m;
x1 = mergesortre ( x(1:m) );
x2 = mergesortre ( x(m+1:n) );
x = merge ( x1 , x2 );
end
endfunction
function [x] = merge ( x1 , x2 )
n1 = length (x1);
n2 = length (x2);
n = n1 + n2;
x = [];
i = 1
j = 1
k = 1
while(j<=n1 && k<=n2)
if x1(j)>=x2(k)
x(i)=x2(k);
k=k+1;
i=i+1;
elseif x1(j)<x2(k)
x(i)=x1(j);
j=j+1;
i=i+1;
end
end
if (j > n1) then
x(i+1:n) = x2(k:n2);
else
x(i+1:n) = x1(j:n1);
end
endfunction
a=[5,4,3,2,1];
x=mergesortre(a);
disp x;
However in when i try to see the sorted array using the terminal window its showing only the first element,for example if my array is [5,4,3,2,1] its only giving output as 1. I need help understanding what i did wrong.
Your error is in the merge function. As i is already incremented at the end of the loop you have to concatenate starting at i:
if (j > n1) then
x(i:n) = x2(k:n2);
else
x(i:n) = x1(j:n1);
end
A recursive algorithm needs a termination condition. There is no such condition in your function mergesortre. It's likely because the declaration of your function does not used the input argument x. Try to change it like this:
function [a] = mergesortre ( a )
I guess you wanted to use a as an input and output argument.

Image Transformation Without Loop

I am writing image transformation function in matlab instead of using predefined functions like 'imwarp or imtransform'. I am done with writing the code roughly but it is taking too long due to the use of loop.
Please suggest me a solution which can achieve the same result without loops
function I2 = f_transform(A, I1)
%A is an affine transformation matrix
%I1 is original image to be transformed
s=size(A);
if(s(1)~=3 || s(2)~=3)
disp("Invalid Transforming Matrix");
I2=0;
return;
end
if(det(A)==0)
disp("The given Transforming Matrix is Singular");
I2=0;
return;
end
[r, c]=size(I1);
extremeValues = [1 1 r r ; 1 c 1 c; 1 1 1 1];
newExtremeValues = A * extremeValues;
minRow = floor( min( newExtremeValues(1,:) ) );
maxRow = ceil( max( newExtremeValues(1,:) ) );
minCol = floor( min( newExtremeValues(2,:) ) );
maxCol = ceil( max( newExtremeValues(2,:) ) );
I2 = zeros(maxRow - minRow + 1, maxCol - minCol + 1);
for i = minRow:maxRow
for j=minCol:maxCol
b = A \ [i j 1]';
p = b(1) / b(3);
q = b(2) / b(3);
if(p >= 1 && p <= r && q >= 1 && q <= c)
I2(i - minRow + 1, j - minCol + 1) = I1(round(p),round(q));
end
end
end
I2 = uint8(I2);
return;
end

about Clamped cubic spline code in Matlab

I did the program, but for some reason it marks a mistake (c = tridiagonal ( hi(1:n-1), dd, hi(1:n-1), ri ); ) and I don't know why, I'm sure it's correct so please somebody help.
Here is the code:
function csc = cubic_clamped ( xi, fi, fpa, fpb )n = length ( xi );
m = length ( fi );
if ( n ~= m )
disp ( 'number of ordinates and number of function values must be equal' )
return
end
for i = 1 : n-1
hi(i) = xi(i+1) - xi(i);
end
dd(1) = 2.0*hi(1); dd(n) = 2.0*hi(n-1);
ri(1) = (3.0/hi(1))*(fi(2)-fi(1)) - 3.0 * fpa;
ri(n) = 3.0 * fpb - (3.0/hi(n-1))*(fi(n)-fi(n-1));
for i = 1 : n-2
dd(i+1) = 2.0 * ( hi(i) + hi(i+1) );
ri(i+1) = (3.0/hi(i+1))*(fi(i+2)-fi(i+1))-(3.0/hi(i))*(fi(i+1)-fi(i));
end
disp ( [dd' ri'] )
c = tridiagonal ( hi(1:n-1), dd, hi(1:n-1), ri );
d = zeros ( n,1 );
b = d;
for i = 1 : n-1
d(i) = (c(i+1)-c(i))/(3.0*hi(i));
b(i) = (fi(i+1)-fi(i))/hi(i) - hi(i)*(c(i+1)+2.0*c(i))/3.0;
end
if ( nargout == 0 )
disp ( [ xi' fi' b c' d ] )
else
csc = [ xi' fi' b c' d ];
end
tridiagonal code (error is: w = a(i) - b(i)*v(i-1); )
function y = tridiagonal( a, b, c, f )
n = length(f);
v = zeros(n,1);
y = v;
w = a(1);
y(1) = f(1)/w;
for i=2:n
v(i-1) = c(i-1)/w;
w = a(i) - b(i)*v(i-1);
y(i) = ( f(i) - b(i)*y(i-1) )/w;
end
for j=n-1:-1:1
y(j) = y(j) - v(j)*y(j+1);
end

Advanced Encryption Standard (AES) polynomial multiplication in octave / matlab

I am trying to perform polynomial multiplication as explained in the Advanced Encryption Standard (AES) draft.
Here's what I have so far:
function y = multiply_x2( a )
% a is a 1 x 8 binary vector
% y is a 1 x 8 binary vector
% t is a 1 x 8 binary vector corresponding to the "AES irreducible polynomial"
y = [ a(2:8) 0 ]; % Multiply byte 'a' by 2 using "left shift"
t = [ 0 0 0 a(1) a(1) 0 a(1) a(1) ]; % 't' only becomes the "AES irreducible
% polynomial" if a(1) == 1, otherwise
% it becomes the "zero" byte array
y = mod( y + t , 2 ) ; % XOR operation on y and t, as described in AES.
end
The code above is for
"y = {02} . a"
(where "{}" denotes hexadecimal notation, whose binary representation can be interpreted as the presense of the respective power of x in a polynomial. For example, {02} corresponds to 00000010, which corresponds to the polynomial "x", {06} would correspond to "x2+x", etc, as per the AES docs)
I want to multiply a with 0e , 09 , 0d, and 0b.
How will the code be for each of them? i.e. for:
"y= ( {0e} . a )"
"y= ( {09} . a )"
"y= ( {0d} . a )"
"y= ( {02} . a )"
This was an interesting problem. Here is a general solution for multiplication as defined in the AES doc you linked. I use the name xtime for the {02} multiplication, and I implement "addition" (xadd) as an XOR operation (i.e. !=) directly, since this is easier.
Helper functions:
%% in file isByte.m
function Out = isByte (a)
a = a(:).'; % ensure horizontal vector representation
if all (a == 0 | a == 1) && length (a) == 8; Out = true; return; end
Out = false;
end
%% in file byte2hex.m
function Out = byte2hex (a)
a = a(:).'; % ensure horizontal vector
assert (isByte (a), 'Input needs to be a valid "byte" array');
Out = sum (a .* ([2,2,2,2,2,2,2,2] .^ [7:-1:0])); Out = dec2hex (Out);
end
%% in file hex2byte.m
function Out = hex2byte (h)
assert (isxdigit (h) && hex2dec (h) < 256, 'Input needs to be a valid hex number below FF');
Out = dec2bin (hex2dec (h)); Out = sprintf ('%8s', Out);
Out = Out - 48 ; Out(Out == -16) = 0; % convert spaces to zeros
end
Polynomial functions:
%% in file xadd.m
function Out = xadd (a, b)
a = a(:).'; b = b(:).'; % ensure horizontal vector representations
assert (isByte (a) && isByte (b), 'Inputs need to be valid "byte" arrays');
Out = a != b;
end
%% in file xtime.m
function Out = xtime (a)
a = a(:).'; % ensure horizontal vector
assert (isByte (a), 'Input needs to be a valid "byte" array');
Out = [a(2 : 8), 0]; % left shift
if a(1) == 1
Out = xadd (Out, [0, 0, 0, 1, 1, 0, 1, 1]); % subtract (= add) the AES m(x) polynomial
end
end
% in file xmultiply.m
function Out = xmultiply (a, b)
a = a(:)'; b = b(:)'; % ensure horizontal vector representations
assert (isByte(a) && isByte(b), 'Inputs need to be valid "byte" arrays');
Out = [0,0,0,0,0,0,0,0];
if a == [0, 0, 0, 0, 0, 0, 0, 0] || b == [ 0, 0, 0, 0, 0, 0, 0, 0]; return; end
if b(8) == 1; Out = xadd (Out, a); end % yes this could be done recursively but, why bother.
if b(7) == 1; Out = xadd (Out, xtime (a)); end
if b(6) == 1; Out = xadd (Out, xtime (xtime (a))); end
if b(5) == 1; Out = xadd (Out, xtime (xtime (xtime (a)))); end
if b(4) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (a))))); end
if b(3) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (xtime (a)))))); end
if b(2) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (xtime (xtime (a))))))); end
if b(1) == 1; Out = xadd (Out, xtime (xtime (xtime (xtime (xtime (xtime (xtime (a)))))))); end
end
Example use: (same example as in the AES doc)
octave:1> a = hex2byte("57")
a =
0 1 0 1 0 1 1 1
octave:2> b = hex2byte("13")
b =
0 0 0 1 0 0 1 1
octave:3> c = xmultiply(a, b)
c =
1 1 1 1 1 1 1 0
octave:4> byte2hex(c)
ans = FE
In MATLAB/Octave, conv and deconv are respectively correspond to multiplication and (division/modulo) operations for polynomials.
function out = multiply(A, x)
mult = mod(conv(A,x), 2); % poynomial multiplication
[~, modulo] = deconv(mult, [1 0 0 0 1 1 0 1 1]); %modulo operation
out = mod(modulo(end-7:end) , 2); %extract last 8 bits
end
For example to multiply 0x57 and 0x13
a = [1 0 1 0 1 1 1]; %0x57
b = [1 0 0 1 1]; %0x13
result = multiply(a,b)
result =
1 1 1 1 1 1 1 0
that is binary representation of 0xFE
Thank you for your interest. I am trying to implement AES in matlab. And I found the solution in the pages of http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf . Here is the function for the y= ( {09} . a ) multiply operation ;
function y = multiply_x9( a )
% Multiply byte A by 9 over finite field of AES
y2 = multiply_x2( a ) ;
y4 = multiply_x2( y2 ) ;
y8 = multiply_x2( y4 ) ;
y = mod( y8 + a , 2 ) ;
end
And also for the any matrix multiplication multiply_xx (a, b, p ) function can be used. Here is the function;
function y = multiply_xx (a, b, p )
% Determine input lengths and check if they are equal
n = length( a ) ;
if ( n ~= length(b) ) ,
error( 'Operand input lengths not equal to each other!' ) ;
elseif ( n ~= length(p) ) ,
error( 'Operand input lengths not equal to modulus length!' ) ;
end
% Initialize result to zeros and start iteration row by row
y = zeros( 1 , n ) ;
for i = 1 : n ,
m = a(i) * b ;
y = mod( y(1) * p + [ y(2:n) 0 ] + m , 2 ) ;
end
end

Converting symbolic expression to function handle in Matlab R2013b

I am struggling to convert a function, which I require for my civil engineering project, from symbolic expression. I need to use fzero to find the root of the function. Here H should be the variable and I need to find out the value of H. The function goes like
function x_c = f_x_c(s,H0,VA,Lo,qc,EAo,NF,Sj,Fj)
if (s < 0) || (s > Lo)
disp('The value of s is invalid')
disp(['s = ' num2str(s)]);
return
end
C1 = H/qc;
if NF == 0
n = 0;
sn = 0;
sum_Fj = 0;
end
if NF >= 1
Sj_Q = [0; Sj; Lo];
%Determine n and sn if 0 <= s < Lo:
if s < Lo
STOP = 0;
k = 0;
while STOP == 0
k = k + 1;
if (s >= Sj_Q(k,1)) && (s < Sj_Q((k + 1),1))
STOP = 1;
end
end
n = k - 1;
sn = Sj_Q(k,1);
end
%Determine n and sn if s = Lo:
if s == Lo
n = NF;
sn = Sj(NF,1);
end
sum_Fj = sum(Fj(1:n,1));
end
x_c = (H/EAo)*s;
x_c = x_c + C1*asinh((qc*s - VA + sum_Fj)/H) + ...
- C1*asinh((qc*sn - VA + sum_Fj)/H);
for j = 1:n
sk = Sj_Q((j + 1),1);
sk_1 = Sj_Q(j,1);
sum_Fj = sum(Fj(1:(j - 1)));
x_c = x_c + ...
+ C1*asinh((qc*sk - VA + sum_Fj)/H) + ...
- C1*asinh((qc*sk_1 - VA + sum_Fj)/H);
end
I want to use this f_x_c.m file in the main file where I will find the roots of this equation.
Could someone guide me how I can do that?
I have tried doing it using the following code but I wasn't successful.
if (s < 0) || (s > Lo)
disp('The value of s is invalid')
disp(['s = ' num2str(s)]);
return
end
C1 = #(H) (H/qc);
if NF == 0
n = 0;
sn = 0;
sum_Fj = 0;
end
if NF >= 1
Sj_Q = [0; Sj; Lo];
%Determine n and sn if 0 <= s < Lo:
if s < Lo
STOP = 0;
k = 0;
while STOP == 0
k = k + 1;
if (s >= Sj_Q(k,1)) && (s < Sj_Q((k + 1),1))
STOP = 1;
end
end
n = k - 1;
sn = Sj_Q(k,1);
end
%Determine n and sn if s = Lo:
if s == Lo
n = NF;
sn = Sj(NF,1);
end
sum_Fj = sum(Fj(1:n,1));
end
x_c =#(H) (H/EAo)*s;
x_c =#(H) (x_c(H) + (C1(H))*asinh((qc*s - VA + sum_Fj)/H) + ...
- (C1(H))*asinh((qc*sn - VA + sum_Fj)/H));
for j = 1:n
sk = Sj_Q((j + 1),1);
sk_1 = Sj_Q(j,1);
sum_Fj = sum(Fj(1:(j - 1)));
x_c =#(H) (x_c(H) + ...
+ C1(H)*asinh((qc*sk - VA + sum_Fj)/H) + ...
- C1(H)*asinh((qc*sk_1 - VA + sum_Fj)/H));
end
Edit:
I want to solve the following equation in the main file:
equation = f_x_c(inext_length, H0, vertical_reaction, inext_length, qc, EAo, NF, hanger_arc_length, point_hanger_force) + 1400;
% Whatever equation f_x_c returns, I have to add another number to it(like here it is 1400), then solve this equation using fzero.
So, in the main file, I wrote like:
equation = #(H) f_x_c(inext_length, H0, vertical_reaction, inext_length, qc, EAo, NF, hanger_arc_length, point_hanger_force);
equation = #(H) (equation(H) + 1400);
answer = fsolve(equation, H0);
A mock answer to your question probably looks like
function x_c = f_x_c(H,A,B,C,D)
x_c = H*A;
x_c = x_c + B*asinh(C/H) - B*asinh(D/H);
end
and a call to solver is
H = fzero(#(H)(f_x_c(H,1,1,1,1)+1400),1);