How do I reassign even and odd indices of a character array into a new smaller character array in Matlab? - arrays

In matlab I have a 32x1 character array A such that
A = {'F1' 'F2' 'F3' 'F4' 'F5' 'F6' ... 'F32'};
A = A';
Now I am trying to do the following with A.
For every even index of A meaning
A{2}, A{4}, A{6}...
I want to assign those values to a 16x1 character array B and for the odd indices of A I want to assign those values to a different 16x1 array C.
I use the following code:
for i=1:32
if mod(i,2)==0
B{i} = A{i};
else
C{i} = A{i};
end
end
and it works, but only partially because it assigns the right values at for e.g. B{2} and B{4} but the values in B{1} and B{3} are the same as in B{2} and B{4}.
Can anybody tell me how to reassign even and odd indices of a character array into a new smaller character array? My problem is that I am going from a 32x1 into a 16x1 and I'm not sure how to avoid the extra 16 entries.
Many thanks!

To get this question actual answered, use the idea of Luis Mendo in the comments. You can combine it with deal to save one line of code:
[B, C] = deal(A(2:2:end), A(1:2:end))
To make your loop work, you need a second running index jj:
A = {'F1' 'F2' 'F3' 'F4' 'F5' 'F6'};
for ii = 1:6
jj = ceil(ii/2);
if mod(ii,2)==0
B{jj} = A{ii};
else
C{jj} = A{ii};
end
end

Related

Subscripted assignment dimension mismatch when combining corresponding array and cell array values in matlab

I have an array and a cell array with the same dimensions: A is a 1x2492 double array, and B is an 1x2492 cell cell array. I want to make a new cell array that assigns the values in A to the corresponding column values of B. Here was my code:
for n = 1:numel(B)
newArray(n) = [A(n),B{n}(2)];
newCellArray{n} = newArray;
end
When I ran the code, I got the error 'Subscripted assignment dimension mismatch.'
I think it's because some cells in B have multiple columns, and the code loop doesn't recognize that I want to assign the same value of A to all values in the cell.
For example, if cell 1 of B contains:
2 2355
23 1293
37 1222
I would like my code loop to assign the corresponding first value of A to 2355, 1293, and 1222. So basically, I'd like to have a new cell like this:
1 2355
1 1293
1 1222
I realize that this is a very confusing explanation, but I hope that it makes sense. Any and all help would be greatly appreciated - thank you very much!
I am not really sure what you are trying to do, but the code below will assign the value of A(ii) to every element in the first column of B{ii}. I am just saying this based on your example, but your explanation is really unclear..
C = B;
for ii=1:numel(C)
C{ii}(:,1)=A(ii);
end
And you are getting an error on newArray(n) = [A(n),B{n}(2)]; because you are trying to assign a vector to a singleton dimension. Try a(1) = [1 2] and you will still get an error, and this is independent on what your cell dimensions are, etc.. a(1,:)=[1 2], however, might work if the 2nd dimension of a is 2.
Try:
newCellArray = cell(numel(B),2);
for n = 1:numel(B)
lenB = length(B{n}(2));
newA = repmat(A(n),lenB);
newArray = [newA,B{n}(2)];
newCellArray = [newCellArray; newArray];
end

Matlab array storing through loop

