Generating two random time depedant veariables with different sample periods

跟風遠走 提交于 2019-12-03 00:12:52

问题


Following this question, I'm trying to generate two time-dependent random functions omega1 and tau using this example. The difference is that I need to have two different sample periods of 0.05 and 0.17 for omega1 and tau respectively. I just duplicated the parts I thought would do the job:

model testData

  extends Modelica.Icons.Example;
  import Modelica.Math.Random.Generators;
  import Modelica.Math.Random.Utilities;

  parameter Real k = 50.0;
  parameter Real J = 0.001;
  Real theta1;
  Real theta2;
  Real omega2;

  parameter Modelica.SIunits.Period samplePeriod1 = 0.05;
  parameter Integer globalSeed1 = 30020;
  parameter Integer localSeed1 = 614657;
  output Real omega1;

  parameter Modelica.SIunits.Period samplePeriod2 = 0.17;
  parameter Integer globalSeed2 = 30020;
  parameter Integer localSeed2 = 614657;
  output Real tau;

protected
  discrete Integer state1024[33](each start=0, each fixed = true);

algorithm
  when initial() then
    state1024 := Generators.Xorshift1024star.initialState(localSeed1, globalSeed1);
    omega1 := 0;
  elsewhen sample(0, samplePeriod1) then
    (omega1, state1024) := Generators.Xorshift1024star.random(pre(state1024));
    omega1 := (omega1 - 0.5) * 13;
  end when;

  when initial() then
    state1024 := Generators.Xorshift1024star.initialState(localSeed2, globalSeed2);
    omega1 := 0;
  elsewhen sample(0, samplePeriod2) then
    (tau, state1024) := Generators.Xorshift1024star.random(pre(state1024));
    tau := (tau - 0.5) * 3;
  end when;

public
  parameter Integer id1 = Utilities.initializeImpureRandom(globalSeed1);
  discrete Real rImpure1;
  Integer iImpure1;

  parameter Integer id2 = Utilities.initializeImpureRandom(globalSeed2);
  discrete Real rImpure2;
  Integer iImpure2;

algorithm
  when initial() then
    rImpure1 := 0;
    iImpure1 := 0;
  elsewhen sample(0, samplePeriod1) then
    rImpure1 := Utilities.impureRandom(id=id1);
    iImpure1 := Utilities.impureRandomInteger(
          id=id1,
          imin=-1234,
          imax=2345);
  end when;

  when initial() then
    rImpure2 := 0;
    iImpure2 := 0;
  elsewhen sample(0, samplePeriod2) then
    rImpure2 := Utilities.impureRandom(id=id2);
    iImpure2 := Utilities.impureRandomInteger(
          id=id2,
          imin=-1234,
          imax=2345);
  end when;

initial equation
  theta1 = 0;
  theta2 = 0;
  der(theta2) = 0;

equation
  der(theta1) = omega1;
  der(theta2) = omega2;
  J * der(omega2) = tau + k * (theta1 - theta2);

annotation(experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.02));

end testData;

however I get the error messages:

Symbolic Error

The given system is mixed-determined. [index > 3]

Please checkout the option "--maxMixedDeterminedIndex".

Translation Error

No system for the symbolic initialization was generated

I would appreciate if you could help me know what is the problem and how I can solve it.

P.S. considering that this code is apparantly compiling fine on Dymola, this could be a problem with OpenModelica. So I'm adding th JModelica tag in the case those guys can help me know if this compiles over there or not.


回答1:


You have omega1 := 0; in two when initial()statements. Replace it by tau := 0; in the second one and the example will work.

I recommend to cleanup your code a bit. I found various smaller issues and needless code lines.

  • everything related to the impure random numbers can be removed
  • localSeed2 and globalSeed2 are useless when they are initialized like the other seed variables
  • state1024 is initialized at 3 different places (even though it works with OpenModelica): with start values and fixed=true and in two different when initial() statements
  • omega2 and tau2 don't need to be outputs. The Tool determines by itself what it has to compute.
  • And finally: Modelica models are a lot easier to debug and understand if existing blocks and physical components are used instead of writing lengthy code in a single class. Your model can also be built graphically with blocks from Modelica.Blocks.Noise and components from Modelica.Mechanics.Rotational.

Below is an updated version of your code with units, only one section for initialization and removed algorithm section (not necessary anymore due to the additional variables rand_omega and rand_tau).

model testData2

  extends Modelica.Icons.Example;
  import Modelica.Math.Random.Generators;
  import Modelica.Math.Random.Utilities;
  import SI = Modelica.SIunits;

  parameter SI.RotationalSpringConstant k = 50.0;
  parameter SI.Inertia J = 0.001;

  parameter SI.Period samplePeriod_tau = 0.17;
  parameter SI.Period samplePeriod_omega = 0.05;

  parameter Integer globalSeed = 30020;
  parameter Integer localSeed_tau = 614657;
  parameter Integer localSeed_omega = 45613;

  SI.Angle theta1, theta2;
  SI.AngularVelocity omega1, omega2, rand_omega;
  SI.Torque tau, rand_tau;

protected 
  discrete Integer state1024_tau[33];
  discrete Integer state1024_omega[33];

initial equation 

  state1024_omega = Generators.Xorshift1024star.initialState(localSeed_omega, globalSeed);
  state1024_tau = Generators.Xorshift1024star.initialState(localSeed_tau, globalSeed);

  theta1 = 0;
  theta2 = 0;
  der(theta2) = 0;

equation 

  when sample(0, samplePeriod_omega) then
    (rand_omega, state1024_omega) = Generators.Xorshift1024star.random(pre(state1024_omega));
  end when;

  when sample(0, samplePeriod_tau) then
    (rand_tau, state1024_tau) = Generators.Xorshift1024star.random(pre(state1024_tau));
  end when;

  der(theta1) = omega1;
  der(theta2) = omega2;

  omega1 = (rand_omega - 0.5) * 13;
  tau = (rand_tau - 0.5) * 3;

  J * der(omega2) = 0 + k * (theta1 - theta2);

annotation(experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-6, Interval = 0.02));
end testData2;


来源:https://stackoverflow.com/questions/57886368/generating-two-random-time-depedant-veariables-with-different-sample-periods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!