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

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.

Related

Matlab: mean and stddev in a cell

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

Vectorize function that outputs a row using arrayfun, returning a matrix

I'm using Octave and would like to vectorize a function that accepts as input a single real number and outputs a row vector of fixed length. I understand that arrayfun should be able to do this from its unclear documentation. From help arrayfun in Octave 3.2:
If the parameter VAL after a further string input argument
"UniformOutput" is set 'true' (the default), then the named
function FUNC must return a single element which then will be
concatenated into the return value and is of type matrix.
Otherwise, if that parameter is set to `false', then the outputs
are concatenated in a cell array.
It seems however that Matlab's version is more forgiving:
[B1,...,Bm] = arrayfun(func,A1,...,An) calls the function specified by function handle func and passes elements from arrays A1,...,An, where n is the number of inputs to function func. Output arrays B1,...,Bm, where m is the number of outputs from function func, contain the combined outputs from the function calls. The ith iteration corresponds to the syntax [B1(i),...,Bm(i)] = func(A1{i},...,An{i}). The arrayfun function does not perform the calls to function func in a specific order.
It looks like this works in Matlab but not in Octave. Am I correct that this generalization cannot be performed using arrayfun in Octave? Is there some more clever way to achieve this without resorting to unvectorized loops?
For reference, here is my Octave result:
octave:5> nums
nums =
#(c) ([c, c + 2, c + 4])
octave:6> arrayfun(nums,[1,2,3])
error: cellfun: expecting all values to be scalars for UniformOutput = true
error: called from:
error: /opt/local/share/octave/3.2.4/m/general/arrayfun.m at line 168, column 21
octave:6>
Use arrayfun to apply the function, nums to an array [1,2,3]
CellArray = arrayfun(nums, [1,2,3], "UniformOutput", false);
That gives you a cell array. If you want the answer in a matrix, use cell2mat
cell2mat(CellArray);
If your actual nums is more complicated, then we'll need a better example of it to suggest a solution.
The error already suggests how to solve the problem:
arrayfun(nums,[1,2,3],'UniformOutput',false)
There is no difference between Matlab and Octave.
Matlab:
>> nums=#(c) ([c, c + 2, c + 4])
nums =
#(c)([c,c+2,c+4])
EDU>> arrayfun(nums,[1,2,3])
Error using arrayfun
Non-scalar in Uniform output, at
index 1, output 1.
Set 'UniformOutput' to false.
>> arrayfun(nums,[1,2,3],'UniformOutput',false)
ans =
Columns 1 through 2
[1x3 double] [1x3 double]
Column 3
[1x3 double]
Octave:
octave:1> nums=#(c) ([c, c + 2, c + 4])
nums =
#(c) ([c, c + 2, c + 4])
octave:2> arrayfun(nums,[1,2,3])
error: arrayfun: all values must be scalars when UniformOutput = true
octave:2> arrayfun(nums,[1,2,3],'UniformOutput',false)
ans =
{
[1,1] =
1 3 5
[1,2] =
2 4 6
[1,3] =
3 5 7
}
octave:3>
If your function is really that simple, I suggest to use:
nums([1,2,3]')

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.

Difference between [] and [1x0] in MATLAB

I have a loop in MATLAB that fills a cell array in my workspace (2011b, Windows 7, 64 bit) with the following entries:
my_array =
[1x219 uint16]
[ 138]
[1x0 uint16] <---- row #3
[1x2 uint16]
[1x0 uint16]
[] <---- row #6
[ 210]
[1x7 uint16]
[1x0 uint16]
[1x4 uint16]
[1x0 uint16]
[ 280]
[]
[]
[ 293]
[ 295]
[1x2 uint16]
[ 298]
[1x0 uint16]
[1x8 uint16]
[1x5 uint16]
Note that some entries hold [], as in row #6, while others hold [1x0] items, as in row #3.
Is there any difference between them? (other than the fact that MATLAB displays them differently). Any differences in how MATLAB represents them in memory?
If the difference is only about how MATLAB internally represents them, why should the programmer be aware of this difference ? (i.e. why display them differently?). Is it a (harmless) bug? or is there any benefit in knowing that such arrays are represented differently?
In most cases (see below for an exception) there is no real difference. Both are considered "empty", since at least one dimension has a size of 0. However, I wouldn't call this a bug, since as a programmer you may want to see this information in some cases.
Say, for example, you have a 2-D matrix and you want to index some rows and some columns to extract into a smaller matrix:
>> M = magic(4) %# Create a 4-by-4 matrix
M =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> rowIndex = [1 3]; %# A set of row indices
>> columnIndex = []; %# A set of column indices, which happen to be empty
>> subM = M(rowIndex,columnIndex)
subM =
Empty matrix: 2-by-0
Note that the empty result still tells you some information, specifically that you tried to index 2 rows from the original matrix. If the result just showed [], you wouldn't know if it was empty because your row indices were empty, or your column indices were empty, or both.
The Caveat...
There are some cases when an empty matrix defined as [] (i.e. all of its dimensions are 0) may give you different results than an empty matrix that still has some non-zero dimensions. For example, matrix multiplication can give you different (and somewhat non-intuitive) results when dealing with different kinds of empty matrices. Let's consider these 3 empty matrices:
>> a = zeros(1,0); %# A 1-by-0 empty matrix
>> b = zeros(0,1); %# A 0-by-1 empty matrix
>> c = []; %# A 0-by-0 empty matrix
Now, let's try multiplying these together in different ways:
>> b*a
ans =
[] %# We get a 0-by-0 empty matrix. OK, makes sense.
>> a*b
ans =
0 %# We get a 1-by-1 matrix of zeroes! Wah?!
>> a*c
ans =
Empty matrix: 1-by-0 %# We get back the same empty matrix as a.
>> c*b
ans =
Empty matrix: 0-by-1 %# We get back the same empty matrix as b.
>> b*c
??? Error using ==> mtimes
Inner matrix dimensions must agree. %# The second dimension of the first
%# argument has to match the first
%# dimension of the second argument
%# when multiplying matrices.
Getting a non-empty matrix by multiplying two empty matrices is probably enough to make your head hurt, but it kinda makes sense since the result still doesn't really contain anything (i.e. it has a value of 0).
When concatenating matrices, the common dimension has to match.
It's not currently an error if it doesn't match when one of the operands is empty, but you do get a nasty warning that future versions might be more strict.
Examples:
>> [ones(1,2);zeros(0,9)]
Warning: Concatenation involves an empty array with an incorrect number of columns.
This may not be allowed in a future release.
ans =
1 1
>> [ones(2,1),zeros(9,0)]
Warning: Concatenation involves an empty array with an incorrect number of rows.
This may not be allowed in a future release.
ans =
1
1
Another difference is in the internal representation of both versions of empty. Especially when it comes to bundle together objects of the same class in an array.
Say you have a dummy class:
classdef A < handle
%A Summary of this class goes here
% Detailed explanation goes here
properties
end
methods
end
end
If you try to start an array from empty and grow it into an array of A objects:
clear all
clc
% Try to use the default [] for an array of A objects.
my_array = [];
my_array(1) = A;
Then you get:
??? The following error occurred converting from A to double:
Error using ==> double
Conversion to double from A is not possible.
Error in ==> main2 at 6
my_array(1) = A;
But if you do:
% Now try to use the class dependent empty for an array of A objects.
my_array = A.empty;
my_array(1) = A;
Then all is fine.
I hope this adds to the explanations given before.
If concatenation and multiplication is not enough to worry about, there is still looping. Here are two ways to observe the difference:
1. Loop over the variable size
for t = 1:size(zeros(0,0),1); % Or simply []
'no'
end
for t = 1:size(zeros(1,0),1); % Or zeros(0,1)
'yes'
end
Will print 'yes', if you replace size by length it will not print anything at all.
If this is not a surprise, perhaps the next one will be.
2. Iterating an empty matrix using a for loop
for t = [] %// Iterate an empty 0x0 matrix
1
end
for t = ones(1, 0) %// Iterate an empty 1x0 matrix
2
end
for t = ones(0, 1) %// Iterate an empty 0x1 matrix
3
end
Will print:
ans =
3
To conclude with a concise answer to both of your questions:
Yes there is definitely a difference between them
Indeed I believe the programmer will benefit from being aware of this difference as the difference may produce unexpected results

MATLAB: Printing comparative columns for elements from different vectors

I´m trying to printing comparative columns to compare elements with the same index of two or three differents vector.
I will illustrate my question with the next example
>> a = [5.47758 7.46578 3.45323]
a =
5.4776 7.4658 3.4532
>> b = [5.65432 4.45678 2.34789]
b =
5.6543 4.4568 2.3479
Now if I write
>> sprintf('%.2f %.2f\n',a, b)
I get the following response from Matlab
ans =
5.48 7.47
3.45 5.65
4.46 2.35`
But what the way I would like to see this presentation of values is this
ans =
5.48 5.65
7.47 4.46
3.45 2.35
How can I use the function sprintf (or other function or way) to get the above representation?
Thank you.
You can fix this problem by concatenating a and b into one 2-by-3 matrix input argument:
>> sprintf('%.2f %.2f\n',[a; b])
ans =
5.48 5.65
7.47 4.46
3.45 2.35
The SPRINTF function works by reusing the formatting string over and over as it traverses (in column order) the elements of each of the input arguments in the order they are entered. That's why in your example all the values of a get printed, then all the values of b, instead of interleaving the values of a and b.
If you are just "printing" it on the screen, you could type on the MATLAB Console (or "Command Window"):
a = [5.47758 7.46578 3.45323];
b = [5.65432 4.45678 2.34789];
c = [a',b']; % Transposing each row vector into a column vector before forming a matrix
c =
5.4776 5.6543
7.4658 4.4568
3.4532 2.3479
This will make it easier when you sort the matrix by rows, for example, using the command 'sortrows' (See the doc on 'sortrows' for its usage: "help sortrows" or "doc sortrows").