Opened 12 years ago
Closed 7 years ago
#2037 closed discussion (worksforme)
Math expressions flattened incorrectly
Reported by: | Bill Janssen | Owned by: | probably noone |
---|---|---|---|
Priority: | high | Milestone: | 1.12.0 |
Component: | Frontend | Version: | trunk |
Keywords: | Cc: |
Description
The flattening code seems to be dropping terms from mathematical expressions. If you take the model
model showBug encapsulated type OperatingModes = enumeration(M1, M2); parameter OperatingModes mode = OperatingModes.M1; parameter Real mode_amount = 1.0; parameter Real d = (if mode == OperatingModes.M2 then (10 + (1.0 - mode_amount) * 1.0e60) else Modelica.Constants.inf); end showBug;
and flatten it with "omc", you get this:
% omc showBug.mo ModelicaServices Modelica class showBug parameter Real mode_amount = 1.0; parameter Real d = if mode == showBug.OperatingModes.M2 then 1e+60 + -1e+60 * mode_amount else 1e+60; parameter enumeration(M1, M2) mode = showBug.OperatingModes.M1; end showBug; %
You see that the expression for "d" is incorrect.
Change History (11)
comment:1 by , 12 years ago
Component: | Backend → Frontend |
---|---|
Resolution: | → invalid |
Status: | new → closed |
comment:2 by , 12 years ago
From a computer science point of view this might be correct, but from a numerical analysis point of view it's a rather bad round-off error. In this case the absolute error becomes 10, but you can replace 10 with e.g. 1e40 and get an absolute error of 1e40 instead. And for what it's worth, dymola handles this much better by not really simplifying the expression at all (it just moves some terms around).
I'm unfortunately not knowledgeable enough in numerical analysis to suggest a solution (if a solution even exists), but perhaps this is an issue that merits further discussion?
comment:3 by , 12 years ago
Yes, in the real world, this could lead to division-by-zero errors, if (10 + (1.0 - 1.0) * 1.0e60) evaluates to 0 instead of 10. This is clearly counter-intuitive, and adding extra parentheses doesn't seem to help.
comment:4 by , 12 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
Type: | defect → discussion |
comment:5 by , 12 years ago
Milestone: | 1.9.0 → 2.0.0 |
---|
comment:10 by , 8 years ago
Milestone: | 1.11.0 → 1.12.0 |
---|
Milestone moved to 1.12.0 due to 1.11.0 already being released.
comment:11 by , 7 years ago
Resolution: | → worksforme |
---|---|
Status: | reopened → closed |
As of v1.13.0-dev-155-g68350e9, the new front-end gives
class M parameter enumeration(M1, M2) mode = OperatingModes.M1; parameter Real mode_amount = 1.0; parameter Real d = if mode == OperatingModes.M2 then 10.0 + (1.0 - mode_amount) * 1e+060 else Modelica.Constants.inf; end M;
which is still amenable to be dealt with correctly by the back end.
No, the flat code is correct.
The Real type matches the double format where
10 + 1e60 = 1e60 is valid.