How can I make a string executable? - modelica

I'm trying to execute a string in Modelica. This string would be saved in a variable in order to be able to change it when I need to.
function Test
input String inComp="resistor.R:=2";
output String outComp;
algorithm
outComp:=inComp;
end Test;
Could you please
I am using Dymola.
What I need to do is the following.
-Read component names from a text file (or input them while executing the function)
-Then change parameters of these components. This code is an example:
function Test
input String inComp="resistor"; //Entered by the user, or read from a text file
output Real result;
algorithm
inComp.R :=2 ; /*This is incorrect since it wouldn't understand that
I want to enter : resistor.R := 2; */
result := inComp.R ; //In order to view the result
end Test;

What you are trying to do is not generally possible in Modelica. It may be that some tools have a "reflective API" that allows this (or perhaps a built-in function that takes a command string and executes it) but there is certainly no universal API that works across tools.
If you want to run a bunch of simulations in Dymola with different parameter values, I can suggest at least three different wants to proceed.
Use the DDE interface to send commands to Dymola. This way you can formulate the parameter values "somehow" (externally from Dymola) and then just request Dymola to run simulations. I'm not sure how rich the DDE interface is, so I'm not sure if it will do what you need (e.g. reaping results).
Write a script file. This is a bit different from writing a function, but nearly the same in syntax. For example, to run the "CoupledClutches" example with several different inertia values, you can do this (in the command window):
for j in {1.0, 1.1, 1.2, 1.5, 1.8} loop
J1.J := j;
simulateModel("Modelica.Mechanics.Rotational.Examples.CoupledClutches",
resultFile="CoupledClutches_"+String(j));
end for;
Use a function (as you were) but call simulateModel with modifiers, e.g.
function RunLoop
algorithm
for j in {1.0, 1.1, 1.2, 1.5, 1.8} loop
simulateModel("Modelica.Mechanics.Rotational.Examples.CoupledClutches(J1(J="+String(j)+"))",
resultFile="CoupledClutches_"+String(j));
end for;
end RunLoop;
Use the built-in functions simulateExtendedModel and simulateMultiExtendedModel which actually do pretty much the same as above but in a cleaner way (type document("simulateExtendedModel") and document("simulateMultiExtendedModel") in the Dymola command window to get more info on these).
OK, that should give you a start. If none of those work for whatever reason, just update the question with whatever additional requirements you have.

A different option to use Perl etc. to dynamically write and execute some script. For example Text::Template could be used as a templating engine. I do this for LaTeX regularly.

Related

Anylogic: can you type a probability distribution into an edit box?

In the simulation window, before the run, I'd like to change some probability distributions (e.g. delay time) by typing, for example, "triangular(5, 20, 15)" into a specific editbox linked to a variable.
I know how to do this with static values, but I couldn't figure out how to do the same with probability distributions.
AnyLogic offers a built-in functionality for that with com.anylogic.engine.database.CodeValue.
It is originally meant that a distribution function stored as text in the internal database can be parsed to java code and executed, but it actually also works without the database and for any kind of code. It is the same idea as in Benjamin's answer, just that you do not need to add any external java library.
Use it like this:
CodeValue myCode = new CodeValue(this,"....java code to be executed");
myCode.execute();
And in your specific case, assuming you have a variable named variableA and an editbox named editbox, use the following to evaluate the expression, get a value and set it for the variable:
CodeValue myCode = new CodeValue(this,"variableA = "+editbox.getText());
myCode.execute();
Obviously, allowing the user to type any command there and running it without a check or error treatment is a bad idea, be aware of that.
This is a Java issue. You need to convert a String (your editbox content) to executable code. Not straight-forward but also not impossible, see Convert String to Code and similar posts.

What's the purpose of 'coder' in matlab?

