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 Willi Braun, 12 years ago

Component: BackendFrontend
Resolution: invalid
Status: newclosed

No, the flat code is correct.
The Real type matches the double format where
10 + 1e60 = 1e60 is valid.

comment:2 by Per Östlund, 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 Bill Janssen, 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 Martin Sjölund, 12 years ago

Resolution: invalid
Status: closedreopened
Type: defectdiscussion

comment:5 by Martin Sjölund, 11 years ago

Milestone: 1.9.02.0.0

comment:6 by Martin Sjölund, 9 years ago

Milestone: 1.9.31.9.4

Moved to new milestone 1.9.4

comment:7 by Martin Sjölund, 9 years ago

Milestone: 1.9.41.9.5

Milestone pushed to 1.9.5

comment:8 by Martin Sjölund, 9 years ago

Milestone: 1.9.51.10.0

Milestone renamed

comment:9 by Martin Sjölund, 8 years ago

Milestone: 1.10.01.11.0

Ticket retargeted after milestone closed

comment:10 by Martin Sjölund, 8 years ago

Milestone: 1.11.01.12.0

Milestone moved to 1.12.0 due to 1.11.0 already being released.

comment:11 by Francesco Casella, 7 years ago

Resolution: worksforme
Status: reopenedclosed

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.

Note: See TracTickets for help on using tickets.