Creating variable from other variables in MATLAB: code with reproduction - matlab

I have a question regarding this type of code:
First = ["A","B","C"];
Second = ["D","E","F"];
Group = ["First", "Second"];
for gr = Group
current = gr;
for number = 1:numel(current)
my_variable(number) = current(number);
end
end
That's the reproduction of my problem. In this case my_variable is equal to "First" for example. But I wanted it to be "A" then "B" then "C" from variable named "First".
For my understanding this code should do the following:
1st step: for gr = Group means gr = First to Second
2nd step: current = gr; means current = First
3rd step: for number = 1:numel(current) means number = 1:3 (number of elements in "First")
4th step: my_variable(number) = current(number); means my_variable = First(1) = "A"
Instead of that I get my variable equal to "First" or "Second".
I hope you understand what I mean.
P.S. the string arrays I'm using with double quotes (" ") like First = ["A","B","C"]; are only available in Matlab 2016b or later.

You should use cell arrays to do this:
first = {'A','B','C'};
second = {'D','E','F'};
group = {first, second};
for group_ind = 1:numel(group)
current = group{group_ind};
my_variable = cell(1,numel(current));
for number = 1:numel(current)
my_variable{number} = current{number};
disp(my_variable)
end
end
For first and second, you can also use the string arrays:
first = ["A","B","C"];
second = ["D","E","F"];
group = {first, second};
for group_ind = 1:numel(group)
current = group{group_ind};
my_variable = strings(1,numel(current));
for number = 1:numel(current)
my_variable(number) = current(number);
disp(my_variable)
end
end

Related

MATLAB: How to dynamically access variables

I declared some variables comprising of simple row vectors which represents input parameters for another function. Within a loop these variables should be used and the result will be assigned to a structure.
Now, my question is how to best access the content of the predefined variables. I found a solution using eval. However, I often read that the usage of eval should be avoided. Apparently it's not best practice. So, what's best practice for my problem?
varABC = [1,2,3];
varDEF = [4,5,6];
varGHI = [7,8,9];
names = {'ABC','DEF','GHI'};
result = {'result1','result2','result3'};
for i = 1 : 3
varString = strcat('var',names{i});
test.(result{i}) = sum(eval(varString));
end
I would suggest rewriting your code a little bit
names = {'ABC','DEF','GHI'};
result = {'result1','result2','result3'};
option 1
% Use struct instead of a simple variable
var.ABC = [1,2,3];
var.DEF = [4,5,6];
var.GHI = [7,8,9];
for i = 1 : 3
test.(result{i}) = sum(var.(names{i}));
end
option 2
% Use dictionary
c = containers.Map;
c('ABC') = [1,2,3];
c('DEF') = [4,5,6];
c('GHI') = [7,8,9];
for i = 1 : 3
test.(result{i}) = sum(c(names{i}));
end

Applying the command unique and lower on a variable

I currently having a script in matlab that creates a cell array that holds all the terms in a document. I need to use the command unique and lower on the variable to avoid duplicates. I can't work out how to place this on the variable.
Mylist = [];
for C = 1:length(docs)
list = tokenize(docs{C}, ' .,-');
Mylist = [Mylist; list];
end
I create a new variable and used unique and lower on the current cell array.
Newlist = unique(lower(list));
My final code is
Mylist = [];
for C = 1:length(docs)
list = tokenize(docs{C}, ' .,()"%-+/');
Newlist = unique(lower(list));
Mylist = [Mylist; Newlist];
end

Defining relationship for symbolic variable in MATLAB

Let's say I have a symbolic variable "q" that depends on another symbolic variable "t".
This is how I define each symbolic variables.
t= sym('t');
q = sym('q(t)');
And I have an expression that contains this (when I use pretty(expression))
result = blah1* diff(q(t),t) *blah2
I want to make this particular part a new variable. Let's say "qdot"
In the end, I want it to be like this.
result2 = blah1*qdot*blah2
I'm in the process of figuring it out. Thank you in advance.
You should use the subs function. Here is how to use it for your particular question
function Rewrite()
t = sym('t');
q = sym('q(t)');
a = sym('a');
blah1 = a^2;
blah2 = t^3;
result1 = blah1*diff(q,t)*blah2;
qDot = sym('qDot');
result2 = subs(result1, diff(q,t), qDot)
% result2 = a^2*qDot*t^3;
end
Note that
result2 = subs(result1, 'diff(q(t),t)', qDot)
and
newMiddle = sym('qDot');
result2 = subs(result1, diff(q,t), newMiddle)
also give the desired result.

Iterate through a MATLAB structure numerically

Is it possible to iterate through a MATLAB structure numerically like a vector instead of using the field names?
Simply, I am trying to do the following inside an EML block for Simulink:
S.a.type = 1;
S.a.val = 100;
S.a.somevar = 123;
S.b.type = 2;
S.b.val = 200;
S.b.somevar2 = 234;
S.c.type = 3;
S.c.val = 300;
S.c.somevar3 = 345;
for i = 1:length(s)
itemType = S(i).type;
switch itemType
case 1
val = S(i).val * S(i).somevar1;
case 2
val = S(i).val * S(i).somevar2;
case 3
val = S(i).val * S(i).somevar3;
otherwise
val = 0
end
end
disp(var);
You should be able to generate the fieldnames dynamically using sprintf using something like the following:
for i = 1:length(s)
theFieldName = sprintf('somevar%d', S(i).type);
val = S(i).val * getfield(S(i), theFieldName);
end
You need to use the field names, but you can do so dynamically. If you have a structure defined as:
s.field1 = 'foo';
s.field2 = 'bar';
Then you can access the field field1 with either
s.field1
s.('field1')
The only thing you need is the function fieldnames to dynamically get the field names such that your code example will look somewhat like
elements = fieldnames(S);
for iElement = 1:numel(elements)
element = S.(elements{iElement});
itemType = element.type;
switch itemType
case 1
val = element.val * element.somevar1;
case 2
val = element.val * element.somevar2;
case 3
val = element.val * element.somevar3;
end
end
If those are the exact field names, you should do some other things. First of all you would need to rethink your names and secondly you could use part of Matt's solution to simplify your code.

How do I rename a field in a structure array in MATLAB?

Given a structure array, how do I rename a field? For example, given the following, how do I change "bar" to "baz".
clear
a(1).foo = 1;
a(1).bar = 'one';
a(2).foo = 2;
a(2).bar = 'two';
a(3).foo = 3;
a(3).bar = 'three';
disp(a)
What is the best method, where "best" is a balance of performance, clarity, and generality?
Expanding on this solution from Matthew, you can also use dynamic field names if the new and old field names are stored as strings:
newName = 'baz';
oldName = 'bar';
[a.(newName)] = a.(oldName);
a = rmfield(a,oldName);
Here's a way to do it with list expansion/rmfield:
[a.baz] = a.bar;
a = rmfield(a,'bar');
disp(a)
The first line was originally written [a(:).baz] = deal(a(:).bar);, but SCFrench pointed out that the deal was unnecessary.
Here's a a way to do it with struct2cell/cell2struct:
f = fieldnames(a);
f{strmatch('bar',f,'exact')} = 'baz';
c = struct2cell(a);
a = cell2struct(c,f);
disp(a)