Opened 10 years ago
Last modified 7 years ago
#2734 new defect
numeric evaluation of expressions in the symbolic pre-processing
Reported by: | Lennart Ochel | Owned by: | somebody |
---|---|---|---|
Priority: | critical | Milestone: | Future |
Component: | Frontend | Version: | trunk |
Keywords: | Cc: | Willi Braun, Vitalij Ruge |
Description
There are a lot of simplification rules, e.g. in ExpressionSimplify, that introduce numeric weaknesses. Just a few examples:
1/3 -> 0.3333333333333333 sqrt(2) -> 1.414213562373095 sin(2*1.23456) = 2*sin(1.23456)*cos(1.23456) -> 0.6229222061594161 = 0.6229222061594162
I think the symbolic pre-processing should not evaluate any expression numerically. Any comments?
Change History (19)
comment:1 by , 10 years ago
Cc: | added |
---|
comment:2 by , 10 years ago
Cc: | added |
---|
comment:3 by , 10 years ago
Cc: | added; removed |
---|
comment:4 by , 10 years ago
comment:5 by , 10 years ago
That is true. The float point math is a problem for symbolic pre-processing.
The issue is, that we are using symbolic manipulations to check if equations are redundant. That gets limited by evaluating expressions numerically.
Afterwards (for code generation), I see no problem with evaluation of constants expressions.
comment:6 by , 10 years ago
Well. According to model balance, all equations are relevant, right? Or do you mean initialization does something fun? Either way, if both equations are simplified the same way, does it matter if we evaluate some sub-expressions?
comment:7 by , 10 years ago
We do check for redundant equations of over-determined initialization problems. And as the third example from the ticket description shows, it does matter if we evaluate sub-expressions.
comment:8 by , 10 years ago
You know there is no equality operator for doubles, right? You always have to allow a relative error... So you can still compare the expression; you just need to change how expression equality is handled for doubles.
comment:9 by , 10 years ago
Yes, for sure. The bad thing with that is, that you need to set more or less arbitrary numerical thresholds.
comment:10 by , 10 years ago
And the hashing algorithms also don't like this (because they hash based on the string representation of the expression)
comment:11 by , 10 years ago
It might well be, that we change the order of handling constant expression(?)
Example:
model foo Real a; Real b; Real x(start = 1,fixed = true); Real y(start = 1,fixed = true); final parameter Real p = 0.2; equation a = (1 - 0.2 - 0.2 - 0.2 - 0.2 - 0.2); //5.551115123125783e-17 b = (1 - p - p - p - p - p ); //0.0 der(x) = a; der(y) = b; end foo;
e.g. move simplifyBinaryConst to the bottom of simplifyBinary2??? (not helpful in the example)
comment:12 by , 10 years ago
Milestone: | 1.9.1 → 1.9.2 |
---|
This ticket was not closed for 1.9.1, which has now been released. It was batch modified for milestone 1.9.2 (but maybe an empty milestone was more appropriate; feel free to change it).
comment:13 by , 10 years ago
Milestone: | 1.9.2 → 1.9.3 |
---|
Milestone changed to 1.9.3 since 1.9.2 was released.
comment:18 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:19 by , 7 years ago
Milestone: | 1.12.0 → Future |
---|
The milestone of this ticket has been reassigned to "Future".
If you think the issue is still valid and relevant for you, please select milestone 1.13.0 for back-end, code generation and run-time issues, or 2.0.0 for front-end issues.
If you are aware that the problem is no longer present, please select the milestone corresponding to the version of OMC you used to check that, and set the status to "worksforme".
In both cases, a short informative comment would be welcome.
What would it help to keep
sqrt(2)
for generated code? Also, the expansion rule you gave is not really "correct" if you use floating point math :(Using doubles, the following values are used:
1.2345600000000001017
2.4691200000000002035
So your assumption that 2*1.23456 = 2.46912 does not hold.
The only thing we could do is increase precision by using a higher precision (like a decimal type or quad precision). But that would make translation slower and consume more memory.
The GCC-only libquadmath produces:
1.234560000000000000000000000000000054357...