handing string to MATLAB function in Simulink - matlab

In my Simulink Model I have a MATLAB function, this_function, which uses as one parameter the name of the Simulink Model, modelname. The name is defined in an extra parameter file with all other parameters needed. Loading the parameter file loads modelname into the workspace. The problem is now, that this_function can't access modelname in the workspace and therefore the model doesn't run.
I tried to use modelname as a constant input source for this_function, which I used as a work-around previously, but Simulink doesn't accept chars/strings as signals. Furthermore does setting modelname to global not work as well.
Is there a way to keep modelname in the parameter file instead of writing it directly into this_function?

Simulink does not support strings. Like, anywhere. It really sucks and I don't know why this limitation exists - it seems like a pretty horrible design choice to me.
I've found the following workarounds for this limitation:
Dirty Casting
Let
function yourFun(num_param1, num_param2, ..., str_param);
be your MATLAB function inside the Simulink block, with str_param the parameter you want to be a string, and num_param[X] any other parameters. Then pass the string signal to the function like so:
yourFun(3, [4 5], ..., 'the_string'+0);
Note that '+0' at the end; that is shorthand for casting a string to an array of integers, corresponding to the ASCII codes of each character in the string. Then, inside the function, you could get the string back by doing the inverse:
model = char(str_param);
but usually that results in problems later on (strcmp not supported, upper/lower not supported, etc.). So, you could do string comparisons (and similar operations) in a similar fashion:
isequal(str_param, 'comparison'+0);
This has all the benefits of strings, without actually using strings.
Of course, the '+0' trick can be used inside constant blocks as well, model callbacks to convert workspace variables on preLoad, etc.
Note that support for variable size arrays must be enabled in the MATLAB function.
Fixed Option Set
Instead of passing in a string, you can pass a numeric scalar, which corresponds to a selection in a list of fixed, hardcoded options:
function yourFun(..., option)
...
switch (option)
case 1
model = 'model_idealised';
case 2
model = 'model_with_drag';
case 3
model = 'model_fullscale';
otherwise
error('Invalid option.');
end
...
end
Both alternatives are not ideal, both are contrived, and both are prone to error and/or have reusability and scalability problems. It's pretty hopeless.
Simulink should start supporting strings natively, I mean, come on.

Related

When subclassing "double" with new properties in MATLAB, is there an easy way to access the data value?

Say I have a class subclassing double, and I want to add a string (Similar to the 'extendDouble' in the documentation). Is there an easy way to access the actual numeric value without the extra properties, particular for reassigning? Or if I want to change the value, will I have to recreate the value as a new member of the class with the new value and the same string?
e.g.
classdef myDouble < double
properties
string
end
methods
function obj = myDouble(s)
% Construct object (simplified)
obj.string = s;
end
end
end
----------
x = myDouble(2,'string')
x =
2 string
x = 3
x =
3 string
Short answer: NO. There is no easy way to access a single member of a class when the class contains more than one member. You'll always have to let MATLAB know which part of the class you want to manipulate.
You have multiple questions in your post but let's tackle the most interesting one first:
% you'd like to instanciate a new class this way (fine)
x = myDouble(2,'string')
x =
2 string
% then you'd like to easily refer to the only numeric part of your class
% for assignment => This can NEVER work in MATLAB.
x = 3
x =
3 string
This can never work in MATLAB because of how the interpreter works. Consider the following statements:
% direct assignment
(1) dummy = 3
% indexed assignments
(2) dummy(1) = 3
(3) dummy{1} = 3
(4) dummy.somefieldname = 3
You would like the simplicity of the first statement for assignment, but this is the one we cannot achieve. The statement 2, 3 and 4 are all possible with some fiddling with subasgn and subsref.
The main difference between (1) and [2,3,4] is this:
Direct assignment:
In MATLAB, when you execute a direct assignment to a simple variable name (without indexing with () or {} or a field name) like dummy=3, MATLAB does not check the type of dummy beforehand, in fact it does not even check whether the variable dummy exists at all. No, with this kind of assignment, MATLAB goes the quickest way, it immediately create a new variable dummy and assign it the type and value accordingly. If a variable dummy existed before, too bad for it, that one is lost forever (and a lot of MATLAB users have had their fingers bitten once or twice by this behavior actually as it is an easy mistake to overwrite a variable and MATLAB will not raise any warning or complaint)
Indexed assignments:
In all the other cases, something different happens. When you execute dummy(1)=3, you are not telling MATLAB "create a new dummy variable with that value", you are telling MATLAB, "find the existing dummy variable, find the existing subindex I am telling you, then assign the value to that specific subindex". MATLAB will happlily go on, if it finds everything it does the sub-assignment, or it might complains/error about any kind of misassignment (wrong index, type mismatch, indices length mismatch...).
To find the subindex, MATLAB will call the subassgn method of dummy. If dummy is a built-in class, the subassgn method is also built in and usually under the hood, if dummy is a custom class, then you can write your own subassgn and have full control on how MATLAB will treat the assignment. You can check for the type of the input and decide to apply to this field or another if it's more suitable. You can even do some range check and reject the assignment altogether if it is not suitable, or just assign a default value. You have full control, MATLAB will not force you to anything in your own subassgn.
The problem is, to trigger MATLAB to relinquish control and give the hand to your own subassgn, you have to use an indexed assignment (like [2,3 or 4] above). You cannot do that with type (1) assignment.
Other considerations: You also ask if you can change the numeric part of the class without creating a new object. The answer to that is no as well. This is because of the way value classes work in matlab. There could be a long explanation of what happens under the hood, but the best example is from the MATLAB example you referenced yourself. If we look at the class definition of ExtendDouble, then observe the custom subassgn method which will perform the change of numeric value, what happens there is:
obj = ExtendDouble(b,obj.DataString);
So even Mathworks, to change the numeric value of their extended double class, have to recreate a brand new one (with a new numeric value b, and transfering the old string value obj.DataString).

