Matlab For loop for matrix shell only

Take a random set of coordinates (x, y, z) that will become the center of my 3x3x3 matrix (also consider a local minimum). I have a J function that takes these coordinates, performs calculations, and returns me a number. If any of these 26 points is less, this will become the focus for my next matrix. In case I do not find a smaller value, the radius of the matrix increases by 1, and we start the cycle again. My question is: how to quote only through the "shell" of the cube and not call the function for previously checked values?

I tried to illustrate this below (this is in 2d here, but you understand). Dots are those values ​​that have been checked, "?" these are the ones that need to be calculated and compared with the local minimum.

enter image description here

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 
+5
source share
3 answers

Here is a simple solution in C ++

This is a 5x5x5 cube represented by 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 to analyze the cube:

 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]; } } 
+1
source

You can use boolean indexing, but I'm not sure if you get speed, do it. Reconstruction of the location of mines is a little inconvenient, but that's how you get rid of all cycles.

 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); 
+1
source

Here is one way you can cover all the shell elements in one loop:

 clear; %// a cube matrix to play with A=nan(5,5,5); n=length( A(:,1,1) ); %// Assuming cube matrix %// lets change all ot the "shell" elements to 1 for i=1:n % 1st and nth level A(1,i,1)=1; A(i,1,1)=1; A(n,i,1)=1; A(i,n,1)=1; A(1,i,n)=1; A(i,1,n)=1; A(n,i,n)=1; A(i,n,n)=1; % 2nd to (n-1)th level A(1,1,i)=1; A(1,n,i)=1; A(n,1,i)=1; A(n,n,i)=1; end 

Note that corner elements are reached more than once. resulting matrix:

 >> A A(:,:,1) = 1 1 1 1 1 1 NaN NaN NaN 1 1 NaN NaN NaN 1 1 NaN NaN NaN 1 1 1 1 1 1 A(:,:,2) = 1 NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN 1 A(:,:,3) = 1 NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN 1 A(:,:,4) = 1 NaN NaN NaN 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 NaN NaN NaN 1 A(:,:,5) = 1 1 1 1 1 1 NaN NaN NaN 1 1 NaN NaN NaN 1 1 NaN NaN NaN 1 1 1 1 1 1 
+1
source

Source: https://habr.com/ru/post/1243589/


All Articles