2

I want to assign some values to a matrix in a loop, but I don't know how many. B is a vector that's calculated based on a data set Data(i,:) inside a loop. The number of elements in B is fixed inside the loop, but is unknown beforehand.

It is like;

A = zeros(n,m) %// I know n but I do not know m
for i = 1 : n
    % some code to calculate B from Data(i,:)
    A(i,:) = B;
end

B is a vector, but I don't know length(B) before the loop so I can't assign it to m.
When I initialize A = [];, Matlab gives a warning

A appears to change size in every loop iteration.

Shai
  • 111,146
  • 38
  • 238
  • 371
Rashid
  • 4,326
  • 2
  • 29
  • 54

2 Answers2

6

If B has a fixed length, one alternative is:

A = zeros(n,[]);
for ii = 1:n
   A(ii,1:numel(B)) = B;
end

This way you will preallocate the number of rows, and after the first iteration, the number of columns will be fixed as numel(B).

So, why does A(ii,1:numel(B)) = B work and A(ii,:) = B doesn't?

When you do A(ii,:) = B, you're trying to place the vector B in row number ii of A. For this to work, the number of columns must be equal in A and B. You can think of it as:

A(ii,:) = B

is equal to

A(ii,1:end) = B(1:end); 

If you start out with an empty array A, or an array with n rows, but zero columns, the two ends won't be equal and you will get a dimension mismatch.

If, however, you do A(ii,1:numel(B)) = B, you specifically say that you're trying to place the vector B in the columns 1 to m in row number ii in A. Now, since B has more columns than A, MATLAB will auto-pad the remaining matrix with zeros.

You can try some yourself. Don't copy-paste, try one after the other so that you can see how A changes after each line. Hope this clears things up!

A = []
A(2,1) = 3
A(1,3) = 2
A(3,:) = [5 6 7]
A(:,6) = [1; 2; 3]
A(3,:)
A(3,1:end)
A(:,3)
A(1:end,3)
Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
  • 1
    @Kamtal, Glad I could help! I gave some examples in the end that works. You might learn a lot by trying things you don't necessarily expect to work. You often learn more from error messages that from working code. Try for instance `A = [6 7 8 9]`, `A(1:0)`, `A(1:5)`, `A([1 1 2 1 1 2])`, `A([1 0 1 0])` and `A(logical([1 0 1 0])`. Try to understand what's happening. What happens if you do: `A(logical([1 0 0])` (three elements instead of four)? – Stewie Griffin Oct 20 '14 at 20:38
2

You can also reverse the order of your loop, without any pre-allocation

for ii=n:-1:1
    A(ii,:) = B;
end

This way, the first time A is accessed Matlab actually access the last row and therefore knows exactly the final size of A, A will not change size during iterations.

See this trick in this thread.

PS,
It is best not to use i as a variable name in Matlab.

Community
  • 1
  • 1
Shai
  • 111,146
  • 38
  • 238
  • 371