Reusable Templates - modelica

Instead of creating text boxes everytime for the displaying the name of the blocks, I thought of creating a reusable template for the same. Following is what I created
partial block BlockTemplate
annotation(Icon(coordinateSystem(extent = {{-100,-100},{100,100}}, preserveAspectRatio = true, initialScale = 0.1, grid = {2,2}), graphics = {Text(origin = {-0.366361,-0.51471}, lineColor = {0,0,255}, extent = {{-150,150},{150,110}}, textString = "%name"),Text(origin = {0,-260}, lineColor = {0,0,255}, extent = {{-150,150},{150,110}}, textString = "%name")}));
end BlockTemplate;
Then I imported this in another block by using
extends BlockTemplate
Turns out that I get the %name displayed on top of the block but I cannot edit it.
What should be done so that I am able to edit it?
Thanks in advance,
MSK

OK then you can do it like this,
Block A
block A
annotation (Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100}, {100,100}}), graphics={Text(extent={{-52,50},{62,-20}}, lineColor={0,0,255}, textString="%name")}));
end A;
Block B
block B
extends A;
end B;
Block C
block C
B abc annotation (Placement(transformation(extent={{-60,20},{-40,40}})));
end C;

I think you can't use Text annotation with extends like this. You need to create an instance of the block.
block A
annotation (Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},
{100,100}}), graphics={Text(
extent={{-52,50},{62,-20}},
lineColor={0,0,255},
textString="%name")}));
end A;
Above is the block which defines a text annotation with %name.
block B
A a annotation (Placement(transformation(extent={{-40,20},{-20,40}})));
end B;
Block B contains a component of Block A which will automatically display the name of the component in place of %name.

Related

Get pointer of class object

I have an object apple created by my own class in MATLAB:
apple = classA();
The class looks like this:
classdef classA < handle
properties
color = 'red';
end
methods
function obj = classA()
% ...
end
end
end
The question: How do I get the object or handle pointer of apple? I want to search for objects by their properties, like:
isprop(eval(mat(i).name),'color')
with mat = whos. So I need to get the pointer of the object, represented by the struct mat(i).name. I just need the reference, not a copy of the desired object. The purpose is this:
If I get the pointer somehow, like
ptr_to_apple_object = get_pointer_fct( mat(i).name )
then I am able to change the properties of the apple-object like:
ptr_to_apple_object. color = 'yellow'
Do you have any ideas? Thanks.
There's really no good way to find all current objects of a particular class, but you could use whos to get a struct about all variables, loop through this and determine which ones have the property you and then modify
variables = whos;
for k = 1:numel(variables)
obj = eval(variables(k).name);
if isobject(obj) && isprop(obj, 'color')
obj.color = 'yellow';
end
end
If you're looking for a specific class, you can use the class field of the output of whos
is_class = ismember({variables.class}, 'classA');
instances = variables(is_class);
for k = 1:numel(instances)
obj = eval(instances(k).name);
obj.color = 'yellow';
end
Update
Since you are subclassing handle, when you assign your instance to a new variable (obj = val(variables(k).name) above), it does not create a copy of your instance, but rather a new reference to the same object.
b = classA;
c = b;
b.color = 'red';
c.color
% 'red'

1-line try/catch equivalent in MATLAB

