1

I need to detect whenever there is a change in a RealInput value X. I habe tried to check if X == pre(X), but only receive an error and a warning that Real cannot be compared for equality. I also thought about using the derivative of X, but there is no explicit expression for this.

Other thoughts of mine have been to try to sample the continuous input into discrete variables that I can compare. Could this work in some way?

  • 1
    If you are using pre(X) in a, X must be a discrete-time expression. Which means it was probably already sampled. Use `change()` as suggested in the answers. – sjoelund.se Jul 04 '14 at 16:36

2 Answers2

2

Try the change() operator. It is described in $3.7.3.1 of the Modelica Specification. According to the specification, it will be expanded to X<>pre(X), so that might work as well.

matth
  • 2,568
  • 2
  • 21
  • 41
MSK
  • 448
  • 2
  • 5
  • 18
  • 1
    As I point out in another answer, the `<>` operator isn't defined for a `Real`. Besides, this is still essentially the same as the OP's `X==pre(X)` in that it requires that `X` be a discrete-time variable. – Michael Tiller Jul 07 '14 at 14:40
2

The change() operator is only practically useful for non-Real signals. The reason is that <> is not defined for Real types. Instead, you'll need to create a model that checks to see whether the signal deviates from the last recorded value by more than a given "epsilon". I haven't tested it, but the code would look something like this:

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;

Again, I haven't tested this. But it gives you some idea.

Michael Tiller
  • 9,291
  • 3
  • 26
  • 41
  • Why can Real types not be compared for equality? This seems like it would be a common use case. – Chad Aug 21 '14 at 12:28
  • 1
    The reason is related to how floating point types are represented internally. They are really disrete values although we rarely perceive them that way. The reason equality is not allowed is because it doesn't really do what people expect. For example, go into a Python shell on a 64-bit Intel machine and evaluate `2.7*3==8.1`. It will come back `False`. That is because `2.7*3` evaluates to `8.10000000000000142` while `8.1` evaluates to `8.09999999999999964`. So, ironically, **neither** of them actually represent `8.1` precisely. – Michael Tiller Sep 05 '14 at 12:38
  • So could I make use of Constants.small, a less than comparison and a greater than comparison to test for approximate equality? – Chad Sep 05 '14 at 13:13
  • I would avoid `eps` and `small` because they are providing information about the granularity of floating point numbers for a given platform. That doesn't have any engineering meaning. Also keep in mind that when integrating differential equations you'll get numerical "noise" that will cause singles to bob up and down. The `eps` I use in the code above should represent some meaningful engineering threshold. In other words, how big of a change (in engineering terms) is big enough to justify taking action. That's `eps` above. – Michael Tiller Sep 05 '14 at 13:24