#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
?