Can we add a statement in between MATLAB codes? - matlab

Is it possible to add statements in between the codes.
For example: If I have a code like this,
r(:,1) = a(:,1) - a(:,2);
Then can I write it as,
r(:,1) = a(:,1)("this is a constant") - a(:,2)("this is a variable");

You need to comment those statements like this
r(:,1) = a(:,1) ... % this is a constant
- a(:,2); % this is a variable
for more information read this

Just as a sideremark to the very correct answer of sudomakeinstall2
In other programming languages, as e.g. Java you can do something like
myvar = 1 + /* some comment here */ 5;
Eventhough MATLAB knows something similar with %{ ending with %}, they only work for multiline comments, so in the end, sudomakeinstall2s answer is the best I can think of.

Related

Dynamic switch in Matlab MAT file

I have a Matlab mat file, which has the following variables:
variable0
variable1
variable2
variable3
Is it possible to dynamically index them and modify, something like this:
function setVariable(obj, variableNum, data)
obj.matFile.(variable0+variableNum) = data;
end
So, if someone passes 0 variable 0 is modified and if someone passes 3 then variable three. I know this code doesn't work, this is just some example of what I tried. My current solution is to use a switch statement. This is not so good as in the C++ code, I am using indexing like above. I would like the C++ and Matlab to be as close as possible.
ANSWER
I did it this way and it is working:
eval(sprintf('obj.matfile_variable%d = data;', variableNum));
function setVariable(obj, variableNum, data)
% check if variableNum is numeric
if isnumeric(variableNum)
variableNum = num2str(variableNum);
varName = strcat('variable',variableNum);
else
varName = strcat('variable',variableNum);
end
obj.matFile.(varName) = data;
end
This should do the trick.
What about using
obj.matFile(variableNum).data = data;

Matlab: how to sum fields of two equivalent structures?

I am working in Matlab. I have defined:
a(1).x=1;
a(1).y=2;
a(1).z.w=3;
a(2).x=4;
a(2).y=5;
a(2).z.w=6;
I am now trying to add the fields in the two structures a(1) and a(2) such that I get:
c.x = 5;
c.y = 7;
c.z.w = 9;
Any idea how I can do this in an elegant way? Note that in the original problem the structures have many more fields (around 50).
Thank you very much in advance!
José
Here is a solution, for any depth of struct
The code of the script (or MATLAB command)
a(1).x=1;
a(1).y=2;
a(1).z.w=3;
a(2).x=4;
a(2).y=5;
a(2).z.w=6;
c=a(1);
c = returnStruct(c, a(2));
%{
you can also sum any amount of structs
for i=2:length(a)
c=returnStruct(c, a(i));
end
%}
with the recursive function
function rs = returnStruct(s,a)
fn = fieldnames(s);
for i=1:length(fn)
if isstruct(s.(fn{i}))
s.(fn{i}) = returnStruct(s.(fn{i}), a.(fn{i}));
else
s.(fn{i}) = s.(fn{i})+a.(fn{i});
end
end
rs = s;
end
I tested it for deeper levels of structs and it worked perfectly. Maybe, you have to adapt it slightly for your case, but this should be the way to go.
Unfortunately, any function like struct2cell only converts the first level, so you need something else.
If the deepest substructure level is 2 then this code will work:
fields=fieldnames(a);
for i=1:numel(fields)
if isstruct(a(1).(fields{i}))
fields2=fieldnames(a(1).(fields{i}));
for j=1:numel(fields2)
a(3).(fields{i}).(fields2{j})= a(1).(fields{i}).(fields2{j})+a(2).(fields{i}).(fields2{j});
end
else
a(3).(fields{i})=a(1).(fields{i})+a(2).(fields{i});
end
end
You can have a simple recursive solution
function r = sumfields(s)
if isstruct(s)
for f = fieldnames(s).'
r.(f{1}) = sumfields([s.(f{1})]);
end
else
r = sum(s);
end
end

