1

I need to pre-allocate arrays in my code below. I don't quite understand how to pre-allocate arrays in multi-loop iteration.

a=0:1:2;
b=0:1:2;
c=0:1:2;
xx1=[];yy1=[];zz1=[];xx2=[];yy2=[];zz2=[];

for k=1:length(c)-1;
    z1=c(k);    z2=c(k+1);
    for w=1:length(b)-1;
        y1=b(w);        y2=b(w+1);
        for q=1:length(a)-1;
            x1=a(q);            x2=a(q+1);
            xx1=[xx1;x1];            xx2=[xx2;x2];
            yy1=[yy1;y1];            yy2=[yy2;y2];
            zz1=[zz1;z1];            zz2=[zz2;z2];
        end
    end
end

The expected results are:

[xx1 xx2 yy1 yy2 zz1 zz2]

ans =

     0     1     0     1     0     1
     1     2     0     1     0     1
     0     1     1     2     0     1
     1     2     1     2     0     1
     0     1     0     1     1     2
     1     2     0     1     1     2
     0     1     1     2     1     2
     1     2     1     2     1     2
paisanco
  • 4,098
  • 6
  • 27
  • 33

1 Answers1

1

Increase a counter in the innermost loop to keep track of which entry of xx1 etc you should fill.

a = 0:1:2;
b = 0:1:2;
c = 0:1:2;
xx1 = NaN((length(a)-1)*(length(b)-1)*(length(c)-1),1); %// preallocate 
xx2 = NaN((length(a)-1)*(length(b)-1)*(length(c)-1),1); 
yy1 = NaN((length(a)-1)*(length(b)-1)*(length(c)-1),1);
yy2 = NaN((length(a)-1)*(length(b)-1)*(length(c)-1),1); 
zz1 = NaN((length(a)-1)*(length(b)-1)*(length(c)-1),1); 
zz2 = NaN((length(a)-1)*(length(b)-1)*(length(c)-1),1);
n = 0; %// initiallize counter
for k=1:length(c)-1;
    z1=c(k);    z2=c(k+1);
    for w=1:length(b)-1;
        y1=b(w);        y2=b(w+1);
        for q=1:length(a)-1;
            n = n + 1; %// increase counter;
            x1 = a(q);           
            x2 = a(q+1);
            xx1(n) = x1; %// fill values
            xx2(n) = x2;
            yy1(n) = y1;
            yy2(n) = y2;
            zz1(n) = z1;
            zz2(n) = z2;
        end
    end
end

Anyway, it can be done without loops, adapting the procedure given in this answer. This has two advantages:

  • It may be faster if a, b, c are large.
  • The same code works for any number of vectors, not just 3. Simply define vectors1 and vectors2 accordingly in the code below.

Code without loops:

a = 0:1:2;
b = 0:1:2;
c = 0:1:2;
vectors1 = { a(1:end-1), b(1:end-1), c(1:end-1) };
vectors2 = { a(2:end), b(2:end), c(2:end) };
n = numel(vectors1);
combs1 = cell(1,n);
[combs1{:}] = ndgrid(vectors1{end:-1:1});
combs1 = reshape(cat(n+1, combs1{:}),[],n);
combs2 = cell(1,n);
[combs2{:}] = ndgrid(vectors2{end:-1:1});
combs2 = reshape(cat(n+1, combs2{:}),[],n);
result(:,2:2:2*n) = combs2;
result(:,1:2:2*n) = combs1;
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147