How to insert page break through the program in maple? - maple

How should we insert a page break via the code itself in maple program ?
Not insert page break? of menu
As I want to insert the page break as the code runs and with other outputs. In maple code.

Let's suppose that you have the following PutGraph procedure defined and available.
(You could define it in the Startup Code region of your Document/Worksheet. Or you could define it in your Maple initialization file. Or you could define it and store it in a .mla Library archive within your libname path. Or you could simply define it at the start of any Document/Worksheet in which you want to utilize it. I leave that choice to you.)
Then you can utilize this Putgraph procedure instead of DrawGraph, with the extra effect that it inserts a pagebreak right before the inlined plot of the Graph.
It also accepts a 2D or 3D plot as its argument. And if its argument is a Graph then you can also pass additional arguments that would normally be accepted by DrawGraph.
The restriction is that you can only effectively use one such call to this implementation of PutGraph per Execution Group or Document Block. If you want it done otherwise then you will have to show me explicitly how you need to call it once for multiple insertions. If you want specific behaviour then you will have to describe it adequately.
Here's the procedure, as 1D Maple notation code:
PutGraph:=proc(GG::{Graph,specfunc({PLOT,PLOT3D})})
local T,xml;
uses DocumentTools,DocumentTools:-Layout,GraphTheory;
if GG::Graph then
T:=DrawGraph(GG,_rest);
else T:=GG; end if;
xml:=Worksheet(Group(Input(Textfield(InlinePlot(T)))));
InsertContent(subsindets(xml,'specfunc(anything,_XML_Input)',
u->':-_XML_Input'(':-_XML_Pagebreak'(),
op(u))));
return NULL;
end proc:
Here's some example of calling it. (I'll mention again: it needs to be called at most once per Execution Group or Document Block. If you put it more than once in the same Execution Group/Block then only the last instance will work as intended.)
G1 := GraphTheory:-RandomGraphs:-RandomGraph(6,degree=3):
Now, in its own Execution Group/Document Block,
PutGraph(G1);
You can have something else appear before the next page break, or several things like text, other input/output, etc.
somethingelse;
And now, in its own Execution Group/Block,
PutGraph(G1,showlabels);
And so on,
somethingelse;
PutGraph(G1,showweights);
somethingelse;
P := GraphTheory:-DrawGraph(G1):
PutGraph(P);
somethingelse;

Related

How to change verbosity of uvm components after certain condition

I am trying to change the UVM verbosity of the simulation after satisfying certain conditions. Verbosity options of different components are passing through the command line as +uvm_set_verbosity. Once the conditions are satisfied, then the simulations should run with the the command line +uvm_set_verbosity option. Till then simulation runs with low verbosity for all components.
Looking through the UVM library code, it appears that there is a function called m_set_cl_msg_args(). This function calls three other functions that appear to consume the command line arguments like: +uvm_set_verbosity, +uvm_set_action, +uvm_set_severity.
So what I did was get the uvm_root instance from the uvm_coreservice singleton, and then use the get_children() function from uvm_component class to recursively get a queue of all of the uvm_components in the simulation. Then call the m_set_cl_msg_args() function on all of the components.
My code looks like:
begin
uvm_root r;
uvm_coreservice_t cs_t;
uvm_component array_uvm[$];
cs_t = uvm_coreservice_t::get();
r = cs_t.get_root();
r.get_children(array_uvm);
foreach(array_uvm[i])
array_uvm[i].m_set_cl_msg_args();
end
Even though this code compiles properly, But this is not changing verbosity. Any idea ?
Moreover I am able to print all the components in array_uvm. So I am guessing
array_uvm[i].m_set_cl_msg_args();
this as a wrong call.
Anyone have any other suggestion to change verbosity during run time.
You should never use functions in the UVM that are not documented in the language reference manual. They can (and do) change in any revision. I'm guessing +uvm_set_verbosity only works at time 0 by default.
There is already a function to do what you want
umm_top.set_report_verbosity_level_hier()
I suggest using +UVM_VERBOSITY=UVM_LOW to start your test, and then define your own switch for activating the conditional setting.
If you want a specific component, use component_h.set_report_verbosity_level() (add the _hier to set all its children)
You can use the UVM's command line processor get_arg_values() method to specify the name of the component(s) you want to set, and then use umm_top.find() to get a handle to the component.

Add inports & outports to Simulink C Mex S-Function mask

