Subject: Re: [Boost-bugs] [Boost C++ Libraries] #3408: gamma distribution's quantile performance
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2009-09-24 11:53:11
#3408: gamma distribution's quantile performance
---------------------------------+------------------------------------------
Reporter: chhenning@⦠| Owner: johnmaddock
Type: Tasks | Status: assigned
Milestone: Boost 1.41.0 | Component: math
Version: Boost 1.40.0 | Severity: Optimization
Keywords: |
---------------------------------+------------------------------------------
Comment(by johnmaddock):
I thought I'd add a short update: I'm concentrating on the igamma and
it's inverse functions at this stage, as ultimately these are what the
stats functions of both libraries depend upon.
Accuracy wise the two libries are broadly similar:
Tests run with Microsoft Visual C++ version 9.0, Dinkumware standard
library version 505, Win32
Testing tgamma(a, z) medium values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_q<double> Max = 23.69 RMS Mean=3.955
worst case at row: 600
{ 91.615684509277344, 183.23136901855469, 6.0094745549395681e+125,
2.5194958887453263e-014, 2.3851892681325433e+139, 0.9999999999999748 }
other::gamma_q(double) Max = 125.1 RMS Mean=9.671
worst case at row: 27
{ 4.053, 405.3, 8.563e-169, 1.334e-169, 6.418, 1 }
boost::math::gamma_p<double> Max = 35.09 RMS Mean=6.961
worst case at row: 651
{ 96.78564453125, 0.96785646677017212, 3.7245981312945362e+149, 1,
0.00016783328089080209, 4.5060775679568222e-154 }
other::gamma_p(double) Max = 426.3 RMS Mean=46.18
worst case at row: 518
{ 80.13, 0.8013, 1.566e+117, 1, 1.104e-010, 7.05e-128 }
Testing tgamma(a, z) small values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_q<double> Max = 2.898 RMS Mean=1.05
worst case at row: 73
{ 1.0221641311147778e-009, 1.0221641311147778e-009,
20.124127878209329, 2.0570161699209098e-008, 978316444.88368392,
0.99999997942983831 }
other::gamma_q(double) Max = 31.86 RMS Mean=7.103
worst case at row: 223
{ 0.001962, 100, 3.717e-046, 7.303e-049, 509, 1 }
boost::math::gamma_p<double> Max = 0.5133 RMS Mean=0.03234
worst case at row: 226
{ 0.0055537549778819084, 0.0049983793869614601, 4.6545082571173033,
0.025932342985794662, 174.83209885998627, 0.97406765701420539 }
other::gamma_p(double) Max = 0.7172 RMS Mean=0.2328
worst case at row: 245
{ 0.05124, 0.0005124, 5.75, 0.3029, 13.24, 0.6971 }
Testing tgamma(a, z) large values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_q<double> Max = 469.8 RMS Mean=31.51
worst case at row: 222
{ 2057.796630859375, 4115.59326171875, 0.1184802275824791,
5.1589245564542783e-277, 0.22966070987459913, 1 }
other::gamma_q(double) Max = 310.7 RMS Mean=35.14
worst case at row: 277
{ 7.884e+005, 7.884e+005, 0.1624, 0.499, 0.1631, 0.501 }
boost::math::gamma_p<double> Max = 244.4 RMS Mean=19.38
worst case at row: 211
{ 1169.2916259765625, 584.64581298828125, 0.22117898880238315, 1,
0.42515811737132952, 1.9222355598668354e-100 }
other::gamma_p(double) Max = 310.3 RMS Mean=36.91
worst case at row: 277
{ 7.884e+005, 7.884e+005, 0.1624, 0.499, 0.1631, 0.501 }
Testing tgamma(a, z) integer and half integer values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_q<double> Max = 8.485 RMS Mean=1.351
worst case at row: 138
{ 37, 74, 2.7177865101844111e+035, 7.306008776118165e-007,
3.7199305501125022e+041, 0.99999926939912243 }
other::gamma_q(double) Max = 103.1 RMS Mean=12.59
worst case at row: 20
{ 4.5, 450, 7.196e-187, 6.187e-188, 11.63, 1 }
boost::math::gamma_p<double> Max = 13.03 RMS Mean=2.932
worst case at row: 133
{ 37, 0.37000000476837158, 3.7199332678990125e+041, 1,
1.9898558488031992e-018, 5.3491708197417564e-060 }
other::gamma_p(double) Max = 123.4 RMS Mean=20.06
worst case at row: 91
{ 25, 0.25, 6.204e+023, 1, 2.794e-017, 4.503e-041 }
So for the most part the Boost version can be a bit more accurate.
And for the inverse:
Tests run with Microsoft Visual C++ version 9.0, Dinkumware standard
library version 505, Win32
Testing incomplete gamma inverse(a, z) medium values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_p_inv<double> Max = 1.652 RMS Mean=0.3353
worst case at row: 2
{ 9.7540397644042969, 0.22103404998779297, 7.2622991072035479,
11.97587613793354 }
boost::math::gamma_q_inv<double> Max = 2.254 RMS Mean=0.3822
worst case at row: 49
{ 22.103404998779297, 0.96886777877807617, 31.653035526093614,
14.199388115898186 }
other::gamma_p_inv<double> Max = 9.755 RMS Mean=2.085
worst case at row: 23
{ 13.547700881958008, 0.30816704034805298, 11.480744407137443,
15.117986636057008 }
other::gamma_q_inv<double> Max = 24.23 RMS Mean=2.871
worst case at row: 49
{ 22.103404998779297, 0.96886777877807617, 31.653035526093614,
14.199388115898186 }
Testing incomplete gamma inverse(a, z) large values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_p_inv<double> Max = 0.9242 RMS Mean=0.1082
worst case at row: 10
{ 581.3642578125, 0.12698681652545929, 553.96697937820386,
608.96241888374834 }
boost::math::gamma_q_inv<double> Max = 0.8143 RMS Mean=0.1072
worst case at row: 70
{ 40010.84375, 0.12698681652545929, 39782.764004009827,
40239.124371052443 }
other::gamma_p_inv<double> Max = 1.22 RMS Mean=0.4401
worst case at row: 88
{ 106978.296875, 0.9133758544921875, 107424.0055670203,
106533.15792214176 }
other::gamma_q_inv<double> Max = 1.07 RMS Mean=0.4135
worst case at row: 30
{ 3758.09765625, 0.12698681652545929, 3688.2692219050818,
3828.1269667349475 }
Testing incomplete gamma inverse(a, z) small values with type double
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
boost::math::gamma_p_inv<double> Max = 1163 RMS Mean=103.7
worst case at row: 86
{ 0.000398525211494416, 0.83500856161117554, 1.7877325072629434e-197,
0 }
boost::math::gamma_q_inv<double> Max = 962.6 RMS Mean=82.05
worst case at row: 82
{ 0.000398525211494416, 0.22103404998779297, 0,
3.4835777677025903e-273 }
other::gamma_p_inv<double> Max = 1229 RMS Mean=108
worst case at row: 86
{ 0.000398525211494416, 0.83500856161117554, 1.7877325072629434e-197,
0 }
other::gamma_q_inv<double> Max = 1145 RMS Mean=135.6
worst case at row: 80
{ 0.000398525211494416, 0.12698681652545929, 0,
5.6992492776090963e-149 }
So broadly similar again.
Time wise, I've modified our performance tests to test dcdflib as well and
get:
Testing igamma 8.611e-007
Testing igamma-dcd 5.849e-007
Testing igamma_inv 3.626e-006
Testing igamma_inv-dcd 1.810e-006
which confirms what you're seeing.
After the first round of changes/optimisations (now in Trunk) I get:
Testing igamma 7.067e-007
Testing igamma-dcd 5.849e-007
Testing igamma_inv 3.003e-006
Testing igamma_inv-dcd 1.855e-006
So a bit better, but still some way to go, unfortunately many of the
remaining differences appear to come from either:
* Not such good optimisations when calling boilerplate code (external
"inline" routines) as compared to the declared-all-inline spagetti code of
the original fortran.
* Apparently a lower overhead in calling the functions and going through
the algorithm-selection logic in the dcd code.
However, I'm not particularly keen to replace the current, almost
readable, structured code, with a bunch of goto's and spagetti code :-(
Still looking for more low hanging fruit yours, John.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/3408#comment:5> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:01 UTC