Assign a single element of a nettype struct - system-verilog

The usual assignment style to a Systemverilog net defined by a typedef struct, like
typedef struct {
real V;
real I;
real R;
} SVAstruct;
// resolution function ommitted
nettype SVAstruct SVAnet with res_SVA;
is
inout SVAnet P;
assign P = '{Vout,0,0};
So the assignments are done simultaneously for all elements of the net structure. Assignments like
P.R = 100;
give an error. Is there any method to do individual assignments?

You cannot do that. Once you create a nettype with a particular data type, each driver needs all fields of type in order to execute its resolution function.
Imagine if you wanted a signal to represent the force on an physical object. A force is a vector quantity that has both magnitude and direction. If each driver on that signal represents a force vector, there is no way to drive a direction without knowing what the magnitude is.
You can create a variable with the same type as a net and then you can make individual assignments to fields of that variable.
inout SVAnet P;
...
SVAstruct S
assign P = S;
...
S.R = 100;

Related

Support for pow() with decision variables in MiniZinc

I am trying to build a model with a decision variable that takes the range 0..10 with the constraint
that it must be divisible by 4.The output must be the one that minimizes the value (x-7)^2. Investigating I see that Gecode already supports it.
I have tried to build the model as follows but I get an error using the built-in pow()
% Decision variable
var 0..10: x;
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
int: obj = pow(x-7, 2);
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
I get the following error:
MiniZinc: type error: initialisation value for `obj' has invalid type-inst: expected `int', actual `var int'
I think it occurs because is considering the variable as a decision variable instead of just an integer parameter.
#hankank's solution is correct. Using var int: obj = pow(x-7, 2);
Variables (e.g., var int) in MiniZinc are decision variables and other names (which you might call variables in Python) are referred to as parameters (e.g., par int or int). These are two distinct types for a good reason: any calculation with only parameter is guaranteed to be able to be executed during MiniZinc compilation, while any calculation that uses a variable will generally have to be decided by a solver.
Note, that using pow actually might also bring problems for linear solver (i.e., MIP solvers). In this case the calculation can still be made linear because the transformation is using a constant, but the expression pow(x,y) where both arguments are variables could not be decided by a linear solver.
To move the pow() call from solution time to compilation time, you could use a pre-calculated array:
% Decision variable
var 0..10: x;
set of int: DomainX = 0..10;
array[DomainX] of int: xa = array1d(DomainX, [pow(i-7, 2) | i in DomainX]);
% Constraints
constraint (x mod 4) == 0;
% Call to the resolver
var int: obj = xa[x];
solve minimize obj;
% Solution
output["x = ", show(x), "\nobj = ", show(obj)];
As commented by hakank, variable obj must be of type var int, as it depends on a decision variable.

How do I default a property of a Matlab instance with a size based on an instance variable that is set upon constructing the instance?

I have a problem in which I want to model some physical phenomenon. This phenomenon consists of several phases, each of which may have its own governing equations (dynamics and thus no. of variables, constraints, variable boundaries, etc.). In order to group this phase's properties, I have written a class phase. An instance of this class has, a.o., a property called nVars, the number of variables in the governing equations (which may thus vary amongst instances of this class).
Now, suppose I want to have another property for this class that is called boundaries. Because I require the variable boundaries to be formulated in a very specific way, I also create a class boundaries. This class has properties lower and upper; the variables' lower and upper boundaries. However, the length of these lower and upper boundaries depend on the phase instance's nVars.
In the most general case, the lower boundaries are all -Inf and the upper boundaries are all Inf. Therefore, I want to default the values of the boundaries properties lower and upper to -Inf * ones([1 nVars]) and to Inf * ones([1 nVars]), respectively. Now, my question is: how do I make the default value of a class property dependent on a variable (nVars in this case).
My first attempt:
classdef phase
properties
nVars(1, 1) double
boundaries boundaries
end
methods
function obj = phase(nVars)
%Some constructor method
obj.nVars = nVars;
obj.boundaries = boundaries(obj);
end
end
end
classdef boundaries
properties
parent phase
lower = -Inf * ones([1 parent.nVars]);
upper = Inf * ones([1 parent.nVars]);
end
methods
function obj = boundaries(parent)
%Some constructor method
obj.parent = parent;
end
end
end
Alternatively, I tried defaulting the boundaries class's properties in the following way:
classdef boundaries
properties
parent phase
lower(1, parent.nVars) double = -Inf;
upper(1, parent.nVars) double = Inf;
end
methods
function obj = boundaries(parent)
%Some constructor method
obj.parent = parent;
end
end
end
Can anyone help me in understanding how to assign these default values based on a variable?
classdef phase < handle
properties
nVars double ;
boundaries boundaries ;
end
methods
function obj = phase(nVars)
%Some constructor method
obj.nVars = nVars;
obj.boundaries = boundaries(obj);
end
end
end
classdef boundaries
properties
parent phase
upper double ;
lower double ;
end
methods
function obj = boundaries( parent )
% Assign the parent handle
obj.parent = parent ;
% Initialise default values for the properties
obj.upper = Inf * ones([1 parent.nVars]);
obj.lower = -obj.upper ;
end
end
end
This initialise correctly:
>> a = phase(5)
a =
phase with properties:
nVars: 5
boundaries: [1x1 boundaries]
>> a.boundaries
ans =
boundaries with properties:
parent: [1x1 phase]
upper: [Inf Inf Inf Inf Inf]
lower: [-Inf -Inf -Inf -Inf -Inf]
The classdef syntax which allow to define default values in the properties in a nice convenience to limit the coding effort which have to be done in the constructor (automatic checking of the input type and all sorts of input check).
However, for every default value you define in the property block, under the hood MATLAB add auto-generated code to the constructor of the object. Once the object is finally created and initialised, it makes no difference if the property values where assigned directly in the property block or in the constructor.
For your case, the code to add to the constructor is so trivial that it is not worth loosing time trying to find a syntax which would work in the property block. Besides, this would always fail in your case because of another issue: the passing by reference.
When you try to assign a handle to the parent object in your boundaries class, you were just sending a copy of your initial phase object. This copy would sit in the boundaries object but is uncoupled from the actual phase parent object. To be able to pass the parent object by reference you need a handle to this parent object, and for that you need to define the parent class as handle.

