MATLAB Nesting Expression - matlab

Just a simple nesting question:
I've got a <100x100 double> matrix mat_B, with I cumsum. From the resulting matrix mat_A, I just need the last row vec_C, which I need to cumsum again. My code looks like this:
mat_A = cumsum(mat_B);
vec_C = cumsum(mat_A(end,:));
My question is, if it's possible to put all of this inside one line of code. I know that cumsum(mat_B) returns a matrix, but if I put (end, :) behind the expression, it won't work.
I know it sounds quite silly, but I'd like to know how nesting works in those kind of situations.

You could skip the first cumsum and just use sum, since the last line of cumsum is equivalent to the result of sum:
>> mat_B=rand(5);
>> cumsum(mat_B)
ans =
0.2517 0.4522 0.8838 0.3751 0.2527
0.6847 0.7778 1.3412 0.7487 0.8376
1.5270 1.1579 2.1404 1.2327 1.3613
1.7115 2.0444 2.2745 2.2021 1.5247
2.2197 2.8056 2.3398 2.5442 2.0111
>> sum(mat_B)
ans =
2.2197 2.8056 2.3398 2.5442 2.0111
Therefore
vec_C = cumsum(sum(mat_B));
should do what you want.

Related

How to make a two-dimensional matrix w/o for?

I'm coding the matrix for the 2-dimensional graph, now.
Although it's so simple equation, it takes a lot of time for performing. I think it could get faster.
especially, "for - command term" could be simplified I think.
How can I simplify this?
q=1:1:30
x(q)=330+q*0.3
F=1:30:8970
T=x(1)-0.3:0.001:x(30)+0.3
n=size(T,2)
k=1:1:n
for a=1:1:30
I(a,k)=F(a)*exp(-2.*(T(:,k)))
end
happy=sum(I)
plot(k,I)
I would say that the time is used to print results. Try to use ; at the end of each line, it will fasten computation.
You can also replace the for loop by the following element by element computation:
a = (1:1:30).';
aux = repmat(exp(-2.*(T(:,k))), length(a), 1);
a = repmat(a, 1, length(k));
I = a.'.*aux.';

Finding all occurences of a string within a cell array (itself part of a struc)

I have the following structure
dataDens =
dens: [1x172 double]
level: {1x172 cell}
raga: {1x172 cell}
within which dataDens.raga consists of (reducing the number of columns below for simplicity)
Columns 1 through 3
'Multani' 'Tori' 'Tori'
I'd like to find the indices at which 'Tori' appears (that is, [2 3] for the example above). However, all of the commands I tried (below) either give an error, or return blank outputs. I think it's probably just a matter of adding/removing a curly bracket somewhere, or using some conversion; but I am at my wit's end, and hope someone can help clarify
indices = find(strcmp([dataDens.raga{:}], {'Tori'}))
indices = ismember('Tori', dataDens.raga)
[if,where] = ismember('Tori', dataDens.raga)
The issue had indeed to do with brackets. [dataDens.raga{:}] will result in concatenation of the character arrays, like so:
>> [dataDens.raga{:}]
ans =
'MultaniToriTori'
Using strcmp to compare this to 'Tori' will result in false, since there is no exact match. You can however compare the entire cell using strcmp, which will then return a boolean array, in which find can be used to obtain the indices of true entries:
indices = find(strcmp(data, {'Tori'}))
Alternatively, ismember would also work, but using ismember('Tori', dataDens.raga) you are checking whether 'Tori' is in dataDens.raga, not the other way around. Changing this to
ismember(dataDens.raga, 'Tori')
would again give you a boolean array, and find will obtain the indices you are looking for.

Setting property in array of Matlab objects

