Создание двух случайных переменных депеданта времени с разными периодами выборки

Следуя этому вопросу, я пытаюсь сгенерировать две зависящие от времени случайные функции omega1 и tau, используя этот пример. Разница в том, что мне нужно иметь два разных периода выборки 0.05 и 0.17 для omega1 и tau соответственно. Я просто продублировал те части, которые, как я думал, сработают:

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;

однако я получаю сообщения об ошибках:

Символическая ошибка

Данная система является смешанно-детерминированной. [индекс ›3]

Пожалуйста, проверьте параметр --maxMixedDeterminedIndex.

Ошибка перевода

Система для символической инициализации не сгенерирована

Буду признателен, если вы поможете мне узнать, в чем проблема и как я могу ее решить.

P.S. с учетом того, что этот код явно отлично компилируется на Dymola, это может быть проблемой с OpenModelica. Поэтому я добавляю тег JModelica на тот случай, если эти ребята могут помочь мне узнать, компилируется ли он там или нет.


person Foad    schedule 11.09.2019    source источник
comment
Код отлично работает в Дымоле. Так что это похоже на инструмент. Если присмотреться к коду, то почти идентичные разделы when(initial) кажутся странными.   -  person Markus A.    schedule 11.09.2019
comment
У меня нет лицензии на Димолу. любая идея, как я могу решить эту проблему в OpenModelica или JMoledlica?   -  person Foad    schedule 11.09.2019


Ответы (1)


У вас есть omega1 := 0; в двух when initial() операторах. Замените его на tau := 0; во втором, и пример будет работать.

Я рекомендую немного почистить ваш код. Я обнаружил различные мелкие проблемы и ненужные строки кода.

  • все, что связано с нечистыми случайными числами, можно удалить
  • localSeed2 и globalSeed2 бесполезны, когда они инициализируются, как другие исходные переменные
  • state1024 инициализируется в 3 разных местах (хотя он работает с OpenModelica): значениями start и fixed=true и двумя разными операторами when initial()
  • omega2 и tau2 не обязательно должны быть выходами. Инструмент сам определяет, что ему нужно вычислить.
  • И наконец: модели Modelica намного проще отлаживать и понимать, используются ли существующие блоки и физические компоненты вместо написания длинного кода в одном классе. Ваша модель также может быть построена графически с помощью блоков из Modelica.Blocks.Noise и компонентов из Modelica.Mechanics.Rotational.

Ниже представлена ​​обновленная версия вашего кода с модулями, только один раздел для инициализации и удаленный раздел алгоритма (больше не требуется из-за дополнительных переменных rand_omega и 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;
person marco    schedule 11.09.2019
comment
Большое спасибо за вашу любезную поддержку. некоторые моменты: 1. не могли бы вы включить правильный код? Я не уверен, как следует реализовать state1024. 2. Я предпочитаю код по той причине, что мне удобнее его использовать, плюс позже, когда я захочу использовать JModelica, я могу привязать его к Python ... 3. Разве у меня не должно быть двух разных начальных значений для двух случайных функций ? они не будут такими же с подобными семенами? - person Foad; 11.09.2019
comment
1. сделано. 2. Никогда не пробовал, но я почти уверен, что JModelica работает также с моделями Modelica, построенными графически. Графическая информация содержится в аннотациях, которые удаляются при переводе. 3. Два разных семени - да, но нельзя использовать одно и то же значение дважды. - person marco; 11.09.2019
comment
Есть одна небольшая проблема. Результаты, которые я получаю от вашего кода, значительно отличаются от той версии, которую я сделал на основе ваших комментариев. см. мой код здесь. Вы тоже наблюдаете такую ​​большую разницу? любая идея, почему это? - person Foad; 11.09.2019
comment
Я бы сказал из-за разных случайных чисел. В вашем коде используется один генератор случайных чисел для вычисления omega1 и tau, тогда как в моем есть два независимых генератора случайных чисел, которые могут быть инициализированы соответствующими начальными числами. - person marco; 11.09.2019
comment
Я думаю, что основная причина в том, что displayUnit из Modelica.SIunits.Angle выражается в градусах. но в моем коде это были радианы. - person Foad; 11.09.2019
comment
Конечно, визуально это имеет большое значение :) - person marco; 12.09.2019
comment
Я также хотел бы пригласить вас в Modelica Discord. Сообщество Modelica могло бы выиграть, если бы у нас были лучшие методы общения. - person Foad; 12.09.2019