Iterate through a lot of Structs

my Problem is the following:
I have about 300 Struct files given.
They are set up like this:
DSC_0001 has about 250 other struct files in it:
-> like this: DSC_0001.marker_1
And this one has 10 Numbers in it.
Like that:
DSC_0001.marker_1.flow_angle = 90
and now I want to iterate through all the Struct files
Something like that:
for i = 1:300
for j = 1:250
flow_angle = DSC_**i**.marker_**j**
end
end
Is there a way to do this?
I have the feeling that it could be really easy but I just can't find the solution...
I hope my question is clear enough...
Thanks for your help!
If possible don't use eval.
It depends on how your data is stored, but one possiblity is that it is in a .mat file. In that case it can be loaded using
DSC_structs = load('My_DSC_struct_file.mat');
and then you can access the values like so:
for i = 1:300
for j = 1:250
flow_angle(i,j) = DSC_structs.(['DSC_' sprintf('%04d',i)]).(['marker_' sprintf('%d',j)]);
end
end
Why avoid the eval function
Edit: You say that each struct is in a different file. That's a bit messier. I would probably do something like this to load them:
DSC_structs = cell(1,300);
for i = 1:300
%Note: I'm guess at your file names here
DSC_structs{i} = load(['DSC_' sprintf('%04d',i) '.mat'];
end
and then access the values as
DSC_structs{i}.(['DSC_' sprintf('%04d',i)]).(['marker_' sprintf('%d',j)]);
I guess this is a use case for the dreaded eval function:
for i = 1:300
for j = 1:250
eval (['flow_angle = DSC_', sprintf('%04d',i), '.marker_', num2str(j)]);
end
end
BUT NB there are 2 problems with my code above
You haven't told us where you want to store your angle, so my code doesn't :/ but you'd want something like this if you just want to store them in a matrix: eval (['flow_angle(', num2str(i), ',', num2str(j), ') = DSC_', sprintf('%04d',i), '.marker_', num2str(j)])
eval is a horrible way of doing things but you're forced to because someone saved your data in a horrible. Sort yourself out now for the future by re-saving your data in a smarter way! so something like:
.
for i = 1:300
eval ( ['DSC(', num2str(i), ') = DSC_', sprintf('%04d',i)]);
end
%// then save DCS!
And now your can iterate through this matrix of structs rather than having a 300 structs polluting your workspace and forcing you to use eval

creating variables from structures in matlab

I have the following example which expresses the type of problem that I'm trying to solve:
clear all
textdata = {'DateTime','St','uSt','Ln','W'};
data = rand(365,4);
Final = struct('data',data,'textdata',{textdata})
clear textdata data
From this, Final.data contains values which correspond to the headings in Final.textdata excluding the first ('DateTime') thus Final.data(:,1) corresponds to the heading 'St'... and so on. What I'm trying to do is to create a variable in the workspace for each of these vectors. So, I would have a variable for St, uSt, Ln, and W in the workspace with the corresponding values given in Final.data.
How could this be done?
Will this solve your problem:
for ii=2:length( textdata )
assignin('base',Final.textdata{ii},Final.data(:,ii-1));
end
Let me know if I misunderstood.
The direct answer to your question is to use the assignin function, like so (edit: just like macduff suggested 10 minutes ago):
%Starting with a Final structure containing the data, like this
Final.textdata = {'DateTime','St','uSt','Ln','W'};
Final.data = rand(365,4);
for ix = 1:4
assignin('base',Final.textdata{ix+1}, Final.data(:,ix));
end
However, I strongly discourage using dynamic variable names to encode data like this. Code that starts this way usually ends up as spaghetti code full of long string concatenations and eval statements. Better is to use a structure, like this
for ix = 1:4
dataValues(Final.textdata{ix+1}) = Final.data(:,ix);
end
Or, to get the same result in a single line:
dataValues = cell2struct(num2cell(Final.data,1), Final.textdata(2:end),2)

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