I am trying to amend the example given here for creating a dynamic masked subsystem, where I want to dynamically change the number of imports and outports to an S-Function.
I have a very simple S-Function implemented in C (it's the timestwo example in the documentation) and for which I wish the user to be able to define the number of inputs and number of outputs in a mask. The intention is then, within the S Function, to manipulate the received input values and write to the output values. The S-Function will eventually do some quite complicated stuff and I need multiple instances of it in Simulink, hence why I want it defined in a library.
I have put the S-Function into a library and unlocked it by choosing Diagram->Unlock Library.
I have defined 2 variables, numInports and numOutports in the Parameters & Dialog pane of the mask editing window.
I then add the following to the Initialization pane:
blocks = find_system(gcb,...
'LookUnderMasks','on',...
'FollowLinks','on',...
'RegExp', 'on',...
'BlockType', 'port');
if ~isempty(blocks)
Simulink.SubSystem.deleteContents(gcb);
end
for n=0:(numInports - 1)
label = sprintf('/In%d', n);
add_block('built-in/Inport',[gcb,label]);
end
for n=0:(numOutports - 1)
label = sprintf('/Out%d', n);
add_block('built-in/Outport',[gcb,label]);
end
The intention is for the initialisation to delete all imports and outports when the parameters are changed, then recreate them. I then save the model within the library.
The find_system() command should find and delete all blocks with port in the type, as suggested here and here.
I have created a model that uses this library model S Function implementation. However, when I update the parameters, I get the error:
Error in 'MyModel/MyLibrarySFunction': Initialization commands cannot be evaluated. Caused by:
A new block named 'MyModel/MyLibrarySFunction/In0' cannot be added.
Can anybody please advise what is going wrong here?
EDIT:
The documentation for find_system() has all as a valid parameter value, not the on I used and which was in the documentation example, but this seems to have no effect when I change it. I added:
msg = sprintf('Num blocks: %d', numel(blocks));
disp(msg);
just after the find_system() call and get 0 for the number of blocks found, so I guess the problem may be that In0 is not deleted and hence I am trying to reinsert it.

Simulink: What happens when subsystems are initialized?

I've been having a lot of trouble getting simulink's block callbacks to run, and the documentation is woefully inadequate and disorganized. It seems that I'm misunderstanding multiple points of how Simulink compiles models, but since StackOverflow dislikes multi-part questions, I will post them one at a time.
The situation: I have a library of components, each of which is a virtual subsystem whose parameters are defined through the masks. Block A has Parameter a which is sent to the base workspace using the 'assignin' command.
Next, the block B has a parameter b which is initialized in the Initialization tab of the mask.
Finally, the StartFcn callback of the block B runs a script which needs to reference both a and b to calculate c. In the script, I reference a simply as a because it's in the 'base' workspace, and I reference b using get_param(gcb,'b').
Now, this last command works when the parameter b is a user input (so it's a constant value). But in my case, this b is calculated using other parameters in the Initialization tab. And for some reason, in the script, this parameter is always zero.
I added a display within the block B to see what these values are, and they are clearly non-zero.
Can someone please explain why the script cannot seem to get the real value of the areas out of the block?
You can get the masked workspace variable using getworkspacevariable

Determining direct-feedthrough paths without compilation/execution

I am currently working on a tool written in M-Script that executes a set of checks on a given simulink model. This tool does not compile/execute the model, I'm using find_system and get_param to retrieve all the information I need in order to run the routines of my tool.
I've reached a point where I need to determine whether a certain block has direct-feedthrough or not. I am not entirely sure how to do this. Two possible solutions come to mind:
A property might store this information and might be accessible via get_param. After investigating this, I could not find any such property.
Some block types have direct-feedthrough (Sum, Logic, ...), some other do not (Unit Delay, Integrator), so I could use the block type to determine whether a block has direct-feedthrough or not. Since I'm not an experienced Simulink modeller, I'm not sure if its possible to tell whether a block has direct-feedthrough by solely looking at its block type. Also, this would require a lookup table including all Simulink block types. An impossible task, since additional block types might get added to Simulink via third party modules.
Any help or pointers to possible solutions are greatly appreciated.
after some further research...
There is an "official solution" by Matlab:
just download the linked m-file
It shows that my idea was not that bad ;)
and for the record, my idea:
I think it's doable quite easily. I cannot present you some code yet, but I'll see what I can do. My idea is the following:
programatically create a new model
Add a Constant source block and a Terminator
add the Block you want to get to know the direct feedthrough ability in the middle
add_lines
run the simulation and log the states, which will give you the xout variable in the workspace.
If there is direct feedthrough the vector is empty, otherwise not.
probably you need to include some try/catch error catching for special cases
This way you can analyse a block for direct feedthrough by just migrating it to another model, without compiling your actual main model. It's not the fastest solution, but I can not imagine that performance matters that much for you.
Here we go, this script works fine for my examples:
function feedthrough = hasfeedthrough( input )
% get block path
blockinfo = find_system('simulink','Name',input);
blockpath = blockinfo{1};
% create new system
new_system('feed');
open_system('feed');
% add test model elements
src = add_block('simulink/Sources/Constant','feed/Constant');
src_ports = get_param(src,'PortHandles');
src_out = src_ports.Outport;
dest = add_block('simulink/Sinks/To Workspace','feed/simout');
dest_ports = get_param(dest,'PortHandles');
dest_in = dest_ports.Inport;
test = add_block(blockpath,'feed/test');
test_ports = get_param(test,'PortHandles');
test_in = test_ports.Inport;
test_out = test_ports.Outport;
add_line('feed',src_out,test_in);
add_line('feed',test_out,dest_in);
% setup simulation
set_param('feed','StopTime','0.1');
set_param('feed','Solver','ode3');
set_param('feed','FixedStep','0.05');
set_param('feed','SaveState','on');
% run simulation and get states
sim('feed');
% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
a = simout.data;
if ~any(a == xout);
feedthrough = ~feedthrough;
end
end
delete system
close_system('feed',1)
delete('feed');
end
When enter for example 'Gain' it will return 1, when you enter 'Integrator' it will return 0.
Execution time on my ancient machine is 1.3sec, not that bad.
Things you probably still have to do:
add another parameter, to define whether the block is continuous or discrete time and set the solver accordingly.
test some "extraordinary" blocks, maybe it's not working for everything. Also I haven implemented anything which could deal with logic, but actually the constant is 1 so it should work as well.
Just try out everything, at least it's a good base for you to work on.
A famous exception is the StateSpace Block which can have direct feedthrough AND states. But there are not sooo much standard blocks with this "behaviour". If you also have to deal with third party blocks you could get into some trouble, I have to admit that.
possible solution for the state space: if one compares xout with yout than one can find another indicator for direct feedthrough: if there is, the vectors are not equal. If so, than they are equal. Just an example, but I can imagine that it is possible to find more general ways to test things like that.
besides the added simout block above one needs the condition:
% if condition for blocks like state space
feedthrough = isempty(xout);
if ~feedthrough
a = simout.data;
if ~any(a == xout);
feedthrough = ~feedthrough;
end
end
From the documentation:
Tip
To determine if a block has direct feedthrough:
Double-click the
block. The block parameter dialog box opens.
Click the Help button in
the block parameter dialog box. The block reference page opens.
Scroll
to the Characteristics section of the block reference page, which
lists whether or not that block has direct feedthrough.
I couldn't find a programmatic equivalent though...
Based on a similar approach to the one by #thewaywewalk, you could set up a temporary model that contains an algebraic loop, similar to,
(Note that you would replace the State-Space block with any block that you want to test.)
Then set the diagnostics to error out if there is an algebraic loop,
If an error occurs when the model is compiled
>> modelname([],[],[],'compile');
(and you should check that it is the Algebraic Loop error that has occured), then the block has direct feed though.
If no error occurs then the block does not have direct feed though.
At this point you would need to terminate the model using
>> modelname([],[],[],'term');
If the block has multiple inports or outprts then you'll need to iterate over all combinations of them.

Software in the Loop mode with Modelica

How to implement Software in the Loop for control systems design with Modelica (OpenModelica, jModelica) for a plant and C/C++ routine for a controller. What approaches you can suggest?
I thought external C Functions would help but seems they have some restrictions such that they should obey reference transparancy property ie return the same values for the same inputs (should not have internal states).
In that case, the issue with calling external C functions does not apply. It is true that Modelica restricts the use of functions in the continuous equations such that the function must return the same value for the same arguments. In those cases, you must find a way to pass the state into the function and have it return the new state (if you want to satisfy this "purity" requirement). This is obviously quite tedious to do with C code (you would have to pass in the state, assign all state variables (probably globals) run your code, then extract the values of all the state variables and return them).
Fortunately for you, you don't need to worry about this. The reason is because your function only needs to be called from within a when clause. If you are triggering your when clause based on time (e.g. using the sample(...) function), I'm pretty sure you are guaranteed that the function will only be invoked once at each time.
Basically, your setup would be something like this:
algorithm
when sample(0, sample_rate) then
u := controllerEvaluation(x, y, t);
end when;
In this way, you can pass time, the necessary states, x, and inputs, y (or u, depending on your perspective), into the controller and you get back the controller command to the plant, u.
In this context, the when clause is a representation of your scheduler and because it doesn't include any state events (like you would have, for example, with a tooth wheel encoder or other asynchronous interrupt) the simulator can schedule all these function invocations without any risk of having to repeat them.