how to resolve a dimensionality-related error in this code? - modelica

I have written a code in Modelica to train a feedforward two-layer neural network for my Master thesis. The code receives a vector of six elements (u[nin]) and provides an output vector of two elements y[nout]. When I translate the code in dymola, I receive an error saying that the dimensionality of the parts included in a specific line of code must be equal. Once I remove this particular line, the code is translated successfully. I really spent much effort trying to resolve this error but in vain! Any help regarding the problem would be very much appreciated.
The code can be found below: (Please note that the line which causes the generation of the translation error is marked with // in the code).
model NN_block
Modelica.Blocks.Interfaces.RealInput
u[nin] "Connector of Real input signals"
annotation (Placement(transformation(extent={{-140,-20},{-100,20}},
rotation=0)));
Modelica.Blocks.Interfaces.RealOutput y[nout]
annotation (Placement(transformation(extent={{100,-10},{120,10}})));
parameter Integer nin2=1;
parameter Integer nin=6;
parameter Integer nout=2;
Real wji[10,6];
Real delta_wij[6,10];
Real bj[10,1];
Real delta_bjT[1,10];
Real wkj[2,10];
Real delta_wjk[10,2];
Real bk[2,1];
Real delta_bkT[1,2];
Real E;
Real ek[1,2];
Real yj[10,1];
Modelica.Blocks.Interfaces.BooleanOutput Input_trigger
annotation (Placement(
transformation(extent={{100,-46},{120,-26}}), iconTransformation(extent=
{{100,-46},{120,-26}})));
Modelica.Blocks.Interfaces.RealInput eTau1 annotation (Placement(
transformation(extent={{-182,36},{-142,76}}), iconTransformation(
extent={{10,-10},{-10,10}},
rotation=90,
origin={-44,90})));
Modelica.Blocks.Interfaces.RealInput eTau2 annotation (Placement(
transformation(extent={{-148,46},{-108,86}}), iconTransformation(
extent={{10,-10},{-10,10}},
rotation=90,
origin={50,90})));
annotation (Placement(transformation(extent={{-10,-10},{10,10}},
rotation=-90,
origin={-50,90}), iconTransformation(
extent={{-10,-10},{10,10}},
rotation=-90,
origin={0,90})));
algorithm
E:=1;
wji:=0.5*ones(10,6);
bj:=0.25*ones(10,1);
wkj:=0.75*ones(2,10);
bk:=0.6*ones(2,1);
delta_wij:=zeros(6,10);
delta_bjT:=zeros(1,10);
delta_wjk:=zeros(10,2);
delta_bkT:=zeros(1,2);
while E>0.01 loop
Input_trigger:=true;
y:=wkj*NeuralNetwork.Utilities.LogSig(wji*u+bj[:,1])+bk[:,1];
yj[:,1]:=NeuralNetwork.Utilities.LogSig(wji*u+bj[:,1]);
ek:=[eTau1,eTau2];
E:=0.5*(eTau1^2+eTau2^2);
if E>0.01 then
// delta_wij:=0.01*u*transpose(yj)*(ones(10,1)-yj)*ek*wkj+0.9*delta_wij;
delta_bjT:=0.01*transpose(yj)*(ones(10,1)-yj)*ek*wkj + 0.9*delta_bjT;
delta_wjk:=0.01*yj*ek + 0.9*delta_wjk;
delta_bkT:=0.01*ek + 0.9*delta_bkT;
wji:=wji+transpose(delta_wij);
bj:=bj+transpose(delta_bjT);
wkj:=wkj+transpose(delta_wjk);
bk:=bk+transpose(delta_bkT);
else
break;
end if;
end while;
annotation (Placement(transformation(extent={{-140,44},{-100,84}})),
uses(Modelica(version="3.2")), Icon(graphics={Rectangle(
extent={{-100,-100},{100,80}},
lineColor={0,0,255},
lineThickness=1), Text(
extent={{-68,20},{78,-16}},
lineColor={0,0,255},
lineThickness=1,
textString="Two-LayerNeural Network")}),
Diagram(graphics));
end NN_block;

Once I remove the lines using LogSig I could get OpenModelica to produce an error-message for you:
[a.mo:59:3-59:71] Error: Incompatible argument types to operation matrix multiplication, left type: Real[6], right type: Real[1, 10]
[a.mo:59:3-59:71] Error: Cannot resolve type of expression 0.01 * u * transpose(yj). The operands have types Real[6], Real[1, 10] in component .
u and yj' have dimensions 6 and 1,10

Looking at the code, it appears that there is mismatch in the sizes of the matrices on the right hand side of the equation concerned.
Try defining u as a 2D matrix of size 6x1.

Have you tested this line in the command line? This could be done by creating the variables used in your model in the workspace and then running the commented out line in the command line to check the sizing is correct. You can do this in the Dymola command line but I am not familiar enough with OpenModelica to tell if you can perform the same check there.

Related

Event triggered definition of array elements gives wrong values

The purpose of this model is to provide the indexed elements of the "vector" array the values of the array "tester", which are increasing numbers from 1 to 12.
This shall happen every time the BooleanPulse is true. The arrays are indexed by the Integer counter, which increases by 1 every boolean pulse.
The model simulates but gives every "vector" element the value 0. Also the warning message is "Failed to solve linear system of equations (no. 21) at time 0.000000. Residual norm is 0.5."
model Array_Test_simple
Real vector[12];
Integer counter;
Real tester[12]=1:1:12;
Modelica.Blocks.Sources.BooleanPulse booleanPulse(period = 0.1);
initial algorithm
counter:=1;
algorithm
when booleanPulse.y then
vector[counter]:=tester[counter];
counter:=pre(counter)+1;
end when;
equation
annotation(
uses(Modelica(version = "4.0.0")));
end Array_Test_simple;
This is a known bug in OpenModelica and was recently fixed in PR #8541.
Try out the latest nightly-build of OpenModelica and check if that solves your issue.
But four your example it should also work to use equations and not algorithm equations. In general they are supported much better and the compiler can try to optimize them. Algorithms stay basically untouched.

How to use unspecified array dimensions in blocks?

Using unspecified array dimensions (:) is an essential feature to design flexible components for reuse. I am well aware that the actual dimension has to be fixed when the model is compiled. To my knowledge binding a variable with unspecified array dimensions to one that has clearly defined dimensions should suffice.
So I am a bit confused why the following model Test will not validate in either OpenModelica or the Wolfram System Modeler:
package VectorFunctions
model Test
VectorSum converter "Component taking the sum of a vector input";
InformationSource source "Vector input";
equation
connect( source.y, converter.u );
end Test;
block VectorSum "Take the sum of an input with unspecified dimension"
Modelica.Blocks.Interfaces.RealInput u[:];
Modelica.Blocks.Interfaces.RealOutput y;
equation
y = sum(u);
end VectorSum;
block InformationSource "Provide some vector output"
Modelica.Blocks.Interfaces.RealOutput y[3];
equation
y = ones( 3 );
end InformationSource;
end VectorFunctions;
How can something like this be done then?
My guess would be that the Modelica Spec does not specify, that vector sizes can be automatically detected from connections, so the tools don't support that.
I think you have to set the vector size somehow by yourself, e.g. with a parameter which is set in your Test model as follows:
model Test
VectorSum converter(nu=size(source.y, 1)) "Pass in the vector size";
InformationSource source "Vector input";
equation
connect(source.y, converter.u);
end Test;
block VectorSum "Take the sum of an input with unspecified dimension"
Modelica.Blocks.Interfaces.RealInput u[nu];
parameter Integer nu(min=0)=0;
output Real y;
equation
y = sum(u);
end VectorSum;
Note that Dymola complains in your example code that connect statements can only be applied to connectors. Therefore I changed input Real to Modelica.Blocks.Interfaces.RealInput(and similar in InformationSource)
I have been given (inofficial) feedback on Wolfram Community by someone from Wolfram MathCore (e.g. the developers of the System Modeler):
Hi, I agree with your interpretation, I think we should support it. I have filed a bug to keep track of this issue internally, unfortunately I do not see any work around. We will come back to you when we have fixed this problem.
So, hopefully flexbile array sizes will be supported for blocks as they are for functions.

Solving Bessel Function using Runge Kutta

I'm working on an assignment for a class of mine and I'm supposed to write a code using a program of my choice (I've chosen Matlab) to solve the Bessel function differential equation using the 4th order Runge-Kutta method. For reference the Bessel function DE is:
x^2*(J_n)''+x*(J_n)'+(x^2-n^2)*J_n=0.
I'm able to separate this into two coupled first order DEs by:
(J_n)'=Z_n and
(Z_n)'+(1/x)*Z_n+[(x^2-n^2)/x^2]*J_n=0.
I have no experience with Matlab nor any other programming language before this assignment. I know Matlab has the 'ode45' command but I'm supposed to write the code myself, not rely on Matlab's commands. So far I've been working on the n=0 case for the Bessel function but I keep getting an error when I try and plot the function. The current error I have says: "Undefined function or method 'J' for input arguments of type 'double'." But I don't know how to fix this error nor if my code is even correct. Could someone tell me where I've gone wrong or what is the correct way to write this code?
h=0.01; %step size
J_0(1)=1; %initial condition for J_0
Z_0(1)=1; %initial condition for Z_0-This value should be zero
%but Matlab gives me an error. To fix this, I input
%Z_0(1)-1 to use the correct value for Z_0(1).
x(1)=0.001; %first value of x
dZ(Z_0,J_0)=(-1/x)*(Z_0-1)-J_0;
for i=[1:1:10]
dZ1=(-1/x)*(Z_0-1)-J_0;
dJ1=(Z_0(1)-1)*h;
dZ2=(-1/x)*(Z_0-1+0.5*h)-(J_0+0.5*h*dJ1);
dJ2=((Z_0(1)-1)+dZ1)*h;
dZ3=(-1/x)*(Z_0-1+0.5*h)-(J_0+0.5*h*dJ2);
dJ3=((Z_0(1)-1)+dZ1+dZ2)*h;
dZ4=(-1/x)*(Z_0-1+h)-(J_0+h*dJ3);
dJ4=((Z_0(1)-1)+dZ1+dZ2+dZ3)*h;
J(i+1)=J(i)+(h/6)*(dJ1+2*dJ2+2*dJ3+dJ4);
end
plot(J_0);
Thanks in advance for any help
Your problem is on the line:
J(i+1)=J(i)+(h/6)*(dJ1+2*dJ2+2*dJ3+dJ4);
In the right-hand side of your assignment operator you use the variable J that is never set before i is taking the value 1. Looks like a typo to me (should it be J_0 instead?)
Also, don't forget your index i when computing your dJ and dZ stuff in the for loop.

Using coupled system of PDEs in modelica

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.

keving murphy's hmm matlab toolbox assertion error

I am working on a project that needs to use hidden markov models. I downloaded Kevin Murphy's toolbox. I have some problems about the usage. In the toolbox webpage, he says that first input of dhmm_em and dhmm_logprob are symbol sequence data. On their examples, they give row vectors as data. So, when I give my symbol sequence as row vector, I get error;
??? Error using ==> assert at 9
assertion violated:
Error in ==> fwdback at 105
assert(approxeq(sum(alpha(:,t)),1))
Error in ==> dhmm_logprob at 17
[alpha, beta, gamma, ll] = fwdback(prior,
transmat, obslik, 'fwd_only', 1);
Error in ==> mainCourseProject at 110
loglik(train_act) =
dhmm_logprob(orderedSymbols,
hmm{train_act}.prior,
hmm{train_act}.trans,
hmm{act}.emiss);
However, before giving this error, code works for some symbol vectors. When I give my data as column vector, functions work fine, no errors. So why exactly am I getting this error?
You might say that I should be giving not single vectors, but vector sets, I also tried to collect my feature vectors in a struct and give row vectors as such, but nothing changed, I still get assertion error.
By the way, my symbol sequence does not have any zeros, I am doing everything almost the same as they showed in their examples, so I would be greatful if anyone could help me please.
Im not sure, but from the function call stack shown above, shouldn't the last line be hmm{train_act}.emiss instead of hmm{act}.emiss.
In other words when you computing the log-probability of a sequence, you should pass components that belong to the same HMM model (transition matrix, emission matrix, and prior probabilities).
By the way, the ASSERT in the code is a sanity check that a vector of probabilities should sum to 1. Oftentimes, when working with very small values (log-probabilities), numerical stability issues can creep in... You could edit the APPROXEQ function to relax the comparison a bit, by giving it a bigger margin of error
This error message and the code it refers to are human-readable. An assertion is a guard put in by the programmer, to ensure that certain conditions are met. In this case, what is the condition? approxeq(sum(alpha(:,t)),1) I'd venture to say that approxeq wants the values to be approximately equal, so this boils down to: sum(alpha(:,t)) ~= 1
Without knowing anything about the code, I'd also guess that these refer to probabilities. The probabilities of a node's edges must sum to one. Hopefully this starts you down a productive debugging path. If you can't figure out what's wrong with your input that produces this condition, start wading into the code a bit to see where this alpha vector comes from, and how it ended up invalid.