Assign a row to cell array in Matlab? - 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.

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

Matlab cell array element assignment

>> 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]

How do I find a specific cell within a cell array?

Let's say I have a cell array containing 1x2 cells. eg. deck = {{4,'c'},{6,'s'}...{13,'c'}...{6,'d'}}
How can I find the index of a specific cell? E.g I want to find the index of the cell with the values {13,'c'}.
Thanks!
Try cellfun with isequal:
>> deck = {{4,'c'},{6,'s'},{13,'c'},{6,'d'}};
>> targetCell = {13,'c'};
>> found = cellfun(#(c) isequal(c,targetCell),deck)
found =
0 0 1 0
cellfun let's you check anyway you want (not just isequal). For example, if you want to check based on the string element in each cell:
>> targetLetter = 'c';
>> found = cellfun(#(c) strcmp(c{2},targetLetter),deck)
found =
1 0 1 0
Another method I can suggest is to operate on each column separately. We could use logical operators on each column to search for cards in your cell array that contain a specific number in the first column, followed by a specific suit in the second column. To denote a match, we would check to see where these two outputs intersect. We can do this by combining both outputs with a logical AND when we're done:
deck = {{4,'c'},{6,'s'},{13,'c'},{6,'d'}};
target_card = {13, 'c'};
deck_unroll = vertcat(deck{:});
a1 = cat(1, deck_unroll{:,1}) == target_card{1};
a2 = cat(1, deck_unroll{:,2}) == target_card{2};
found = a1 & a2
found =
0
0
1
0
Because deck is a nested cell array, I unrolled it so that it becomes a 2D cell array where each row denotes one card. This is stored in deck_unroll. Once I do this, I further unroll the cells so that the first column gets placed into a numeric array and we search for a particular number (13 in your example) and the second column gets placed into a string array where we search for a particular character ('c' in your example). This is done with the help of cat to extract each element from a particular column and we construct an array out of these elements.

subindex into a cell array of strings

I have a 6 x 3 cell (called strat) where the first two columns contain text, the last column has either 1 or 2.
I want to take a subset of this cell array. Basically select only the rows where the last column has a 1 in it.
I tried the following,
ff = strat(strat(:, 3), 1:2) == 1;
The error message is,
Function 'subsindex' is not defined for values of class 'cell'.
How can I index into a cell array?
Cell arrays are accessed through braces {} instead of parentheses (). Then, as a 2nd subtlety, when pulling values out of a cell arrays, you need to gather them...for numerics you gather them into regular arrays using [] and for strings you gather them into a new cell array using {}. Confusing, eh?
ff = { strat{ [strat{:,3}]==1 , 1:2 } };
Gathering into cell arrays this way can often give the wrong shape when you're done. So, you might try something like this
ind = find([strat{:,3}]==1); %find the relevant indices
ff = {{strat{ind,1}; strat{ind,2}}'; %this will probably give you the right shape

Matlab Array has strange syntax

In Matlab, we use textscan to get a cell array from a file or somewhere. But the behavior of the cell array is so strange.
There is the sample code:
>> str = '0.41 8.24 3.57 6.24 9.27';
>> C = textscan(str, '%3.1f %*1d');
>> C
C =
[5x1 double]
We can know that C is a cell array of size 5 * 1. When I use C{1}, C{1}{1} and C(1). I get the following result:
>> C{1}
ans =
0.4000
8.2000
3.5000
6.2000
9.2000
>> C{1}{1}
Cell contents reference from a non-cell array object.
>> C(1)
ans =
[5x1 double]
Why I cannot use C{1}{1} to get the element from the cell array ? Then how can I get the elements from that cell array ?
An example I found on the Internet is :
%% First import the words from the text file into a cell array
fid = fopen(filename);
words = textscan(fid, '%s');
%% Get rid of all the characters that are not letters or numbers
for i=1:numel(words{1,1})
ind = find(isstrprop(words{1,1}{i,1}, 'alphanum') == 0);
words{1,1}{i,1}(ind)=[];
end
As words{1,1}{i,1}(ind)=[] show, what is the mechanism of using {}?
Thanks
Then how can I get the elements from that cell array ?
C = C{:}; % or C = C{1};
Access values by C(1), C(2) and so on
There is a slightly different syntax for indexing into cell arrays and numerical arrays. Your output
>> C
C =
[5x1 double]
is telling you that what you have is a 1x1 cell array, and in that 1 cell is a 5x1 array of doubles. Cell arrays are indexed into with {}, while 'normal' arrays are indexed into with ().
So you want to index into the first element of the cell array, and then index down to the first value in the 5x1 array of doubles using C{1}(1). To get the second value - C{1}(2), and so forth.
If you're familiar with other programming languages, cell arrays are something like arrays of pointers; the operator A(n) is used to get the nth element of the array A, while A{n} gets the object pointed to by the nth element of the array A (or 'contained in the nth cell of cell array A'). If A is not a cell array, A{n} fails.
So, knowing that C is a cell array, here's why you got what you got in the cases you tried -
C{1} returns the 5x1 double array contained in the first cell of C.
C{1}{1} gets the object (call it B) contained in the first cell of C, and then tried to get the object contained in the first cell of B. It fails because B is not a cell array, it is a 5x1 double array.
And C(1) returns the first element of C, which is a single cell containing a 5x1 double array.
But C{1}(1) would get you the first element of the 5x1 array contained in the first cell of C, which is what you are looking for. As #Cheery above me noted, it's probably easier, instead of writing C{1}(1), C{1}(2), ... to remove the 'cell-level' indexing by setting C=C{1}, which means C is now a 5x1 double array, and you can get the elements of it using C(1), C(2), ... Hope that makes sense!