Matlab cell array element assignment - matlab

>> v1
[0.6324] [0.0975] [0.2785]
>> c1
[0.8147] [0.9058] [0.1270] [0.9134]
>> c1{1:3} = v1{1:3}
I get the following error message:
The right hand side of this assignment has too few values to satisfy
the left hand side.
Here c1 and v1 are both simple cell arrays, ie, both have simple numerical values. Then, why shouldn’t this work?

When using curly brackets {}, you are extracting the values of the cells. Use normal brackets () to refer to a set of cells and therefore keep the cells without extracting the actual content. So the following line will assign the cells (not the values inside the cells) from the right hand side to the left hand side:
c1(1:3) = v1(1:3)
We can check the datatype of c1(1:3) easily and see that it is in fact a cell-array:
>> A = c1(1:3)
A =
[1] [2] [3]
>> class(A)
ans =
cell
To see that curly brackets {} extract the values itself, we can do the following and see that the datatype of B is double:
>> B = c1{1}
B =
1
>> class(B)
ans =
double
As #Dan mentions in his comment, v1{1:3} gives you a comma-separated list of three separate doubles. You can notice that by seeing three ans = using the command line, because all the values will be returned individually:
>> v1{1:3}
ans =
1
ans =
2
ans =
3
Following that, you can do the assignment in a different way, which I do not recommend. The following provides three elements on the LHS by using the concatenation operator [] , the RHS provides three elements as well as we saw above.
>> [c1{1:3}] = v1{1:3}
c1 =
[1] [2] [3] [7]

Related

MATLAB: A{:} vs A(:) when A is a cell array

If A is a cell array in MATLAB, I wanted to learn the difference between A{:} and A(:) and where I should them.
As you can read in official documentation, the former refers to indexing a set of cells in the array (actually, all of them) and the latter refers to indexing a set of underlying values in the array (again, all of them).
Cell arrays are nothing but homogenic arrays whose elements are all cells, and cells have an underlying value that can be of any type. Round parentheses simply access the cells (the wrapping objects of the underlying values), while curly braces access the elements wrapped by the cells themselves (the underlying values).
Let's make a quick example. Round parentheses will return a cell array, since a single colon operator (:) is used and the matrix is flattened:
A = {1 2; 3 4};
A(:)
ans =
4×1 cell array
[1]
[3]
[2]
[4]
Curly braces, on the opposite, will return the underlying value of each cell (doubles):
A = {1 2; 3 4};
A{:}
ans =
1
ans =
3
ans =
2
ans =
4
In this second case, if you want an array to be returned, you have to write the selector as follows:
[A{:}]
ans =
1 3 2 4

List declaration with/without bracket in matlab