I am working with arrays of structs and objects in Matlab. I want to set properties for all the members of a certain array as fast as possible.
For the problem of setting a certain struct field, I reached a solution that involves using arrayfun and setfield. The following works like a charm:
myStru.id = 0;
myStru.name = 'blah';
arrayStru = repmat(myStru,10,1); % Array of 10 elements. All of them have id=0
arrayStru = cell2mat( arrayfun( #(x,y)setfield(x,'id',y), arrayStru, (1:10)', 'UniformOutput', false ) ); % ids ranging from 1 to 10 :D
The problem is that, for objects, this does not work. I understand that setfield is for structures, so I have tried some other alternatives. The most excruciating error pops out when I try the following:
arrayfun( #(x,y) eval(['x.id=y;']), arrayOfObjects, arrayOfValues, 'UniformOutput', false );
(The class is a very simple one, which accepts empty constructor and has a real public property called 'id'). It results in:
Error using setFieldOfStructArray>#(x,y)eval(['x.id=y;']) (line 17)
Error: The expression to the left of the equals sign is not a valid target for an
assignment.
ALTHOUGH if I put a breakpoint in that line, it seems that the expression can be executed with the expected effects.
My two (three) questions:
Why does the above solution fail? How can I get that to work?
My final goal is to set properties fast and simple in arrays of objects. Which is the best technique for this?
(Note: I can write loops, but I always feel itchy when I have to do that :P)
I think the problem may be that your propety may be readonly because setfield works also for classes.
Anyway there is some alternative, if your class inherit from hgsetget you can use set instead of setfield.
You can also use
subsasgn(x,struct('type','.','subs','id'),y)
instead of
setfield(x,'id',y)
If can use cell of values, which will be automatically interpreted as struct array
>> s = struct('a', num2cell(1:10)', 'b', 's')
s =
10x1 struct array with fields:
a
b
>> [s.a]
ans =
1 2 3 4 5 6 7 8 9 10
>> [s.b]
ans =
ssssssssss

Switching even- and odd-indexed characters in Matlab

Using Matlab, write a function called tripFlip that takes in one string and switches each even-indexed charactar with the odd-indexed character immediately preceding it. Use iteration. Example: tripFlip('orange') ->'ronaeg'
I assume this is homework, so I won't give a complete answer. You can use double to convert a string to an array, and char to go back, if working with arrays makes the problem any easier. Otherwise, strings seem to work just like arrays in terms of indexing: s(1) gets the first character, length(s) gets the length, etc.
I agree its a homework question, and posting it here will only bite you back in the long run. But here goes:
a = 'orange';
b = '';
b(2:2:length(a))= a(1:2:end);
b(1:2:length(a))= a(2:2:end);
disp(b)
In one line:
>> input = 'orange';
>> output = input(reshape([2:2:end;1:2:end],1,[]))
output =
ronaeg
It's not a function and doesn't use iteration, but it's how you'd solve this if you were to learn Matlab.
Something like this should do the trick, perhaps you want to make it a bit more robust.
function b = TripFlip(a)
a = 'orange';
b = '';
for i = 2:2:length(a)
b=[b a(i) a(i-1)]
end

How can I count the number of properties in a structure in MATLAB?

I have a function that returns one or more variables, but as it changes (depending on whether the function is successful or not), the following does NOT work:
[resultA, resultB, resultC, resultD, resultE, resultF] = func(somevars);
This will sometimes return an error, varargout{2} not defined, since only the first variable resultA is actually given a value when the function fails. Instead I put all the output in one variable:
output = func(somevars);
However, the variables are defined as properties of a struct, meaning I have to access them with output.A. This is not a problem in itself, but I need to count the number of properties to determine if I got the proper result.
I tried length(output), numel(output) and size(output) to no avail, so if anyone has a clever way of doing this I would be very grateful.
length(fieldnames(output))
There's probably a better way, but I can't think of it.
It looks like Matthews answer is the best for your problem:
nFields = numel(fieldnames(output));
There's one caveat which probably doesn't apply for your situation but may be interesting to know nonetheless: even if a structure field is empty, FIELDNAMES will still return the name of that field. For example:
>> s.a = 5;
>> s.b = [1 2 3];
>> s.c = [];
>> fieldnames(s)
ans =
'a'
'b'
'c'
If you are interested in knowing the number of fields that are not empty, you could use either STRUCTFUN:
nFields = sum(~structfun(#isempty,s));
or a combination of STRUCT2CELL and CELLFUN:
nFields = sum(~cellfun('isempty',struct2cell(s)));
Both of the above return an answer of 2, whereas:
nFields = numel(fieldnames(s));
returns 3.