I have a for loop and each value a{i} b{i} c{i} is equal each time with a specific number. So I was wondering how can I put all those value in an array through loop. The way that I am using I mean this one [a{i};b{i};c{i}] it seems that it doesn't work! If I keep 2 out of three values is working but I want the data from all of the values (a b c)
You can see the (pseudo)code below:
for i=1:number of cells
Cell{i}.Tri=[a{i};b{i};c{i}]
end
cell2mat is what you need:
a = num2cell(rand(1,10));
b = num2cell(rand(1,10));
c = num2cell(rand(1,10));
abc = cell2mat([a;b;c]);
This can be done without a for loop by using cellfun combined with the cat function. EDIT: As noted in the comments, cellfun is itself a loop.
% Create all variables
a{1}=rand(10);
a=repmat(a,10,1);
b=a;
c=a;
% Add a cell array of equal size to a. The contents of each cell are the dimension along which to concatenate.
catarg=num2cell(ones(size(a)))
% Do the concatenation
d=cellfun(#cat,catarg,a,b,c,'UniformOutput',false);

Matlab replacing 0 with empty cell in Cell array

I have a 10,000 x 65 Cell with 0's and 1's so for example if I type
C(1,1) I get [0] returned or likewise C(3,4) a [1] is returned
I need a way to turn every 0 into a blank cell and every 1 into a char t
I've tried the following with little success
[rows, cols] = size(M);
for i = 1:rows
for j = 1:cols
if strcmp(M(i,j), 1)
M(i,j) = 't';
end
end
end
It returns the same thing, I'm guessing its not recognising the 1's as strings. Any idea sort of simply doing the conversion straight in Excel.
thanks
You are not accessing the cell data-structure correctly.
First of all, if M really is a cell array, you will have to use M{i,j} to access the data.
What M(i,j)does is just create a sub-cell-array, which contains M{i,j} as entry.
Also strcmp isn't used correctly, if your cell array contains strings you should use strcmp(M{i,j}, '1').
If your cell array on the other hand contains integers, you would have to use: M{i,j}==1.

Concatenating 1D matrices of different sizes

I perhaps am going about this wrong, but I have data{1}, data{2}...data{i}. Within each, I have .type1, .type2.... .typeN. The arrays are different lengths, so horizontal concatenation does not work.
For simplicity sake
>> data{1}.type1
ans =
1
2
3
>> data{2}.type1
ans =
2
4
5
6
Results should be [1;2;3;2;4;5;6]
I've been trying to loop it but not sure how? I will have a variable number of files (a,b..). How do I go about looping and concatenating? Ultimately I need a 1xN array of all of this..
My working code, thanks..figured it out..
for i = 1:Types
currentType = nTypes{i}
allData.(currentType)=[];
for j = 1:nData
allData.(currentType) = [allData.(currentType); data{j}.(currentType)(:,3)]; %3rd column
end
end
Look at cat, the first argument is the dimension. In your simple example it would be:
result = cat(1,a,b);
Which is equivalent to:
result = [a;b];
Or you can concatenate them as row vectors and transpose back to a column vector:
result = [a',b']';
For the case of a structure inside a cell array I don't think there will be any way around looping. Let's say you have a cell array with M elements and N "types" as the structure fields for each element. You could do:
M=length(data);
newData=struct;
for i=1:M
for j=1:N
field=sprintf('type%d',j); % //field name
if (M==1), newData.(field)=[]; end % //if this is a new field, create it
newData.(field)=[newData.(field);data{i}.(field)];
end
end

Is there a more efficient way of choosing an element from 1 array and to every element of the same array

I want to, for every element of an array ZAbs, compare it for equality to every element of the array itself and put them into another distinct array. I want the distinct array's elements to have the same index as the ZAbs array.
I did this by creating 4 nested for loops:
for pAbs2 = 1:400
for qAbs2 = 1:300
zAbsCompare = ZAbs(qAbs2, pAbs2);
for pAbs3 = 1:400
for qAbs3 = 1:300
zAbsCompare2 = ZAbs(qAbs3, pAbs3);
if (zAbsCompare == zAbsCompare2)
InitialZModEqualsImag(pAbs2,qAbs2) = InitialZImag(qAbs2, pAbs2);
InitialZModEqualsReal(pAbs2,qAbs2) = InitialZReal(qAbs2, pAbs2);
end
end
end
end
end
However, this runs really slowly. I can't think of a better way to do this, but as I'm inexperienced with MATLAB there's probably something I'm overlooking here. Any help?
EDIT: Fixed an error and restated the question.
You can do the comparison (not sure that's what you want) efficently with bsxfun:
comp = bsxfun(#eq, X, shiftdim(X,-2));
The result comp(m,n,p,q) is 1 if X(m,n) == X(p,q), and 0 otherwise.

Resources