MATLAB Incorrect number of right hand side elements - matlab

Matlab's syntax is infuriating, specifically with structs. In the Bioinformatics toolkit, there is a method called jcampread(File) which is described here.
In the description, the method jcampread() takes a Filepath and outputs into a struct called jcampStruct. From my understanding, in Matlab, you don't declare return variable types like you do in C: you just give the return variable a name and it somehow knows that the return of jcampread() method will be a jcampStruct. How it does, I have no idea, but it does.
I put in the code exactly how their example shows in step 4 of the Example section, and I get the following error message back from Matlab:
Incorrect number of right hand side elements in
dot name assignment. Missing [] around left hand
side is a likely cause.
Error in jcampread>ntupleRead (line 510)
dataBlock.ZName = name{Zidx};
Error in jcampread (line 192)
dataBlocks = ntupleRead(fid);
This site says the problem occurs "when f has more than one matrix element." Code is below:
»f.a = [1 0]
f =
a: [1 0]
»f.b = [1 2]
f =
a: [1 0]
b: [1 2]
»f = setfield(f,'a',[2 2])
f =
a: [2 2]
b: [1 2]
»f(2).a=1
f =
1x2 struct array with fields:
a
b
»f = setfield(f,'a',[2 2])
??? Error using ==> setfield
Incorrect number of right hand side elements in dot name assignment.
Missing [] around left hand side is a likely cause.
I assume this means the matrix f looks like this:
f = [ [a1; b1]; [a2; b2]; ]
f = [ [[2 2]; [1 2]]; [[1]; []]; ]
When they tried to update f.a which was set to
f.a = [[2 2]; [1]]
...to a single element [2 2], it doesn't like that because f.a is currently a matrix with 2 vector elements. Basically if you are going to reassign f.a (all elements of the attribute a of matrix f), you have to reassign f.a to have the same number of elements as it currently has.
I think that is why this error is occuring in the setfield example.
My question: how does this apply to jcampread()? jcampStruct is literally a structure with the same attributes, and those attributes are assigned only once. I do not understand:
a. How matlab knows the return value of jcampread() is a jcampStruct, and
b. Why (given that it knows (a)), the 'Incorrect number of right hand..' error message is firing here.
Can anyone clear this up for me?