I was seeing the built-in function estimateFundamentalMatrix and it looks like as follows
function r = checkOutputClassStrings(list, value)
potentialMatch = validatestring(value, list, ...
'estimateFundamentalMatrix', 'OutputClass');
coder.internal.errorIf(~strcmpi(value, potentialMatch), ...
'vision:estimateFundamentalMatrix:invalidOutputClassString');
r = 1;
I was curious about the coder.internal.errorIf function. I guessed that coder is a system object that shows internal states of a function, but I don't know exactly.
coder is a package that is part of the MATLAB Coder product.
MATLAB Coder allows you to convert a subset of the MATLAB language into C code - the C code can then subsequently be incorporated into wider C applications, or brought back into MATLAB via the MEX interface, or delivered to an embedded device. When using MATLAB Coder, you will include commands from the coder package within your MATLAB code - they typically have no effect on the code when it is run within MATLAB, but when converting to C code they help you to control the way it is converted, by adding additional information necessary to help with the conversion (for example, by controlling the inlining of a function, or specifying that a for-loop should be unrolled).
Some toolboxes, including the Computer Vision Toolbox that contains the code snippet you refer to, explicitly support the use of MATLAB Coder to generate C code from them, in that they make sure to only use the subset of the MATLAB language that is convertible into C, and they include coder commands to help optimise their conversion into C.
The command you're seeing here says that, when converting the MATLAB code into C, it should include an explicit check in the C code to compare value with potentialMatch, and exit with an error if they don't match.
(I'll be honest - I'm not entirely sure why this is necessary. As far as I can see, if the code has got past the validatestrings statement, then by definition it should always pass the test in the subsequent statement. Seems a bit redundant to me, but maybe I'm overlooking some detail).
I'm just formalising the answer I gave in the comments...
The coder.internal.errorIf is exactly what the name suggests. It's an internal command to conditionally issue an error.
The strcmpi function performs a case insensitive string compare, and returns a Boolean (true/false) value.
The tilde (~) negates the result of the call to strcmpi.
So the line you're curious about is somewhat equivalent to this on the surface:
% Use strcmpi for case insensitive string comparison
if ~strcmpi(value, potentialMatch)
% When using 'error', the string must be specified along with the message identifier.
% The errorIf command was leveraging the in-built 'message' catalog.
% In this case I've lifted the error message from calling the original errorIf command.
error('vision:estimateFundamentalMatrix:invalidOutputClassString', ...
'Expected OutputClass to be ''double'' or ''single''');
end
The code.internal.errorIf command is, as pointed out in other answers and comments, a different construct than the common error command, which allows MATLAB to optimise C code generation (hence why it is in the coder package).
For more coder-specific details, see Sam's answer.

How to include a c-header with constants in Matlab Simulink

I'm developing a Simulink modell with many C-s-functions. For an easier handling I want to use constants in the c-s-function as in the simulink-modell. So I have a c-header with preprocesser constants like:
#define THIS_IS_A_CONSANT 10
And there is the question:
How it is possible to include this in Simulink in this way I can use THIS_IS_A_CONSANT for example in a constant source like a workspace-variable?
Thanks and regards
Alex
There is functionality in Simulink that will allow you to include custom C header files that define constants, variables, etc.; however, as far as I know (and as one might expect) this really is only pertinent in cases where code is being generated and compiled.
So, for the most part, this particular functionality is only relevant when you are using Simulink Coder to generate a stand-alone executable from your model. For example, this link shows how to include parameters stored in an external header file during code generation through the use of Simulink.Parameter objects with Custom Storage Classes and the Code Generation - Custom Code Pane under the model's Configuration Parameters.
This link from the Simulink doc shows how to use the #define custom storage class to achieve similar results.
However, it sounds like neither of these really solve your issue, as you want to make use of the code in the header file during simulation.
That said, considering that there are elements in Simulink, such as Stateflow Charts and MATLAB Function blocks, that generate and build code "under the hood" during simulation, it's (at least hypothetically) possible that you might be able to use some of the concepts described above to access the values in your header file from one of those elements during simulation. For example, I was successfully able to access preprocessor macros in a Stateflow chart just by going to the Simulation Target->Custom Code pane under Configuration Parameters and including the text #include "header.h" under Include custom C code in generated: Header file. (In this case, header.h contained the line of C code that you included in your post)
Although it seems like you should be able to extend this functionality further, this really was the limit of what I was able to achieve as far as accessing the header file during simulation was concerned. For example, I know that running a model in Rapid Accelerator mode actually generates and builds code under the hood, so seemingly you should be able to use some combination of the techniques I described above to be able to access values from the header file during simulation. It looks like the code that Rapid Accelerator mode generates doesn't respect all of the settings defined by those techniques in the same way that Simulink/Embedded Coder do, though, so I just kept running into compilation errors. (Although maybe I'm just missing some creative combination of settings that could make that work).
Hopefully that helps explain Simulink's abilities (and limitations) regarding the inclusion of C header files. So to summarize, according to the links included above, what you are asking for is almost barely possible, but in practice... not really.
So if really all you want is to be able to create workspace variables out of the preprocessor #define's in your header file, it probably is just easiest to manually parse the file with a MATLAB script, as had previously been suggested in the comments. Here is a quick-and-dirty script that loads in a header file, iterates over each line, uses a regular expression (which you can improve upon if needed) to parse #define statements, and then calls eval to create variables from the parsed input.
filename = 'header.h';
pattern = '^\s*#define\s*(\w*)\s*(\d*\.?\d+)';
fid = fopen(filename);
tline = fgetl(fid);
while ischar(tline)
tokens = regexp(tline, pattern,'tokens','once');
if(numel(tokens) == 2)
eval([tokens{1} ' = ' tokens{2}]);
end
tline = fgetl(fid);
end
fclose(fid);
You could put this code in a callback so that it will execute every time you load your model. Just goto File->Model Properties->Model Properties, click on the Callbacks tab, and then place the code under whichever callback you desire (such as PreLoadFcn if you want it to run immediately before the model loads).

Matlab function signature changes

