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

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.

Related

Collect internal variables of nested functions in matlab

I have a project consisting of multiple nested functions.
For debugging purpose I want to save all internal variables in one way or another, in order to display figures, replay parts of code etc...
I also want to keep this as transparent as possible regarding calculation time.
My first thought was to create a global variable, and store programmatically at the end of each function the inputs and outputs inside the variable as a structure :
globalVariable.nameOfParentfunction_NameOfFunction.nameInput1 = valueInput1;
globalVariable.nameOfParentfunction_NameOfFunction.nameInput2 = valueInput2;
...
globalVariable.nameOfParentfunction_NameOfFunction.nameOutput1 = valueOutput1;
...
Is it possible to use some kind of reflection to get the name and value of inputs/outputs without necessarily parse the file where the function is written?
I found a good but maybe outdated topic about parsing
How do I collect internal signals?
The simple solution is to use save, which will save all variables in the current workspace (the function’s context) to file.
If you want to keep the values in memory, not in a file, you can use names = who to get a list of all variables defined in the current workspace, then use val = eval(names{i}) to get the value of the variable called name{i}.
I would recommend putting all of that in a separate function, which you can call from any other function to store its variables, to avoid repeating code. This function would use evalin('caller',…) to get names and values of variables in the workspace of the calling function.
Note that using eval or evalin prevents MATLAB from optimizing code using its JIT. They also are dangerous to use, since they can execute arbitrary code, however in this case you control what is being executed so that is no a concern.

How to select output in Anylogic by agent parameter?

So, I'm pretty new with Anylogic, but have done a lot of tutorials and I have programming experience in Java. For my thesis I'm modelling a vehicle flow as a process. In the source block, I create custom agents (vehicles) with some parameters from the database. This works fine. Then I want to assign an electric parameter with randomTrue(0.5). For this, I call a setupTaxi-function, where electric ist set. The parameter for the randomTrue-function should be changeable, so I set it as an extra paramter anteilEtaxis (0.5).
After that, I want the vehicles to do different things depending on the value of electric using SelectOutput. I selected the Condition and test on agent.electric.
I basically did the exact same thing as described in the Anylogic help. And yet the framework always chooses the true Output port, no matter if the parameter ist set to true or false.
See the image for setup and parameters. I tested this via console (the first line is a println-call in source, the second a println-call in selectOutput.). Plus you can see that the parameter is set to different values, because the 3D visualisation model depends on it:
enter image description here
Also, I tried a few different combinations of setting the parameters, reading them etc... The only thing that will work is putting randomTrue(0.5) directly in the Condition box. This is not what I want though. So if you have an idea, what is wrong, please tell me.
This is a typical beginners problem.
I will assume you are calling the setupTaxi-function in your source in the "on exit" action... If you are doing that, then it's too late and the agent already made its decision on where it will go after the select output block.
You have to call your setupTaxi-function in 2 possible places:
1) In your source on the "on at exit" action
2) In your vehicle agent on the "on startup" action
Or even.. just make electric variable have a default value of randomTrue(main.anteilEtaxis)... that will also work.

Impossible to tune Simulink Parameter at simulation time

I have a problem. I have an embedded function in my simulink model which has a structure (struct) as parameter. It contains only numerical values and I generate an S-Function of the embedded function by right clicking on the block and C/C++ code --> Generate S-function.
I then have the compiled block, if I try to change some values of my struct nothing changes (the fields of my struct stay the same as when I first compiled my embedded function).
When I compiled the embedded function block I selected the parameter to be tunable. I selected the parameter to be tunable in the Model Explorer. I tried to follow this video tutorial by mathworks: http://fr.mathworks.com/videos/tunable-structure-parameters-68947.html (The video is for r2010a while I am at r2015b) It is a bit different the interface in r2015b (from the one in the video) but when I click on Configure , like the guy does in the video, nothing happens.
Could you help me please?
Thanks a lot.
Once I had also decided to reduce the number of tunable parameters by checking the 'inline parameters' checkbox and then specifying the exception variables (variable that have the permission to be tunable even when 'inline parameters' is turned on. It did not work.
In case you aim does not heavily rely on optimization, it would be better if you simply turn off 'inline parameters'.
After that, the constant blocks (i suppose you are giving the input to your s-function from constant blocks) will become tunable.
Another advice: add mex in the init function of your model callbacks. It will save you from getting weird output (usually due to uncleared/un-reset variables from previous runs).
Hope it helps!

Loading Variable-Based Parameters in Behavior Search

I am using Behavior Search to calibrate my NetLogo model for 20 different hospital units. I am using global variables to set the min and max for several sliders in my model, but I think this is causing an error in Behavior Search when I attempt to load the parameter values from the model. However, I don't want to manually enter these parameter ranges manually each time I use Behavior Search.
Is there a way to get around this error? Is there a way to set the min and max for a specific slider to a constant, rather than using global variables?
Thanks for your help!
BehaviorSearch developer here -- if I'm understanding your question correctly, your NetLogo model has a slider which has a min/max constraint that is not set to a constant, but is instead set to a global variable (in the slider settings, accessed from the NetLogo interface).
When I choose such a model using the BehaviorSearch GUI, and then click the "Load parameter ranges from model interface" button, then I get the value of 0 for that constraint. (I don't see any error message -- just the value 0 (if you're getting an error message instead, then I may not be understanding your situation correctly, and perhaps you could post exactly what error message you're seeing?)
This will be true even if you are setting the slider min/max to a global value in the special STARTUP procedure (see: http://ccl.northwestern.edu/netlogo/docs/dict/startup.html), because STARTUP is only run when a model loads in the NetLogo GUI, and not when a model is loaded in headless NetLogo.
Thus, unfortunately, I think the answer to your question is: "no, there isn't a way to get BehaviorSearch to load the parameter ranges from global variables within the model".
Some possible work-arounds:
BehaviorSearch is open-source -- some changes could be made to it -- i.e., maybe adding in a call to "startup" whenever BehaviorSearch GUI loads the parameter ranges would be sufficient for you.
If you're only doing a few searches, I don't see why manually editing the parameter ranges would be particularly onerous. However, if you're generating a lot of different searches with this model, then I can see how it might be an issue. The .bsearch files are just XML text files, so you might consider generating them without the BehaviorSearch GUI, e.g. using a scripting language.

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.