You are creating a non scalar structure and there is no way to assign at once, i.e. without a loop, a different value to the same field of each sub-structure.What does it mean?
Scalar structure
s.a = 1;
size(s)
ans =
1 1
Now, adding fields doesn't change the size of the structure:
s.b = 2;
size(s)
ans =
1 1
Non-scalar structure
However, assigning a value to the same field, but into a position > 1 of the structure, will grow it a non-scalar one:
s(2).a = 3
size(s)
ans =
1 2
Also, notice how the sub-structure in position 2 replicates/pre-allocates the fields of the initial structure even though you assigned to a alone:
s(2)
ans =
a: 3
b: []
Pointers
Additionally, the field s(2).b is just an empty pointer:
whos s
Name Size Bytes Class
s 1x2 496 struct
and by adding a scalar double (8 bytes), we get
s(2).b = 4;
whos s
Name Size Bytes Class
s 1x2 608 struct
Pro of non-scalar structure
What you can do with a non-scalar structure, is retrieve one field across all sub-structure (considering you don't run into concatenation issues):
for ii = 1:100
s(ii).a = rand(1,2);
end
cat(1,s.a)
the last command will concatenate all values of a single field from all sub-structure into a 100 by 2 array.
Cons
To assign different values across the sub-structures, even if the same field, you need to loop (as above in the for loop).
At most you could deal() the same values into one field across all sub-structures:
clear s
[s(1:100)] = deal([1, 2]);

Related

How to assign values to variables in a handle function?

This is simplified but take as an example the following MATLAB function handle:
F = #(x)[x(1)-x(2);x(2)-x(3)]
The system has of course has many solutions. Is it possible to obtain a solution for a function like this one after substituting at least one variable? For example, substituting x(3)=1 the function would become:
G = #(x)[x(1)-x(2);x(2)-1]
And a solution for the other variables can be obtained. I use fsolve and it works quite well for the system of equations I have. Of course what I need to do can be done using the Symbolic Toolbox, but calling it in a big for loop makes it too slow to use for my code.
I'm trying to come up with some code that can return G given F and a set of indices in x to replace with given values.
What you're basically asking to do is have G call F with values in x reassigned based on a logical replacement index index and a set of replacement values values, which is doable but messy since anonymous functions can only have a single executable statement.
The solution is similar to what is done in this answer, but instead of using the functional form for subscripted reference we'll need to use the functional form for subscripted assignment: subsasgn. Here's what it would look like:
F = #(x)[x(1)-x(2); x(2)-x(3)];
values = [3 2 1];
index = logical([0 0 1]);
G = #(x) F(subsasgn(x, struct('type', '()', 'subs', {{index}}), values(index)));
And here's a test:
>> F([3 2 3])
ans =
1
-1
>> F([3 2 1]) % Replace the last element by 1
ans =
1
1
>> G([3 2 3]) % G handles replacing the last element by 1
ans =
1
1

shape intrinsic function in fortran

I am playing around with the shape() intrinsic function in fortran:
program test
integer, dimension(5,3) :: A
integer, dimension(2) :: ShapeA
ShapeA = shape(A)
print *, ShapeA(1)
print *, ShapeA(2)
end program test
I understand the shape function returns a 2 element vector containing the length and width of array A. In the above code, the output of shape(A) is passed to the predefined variable ShapeA. Then the contents of ShapeA are printed out, namely 5 and 3.
I would like to find a way to refer to the contents of the output of shape(A) without having to assign it to an intermediate variable ShapeA.
This would be similar to the matlab size function which enables looping constructs like this:
A = [1 2 3 5 4; 2 3 5 4 5]
for i = 1:size(A,2)
A(2,i)
end
Which means the user need not assign another variable like so:
A = [1 2 3 5 4; 2 3 5 4 5]
sizeA = size(A,2)
for i = 1:sizeA
A(2,i)
end
In fortran it is necessary to both declare the variable, assign it a value using size statement then include that variable in the loop. I would like to remove the first two steps and see if it can be done like in matlab. Any ideas? Thanks.
From the fortran manual page for shape there is a link to SIZE, specifically (emphasis mine)
Description:
Determine the extent of ARRAY along a specified dimension DIM, or the total number of elements in ARRAY if DIM is absent.
program test
integer, dimension(5,3) :: A
print *, size(A,1)
print *, size(A,2)
end program test

Combination of colon-operations in MATLAB

I have a question concerning the colon operator and expansion of vectors in MATLAB. My problem is to understand how the following line of code expands, to be able to use it for other sequences. The line of MATLAB code is:
a(1:2:5) = 1:-4:-7
Note that a is not defined before the expansion. This returns the vector
a = 1 0 3 0 -7
I know how the colon operator works with {start}:{step}:{stop}, my problem is to understand how and why the combination of a(1:2:5)and 1:-4:-7 returns a vector of five elements with zeros in position 2 and 5?
Whenever Matlab detects you're indecing to an element outside the current bounds of the matrix/array, it will automatically pad the missing elements with zeros:
>> clear b; b(10) = 5
b =
0 0 0 0 0 0 0 0 0 5
This feature is both very useful, and very dangerous. It is useful for the fact declarations can be made very easy, such as your own case. You can create a whole array of custom-made classes by issuing something like
myClassArray(500) = myClass(1, 2);
which is infinitely better than something like
% cannot pre-allocate (zeros() or ones() give double/uint8/..., not myClass)
for ii = 1:499
myClassArray(ii) = myClass; % so, growing array
end
myClassArray(500) = myClass(1,2);
But, growing arrays can be hard to spot:
a = zeros(10,1);
for ii = 1:10
a(ii+1) = rand;
end
which can make performance drop tremendously. Also, when you translate code prototyped in Matlab to a statically-typed language like C++, copying this code will result in buffer overflows and thus segfaults.
Now, going back to your case:
clear a; a(1:2:5) = 1:-4:-7
The 1:2:5 will expand to the array [1 3 5], and the 1:-4:-7 will give the values [1 -3 -7]. Since the variable a does not exist yet, Matlab will create a new one and fill the elements [1 3 5] with the values [1 -3 -7]. The indices that have been skipped in order to initialize variable a (namely, [2 4]) will then have been initialized automatically to zero.
If you're familiar with Python, it's a bit like the syntax to assign multiple values to multiple variables
x,y = 1,2
But in your Matlab case, these different variables are indices to a non-existent array, which requires "filling the holes with something" to make it a valid, consistent array.
Does this make things clear?
when you define a(1:2:5), it creates a size 5 vector (zero-valued), and selecting odd indexed(3 of them exists) cells. 1:-4:-7 creates three values (not five). Finally your selected three cells are filled with data of 3 values coming from 1:-4:-7

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

How to convert numeric results in symbols or strings?

this is my problem.
I made an algorithm that makes permutations of certain words. I substituted each word with a numeric value so I can make arithmetical operations with them (e.g. 1 = 'banana' 2 = 'child' 3 = 'car' 4 = 'tree' etc.).
Let's say that after running an algorithm, matlab gave me this matrix as result:
ans = [2,2,1; 4,3,3]
What I never can figure out is how to tell him - substitute digits with symbols and write:
ans = [child,child,banana; tree,car,car] - so I don't have to look up every number in my chart and replace it with a corresponding word!?
If you have an array with your words, and another array with the indices, you can produce an array that replaces every index with the corresponding word like so:
words = {'banana','child','car','tree'};
numbers = [2 2 1;4 3 3];
>> words(numbers)
ans =
'child' 'child' 'banana'
'tree' 'car' 'car'
You can also use the ordinal datatype if you have the statistics toolbox.
>> B = ordinal([2 2 0; 4 3 3], {'banana','child','car','tree'})
B =
child child banana
tree car car
Note that it handles zeros automatically. Then you can do things like:
>> B=='child'
ans =
1 1 0
0 0 0