I have a situation in MATLAB where I want to try to assign a struct field into a new variable, like this:
swimming = fish.carp;
BUT the field carp may or may not be defined. Is there a way to specify a default value in case carp is not a valid field? For example, in Perl I would write
my $swimming = $fish{carp} or my $swimming = 0;
where 0 is the default value and or specifies the action to be performed if the assignment fails. Seems like something similar should exist in MATLAB, but I can't seem to find any documentation of it. For the sake of code readability I'd rather not use an if statement or a try/catch block, if I can help it.
You can make your own function to handle this and keep the code rather clear. Something like:
swimming = get_struct(fish, 'carp', 0);
with
function v = get_struct(s, f, d)
if isfield(s, f)
v = s.(f); % Struct value
else
v = d; % Default value
end
Best,
From what I know, you can't do it in one line in MATLAB. MATLAB logical constructs require explicit if/else statements and can't do it in one line... like in Perl or Python.
What you can do is check to see if the fish structure contains the carp field. If it isn't, then you can set the default value to be 0.
Use isfield to help you do that. Therefore:
if isfield(fish, 'carp')
swimming = fish.carp;
else
swimming = 0;
end
Also, as what Ratbert said, you can put it into one line with commas... but again, you still need that if/else construct:
if isfield(fish,'carp'), swimming = fish.carp; else, swimming = 0;
Another possible workaround is to declare a custom function yourself that takes in a structure and a field, and allow it to return the value at the field, or 0.
function [out] = get_field(S, field)
if isfield(S, field)
out = S.(field);
else
out = 0;
end
Then, you can do this:
swimming = get_field(fish, 'carp');
swimming will either by 0, or fish.carp. This way, it doesn't sacrifice code readability, but you'll need to create a custom function to do what you want.
If you don't like to define a custom function in a separate function file - which is certainly a good option - you can define two anonymous functions at the beginning of your script instead.
helper = {#(s,f) 0, #(s,f) s.(f)}
getfieldOrDefault = #(s,f) helper{ isfield(s,f) + 1 }(s,f)
With the definition
fish.carp = 42
and the function calls
a = getfieldOrDefault(fish,'carp')
b = getfieldOrDefault(fish,'codfish')
you get for the first one
a = 42
and the previous defined default value for the second case
b = 0

Progress 4GL: Labelling a field from a variable

I am having trouble labelling a field(s) on a frame. The number of fields and the required labels are determined at run-time.
the required labels are stored in char array:
w-indarray[]
I am using the following loop to add the required fields to the frame
do i = 1 to w-nooff:
form w-sstrings[i] with frame f1.
w-sstrings[i]:label in frame f1 = w-indarray[i].
end.
But I get an error:
Widget array-element requires constant subscript.
I have googled but the only occurrence looks slightly different and I'm not sure if the solution is applicable. http://www.mofeel.net/258-comp-databases-progress/5295a6889.aspx
I am assuming that being able to reference the elements of w-indarray[] as literals would resolve this as i could just do:
form w-sstrings[i] label "abc" with frame f1.
is there any way of referencing the elements of the w-indarray[] as literals that I am missing?
Thanks for your time.
You can do this without using static numbers for the extent by getting all widget handles and modifying their labels. It works but it's kind of a lot code to do something that really should be easier.
Something like this:
DEFINE VARIABLE cLabel AS CHARACTER NO-UNDO EXTENT 10 INIT ["One","Two","three","Four","Five","Six","Seven","Eight","Nine","Ten"].
DEFINE VARIABLE cField AS CHARACTER NO-UNDO EXTENT 10.
DEFINE VARIABLE hFieldGroup AS HANDLE NO-UNDO.
DEFINE VARIABLE hFirstWidget AS HANDLE NO-UNDO.
DEFINE VARIABLE iExtent AS INTEGER NO-UNDO.
DEFINE VARIABLE iLoop AS INTEGER NO-UNDO.
DEFINE FRAME f1 WITH SIDE-LABELS 1 COLUMN.
DISPLAY
cField
WITH FRAME f1.
/* Static will be done like this
Commenting out this
ASSIGN
cField[1]:LABEL = cLabel[1]
cField[2]:LABEL = cLabel[2]
cField[3]:LABEL = cLabel[3]
cField[4]:LABEL = cLabel[4]
cField[5]:LABEL = cLabel[5]
cField[6]:LABEL = cLabel[6]
cField[7]:LABEL = cLabel[7]
cField[8]:LABEL = cLabel[8]
cField[9]:LABEL = cLabel[9]
cField[10]:LABEL = cLabel[10].
*/
ASSIGN
hFieldGroup = FRAME f1:FIRST-CHILD
hFirstWidget = hFieldGroup:FIRST-CHILD.
/* Widget-loop. Could really be done prettier... */
REPEAT:
iLoop = iLoop + 1.
hFirstWidget = hFirstWidget:NEXT-SIBLING NO-ERROR.
IF hFirstwIDGET = ? THEN LEAVE.
IF hFirstWidget:TYPE = "FILL-IN" THEN DO:
iExtent = iExtent + 1.
/* Set dynamic label */
hFirstWidget:LABEL = cLabel[iExtent].
END.
END.
The error message says you need to use a constant in the array instead of a variable. This means you'll need to do a CASE statement to get the functionality you're looking for - like so:
CASE i:
WHEN 1 THEN w-sstrings[1]:label in frame f1 = w-indarray[i].
WHEN 2 THEN w-sstrings[2]:label in frame f1 = w-indarray[i].
WHEN 3 THEN w-sstrings[3]:label in frame f1 = w-indarray[i].
WHEN 4 THEN w-sstrings[4]:label in frame f1 = w-indarray[i].
WHEN 5 THEN w-sstrings[5]:label in frame f1 = w-indarray[i].
END CASE.
The reason for the constant array element is the compiler can't discern which field the array element corresponds to when you give it a variable designation.

Sub-struct with dependent fields

In Matlab, I would like a data structure that looks like so:
DataStruct
.model
.Q
.Qchol
.
.
.system
.
.
The structure may well be a class, although I don't really need all the other functionality that goes with oop.
But I require
If Q is assigned something, then automatically Qchol = cholcov(Q).
If Qchol is assigned something, then automatically Q = Qchol' * Qchol.
Meanwhile, both Q and Qchol are stored for fast read-access
And Q and Qchol are writable through simple assignment, e.g.: DS1.mod.Q = value
I know I can make model a class, and have set/get methods for Q and Qchol. However, this really seems like an overkill for just two matrices (plus maybe some more fields). Also Matlab warns me that I should not access other properties during in a set method.
So: What is the best way to have such data structures, preferably without warnings?
You basically want assignment (DS1.mod.Q = value) to have side-effects, which inevitably implies a setter, and hence a class. You should either drop this requirement, or write a class.
If you wish to avoid definition of properties in the class declaration, you could use Dynamic Properties, which allows you to add properties at runtime (although with some telltale syntax addprop()).
EDIT
Patric, the problem goes deeper then just M-lint. Consider the following class:
classdef cantInstantiateMe < handle
properties
x
minus_x
end
methods
function obj = cantInstantiateMe(x)
obj.x = x; % <-- this calls set.x(), which calls set.minus_x(), which calls set.x(), ...
obj.minus_x = -x;
end
function set.x(obj, value)
obj.x = value;
obj.minus_x = -value; % <-- this gives an M-Lint warning
end
function set.minus_x(obj, value)
obj.minus_x = value;
obj.x = -value;
end
end
end
This class cannot be instantiated, because each setter calls the other setter (this is not Matlab-specific). Trying to instantiate on my machine gives:
??? Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)
to change the limit. Be aware that exceeding your available stack space can
crash MATLAB and/or your computer.
At this point I think you have two options:
Make either Q or Qchol a dependent property. This will come at the cost of re-calculating the dependent property each time you read-access it.
Use some private shadow properties e.g. shadow_Q and shadow_Qchol which will be set when the setter for the public property is called, and returned when their getter is called. Similar to:
function set.x(obj, value)
obj.shadow_x = value;
obj.shadow_minus_x = -value;
end
function value = get.x(obj)
value = obj.shadow_x;
end
Note the I did not test this properly, so I don't know all implications in Matlab. In other languages I'm familiar with, this should work fine.
Regarding the warning - my approach is that it is safe to disable the warning, as long as you really know what you are doing.
As suggested by #bavaza, one way to implement this is to use a dependent property with corresponding shadow private properties.
Below is the code implementing the inner data structure (inspired by this post). You need to use composition to make an instance of this class a property of the outer object:
classdef Model < handle
properties (Dependent)
Q
Qchol
end
properties (Access = private)
Q_
Qchol_
end
methods
function obj = Model()
end
function val = get.Q(obj)
val = obj.Q_;
end
function val = get.Qchol(obj)
val = obj.Qchol_;
end
function set.Q(obj, val)
obj.Q_ = val;
obj.Qchol_ = cholcov(val);
end
function set.Qchol(obj, val)
obj.Qchol_ = val;
obj.Q_ = val'*val;
end
end
end
Setting one value using the exposed dependent properties affects both underlying variables:
>> m = Model
m =
Model with properties:
Q: []
Qchol: []
>> m.Qchol = rand(3)
m =
Model with properties:
Q: [3x3 double]
Qchol: [3x3 double]

