Take a random set of coordinates (x, y, z) that will be the center of my 3x3x3 matrix( considered local minimum as well). I have a function J that takes those coordinates, does the calculations and returns me a number. If any of those 26 points will be smaller, that would be the center for my next matrice. In case I don't find a smaller value, the radius of the matrice is increased by 1, and we run the loop again. My question is : how to loop only through the "shell" of the cube and not call the function for the previously tested values?
I tried to illustrate it below ( it's in 2d here, but you get the point) .. the dots are the values that were tested, the "?" are the ones that need to be calculated and compared to the local min.
here is the code
minim=100;
%%the initial size of the search matrix 2*level +1
level=1;
x=input('Enter the starting coordinate for X : ');
y=input('Enter the starting coordinate for Y : ');
z=input('Enter the starting coordinate for Z : ');
%%The loop
if(level<=10)
for m=x-level:x+level
for n=y-level:y+level
for p=z-level:z+level
A(m,n,p)=J(m,n,p);
if A(m,n,p)<minim
minim=A(m,n,p);
x=m;y=n;z=p;
level=1;
else
level=level+1;
%<<----shell loop here ---->>
end
end
end
end
else
%Display global min
display(minim, 'Minim');
%Coordinates of the global min
[r,c,d] = ind2sub(size(A),find(A ==minim));
display(r,'X');
display(c,'Y');
display(d,'Z');
end
Here is a simple C++ solution
This is a 5x5x5 cube represented 2D:
a[i][j][0]
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
a[i][j][1]
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
a[i][j][2]
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
a[i][j][3]
1 1 1 1 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 1 1 1 1
a[i][j][4]
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
And here is the code for cube parse:
int a[5][5][5]
int matrix_size = 2*level+1;
for(int z=0;z<matrix_size;z++)
if(z==0 || z= matrix_size-1)
{
for(int i=0;i<matrix_size-1;i++)
for(int j=0;j<matrix_size-1;j++)
{
//compare minim with a[i][j][z];
}
}
else
for(int i=0;i<matrix_size-1;i++)
{
if(i==1 || i==matrix_size-1)
{
for(int j=0;j<matrix_size-1;j++)
//compare minim with a[i][j][z];
}
else
{
//compare minim with a[i][1][z] and a[i][matrix_size-1][z];
}
}
You can use logical indexing, I'm not sure however if you will gain speed by doing so. The reconstruction of the location of the min is a bit awkward, but like this you get rid of all the for loops.
A = rand(7,7,7);
%"shell" mask for extraction
B = ones(5,5,5);
B = padarray(B,[1,1,1]);
B = logical(abs(B-1));
[val, ind] = min(A(B))
%reconstruct location
tmp = zeros(1,sum(B(:)));
tmp(ind) = 1;
C = zeros(size(A));
C(B) = tmp;
[~, ind] = max(C(:));
[r,c,d] = ind2sub(size(A),ind);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With