How to pre-allocate a matrix (from cell) when dimensions change

Dear all,
B is a 1x3 cell. The 1st element is empty (it doesn't matter because my loop will start at position 2). the other elements are 218x2 and 266x2.
I have a loop that is meant to do 'stuff', resulting in a vector 'cofcoefvector' that is 2X13. What I'm doing is partly correct, partly because row 1 and row 2 have the same values (the values are correct for r=3). Somehow, I repeat the operation. I think that's because I over-write C (see below) in the loop, and that because I haven't indexed it. I haven't done so, because I'm not able to.
for r = 2: size(B,2);
C=cell2mat(B(r));
for m=1:size(A,2);
j=A(m);
tempmat1 = corrcoef(bpassf(C(:,2),6,32),lagmatrix(bpassf(C(:,1),6,32),j),'rows','complete');
for row=1:size(corcoefvector,1);
corcoefvector(row,m) = tempmat1(1,2); %this puts the same results in both rows. why?
end
end %this is the end of for t = etc, but it just creates 2 identical copies
end
I thought that was because I (think, going through questions asked before on related issues) over-write C (see above) in the loop, and that because I haven't indexed it. I haven't done so, because I'm not able to.
So I took the largest dimension of the content of B, that is, 266x2 and pre-allocate C before the loop, so
C = zeros(266,2);
and change C=cell2mat(B(r)); to C(r)=cell2mat(B(r));
To no avail, I get 'Unable to perform assignment because the left and right sides have a different number of elements.'
Any thougths?

Antworten (1)

Jan
Jan am 24 Jul. 2021
Simplify
C=cell2mat(B(r));
to
C = B{r};
This creates a cheap shared data copy, so C does not occupy additional memory: it re-uses the data of B{r}. Therefore a pre-allocation is not useful here.
I do not see a reason to collect the diffent values of C by
C{r} = B{r};
because then C and B contain identical elements.

3 Kommentare

Jan,
Modifying that doesn’t actually make any difference.
Also, C contains B(1,2). C and B, in fact, shouldn’t have the same elements. B(1,1) is a 218x2 double, B(1,2) is a 266x2 double.
I got rid of the 1st, empty element of B, to avoid confusion. Now, obviously, r runs from 1 to 2, rather than starting from 2.
Corcoefvector is 2x13 row vector, filled by zeros before the loop.
The loop fills both rows of corcoefvector with the same values, the value computed by the line tempmat1 = corrcoef(etcetera), and which correspond to the contents of B(1,2) (whereas there should be a set of a values from B(1,1) in row 1 and a different set from B(1,2) in row 2).
To sum up, the 1st for loop should look up the different elements of cell B, first B(1,1) then B(1,2).
The 2nd for loop runs from -6 to 6 (lags and leads) to compute some correlation coefficients.
The 3rd loop should grab the relevant results from tempmat1 (tempmat1(1,2)) and place it in corcoefvector -it puts them in the right place in terms of m, the columns, but not in terms of rows. It seems to just perform the operation for B(1,2) and places the results twice, so row 1 and row 2 of corcoefvector is identical.
I think the problem -that I can’t identify- is in the two 1stlines of the piece of code posted, but the change you suggested doesn’t address it.
I’ve been repetitive and pendantic in my explanations to try and convey as much information as possible.
Jan
Jan am 26 Jul. 2021
Bearbeitet: Jan am 26 Jul. 2021
Simplifying cell2mat(B(r)) to B{r} does not solve any problem, but the code gets nicer and faster. This was a general hint only.
Pre-allocating C before the loop is not useful. Most of all:
C = zeros(266,2);
C(r) = cell2mat(B(r));
% Or with my nicer and cheaper code suggestion:
C(r) = B{r};
cannot work, because C(r) is a scalar, but B{r} contains a matrix.
Your explanations still did not clarify, why
C = B{r};
does not satisfy your needs.
You've asked:
for row=1:size(corcoefvector,1);
corcoefvector(row,m) = tempmat1(1,2); %this puts the same results in both rows. why?
end
tempmat1(1,2) is a scalar value. Of course you write it to all elements of corcoefvector(row, m).
By the way, this loop can be avoided also. Faster and easier:
corcoefvector(:, m) = tempmat1(1,2);
Summary: A simplified version of the complete code:
for r = 2:numel(B);
C = B{r};
for m = 1:size(A,2);
j = A(m);
temp = corrcoef(bpassf(C(:,2), 6, 32), ...
lagmatrix(bpassf(C(:,1), 6, 32), j), 'rows', 'complete');
corcoefvector(:, m) = temp(1, 2);
end
end
What do you want to change now?
Hi Jan,
You're absolutely right, it IS much faster.
C = B{r}; puts into C only the data that is in B{1,2}.
B{1,1} and B{1,2} each contain two matrices, of different row size. Corcoefvector has two rows because I want to store in each the correlation coefficients computed for the data in B{1,1} and B{1,2}.
However, somehow, I only seem to perform this for B{1,2}. However much I fiddle, I can't seem to alter that.
Your simplified (and faster) version also does that, except that now corcoefvector has one row.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Loops and Conditional Statements finden Sie in Hilfe-Center und File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by