#modelica #dymola
#modelica #dymola
Вопрос:
Мне нужно обнаруживать всякий раз, когда происходит изменение в значении RealInput X. Я пытался проверить, является ли X == pre (X), но получаю только ошибку и предупреждение о том, что Real нельзя сравнить на равенство. Я также думал об использовании производной от X, но для этого нет явного выражения.
Другие мои мысли заключались в том, чтобы попытаться преобразовать непрерывный ввод в дискретные переменные, которые я могу сравнить. Может ли это каким-то образом сработать?
Комментарии:
1. Если вы используете pre (X) в a, X должно быть выражением с дискретным временем. Что означает, что, вероятно, она уже была выбрана. Используйте
change()
, как предложено в ответах.
Ответ №1:
Попробуйте change()
оператор. Это описано в $ 3.7.3.1 спецификации Modelica. Согласно спецификации, она будет расширена до X<>pre(X)
, так что это тоже может сработать.
Комментарии:
1. Как я указываю в другом ответе,
<>
оператор не определен дляReal
. Кроме того, это все еще по существу то же самое, что и в OP,X==pre(X)
в том смысле, что для этого требуется, чтобыX
была переменная с дискретным временем.
Ответ №2:
change()
Оператор практически полезен только для не Real
сигналов. Причина в том, что <>
не определено для Real
типов. Вместо этого вам нужно будет создать модель, которая проверяет, отклоняется ли сигнал от последнего записанного значения более чем на заданный «эпсилон». Я не тестировал это, но код будет выглядеть примерно так:
model DetectChange
parameter Real eps;
input Real signal;
output Boolean change;
protected
Real last_value;
initial algorithm
last_value = signal;
algorithm
when pre(change) then
last_value := signal;
end when;
change := abs(signal-last_value)>=eps;
end DetectChange;
Опять же, я это не тестировал. Но это дает вам некоторое представление.
Комментарии:
1. Почему реальные типы нельзя сравнивать на предмет равенства? Похоже, что это был бы обычный вариант использования.
2. Причина связана с тем, как типы с плавающей запятой представлены внутри. На самом деле это дискретные значения, хотя мы редко воспринимаем их таким образом. Причина, по которой равенство не допускается, заключается в том, что оно на самом деле не делает того, чего ожидают люди. Например, зайдите в оболочку Python на 64-разрядной машине Intel и выполните оценку
2.7*3==8.1
. Оно вернетсяFalse
. Это происходит потому, что2.7*3
вычисляется как8.10000000000000142
,8.1
в то время как8.09999999999999964
вычисляется как в,,. Итак, по иронии судьбы, ни один из них на самом деле не представляет8.1
точно.3. Итак, могу ли я использовать Constants.small, значение меньше, чем сравнение, и больше, чем сравнение, для проверки приблизительного равенства?
4. Я бы избегал
eps
иsmall
, потому что они предоставляют информацию о степени детализации чисел с плавающей запятой для данной платформы. Это не имеет никакого инженерного значения. Также имейте в виду, что при интегрировании дифференциальных уравнений вы получите числовой «шум», который заставит одиночные значения прыгать вверх и вниз.eps
, который я использую в приведенном выше коде, должен представлять некоторый значимый инженерный порог. Другими словами, насколько велико изменение (в инженерных терминах), достаточно большое, чтобы оправдать принятие мер. Этоeps
выше.