how single and double type variables work in the same copy of code in Matlab like template in C++

I am writing a signal processing program using matlab. I know there are two types of float-pointing variables, single and double. Considering the memory usage, I want my code to work with only single type variable when the system's memory is not large, while it can also be adapted to work with double type variables when necessary, without significant modification (simple and light modification before running is OK, i.e., I don't need runtime-check technique). I know this can be done by macro in C and by template in C++. I don't find practical techniques which can do this in matlab. Do you have any experience with this?
I have a simple idea that I define a global string containing "single" or "double", then I pass this string to any memory allocation method called in my code to indicate what type I need. I think this can work, I just want to know which technique you guys use and is widely accepted.
I cannot see how a template would help here. The type of c++ templates are still determined in compile time (std::vector vec ...). Also note that Matlab defines all variables as double by default unless something else is stated. You basically want runtime checks for your code. I can think of one solution as using a function with a persistent variable. The variable is set once per run. When you generate variables you would then have to generate all variables you want to have as float through this function. This will slow down assignment though, since you have to call a function to assign variables.
This example is somehow an implementation of the singleton pattern (but not exactly). The persistent variable type is set at the first use and cannot change later in the program (assuming that you do not do anything stupid as clearing the variable explicitly). I would recommend to go for hardcoding single in case performance is an issue, instead of having runtime checks or assignment functions or classes or what you can come up with.
function c = assignFloat(a,b)
persistent type;
if (isempty(type) & nargin==2)
type = b;
elseif (isempty(type))
type = 'single';
% elseif(nargin==2), error('Do not set twice!') % Optional code, imo unnecessary.
end
if (strcmp(type,'single'))
c = single(a);
return;
end
c = double(a);
end

get string of enum - matlab coder

