Аннотация Modelica, обратная функции, игнорируется

#annotations #modelica #inverse #dymola #openmodelica

#примечания #modelica #обратная #dymola #openmodelica

Вопрос:

Проблема: inverse аннотация функции игнорируется, а обратное вычисляется численно.

В соответствии со спецификациями Modelica можно указать обратную функцию для данной функции.

Чтобы проверить эту функциональность, я попробовал использовать очень тривиальную модель с двумя функциями:

  • прямая функция y(x) = sin(x)
     function y_from_x
      input Real x;
      output Real y;
    algorithm
      y:=sin(x);
      annotation(inverse(x = x_from_y(y)));
    end y_from_x;
      
  • ее обратная функция x (y) = asin(y)
     function x_from_y
      input Real y;
      output Real x;
    algorithm
      x:=asin(y);
    end x_from_y;
      
  • пара соответствующих уравнений
     y = time;
    y = y_from_x(x);
      

Как вы можете видеть, чтобы получить значение переменной x, функция y_from_x должна быть инвертирована; следовательно, поскольку в inverse аннотации явно указано, как инвертировать функцию, я ожидаю, что будет вызван x_from_y.

Нет, это не то, что происходит. Даже просто на этапе выравнивания обратная функция отбрасывается, и решение y_from_x вычисляется численно с помощью итерационного цикла. Это происходит как с OpenModelica версии v1.14, так и с Dymola 2018.

Это ожидаемое поведение? Как следует использовать эту inverse аннотацию? Есть ли способ избежать такого неэффективного итеративного решения?

Полный код

 model test_inverse

Real y, x;

function y_from_x
  input Real x;
  output Real y;
algorithm
  y:=sin(x);
  annotation(inverse(x = x_from_y(y)));
end y_from_x;

function x_from_y
  input Real y;
  output Real x;
algorithm
  x:=asin(y);
end x_from_y;


equation
  y = time;
  y = y_from_x(x);
end test_inverse;
  

Комментарии:

1. Как указал Маттис Тораде, этот вопрос теперь является темой открытой проблемы в спецификации Modelica: github.com/modelica/ModelicaSpecification/issues/… Не стесняйтесь присоединиться к этому обсуждению, чтобы мы могли найти переносимое решение этой проблемы!

Ответ №1:

Проблема в Dymola (и, вероятно, также в OpenModelica) заключается в том, что функция встроена до использования обратной функции, но ваш синтаксис правильный.

Встраивания можно избежать, используя:

 function y_from_x
  input Real x;
  output Real y;
algorithm
  y:=sin(x);
  annotation(LateInline=true, inverse(x = x_from_y(y)));
end y_from_x;
  

Однако обратите внимание, что Dymola не инвертирует синусоидальную функцию численно — вместо этого она использует встроенную инверсию для синусоидальной функции; которая похожа на asin.

Комментарии:

1. Проверено с помощью Dymola: это работает! К сожалению, у OpenModelica, похоже, есть некоторые проблемы: даже если опция lateInlineFunction postOptModules активна по умолчанию, обратная функция по-прежнему игнорируется (или, по крайней мере, я вижу, что она все еще пытается вычислить x с помощью итеративного подхода)

2. Согласно OpenModelica trac и форуму OpenModelica , inverse аннотация еще не реализована.

3. Ханс, означает ли это, что обратная аннотация всегда должна сочетаться с LateInline?

4. @matth Это часто не требуется (поскольку функция не может быть встроенной), и я считаю, что инструменты должны быть обновлены, чтобы избежать необходимости в этом. (Будет проверено для следующей версии Dymola.)

5. Связано ли это с флагом Dymola Advanced.Translation.DelayInliningForInverseDerivatives = true ?