Fill an array after a for loop

Hi, given the following code
v = [1 2 3 4 1];
P = unique(perms(v),'rows');
nraw = size (P,1);
G=zeros()
for i=1:nraw
x=P(i,:)
n=length(x);
f = zeros(1,n);
for k = 1:n
if x(k) == 1
f(1,k) = 1;
elseif x(k)==2
f(1,k) = 2;
elseif x(k)==3
f(1,k)= 3;
elseif x(k)==4
f(1,k) = 4;
elseif x(k)==5
f(1,k)= 1;
end
end
G(i,:)=x(i,:)
end
I would like to fill the matrix G with every raw x that undergoes through the for cycle.
but I receive the followign error:
Unable to perform assignment because the size of the left side is 1-by-1 and the size of the
right side is 1-by-5.
Error in
G(i,:)=x(i,:)
Does someone know where the problem is? and why is not working?
Thanks

 Accepted Answer

Stephen23
Stephen23 on 25 Jul 2019
Edited: Stephen23 on 25 Jul 2019
These two changes make the code run without error:
G = zeros(nraw,numel(x));
and
G(i,:) = x;
Whether it is correct only you can decide.
"Does someone know where the problem is? and why is not working? "
In several parts of your code you are trying to use indexing to acess array elements that do not exist. For example:
1. you defined G to be a scalar numeric (using some rather obfuscated code):
>> G = zeros()
G = 0
then later you try to allocate a 1x5 array to a 1x1 element (remember that G only has one column):
G(i,:)=x(i,:)
% ^^^ indexing 1 row and all columns of G, i.e. 1 row & 1 columm
% ^^^^^^ on first iteration has size 1x5, i.e. 1 row and 5 columns
2. you defined x to be a row vector (i.e. an array with size 1xN):
x=P(i,:);
and then later you try to access the i-th row of a that array:
G(i,:)=x(i,:)
When you try to access the second row of an array that only has one row, then you get an error. What do you expect MATLAB to do when you try to access non-existent rows of an array?
PS: Note that your entire code concept is likely far too complex. You can replace the entire f definition (loop and everything) with one simple indexing operation. The values that you allocate to f seem to be the same as those in v (except that you hard-coded them). Is that just a coincidence? Why not just use indexing?

5 Comments

Hi Stephen, thanks for your accurate answer.
For what concerne
"The values that you allocate to f seem to be the same as those in v (except that you hard-coded them)"
v and f are slightly different vector. What i'm trying to do is to assign an attribute to each element of the vector v. For example, if v=[1 2 3 4 1 3 2 4 5], i need that 1 and 4 have attribute A. 2 and 5 have attribute B. 3 has attribute C. and so obtain the vector [A B C A A C B A B], that I will use for a switch case.
With the code
c=['A':'Z'].'; % the population of categorical labels
u=unique(v); % unique elements in initial vector
V = categorical(v,u,cellstr(c(u)));
I can obtain only [A B C D A C B D E]. that is not what i want.
So with the for loop, I have created before the new vector f=[1 2 3 1 1 3 2 1 2]. where 4 has been substituted with 1 and 5 with 2.
and then applying again
c=['A':'Z'].'; % the population of categorical labels
u=unique(f); % unique elements in initial vector
V = categorical(f,u,cellstr(c(u)));
I obtain what I want
[A B C A A C B A B].
I know that is not the optimal one. but it works. Do you know a faster way? maybe using another solution.
"v and f are slightly different vector"
Sure, but I was not talking about f (whose values are not hard-coded). I was talking about the hard-coded values that you are assigning to f, which are exactly a duplicate of the values in v, in exactly the same order. The coincidence is rather obvious.
"Do you know a faster way? maybe using another solution."
Indexing:
>> v = [1,2,3,4,1,3,2,4,5];
>> C = 'ABCAB'; % 1 and 4 have attribute A. 2 and 5 have attribute B. 3 has attribute C
>> C(v)
ans = ABCAACBAB
luca
luca on 25 Jul 2019
Edited: Stephen23 on 25 Jul 2019
I think I've the last question to fix all. And so avoiding to write f. I need to use C in a switch case. To do so I've write the following
v = [1,2,3,4,1,3,2,4,5];
C = 'ABCAB'; % 1 and 4 have attribute A. 2 and 5 have attribute B. 3 has attribute C
S = C(v)
n=length(S);
TA=3;
TB=3;
TC=3;
TD=2;
for i=1:n
%G=zeros(nraw,numel(x))
switch S(i)
case 'A'
TA= TA-1;
case 'B'
TB= TB-1;
case 'C'
TC= TC-1;
case 'D'
TD= TD-1;
otherwise
disp ('qwert');
end
end
S turn to be 'ABCAACBAB'
the problem is that during iteration, the switch cycle read S but skip the first A. In reality debugging and looking at Workspace, the first value of TA when I run the cycle is immediately 2 and not 3. Maybe matlab hide the first iteration. Do you know why? How it works?
Thanks for your help Stephen, I'm realy a beginner.
"Maybe matlab hide the first iteration"
MATLAB does not "hide" loop iterations.
I have no idea what the problem is (because you did not explain it): I copied your code, removed the semi-colons from all lines that define TA (which is what I guess you are referring to when you write "A"), and this is what is displayed:
TA = 3 % initial assignment
TA = 2 % 1st loop iteration
TA = 1 % 2nd loop iteration
TA = 0 % 3rd loop iteration
TA = -1 % 4th loop iteration
Given that 'A' occurs exactly four times in S:
>> nnz('A'==S)
ans = 4
this is exactly what I would expect: you define TA to be 3, then four times you subtract 1, thus giving a final value of 3-4 = -1. So far MATLAB seems to agree with the basic rules of arithmetic.
What do you expect to occur?
Thanks Stephen. You are right! Now it workd!
THANKS for your help!

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Release

R2019a

Asked:

on 25 Jul 2019

Commented:

on 25 Jul 2019

Community Treasure Hunt

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

Start Hunting!