Let us say that I have a Matlab function and I change its signature (i.e. add parameter). As Matlab does not 'compile' is there an easy way to determine which other functions do not use the right signature (i.e. submits the additional parameter). I do not want to determine this at runtime (i.e. get an error message) or have to do text searches. Hope this makes sense. Any feedback would be very much appreciated. Many thanks.
If I understand you correctly, you want to change a function's signature and find all functions/scripts/classes that call it in the "old" way, and change it to the "new" way.
You also indicated you don't want to do it at runtime, or do text searches, but there is no way to detect "incorrect" calls at "parse-time", so I'm afraid these demands leave no option at all to detect old function calls...
What I would do in that case is temporarily add a few lines to the new function:
function myFunc(param1, param2, newParam) % <-- the NEW signature
if nargin == 2
clc, error('old call detected.'); end
and then run the main script/function/whatever in which this function resides. You'll get one error for each time something calls the function incorrectly, along with the error stack in the Matlab command window.
It is then a matter of clicking on the link in the bottom of the error stack, correct the function call, and repeat from the top until no more errors occur.
Don't forget to remove these lines when you're done, or better, replace the word error with warning just to capture anything that was missed.
Better yet: if you're on linux, a text search would be a matter of
$ grep -l 'myFunc(.*,.*); *.m'
which will list all the files having the "incorrect" call. That's not too difficult I'd say...You can probably do a similar thing with the standard windows search, but I can't test that right now.
This is more or less what the dependency report was invented for. Using that tool, you can find what functions/scripts call your altered function. Then it is just a question of manually inspecting every occurrence.
However, I'd advise to make your changes to the function signature such that backwards compatibility is maintained. You can do so by specifying default values for new parameters and/or issuing a warning in those scenarios. That way, your code will run, and you will get run-time hints of deprecated code (which is more or less a necessary evil in interpreted/dynamic languages).
For many dynamic languages (and MATLAB specifically) it is generally impossible to fully inspect the code without the interpreter executing the code. Just imagine the following piece of code:
x = magic(10);
In general, you'd say that the magic function is called. However, magic could map to a totally different function. This could be done in ways that are invisible to a static analysis tool (such as the dependency report): e.g. eval('magic = 1:100;');.
The only way is to go through your whole code base, either inspecting every occurrence manually (which can be found easily with a text search) or by running a test that fully covers your code base.
edit:
There is however a way to access intermediate outputs of the MATLAB parser. This can be accessed using the undocumented and unsupported mtree function (which can be called like this: t = mtree(file, '-file'); for every file in your code base). Using the resulting structure you might be able to find calls with a certain amount of parameters.

Accessing variable by string name

I need to load experimental data into scicoslab, a (pretty badly designed) clone fork of scilab which happens to support graphical modeling. The documentation on the web is pretty poor, but it's reasonably similar to scilab and octave.
The data I need to process is contained into a certain number of text files: Data_005, Data_010, …, Data_100. Each of them can be loaded using the -ascii flag for the loadmatfile command.
The problem comes from the fact that loadmatfile("foo", "-ascii") loads the file foo.mat into a variable named foo. In order to to cycle on the data files, I would need to do something like:
for i = [5:5:100]
name = sprintf("Data_%02d", i);
loadmatfile(name, "-ascii");
x = read_var_from_name(name);
do_something(x);
end
where what I search for is a builtin read_var_from_name which would allow me to access the internal symbol table by string.
Do you know if there exist a similar function?
Notes:
There's no way of overriding this behavior if your file is in ascii format;
In this phase I could also use octave (no graphical modelling is involved), although it behaves in the same way.
>> foo = 3.14; name = 'foo'; eval(name)
foo =
3.1400
The above works in MATLAB, and Scilab's documentation says it also has an eval function. Not sure if I understood you correctly, though.
#arne.b has a good answer.
In your case you can also do that in matlab:
a=load('filename.mat')
x=a.('variable_name')
lets go through your points one by one:
"ScicosLab, a (pretty badly designed) clone of Scilab" This in my opinion is an inaccurate way of introducing the software. ScicosLab is not a clone of Scilab but a fork of it. The team behind ScicosLab (INRIA) are the ones who made scocos (now called xcos in Scilab development line). At some point (from Scilab v4) the Scilab team decided to move away from Tcl/tk towards Java, but the SciccosLab/scicos team departed, keep using the language (Tcl) and it's graphical user interface design package (tk). Giving the ScocosLab community the credit that the whole Scilab documentation and support is not very good in general. :) (more about Scilab and the forks here)
Regarding the technical question I'm not sure what you are trying to achieve here, Scilab/ScicosLab still have the eval function which basically does what you want. However this function is to be deprecated in favor of evstr. There is also the execstr function which worth studying.
The loadmatfile, as far as I have understood, "tries" to load the variables defined in a MATLAB .mat file (MATLAB's proprietary tabular format) into the Scilab workspace. For example if there is a variable foo it will "try" to create the variable foo and loads its value from the MATLAB script. Check this example. I would create a variable x(i) = foo in the for loop. again your question is not completely clear.
As a side note maybe you could consider exporting your data as CSV instead of .mat files.