For example, Why are 1:5 and [1:5] the same in matlab?
What is the reason behind this convention?
The reason for the convention is hard to tell without asking the creators of MATLAB, but here's a little insight. I apologies if this is a bit messy.
If you don't bother reading it all, here's the executive summary:
: is used to create regularly spaced vectors, while square brackets are used for concatenating.
First, you should know that even scalars are considered to be matrices in MATLAB. Scalars are simply 1x1 matrices, or to be more specific: 1x1x1x1x......1. There are in theory infinite amount of trailing singleton dimensions.
1 == [1] == [[[1]]]
Also:
a = 1;
a(1,1,1,:,:,1) %% Messy indexing showing how you can index a matrix using more dimensions than it appears to have.
ans =
1
The documentation says:
The colon operator is used to create regularly spaced vectors (and subscript arrays, and specify for iterations).
As scalars can be created without brackets, there's no reason you should need brackets around a clearly and unambiguously defined operator.
Brackets [] on the other hand creates vectors or matrices by concatenating values and vectors. From the documentation:
Square brackets are used in array construction and concatenation, and also in declaring and capturing values returned by a function.
Therefore, you can basically put brackets around anything you want. The same example as with the scalar above:
1:4 == [1:4] == [[[1:4]]]
Or around cells (doesn't change anything):
a = {3,1:4,'Hello, World!'}
a =
[3] [1x4 double] 'Hello, World!'
b = [a]
b =
[3] [1x4 double] 'Hello, World!'
Concatenating strings:
str1 = 'Hello';
str2 = ', World!';
str = [str1 str2]
str =
Hello, World!
Concatenating vectors:
[1:4, 6:8, 10]
ans =
1 2 3 4 6 7 8 10
If you had to put brackets around the 1:4 part, this would be (also works, but much more cumbersome):
[[1:4], [6:8], 10]
ans =
1 2 3 4 6 7 8 10
A possible reason for the convention:
It would be inconsistent if you needed brackets around 1:3.
Unrelated: For anyone used to other programming languages, brackets inside brackets often means you "go up" one dimension. Therefore, this might be confusing to some.
Well in a way they are and are not the same , In MATLAB every thing is a matrix , even
a = 5
is 1x1 matrix , for 1-D matrix or vector they will perform the same operation
when you write
>> x=1:3
ans =
1 2 3
MATLAB consider the matrix as one dimensional , like for instance in the example below it consider only the last row of the declaration
>> x=1:3;2:4
ans =
2 3 4
but when you specify brackets it can be an nxm dimensional matrix
>> x=[1:3;1:3]
x =
1 2 3
1 2 3

What is the difference between 5 and [5] in MATLAB?

They seem to be exactly the same, like:
>> v1 = [5];
>> v2 = 5;
>> isequal(v1, v2)
ans =
1
>> [5] * [1,2,3]
ans =
5 10 15
>> v1(1)
ans =
5
>> v2(1)
ans =
5
Is there any differenceI should be aware of?
Thanks.
Is there any difference I should be aware of?
No
Although there is no significant difference, there is a difference.
v1=5; is creating a variable called v1 that has a value of 5.
v1=[5]; is defining a matrix/scalar with the value of 5; then it is concatenating that matrix with nothing - concatenation is the operation performed by the square brackets, and is why you do need them to define [1,2,3] - and then the result is assigned to the variable v1. So using the square brackets performs an additional operation.
This is why if you write your code in the editor you'll receive an m-lint message saying
The use of brackets [] is unnecessary. Use parenthesis to group, if needed.
There is no difference between [5] and 5. But in general there may be a difference between an expression [f] and f, where f is some expression. Here is an example:
c = {10,20,30,40,50,60};
x = c{1:3}
y = [c{1:3}]
Here, c is a cell array, so the operation c{1:3} returns all objects in places 1 to 3 of c as a comma-separated list, in other words it returns 10,20,30. It does not return the array [10,20,30]. So, the command x = c{1:3} is equivalent to x=10,20,30, which is equivalent to assigning x the value 10, and then doing nothing with the literals 20 and 30. On the other hand, the command y = [c{1:3}] groups the comma-separated list between brackets [], so it is equivalent to y=[10,20,30]. To conclude, x will have the value 10 while y will have the value [10,20,30].

Matlab - for loop over cell array "foreach"-like syntax loops only over the first element [duplicate]

This question already has answers here:
Is there a foreach in MATLAB? If so, how does it behave if the underlying data changes?
(9 answers)
Closed 8 years ago.
I thought that if I write
for x = cell_array
...
end
then the loop will run over the elements of cell_array, but in the following case it doesn't:
>> tags
tags =
'dset3'
'dset4'
'cpl1'
>> class(tags)
ans =
cell
>> for t = tags
tmp = t{:} %No semicolon: i.e. print it.
end
tmp =
dset3
So it only works for the first element.
What's the problem?
According to the documentation, for x = cell_array will iterate over columns of the cell array.
The reason for the confusion in the question is to do with how the {:} expansion behaves:
>> a = {3;4}
a =
[3]
[4]
>> b = a{:}
b =
3
In the above, a{:} does something akin to typing in a comma-separated list where the elements are the elements of the cell array a. Except not quite! If we write such a list explicitly, we get:
>> c = 3,4
c =
3
ans =
4
Somehow, with the >> b = a{:}, the other elements of a are discarded silently, even if e.g. a = {1 2; 3 4}.
However, in other contexts, a{:} will expand into the full comma-separated list:
>> extra_args = {'*-'; 'linewidth'; 30};
>> plot(1:2, extra_args{:})
>> extra_args = {};
>> plot(1:2, extra_args{:})
This will do what it's intended to do.
There is a nice function built into Matlab called cellfun. It allows you to "do something" with every element in the array in turn - regardless of its shape.
For example:
cellfun(#(x)fprintf(1,'%s',x), cellArray);
will loop over cellArray, and print the string in each cell.
You can also do one of the following things:
for x = cellArray(:)
% do stuff to x
end

Assign a row to cell array in Matlab?

I am trying to do this as with matrices:
>> line_params{1,:} = {numberPatterns{i}, lw, iw};
The right hand side of this assignment has too few values to satisfy the left hand side.
but getting error above.
Types are following:
>> class(line_params)
ans =
cell
>> size(line_params)
ans =
21 3
>> a={numberPatterns{i}, lw, iw};
>> class(a)
ans =
cell
>> size(a)
ans =
1 3
Change
line_params{1,:} = {numberPatterns{i}, lw, iw}
into
line_params(1,:) = {numberPatterns{i}, lw, iw}
(normal parenthesis).
If you use curly braces ({}), you reference the individual elements. That is,
line_params{1,:}
will return a comma-separated list of elements in the cell line_params in its first row. You cannot assign a cell array (single item) to a comma-separated list (multiple items).
If you use parenthesis (()), you reference the cell entry, i.e., a cell array will be returned. And you can assign a cell array (single item) to another cell array (single item) -- provided they have the same dimensions of course.