Size of a {mxn} cell in Matlab - matlab

When I create a cell from a text file and print it I get:
params =
{4x1 cell}
However when I use:
size(X)
I get:
1 1
So what can I use to see the size of the cell (I'm trying to get the size(in this case 4) of the cell to use in a loop).

If it's always going to be a 1x1 cell, then you can do
size(X{1})
If not you could do
s = cellfun(#size, X, 'uni', 0);
s{:}

Related

Inserting new values to cell array[MATLAB]

[EDIT]
Say, I have a cell array A consisting of n cells and each of them is a zero vector of size (m,1).
Example: A is a 1x2 cell array A = [100x1 double] [100x1
double]
How can I insert new values to each cells, on the same rows and at the same time without having to write separate lines of code? Can I use cellfun to do so?
For instance, how can I replace the ithrow of the first cell with the new value m and the ithrow of the second cell with the new value n, using a single line of code?
m and n may or may not be the same values.
as in comments noted you may try other options such as array for its efficiency, however as an answer to the question you can use evalin function and using change_cell you can for example change contents of second row fo each cell to the vals just in one line of code!:
A = {[1 2 3],[4 5 6]};
change_cell = #(rownum , vals) evalin(...
'base', ...
[...
'rownum =', int2str(rownum),';',...
'vals=[', num2str(vals),'];',...
'for i = 1:length(A);',...
'A{i}(rownum)=vals(i);',...
'end;'...
]);
change_cell(2, [6 8])

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!

Convert matrix to cell array of cell arrays

I want to change a matrix N*123456 to a cells of cells, each sub-cell contains a N*L matrix
Eg:
matrixSize= 50*123456
N=50
L=100
Output will be 1*1235 cell and each cell has a 50*L matrix (last cell has only 50*56)
I know there is a function mat2cell in matlab:
Output = mat2cell(x, [50], [100,100,100,......56])
But it doesn't sound an intuitive solution.
So is there a good solution?
If I understand you correctly, assuming your matrix is denoted m, this is what you wanted:
a=num2cell(reshape(m(:,1:size(m,2)-mod(size(m,2),L)),N*L,[]),1);
a=cellfun(#(n) reshape(n,N,L), a,'UniformOutput',false);
a{end+1}=m(:,end-mod(size(m,2),L)+1:end);
(this can be shortened to a single line if you wish)...
Lets test with some minimal numbers:
m=rand(50,334);
N=50;
L=100;
yields:
a =
[50x100 double] [50x100 double] [50x100 double] [50x34 double]
note that I didn't check for the exact dimension in the reshape, so you may need to reshape to ...,[],N*L) etc.
Just use elementary maths.
q = floor(123456/100);
r = rem(123456,100);
Output = mat2cell(x, 50, [repmat(100,1,q),r])

Combine Columns of Cell Array Matlab

I have a 2D cell array with dynamic row sizes and column sizes. One example:
cell3 = [{'abe' 'basdasd' 'ceee'}; {'d' 'eass' 'feeeeeeeeee'}]
Gives: (with dimension 2 by 3)
'abe' 'basdasd' 'ceee'
'd' 'eass' 'feeeeeeeeee'
I want to be able to combine the columns and reproduce a aggregate string cell array where each string is separated by a single white space. Any idea how to do that?
So the output i am looking for is:
'abe basdasd ceee'
'd eass feeeeeeeeee'
The final dimension is 2 by 1.
Is this possible?
Apply strjoin either in a loop or via cellfun. The latter:
>> cellRows = mat2cell(cell3,ones(size(cell3,1),1),size(cell3,2));
>> out = cellfun(#strjoin,cellRows,'uni',0)
out =
'abe basdasd ceee'
'd eass feeeeeeeeee'
Solution without loops or cellfun:
[m n] = size(cell3);
cellCols = mat2cell(cell3,m,ones(1,n)); %// group by columns
cellColsSpace(1:2:2*size(cell3,2)-1) = cellCols; %// make room (columns)...
cellColsSpace(2:2:2*size(cell3,2)-1) = {{' '}}; %// ...to introduce spaces
%// Note that a cell within cell is needed, because of how strcat works.
result = strcat(cellColsSpace{:});

Read string from txt file and use string for loop

Trying to read a txt file, then to loop through all string of the txt file. Unfortunately not getting it to work.
fid = fopen(fullfile(source_dir, '1.txt'),'r')
read_current_item_cells = textscan(fid,'%s')
read_current_item = cell2mat(read_current_item_cells);
for i=1:length(read_current_item)
current_stock = read_current_item(i,1);
current_url = sprintf('http:/www.', current_item)
.....
I basically try to convert the cell arrays to a matrix as textscan outputs cell arrays. However now I get the message
Error using cell2mat (line 53) Cannot support cell arrays containing cell arrays or objects.
Any help is very much appreciated
That is the normal behaviour of textscan. It returns a cell array where each element of it is another cell OR array (depending on the specifier) containing the values corresponding to each format specifier in the format string you have passed to the function. For example, if 1.txt contains
appl 12
msft 23
running your code returns
>> read_current_item_cells
read_current_item_cells =
{4x1 cell}
>> read_current_item_cells{1}
ans =
'appl'
'12'
'msft'
'23'
which itself is another cell array:
>> iscell(read_current_item_cells{1})
ans =
1
and its elements can be accessed using
>> read_current_item_cells{1}{1}
ans =
appl
Now if you change the format from '%s' to '%s %d' you get
>> read_current_item_cells
read_current_item_cells =
{2x1 cell} [2x1 int32]
>> read_current_item_cells{1}
ans =
'appl'
'msft'
>> read_current_item_cells{2}
ans =
12
23
But the interesting part is that
>> iscell(read_current_item_cells{1})
ans =
1
>> iscell(read_current_item_cells{2})
ans =
0
That means the cell element corresponding to %s is turned into a cell array, while the one corresponding to %d is left as an array. Now since I do not know the exact format of the rows in your file, I guess you have one cell array with one element which in turn is another cell array containing all the elements in the table.
What can happen is that the data gets wrapped into a cell array of cell arrays, and to access the stored strings you need to index past the first array with
read_current_item_cells = read_current_item_cells{1};
Converting from cell2mat will not work if your strings are not equal in length, in which case you can use strvcat:
read_current_item = strvcat(read_current_item_cells{:});
Then you should be able to loop through the char array:
for ii=1:size(read_current_item,1)
current_stock = read_current_item(ii,:);
current_url = sprintf('http:/www.', current_stock)
.....