Matlab: mean and stddev in a cell - matlab

In a single array it's pretty simple to get the mean or standard deviation (std) of its numbers, however in a cell, whose data doesn't have the same size in each of its positions I couldn't do mean2 or std2.
I know it's possible to do something if I copy all of the data in a single row or single column but I just wanted to ask if someone knows if there is a single formula to do it?
Thanks

You can use cellfun to compute per-cell mean and std:
cell_mean = cellfun(#mean, my_cell);
cell_std = cellfun(#std, my_cell);
For example:
>> my_cell = {[1,2,3,6,8], [2,4,20]}
>> cellfun(#mean, my_cell)
ans =
4.0000 8.6667
>> cellfun(#std, my_cell)
ans =
2.9155 9.8658
If you want the mean and/or std of all the elements in all the cells, you can:
>> mean([my_cell{:}])
ans =
5.7500
>> std([my_cell{:}])
ans =
6.2048
And, if your cell elements are all of different sizes, you can use cell2mat to assist you:
>> mean(cell2mat(cellfun(#(x) x(:)', my_cell, 'uni', 0)))
ans =
5.7500
>> std(cell2mat(cellfun(#(x) x(:)', my_cell, 'uni', 0)))
ans =
6.2048

Related

What does the Matlab vector operation myVector.(':')(':') do?

I came across the following expression in the function mavolcanoplot.m:
X = X.(':')(':');
I tried it with a simple example X = [1 2 3] but then I got
Struct contents reference from a non-struct array object.
Since I don't know what the expression does, I don't know what X should look like to test it.
Can anyone tell me what the expression does?
According to the documentation,
When using dot indexing with DataMatrix objects, you specify all rows or all columns using a colon within single quotation marks, (':').
Take a look at this example:
import bioma.data.*
dmo = DataMatrix(rand(3,3), {'A', 'B', 'C'}, {'X','Y','Z'})
dmo =
X Y Z
A 0.69908 0.54722 0.25751
B 0.8909 0.13862 0.84072
C 0.95929 0.14929 0.25428
>> %to extract all rows and first two columns (X and Y)
>> %you can specify any of column scripts and column labels
>> %same goes for rows
>> dmo.(':')(1:2) % or dmo.(':')({'X','Y'})
ans =
0.6991 0.5472
0.8909 0.1386
0.9593 0.1493
>> dmo.(':') %or dmo.(':')(':') to extract all rows and columns
ans =
0.6991 0.5472 0.2575
0.8909 0.1386 0.8407
0.9593 0.1493 0.2543
Furthermore, specifying a row/column label that doesn't exist gives 1 i.e.
>> dmo.('e')('X')
ans =
1
and end cannot be used for indexing.
>> dmo.(end)('X')
Error: The end operator must be used within an array index
expression.

I need to write an if statement that compares the size of 2 matrices in Matlab

Matrix_A=input('Enter your dimensions')
Matrix_B=input('Enter your dimensions')
If Matrix_A ~= dimensions of Matrix_B
disp('Please enter matrices of equal dimensions')
To test if two arrays A and B have the same size, use
isequal(size(A), size(B))
This works even if the arrays A and B have different numbers of dimensions (in which case using size(A)==size(B) would give an error). For example,
>> A = rand(2,3);
>> B = rand(3,4,5);
>> isequal(size(A), size(B))
ans =
0
There is size function in Matlab returns array dimensions:
if size(matrix_A) ~= size(matrix_B)
disp('AH CMON!');
end
You can get more examples here: http://www.mathworks.com/help/matlab/ref/size.html

MATLAB: Structure containing an column vector won't display the vector

I have defined a structures array as such:
oRandVecs = struct('vV',{[],[]},...
'ind_min',{[],[]},...
'mean',{[],[]},...
'vV_descending',{[],[]},...
'largest_diff',{[],[]});
oRandVecs(1).vV and oRandVecs(2).vv both get column vectors assigned to them. However, the problem is that the output is as follows:
>> oRandVecs(1)
ans =
vV: [4x1 double]
ind_min: 2
mean: 6.5500
vV_descending: [4x1 double]
largest_diff: 2.8000
Instead of actually showing the vector, it only describes its type.
What am I to do?
The reason why is because it's simply too big to display on the screen with that structure :) If you want to actually display it, use dot notation to display your data.
In other words, do this:
disp(oRandVecs(1).vV);
You can also do that with the other variable:
disp(oRandVecs(1).vV_descending);
The answer by rayryeng is probably the way to go.
An alternative is to convert from structure to cell and then use celldisp:
celldisp(struct2cell(oRandVecs(1)))
Example:
>> oRandVecs = struct('vV',{[],[]},...
'ind_min',{[],[]},...
'mean',{[],[]},...
'vV_descending',{[],[]},...
'largest_diff',{[],[]}); %// define empty struct
>> oRandVecs(1).vV = (1:4).'; %'// fill some fields: column vector, ...
>> oRandVecs(1).mean = 5:7; %// ... row vector, ...
>> oRandVecs(1).vV_descending = randn(2,3); %// ... matrix
>> celldisp(struct2cell(oRandVecs(1)))
ans{1} =
1
2
3
4
ans{2} =
[]
ans{3} =
5 6 7
ans{4} =
0.016805198757746 0.236095190511728 0.735153386198679
2.162769508502985 -0.158789830267017 0.661856091557715
ans{5} =
[]

Doing operations between subsequent elements without using a FOR loop?

In Matlab, Is it possible to do simple operations between subsequent elements of an array without using a for loop? Something like diff(). For example, I have this vector:
A = [2 4 8 16 32]
and I want each element to be divided by its predecessor:
ans = [2 2 2 2]
How can I do it without going through all elements (without using loops)?
You can use the fact that division in Matlab work on both scalars and matrices, if you use the ./ operator rather than /
>> A = [2 4 8 16 32];
>> A(2:end) ./ A(1:end-1)
ans =
2 2 2 2
Regarding your question about doing dot() between vectors stored in the rows of a matrix. There is an additional argument to dot() that tells it whether your vectors are stored in columns (the default) or rows;
>> x = rand(3);
>> y = rand(3); # random vectors
>> dot(x,y) # dot product of column vectors
ans =
0.5504 0.5561 0.5615
>> dot(x,y,2) # dot product of row vectors
ans =
0.3170
1.0938
0.2572
Most functions in Matlab are vectorized so that they can work on scalars, vectors and matrices, but you sometimes have the read the documentation (e.g. type help dot) to work out how to use them.

prepend a list to a matrix in matlab

i wanted to ask this:
If i have this matrix:
magnetT=NaN(Maxstep,2);
and want to prepend to it the "{0 1}"
how can i write it?
Also,if i have this in mathematica in a loop:
magnetT[[i]] = {T, Apply[Plus, Flatten[mlat]]/L2}
the equivalent in matlab isn't this???
magnetT(i,2)=[T ,sum(mlat(:))./L2];
because it gives me :Subscripted assignment dimension mismatch.
Error in ==> metropolis at 128
magnetT(i,2)=[T,sum(mlat(:))./L2];
Thanks
I'll attempt to answer your first question both questions.
You asked about prepending the NaN array to {0,1} which is a cell array. Any data objects can be readily bundled into a cell array:
>> anyData = NaN(3, 2);
>> newCellArray = {anyData; {0, 1}}
newCellArray =
[3x2 double]
{1x2 cell }
If you are instead trying to concatenate the results into a numeric matrix, the following will help:
>> Maxstep=3;
>> magnetT=NaN(Maxstep,2);
>> newArray = [magnetT; 0 1]
newArray =
NaN NaN
NaN NaN
NaN NaN
0 1
For your second question, MATLAB is complaining about trying to store a vector in one element of magnetT. When computing:
magnetT(i,2)=[T ,sum(mlat(:))./L2];
the right-hand side will create a vector while the left-hand side is trying to store that vector where a scalar is expected. I don't know exactly what you're trying to achieve and I'm not very familiar with Mathematica syntax but perhaps you need to do this instead:
magnetT(ii,:) = [T sum(mlat(:))./L2];
or, in other words:
magnetT(ii,1) = T;
magnetT(ii,2) = sum(mlat(:)) ./ L2;