Accessing record parameters in Modelica without declaring a record instance

In Modelica, I'm able to access the contents of a record instance like so:
model Unnamed1
record Example
parameter Real x = 5;
end Example;
Example ex;
Real test;
equation
test = ex.x;
end Unnamed1;
However, I'd like to access the contents of the record without declaring an instance of the record, like so:
model Unnamed1
record Example
parameter Real x = 5;
end Example;
Real test;
equation
test = Example().x;
end Unnamed1;
...but this doesn't work. Is there some way to achieve what I'm trying to do?
Yes, it is possible without having an actual instance in the model but it requires some extra code.
model Unnamed1
record Example
parameter Real x = 5;
end Example;
function getX
input Example r;
output Real x;
algorithm
x:=r.x;
end getX;
Real test;
equation
test = getX(Example());
end Unnamed1;
(I'm aware that it is cheating by having the instance in the function, but....)
Another option is
for r in {Example()} loop
test=r.x;
end for;
(allowed according to https://github.com/modelica/ModelicaSpecification/issues/1521 )
This is not possible (even from a grammar point of view). The right hand side of dot (.) needs to be a class or component reference. You can only access constants/parameters in packages via the dot notation.
package X
constant Real x = 1;
end X;
model M
Real x = X.x
end M;

Modelica Class Method

I would like to use a class function/method in my Modelica model as follows:
optimization Moo(objective=-x(finalTime), startTime = 0, finalTime = 12)
parameter Real e = 0.05;
Real x(start=2, fixed=true, min=0, max=100);
input Real v (min=0, max=1);
function omega
input Real t;
output Real y;
algorithm
y := e;
end omega;
equation
der(x) = v*omega(time);
constraint
v<=1;
end Moo;
I would like the variable e in the function omega to be a variable so that I can easily change its value at a later point in time when I am doing a parameter sweep. Unfortunately, the function omega does not seem to know about the variable e and the JModelica compiler returns the error:
Cannot find class or component declaration for e
I would naïvely expect that since omega and e belong to the same class omega would be able to see e.
Is there a way to achieve this?
Member functions are not supported in Modelica, so a function declared inside a model acts like a standalone function without having access to the surrounding model variables.
Member functions are not allowed due to functions need to be pure, i.e. they are not allowed to have any side effect. This is a fundamental assumption in Modelica that makes it possible for a tool to apply symbolic transformation and rearrange calculations.
You can have something like a member function, if you explicitly pass the needed variables as additional input to the function. See this example:
package MemberFunction
model A
Real x=1;
function get_x = MemberFunction.get(u=x);
end A;
function get
input Real u;
output Real y;
algorithm
y := u;
end get;
model Test
A a;
Real x;
equation
x = a.get_x();
end Test;
end MemberFunction;

Matlab function as Simulink block

I tryed to write an Matlab function in Simulink.
My first func like this:
function y = fcn(u, v)
coder.extrinsic('detectSURFFeatures');
boxPoints = detectSURFFeatures(u);
%scenePoints = detectSURFFeatures(v);
vBoxPoints = boxPoints.selectStrongest(100);
y = 0;
y = vBoxPoints;
But I see errors:
1. Attempt to extract field 'selectStrongest' from 'mxArray'.
2.Undefined function or variable 'vBoxPoints'. The first assignment to a local variable determines its class.
3. Error in port widths or dimensions. Output port 1 of 'detecting_cross/MATLAB Function/v' is a [400x239] matrix.
Pls, help.
The data returned from extrinsic functions are mxArray types. If you want to get the values from these mxArrays you need to pre-declare them so that the result of extrinsic function can be auto-converted to that type. You can use something like
boxPoints = struct('selectStrongest',zeros(100,1));
before calling detectSUTFFeatures. If the mxArray does not match the one from the function, you will get a run-time error. Your errors 2 and 3 are because of the first problem.