Is it possible to hide the methods inherited from the handle class in matlab?

I'm working on a command line application for ultrasound simulation in MATLAB. Nearly every object in our code is a subclass of handle (to pass as references). The problem I'm having is that all the methods inherited from the handle class shows up under the "Methods" section in MATLAB (see example below).
What I want is to hide the inherited methods from the handle class so that only the function the user is allowed to use is shown under "Methods". This way it doesn't look so messy for the user if he/she wants to know which methods to use.
Example Test class:
classdef Test < handle
methods
function myFunction(obj)
end
end
end
In the command line:
T = Test()
T =
Test handle with no properties.
Methods, Events, Superclasses
After clicking on "Methods":
Methods for class Test:
Test delete findobj ge isvalid lt ne
addlistener eq findprop gt le myFunction notify
What I want:
Methods for class Test:
Test myFunction
Is this possible in MATLAB?
If you overload all of the subclass methods in a hidden methods block I think it will do exactly what you're looking for.
I'm not sure which versions of Matlab this works in, but it definitely works for me in R2012b.
The exception is isvalid as it is Sealed so you can't override it in a handle subclass.
classdef handle_light < handle
methods(Hidden)
function lh = addlistener(varargin)
lh = addlistener#handle(varargin{:});
end
function notify(varargin)
notify#handle(varargin{:});
end
function delete(varargin)
delete#handle(varargin{:});
end
function Hmatch = findobj(varargin)
Hmatch = findobj#handle(varargin{:});
end
function p = findprop(varargin)
p = findprop#handle(varargin{:});
end
function TF = eq(varargin)
TF = eq#handle(varargin{:});
end
function TF = ne(varargin)
TF = ne#handle(varargin{:});
end
function TF = lt(varargin)
TF = lt#handle(varargin{:});
end
function TF = le(varargin)
TF = le#handle(varargin{:});
end
function TF = gt(varargin)
TF = gt#handle(varargin{:});
end
function TF = ge(varargin)
TF = ge#handle(varargin{:});
end
function TF = isvalid(varargin)
TF = isvalid#handle(varargin{:});
end
end
end
If you save the above class to handle_light.m and then type methods handle_light in the command window you will get the following result:
Methods for class handle_light:
handle_light isvalid
The Test class then becomes:
classdef Test < handle_light
methods
function myFunction(obj)
end
end
end
Doing it in this way means that you don't need to put the overloads in the Test class which keeps things neater.
There is a solution here, including sample code.
In short, what you need to do is to overload Matlab's built-in function methods, so that when it is called on your class, it removes the methods of handle from the output. Make sure it works on everything else, though so that you don't mess up your user's other code. If you don't use the #foldername variant to store your class, you could put it into a private directory, for example.
Not a full solution, but if you do methods(T, '-full'), then it at least tells you which methods are inherited from handle, so you know what to ignore.
Just get the functions from the inherited class and cancel them out with the ones from the main class using setdiff.
mH = methods('handle');
m = methods('MyClass');
m = setdiff(m,mH);