Serving the Quantitative Finance Community

  • 1
  • 2
  • 3
  • 4
  • 5
  • 37
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

C++ quiz - Maths and acccuracy

March 14th, 2013, 10:05 pm

Nasty!pow(x, 2) != pow(x, 2.0) (4.65e-10 difference)and..
Last edited by Cuchulainn on March 13th, 2013, 11:00 pm, edited 1 time in total.
 
User avatar
Traden4Alpha
Posts: 3300
Joined: September 20th, 2002, 8:30 pm

C++ quiz - Maths and acccuracy

March 14th, 2013, 11:07 pm

QuoteOriginally posted by: Cuchulainn....!! max == 0.0002441 These errors seem unavoidable due to round-off in different algorithms and the large numbers being bandied about, no?exp(sqrt(200))^2 = 1.92 e12. And an error of 0.0002441 in 1.92 e12 is about 1 part in 2^53 which is about the LSB on a double.Double trouble, what?-----------Perhaps the more interesting question is which variant is closer to the truth?
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

C++ quiz - Maths and acccuracy

March 15th, 2013, 8:29 am

QuoteOriginally posted by: Traden4AlphaQuoteOriginally posted by: Cuchulainn....!! max == 0.0002441 These errors seem unavoidable due to round-off in different algorithms and the large numbers being bandied about, no?exp(sqrt(200))^2 = 1.92 e12. And an error of 0.0002441 in 1.92 e12 is about 1 part in 2^53 which is about the LSB on a double.Double trouble, what?-----------Perhaps the more interesting question is which variant is closer to the truth?I don't want to tempt fate but in general;t*t is the same as pow(t,2) but pow(t, 2.0) is out by a miniscule margin.
 
User avatar
Traden4Alpha
Posts: 3300
Joined: September 20th, 2002, 8:30 pm

C++ quiz - Maths and acccuracy

March 15th, 2013, 11:31 am

QuoteOriginally posted by: CuchulainnQuoteOriginally posted by: Traden4AlphaQuoteOriginally posted by: Cuchulainn....!! max == 0.0002441 These errors seem unavoidable due to round-off in different algorithms and the large numbers being bandied about, no?exp(sqrt(200))^2 = 1.92 e12. And an error of 0.0002441 in 1.92 e12 is about 1 part in 2^53 which is about the LSB on a double.Double trouble, what?-----------Perhaps the more interesting question is which variant is closer to the truth?I don't want to tempt fate but in general;t*t is the same as pow(t,2) but pow(t, 2.0) is out by a miniscule margin.Perhaps an old but interesting man page might be still valid today. QuoteERROR (due to Roundoff etc.) exp(x), log(x), expm1(x) and log1p(x) are accurate to within an ulp, and log10(x) to within about 2 ulps; an ulp is one Unit in the Last Place. The error in pow(x,y) is below about 2 ulps when its magnitude is moderate, but increases as pow(x,y) approaches the over/underflow thresholds until almost as many bits could be lost as are occupied by the floating-point format's exponent field; 11 bits for double. No such drastic loss has been exposed by testing; the worst errors observed have been below 300 ulps for double. Moderate values of pow are accurate enough that pow(integer,integer) is exact until it is bigger than 2**53 for double.Who wrote pow() and what compromises did they use to make it "good enough"?
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

C++ quiz - Maths and acccuracy

March 16th, 2013, 2:28 pm

QuoteOriginally posted by: outrunI tried to find it in the standard which is supposed to say "pow should be implemented as exp(y*log(x))"This will be a super-slow algorithm?(?) An exp and a log...
 
User avatar
Traden4Alpha
Posts: 3300
Joined: September 20th, 2002, 8:30 pm

C++ quiz - Maths and acccuracy

March 16th, 2013, 3:18 pm

I was playing around with a graphing calc app on the iPad (plotting x^2.0 - x*x) and seeing similar sorts of errors. The properties of the error seemed to be:1. There's a strong bias in the error: x^2.0 ≤ x*x for both positive and negative values of x.2. The error is always 0 or -1 LSB so that the error doubles as the binary exponent on x^2 increments (e.g., error in 16 < x^2 < 32 is half that of the error in 32 < x^2 < 64 )3. The density of errors appears uniform in x (no "obvious" pattern) and seems to occur about once in every 20-50 values of x.Overall, the frequency of the errors surprised me and the bias in the error frightened me. It implies that if one sums a very large number of values of x^2.0, one can get a significantly lower number than if one sums a very large number of values of x*x (with the same {x}).
Last edited by Traden4Alpha on March 15th, 2013, 11:00 pm, edited 1 time in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

C++ quiz - Maths and acccuracy

March 16th, 2013, 3:27 pm

QuoteIt implies that if one sums a very large number of values of x^2.0, one can get a significantly lower number than if one sums a very large number of values of x*x (with the same {x}). Yep.The fun begins when these (embedded) maths things start throwing exceptions into the blue skies.
Last edited by Cuchulainn on March 15th, 2013, 11:00 pm, edited 1 time in total.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

C++ quiz - Maths and acccuracy

March 16th, 2013, 9:27 pm

What about Boost Math Toolkit pow?
 
User avatar
Traden4Alpha
Posts: 3300
Joined: September 20th, 2002, 8:30 pm

C++ quiz - Maths and acccuracy

March 17th, 2013, 3:42 pm

P.S. Delving a little deeper finds that these errors are not random in x at all. They have quasiperiodic and log-periodic structure and grow denser as x^2 -> an integer power of 2.
 
User avatar
Traden4Alpha
Posts: 3300
Joined: September 20th, 2002, 8:30 pm

C++ quiz - Maths and acccuracy

March 17th, 2013, 9:58 pm

QuoteOriginally posted by: outrunInteresting, that makes sense: the floating point representation <integer> * 2^<exponent> makes the algorithm for log precision-invariant for powers of two.NiceYes. The strange part is that the density of errors is much much higher for values of X in the neighborhood of (2^N) -∆ than in the neighborhood of (2^N)+∆. The density of errors seems to drop by a factor of maybe 6 to 20 across the 2^N boundary.
 
User avatar
Cuchulainn
Topic Author
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

C++ quiz - Maths and acccuracy

March 18th, 2013, 6:18 am

QuoteOriginally posted by: Traden4AlphaQuoteOriginally posted by: outrunInteresting, that makes sense: the floating point representation <integer> * 2^<exponent> makes the algorithm for log precision-invariant for powers of two.NiceYes. The strange part is that the density of errors is much much higher for values of X in the neighborhood of (2^N) -∆ than in the neighborhood of (2^N)+∆. The density of errors seems to drop by a factor of maybe 6 to 20 across the 2^N boundary.What I see (in an extended case) is that pow(x,2.0) is wrong for let's say x = 3.51, while for x = 3.50 and x = 3.52 the value is OK. Better to use pow(x,2) no matter what. So, the problem points seem to be well-defined and repeatable in that sense.
Last edited by Cuchulainn on March 17th, 2013, 11:00 pm, edited 1 time in total.