I have an enum like this:
classdef(Enumeration) bla_type < int32
enumeration
bla_one(1)
bla_2(2)
end
end
I can get the 'string representation of an element' like this:
char(bla_type.bla_one)
=>
bla_one
Unfortunately, matlab coder does not like this. Are there any alternatives?
There's no elegant built-in way in Coder to do this; the enumerated type becomes a standard enum in C, and the enumeration function in MATLAB is unavailable in Coder. The simplest, but unpleasant, way to do it is to create a function with a switch statement with the manually populated string names. It's not nice, since now you have to maintain the names in two places.
However, one way that does work nicely is to use one of the more powerful features of Coder: coder.const.
The solution is to have a function that creates a table of the enumeration members and their values. This function itself cannot be compiled, but rather is called during compilation to build a lookup table in the resulting C code. We can use this lookup table in a Coder compatible function to get the data.
Imagine we have an enumerated type like this (in someenum.m):
classdef someenum < int32 %#codegen
enumeration
First_thing (0)
Second_thing (2)
Another_thing (3)
No_thing (4000)
end
end
We also then have the build-time function called 'buildsomeenum2name.m':
function [namearray, memberidx] = buildsomeenum2name
%BUILDSOMEENUM2NAME Compile-time creation of lookup table for someenum
% THIS FUNCTION IS NOT CODER COMPATIBLE, BUT IS CALLED DURING COMPILE
% TO CREATE A LOOKUP TABLE.
[members, names]=enumeration('someenum');
maxlen = 0;
for i=1:numel(names)
maxlen = max(maxlen, numel(names{i}));
end
namearray = char(zeros(numel(names), maxlen));
for i=1:numel(names)
namearray(i, 1:numel(names{i})) = names{i};
end
memberidx = int32(members); %#ok<NASGU>
end
When buildsomeenum2name is called in MATLAB, it creates an array of string names of all the members of the enumerated type and another vector list of their numeric values in the same order.
Here's the cool part. MATLAB Coder can evaluate functions at build time and turn them into constants. These constants become literals in the resulting C code, rather than actual code. Since the functions are evaluated at build time, the enumeration information is put into a nice table, therefore if we make a Coder-compatible lookup function, we can use it to convert the member types into a string. We'll call this function 'someenum2name.m':
function name = someenum2name(enum) %#codegen
%SOMEENUM2NAME Get the string name of an enumerated type
% The following line loads namearray and memberidx with constant arrays
coder.extrinsic('buildsomeenum2name');
[namearray, memberidx] = coder.const(#buildsomeenum2name);
% First find the index of the enumerated type in the memberidx vector
index = find(memberidx==int32(enum));
if isempty(index)
name = 'UNKNOWN';
return;
end
name = deblank(namearray(index,:));
end
This function uses the coder.const command to evaluate buildsomeenum2name at compile time and create the lookup tables. We have to instruct Coder not to try to compile buildsomeenum2name, so use the coder.extrinsic command to tell it to ignore the function. Then someenum2name can look up the index for the string and pull it out (deblank is used because the strings in the array have trailing 0's that need to be pulled out.) The function someenum2name can be called both within MATLAB and in Coder compiled code.
This method keeps everything in-sync, so if you ever add a new member to the enum or rearrange them, the coder.const function will make sure that the values are rebuilt in the output code so that someenum2name works.
At the command line, this looks like:
>> someenum2name(someenum.No_thing)
ans =
No_thing
Try [~,s]=enumeration('bla_type'). You get a cell array of strings containing the name of elements in s. So bla_one will be in s{1}. Don't know whether that is supported by MATLAB coder though.

What does the . operator do in matlab?

I came across some matlab code that did the following:
thing.x=linspace(...
I know that usually the . operator makes the next operation elementwise, but what does it do by itself? Is this just a sub-object operator, like in C++?
Yes its subobject.
You can have things like
Roger.lastname = "Poodle";
Roger.SSID = 111234997;
Roger.children.boys = {"Jim", "John"};
Roger.children.girls = {"Lucy"};
And the things to the right of the dots are called fields.
You can also define classes in Matlab, instatiate objects of those classes, and then if thing was one of those objects, thing.x would be an instance variable in that object.
The matlab documentation is excellent, look up "fields" and "classes" in it.
There are other uses for ., M*N means multiploy two things, if M, N are both matrices, this implements the rules for matrix multiplication to get a new matrix as its result. But M.*N means, if M, N are same shape, multiply each element. And so no like that with more subtleties, but out of scope of what you asked here.
As #marc points out, dot is also used to reference fields and subfields of something matlab calls a struct or structure. These are a lot like classes, subclasses and enums, seems to me. The idea is you can have a struct data say, and store all the info that goes with data like this:
olddata = data; % we assume we have an old struct like the one we are creating, we keep a reference to it
data.date_created=date();
data.x_axis = [1 5 2 9];
data.notes = "This is just a trivial example for stackoverflow. I didn't check to see if it runs in matlab or not, my bad."
data.versions.current = "this one";
data.versions.previous = olddata;
The point is ANY matlab object/datatype/whatever you want to call it, can be referenced by a field in the struct. The last entry shows that we can even reference another struct in the field of a struct. The implication of this last bit is we could look at the date of creation of the previous verions:
data.versions.previous.date_created
To me this looks just like objects in java EXCEPT I haven't put any methods in there. Matlab does support java objects which to me look a lot like these structs, except some of the fields can reference functions.
Technically, it's a form of indexing, as per mwengler's answer. However, it can also be used for method invocation on objects in recent versions of MATLAB, i.e.
obj.methodCall;
However note that there is some inefficiency in that style - basically, the system has to first work out if you meant indexing into a field, and if not, then call the method. It's more efficient to do
methodCall(obj);

matlab: is there a way to import/promote variables from a structure to the current workspace?

function y = myfunc(param)
C = param.C;
L = param.L;
Kp = param.Kp;
Ki = param.Ki;
...
Is there a way to generalize the above code? I know how to generalize the structure access using fieldnames() and getfield(), but not how to set variables without calling eval() (which is evil).
for n = fieldnames(param)'
name = n{1};
value = param.(name);
do_something_with(name,value); % ????
never mind, I figured it out; this helper function works:
function vars_pull(s)
for n = fieldnames(s)'
name = n{1};
value = s.(name);
assignin('caller',name,value);
end
The only way to create a variable whose name is determined at run-time is to use a function like eval, evalin, feval, or assignin. (assignin is the least evil choice BTW, at least you don't need to convert your value to a string and back.)
However, I question why you want to do that, why not just access the values through the input structure as you need them. If you want to save typing (speaking from experience, as I am extremely lazy), I usually name my input parameter structure something short, like p. The throughout my code I just access the fields directly, (e.g. p.Kp, and after a while I don't even see the p. anymore.) This also makes it easy to pass the structure into subfunctions as needed.
You can use the excellent submission at FileExchange:
V2STRUCT - Pack & Unpack variables to & from structures with enhanced functionality
Here's a workaround: save the structure to a .mat file using the '-struct' option, and then immediately reload it. Here's an example for struct variable X:
save('deleteme.mat','-struct','X');
load('deleteme.mat');
delete('deleteme.mat');
It's kludgey, but actually pretty fast, at least with an SSD.