Alternative for nested for loop
    15 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    Fawad Khan
      
 el 20 de Feb. de 2021
  
    
    
    
    
    Comentada: Fawad Khan
      
 el 23 de Feb. de 2021
            I need to implement this logic to make combinations of a matrix. This code is a bit cumbersome since I need to add more rows and columns at some point. Is there a simpler way to do this?
k = 0;
for x1 = 1:2
    for x2 = 1:2
        for x3 = 1:2
            for y1 = 1:2
                for y2 = 1:2
                    for y3 = 1:2
                        for z1 = 1:2
                            for z2 = 1:2
                                for z3 = 1:2
                                    k = k+1;
                                    JV{k} = [J1(1,x1),J2(1,x2),J3(1,x3);
                                        J1(2,y1),J2(2,y2),J3(2,y3);
                                        J1(3,z1),J2(3,z2),J3(3,z3)];
                                end
                            end
                        end
                    end
                end
            end
        end
    end
end
J1, J2 & J3 are 3x2 matrices.
1 comentario
  Rik
      
      
 el 20 de Feb. de 2021
				You can probably use a function that generates all permutations to simplify this. Maybe even ndgrid could help you out.
Respuesta aceptada
  Adam Danz
    
      
 el 20 de Feb. de 2021
        
      Editada: Adam Danz
    
      
 el 21 de Feb. de 2021
  
      > Is there a simpler way to do this?
As long as you're preallocating the JV cell array, your approach is very simple, fast, and readable.  The alternative below does the same thing but is much less readable and it's slower (there may be faster ways than mine). 
However, depending on how you're using the JV cell array, it may be more efficient to pack those values into a 3D array instead.  So, my recommendations are 
- keep the nested loops; it's fast, readable, and simple.
- definitely preallocate the JV variable whether you're using a cell array or 3D array.
- Consider using a 3D array for JV.
% Demo values; J1 J2 and J3 must be the same size
J1 = [1:3;4:6]';
J2 = J1.*10;
J3 = J2.*10;
allJ = cat(3,J1, J2, J3);  % 3x2x3 
colidx = flipud(combvec(1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2,1:2)); % * see note
rowidx = repmat([1 1 1 2 2 2 3 3 3]', 1, size(colidx,2));
pageIdx = repmat([1 2 3 1 2 3 1 2 3]', 1, size(colidx,2));
ind = sub2ind(size(allJ), rowidx, colidx, pageIdx);
JVec = allJ(ind); 
JArray = permute(reshape(JVec, 3,3,[]),[2,1,3]); % you could stop here and use a 3D array
JV = arrayfun(@(page){JArray(:,:,page)}, 1:size(JArray,3));
I ran your nested conditional version with the same inputs and confirmed that both methods produce the same results.  
6 comentarios
  Adam Danz
    
      
 el 23 de Feb. de 2021
				
      Editada: Adam Danz
    
      
 el 23 de Feb. de 2021
  
			I disagree with the documentation that those statements are equivalent (btw @Fawad han I edited your comment to fix the broken URL). 
1. Problems when cell array size decreases
Here's an example of what Rik said. 
for i = [ 5 4 3];
    c{1,i} = [];
    disp(numel(c))
end
Compare that to 
for i = [ 5 4 3];
    c = cell(1,i);
    disp(numel(c))
end
2. Problems when var already exists but isn't a cell array
c = 1:20; 
c{1,5} = []
But this works, 
c = cell(1,5)
  1×5 cell array
    {0×0 double}    {0×0 double}    {0×0 double}    {0×0 double}    {0×0 double}
Más respuestas (0)
Ver también
Categorías
				Más información sobre Matrix Indexing en Help Center y File Exchange.
			
	Productos
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


