I am trying to get the model Jacobian matrix from FMU, according to the following literature, I could use fmi2GetDirectionalDerivative to do this, but I am not sure what I need to do exactly.
My question is:
Could I call this function in Dymola or MATLAB?
A screenshot or an example would be very helpful.
https://ep.liu.se/ecp/132/091/ecp17132831.pdf
I am not familiar with calling DLL functions in MATLAB but this is an example in Python. FMPy (https://github.com/CATIA-Systems/FMPy) has these wrappers for running FMUs in python.
I've tested this for a simple model I've written here(How to access model jacobian from FMU or Dymola without analytical jacobian). In this case, knowns are value references of either states or inputs, unknowns are value references of derivatives or outputs.
I have had success extracting the Jacobian when exported through Dymola as Model Exchange FMU but not Co-Simulation FMU.
def get_jacobian(fmu, vr_knowns, vr_unknowns):
"""
populates jacobian from list of knowns and unknowns
can be only called after the current sim time and inputs are set
"""
jacobian = []
try:
for vr_known in vr_knowns:
for vr_unknown in vr_unknowns:
jacobian.extend(
fmu.getDirectionalDerivative(
vUnknown_ref=[vr_unknown],
vKnown_ref=[vr_known],
dvKnown=[1.0]
))
print_status(f'Jacobian Elements: {jacobian}')
except Exception as e:
print("[ERROR] cannot compute jacobian at current timestep")
print(f"[ERROR] {e}")
I use this code snippet to collect the value references for states and derivatives using FMPy:
# get FMU model description object
model_description = fmpy.read_model_description(
os.path.join(fmu_path, fmu_filename)
)
# collect the value references
vrs = {}
for variable in model_description.modelVariables:
vrs[variable.name] = variable.valueReference
# collect list of states and derivatives
states = []
derivatives = []
for derivative in model_description.derivatives:
derivatives.append(derivative.variable.name)
states.append(re.findall('^der\((.*)\)$',derivative.variable.name)[0])
# collect the value references for states and derivatives
vr_states = [vrs[x] for x in states]
vr_derivatives = [vrs[x] for x in derivatives]
There was a paper from Mitsubishi Electric at the recent NAM Modelica Conference 2020 that might be related.
Related
I use Matlab coder to generate C code of the following function:
function [out] = myresample(in)
out = resample(in,4644,1000,10);
end
and generate the code by codegen myresample -args {coder.typeof(0, [1 Inf]), 0} -config cfg, where cfg = coder.config('lib'), cfg.DynamicMemoryAllocation = 'AllVariableSizeArrays'.
But it reports the error as:
??? The number of terms N must be constant.
I am confused why it is wrong. Interestingly, when I change the function to
function [out] = myresample(in)
out = resample(in,10,10,10);
end
it works.
I have found some links explaining how to generate code of resample. But it seems not work for my case.
I use Matlab 2017b.
Thanks.
According to Matlab 2017b documentation:
C/C++ Code Generation: Generate C and C++ code using MATLAB® Coder™.
Usage notes and limitations:
C and C++ code generation for resample requires DSP System Toolbox™ software.
The upsampling and downsampling factors must be specified as constants. Expressions or variables are allowed if their values do not change.
Variable-size inputs are not supported.
Here on your code, you have in that is not limited in size.
in your function myresample, you should try to specify a limitation. Something like:
limited_in = in(1:128);
out = resample(limited_in,4644,1000,10);
So the size of the inputs of resample will always be constant.
I have some troubles to understand how to implement the following MIQP (Mixed Integer Quadratic Programming) with linear constraints in Matlab calling Gurobi.
Let me explain in a schematic way my setting.
(1) x is the unknown and it is a column vector with size 225x1.
(2) The objective function (which should be minimised wrto x) looks like
which can be rewritten as
I have a Matlab script computing alpha, Q,c (Q,c sparse) when some_known_parameters1 are given:
function [alpha, Q,c]=matrix_objective_function(some_known_parameters1)
%...
end
(3) The constraints are linear in x, include equalities and inequalities, and are written in the form
I have a Matlab script computing Aeq,beq,Aineq,bineq (Aeq,Aineq sparse) when some_known_parameters2 is given:
function [Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
%...
end
(4) Some components of x are restricted to be in {0,1}. I have a Matlab script producing a string of letters B (binary), C (continous) when some_known_parameters3 is given:
function type=binary_continuous(some_known_parameters3)
%...
end
Now, I need to put together (1)-(4) using Gurobi. I am struggling to understand how. I found this example but it looks very cryptic to me. Below I report some lines I have attempted to write, but they are incomplete and I would like your help to complete them.
clear
rng default
%Define some_known_parameters1,
some_known_parameters2,some_known_parameters3 [...]
%1) generate alpha,Q,c,Aeq,beq,Aineq,bineq,type with Q,c,Aeq, Aineq sparse
[alpha, Q,c]=matrix_objective_function(some_known_parameters1)
[Aeq,beq,Aineq,bineq]=constraints(some_known_parameters2)
type=binary_continuous(some_known_parameters3)
%2) Set up Gurobi
clear model;
model.A=[Aineq; Aeq];
model.rhs=full([bineq(:); beq(:)]);
model.sense=[repmat('<', size(Aineq,1),1); repmat('=', size(Aeq,1),1)];
model.Q=Q; %not sure?
model.alpha=alpha; %not sure?
model.c=c; %not sure?
model.vtype=type;
result=gurobi(model); %how do I get just the objective function here without the minimiser?
Questions:
(1) I'm not sure about
model.Q=Q;
model.alpha=alpha;
model.c=c;
I'm just trying to set the matrices of the objective function using the letters provided here but it gives me error. The example here seems to me doing
model.Q=Q;
model.obj=c;
But then how do I set alpha? Is it ignoring it because it does not change the set of solutions?
(2) How do I get as output stored in a matrix just the minimum value of the objective function without the corresponding x?
(1) You're right, there's no need to pass the constant alpha since it doesn't affect the optimal solution. Gurobi's MATLAB API only accepts sparse matrices. Furthermore model.obj is always the c vector in the problem statement:
model.Q = sparse(Q);
model.obj = c;
(2) To get the optimal objective value, you first need to pass your model to gurobi and solve it. Then you can access it via the objval attribute:
results = gurobi(model);
val = results.objval + alpha
I am using Gurobi in Matlab to determine whether a system of linear equalities and linear inequalities has at least one solution. I don't have an objective function to minimise/maximise.
This is my code (I haven't posted the actual content of the matrices Aineq, Aeq, bineq, beq)
clear model;
model.A=[Aineq; Aeq];
model.obj=[];
model.sense=[repmat('<', size(Aineq,1),1); repmat('=', size(Aeq,1),1)];
model.rhs=full([bineq; beq]);
params.outputflag = 0;
result=gurobi(model, params);
if isfield(result,'x')
exists=1;
else
exists=0;
end
Question: what should I set as objective function? If I write model.obj=[]; as above I get
Error using gurobi
Incorrect size(model.obj)
If I delete the model line I get
Error using gurobi
model must contain fields: A, obj, sense, and rhs
This question is related to mine but it doesn't explain what to put in place of the objective function.
Unfortunately I don't have the needed reputation to comment, so this is an answer.
It's important that your matrix A is a sparse matrix, because Gurobi's MATLAB API only accepts sparse matrices: model.A=sparse([Aineq; Aeq]). Then it should work by just removing the line model.obj = [] from your code. If no objective is passed to Gurobi, it will automatically use 0 as the objective function, so that your model will minimize 0 in subject to your constraints. In this case every feasible solution is optimal and satisfies your constraints. Alternatively, you could do this by hand with
model.obj = zeros(size(model.A, 2), 1);
I am currently doing a project on multimodal biometrics (fusion at score level). So I need to get the score before fusion.
Can anyone tell me how to get the score of the particular test sample using a trained SVM classifier?
I have used the inbuilt svmtrain and svmclassify functions in MATLAB.
Unfortunately the svmclassify function only outputs the label of the class and no distance (score). You will have to write your own classification function. Luckily, this is very easy: As you do have the Statistics Toolbox with svmclassify, you can easily look at the source code of the function with
edit svmclassify
You will see that most of the function is checking inputs etc. The important parts are scaling the data:
sample(:,c) = svmStruct.ScaleData.scaleFactor(c) * ...
(sample(:,c) + svmStruct.ScaleData.shift(c));
and doing the classification using a built-in function svmdecision:
outclass = svmdecision(sample,svmStruct);
From the definition of svmdecision you will see that it outputs the distance f, but svmclassify ignores it. You could therefore easily create a new function, which looks almost exactly like svmclassify, but also returns f:
1 function [outclass,f] = svmclassify(svmStruct,sample, varargin)
...
112 [outclass,f] = svmdecision(sample,svmStruct);
...
158 outclass = []; f = [];
You will find that svmdecision is a private function. To be able to call it from your function, you have to make a copy in your local folder (or any subfolder).
Just few questions, i hope someone will find time to answer :).
What if we have COUPLED model example: system of n indepedent variables X and n nonlinear partial differential equations PDEf(X,PDEf(X)) with respect to TIME that depends of X,PDEf(X)(partial differential equation depending of variables X ). Can you give some advice? Here is one example:
Let’s say that c is output, or desired variable. Let’s say that r is independent variable.Partial differential equation looks like:
∂c/∂t=D*1/r+∂c/∂r+2(D* (∂^2 c)/(∂r^2 ))
D=constant
r=0:0.1:Rp- Matlab syntaxis, how to represent same in Modelica (I use integrator,but didn't work)?
Here is a code (does not work):
model PDEtest
/* Boundary conditions
1. delta(c)/delta(r)=0 for r=0
2. delta(c)/delta(r)=-j*d for r=Rp*/
parameter Real Rp=88*1e-3; // length
parameter Real initialConc=1000;
parameter Real Dp=1e-14;
parameter Integer np=10; // num. of points
Real cp[np](start=fill(initialConc,np));
Modelica.Blocks.Continuous.Integrator r(k=1); // independent x1
Real j;
protected
parameter Real dr=Rp/np;
parameter Real ts= 0.01; // for using when loop (sample(0,ts) )
algorithm
j:=sin(time); // this should be indepedent variable like x2
r.u:=dr;
while r.y<=Rp loop
for i in 2:np-1 loop
der(cp[i]):=2*Dp/r.y+(cp[i]-cp[i-1])/dr+2*(Dp*(cp[i+1]-2*cp[i]+cp[i-1])/dr^2);
end for;
if r.y==Rp then
cp[np]:=-j*Dp;
end if;
cp[1]:=if time >=0 then initialConc else initialConc;
end while;
annotation (uses(Modelica(version="3.2")));
end PDEtest;
Here are more questions:
This code don’t work in OpenModelica 1.8.1, also don’t work in Dymola 2013demo. How can we have continuos function of variable c, not array of functions ?
Can we place values of array cp in combiTable? And how?
If instead “algorithm” stay “equation” code can’t be succesfull checked.Why? In OpenModelica, error is :could not flattening model :S.
Is there any simplified way to use a set of equation (PDE’s) that are coupled? I know for PDEs library in Modelica, but I think they are complicated. I want to write a function for solving PDE and call these function in “main model”, so that output of function be continuos function of “c”.I don’t know what for doing with array of functions.
Can you give me advice how to understand Modelica language, if we “speak” like in Matlab? For example: Values of independent variable r,we can specife in Matlab, like r=0:TimeStep:Rp…How to do same in Modelica? And please explain me how section “equation” works, is there similarity with Matlab, and is there necessary sequancial approach?
Cheers :)
It's hard to answer your question, since you assuming that Modelica ~ Matlab, but that's not the case. So I won't comment your code, since it's really wrong. Let me give you an example model to the burger equation. Maybe you could use it as starting point.
model burgereqn
Real u[N+2](start=u0);
parameter Real h = 1/(N+1);
parameter Integer N = 10;
parameter Real v = 234;
parameter Real Pi = 3.14159265358979;
parameter Real u0[N+2]={((sin(2*Pi*x[i]))+0.5*sin(Pi*x[i])) for i in 1:N+2};
parameter Real x[N+2] = { h*i for i in 1:N+2};
equation
der(u[1]) = 0;
for i in 2:N+1 loop
der(u[i]) = - ((u[i+1]^2-u[i-1]^2)/(4*(x[i+1]-x[i-1])))
+ (v/(x[i+1]-x[i-1])^2)*(u[i+1]-2*u[i]+u[i+1]);
end for;
der(u[N+2]) = 0;
end burgereqn;
Your further questions:
cp is an continuous variable and the array is representing
every discretization point.
Why you should want to do that, as far as I understand cp is
your desired solution variable.
You should try to use almost always equation section
algorithm sections are usually used in functions. I'm pretty
sure you can represent your desire behaviour with equations.
I don't know that library, but the hard thing on a pde is the
discretization and the solving it self. You may run into issues
while solving the pde with a modelica tool, since usually
a Modelica tool has no specialized solving algorithm for pdes.
Please consider for that question further references. You could
start with Modelica.org.