Changeset 19
- Timestamp:
- 11/17/05 02:57:54 (3 years ago)
- Files:
-
- trunk/betadist.d (modified) (1 diff)
- trunk/docs/mathspecial.html (modified) (1 diff)
- trunk/docs/realtest.html (added)
- trunk/etcgamma.d (modified) (1 diff)
- trunk/gammadist.d (modified) (1 diff)
- trunk/mathspecial.d (modified) (3 diffs)
- trunk/normaldist.d (modified) (3 diffs)
- trunk/realtest.d (modified) (4 diffs)
- trunk/testconsistency.d (added)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/betadist.d
r18 r19 547 547 // underflow has occurred 548 548 //mtherr( "incbil", UNDERFLOW ); 549 writefln("InverseBeta: underflow");550 549 x = 0.0L; 551 550 goto done; trunk/docs/mathspecial.html
r17 r19 38 38 </big></dt> 39 39 <dd>Lambert's W function, also known as ProductLog 40 <u>productLog</u>() is the inverse of <i>x</i>*exp(<i>x</i>) 40 <br><br> 41 <u>productLog</u>() is the inverse of <i>x</i>*exp(<i>x</i>) 41 42 and is also known as Lambert's W-function. 42 <u>productLog</u>(<i>x</i>*exp(<i>x</i>)) == <i>x</i>, where <i>x</i> >= -exp(-1) 43 A second inverse, productLog_1(<i>x</i>), can be defined for real <i>x</i><=-exp(-1). 43 <br><br> 44 45 It has two real branches for -exp(-1) < <i>x</i> < 0. 46 ProductLog returns the primary branch, ProductLog_1 returns 47 the secondary branch. 48 Mathematically, 49 <pre class="d_code"> <u>productLog</u>(y*exp(y)) == y, where y >= -exp(-1) 50 productLog_1(y*exp(y)) == y, where y <= -exp(-1) 51 </pre> 44 52 <br><br> 45 53 trunk/etcgamma.d
r18 r19 425 425 assert( feqrel(lgamma(testpoints[i]), testpoints[i+1]) > real.mant_dig-5); 426 426 } 427 428 static real logabsgamma(real x) 429 { 430 // For poles, gamma(x) returns nan, but loggamma() returns infinity. 431 if (x<0 && x==floor(x)) return real.infinity; 432 return log(fabs(tgamma(x))); 433 } 434 static real exploggamma(real x) 435 { 436 return exp(lgamma(x)); 437 } 438 static real absgamma(real x) 439 { 440 if (x<0 && x==floor(x)) return real.infinity; 441 return fabs(tgamma(x)); 442 } 443 444 // Check that loggamma(x) = log(gamma(x)) provided x is not -1, -2, -3, ... 445 assert(consistencyTwoFuncs(&lgamma, &logabsgamma, -1000, 1700) > real.mant_dig-7); 446 assert(consistencyTwoFuncs(&exploggamma, &absgamma, -2000, real.infinity) > real.mant_dig-16); 447 } 427 } trunk/gammadist.d
r18 r19 124 124 real gammaIncompleteComplInv(real a, real y0 ) 125 125 { 126 const real MAXLOGL = 1.1356523406294143949492E4L;126 const real MAXLOGL = 1.1356523406294143949492E4L; 127 127 real x0, x1, x, yl, yh, y, d, lgm, dithresh; 128 128 int i, dir; trunk/mathspecial.d
r11 r19 23 23 24 24 private import std.math; 25 import realtest;26 25 27 26 /******************* … … 57 56 /** 58 57 * Lambert's W function, also known as ProductLog 58 59 59 productLog() is the inverse of x*exp(x) 60 60 and is also known as Lambert's W-function. 61 productLog(x*exp(x)) == x, where x >= -exp(-1) 62 A second inverse, productLog_1(x), can be defined for real x<=-exp(-1). 61 62 It has two real branches for -exp(-1) < x < 0. 63 ProductLog returns the primary branch, ProductLog_1 returns 64 the secondary branch. 65 Mathematically, 66 ---- 67 productLog(y*exp(y)) == y, where y >= -exp(-1) 68 productLog_1(y*exp(y)) == y, where y <= -exp(-1) 69 ---- 63 70 */ 64 71 real productLog(real x) … … 136 143 } 137 144 138 // x*exp(x). Used only for testing139 real productExp(real x)140 {141 return x*exp(x);142 }143 145 144 146 unittest { 145 147 assert(productLog(-1/E)==-1); 146 148 assert(isnan(productLog(real.nan))); 147 assert(isNegZero(productLog(-0.0)));148 assert(isPosZero(productLog(0.0)));149 149 assert(productLog(E)==1); 150 version (X86) {151 assert( consistencyRealInverse(&productLog, &productExp,152 -1/E, double.max) >= double.mant_dig);153 assert( consistencyRealInverse(&productExp, &productLog,-1, 11000)154 >= real.mant_dig-3);155 }156 150 157 151 assert(productLog_1(-1/E)==-1); 158 152 assert(productLog_1(-real.infinity)==0); 159 153 assert(isnan(productLog_1(real.nan))); 160 version (X86) {161 assert( consistencyRealInverse(&productLog_1, &productExp,162 -1/E, -real.epsilon) >= double.mant_dig);163 assert( consistencyRealInverse(&productExp, &productLog_1,164 log(real.epsilon), -1) >= double.mant_dig);165 }166 154 } trunk/normaldist.d
r6 r19 245 245 } 246 246 247 import realtest;248 249 real swapsign(real x)250 {251 return normalDistributionInv(x);252 }253 247 254 248 unittest { … … 257 251 assert(normalDistributionInv(0.5)==0); 258 252 //assert(normalDistribution(0)==0.5); 259 260 writefln("inverse normal"); 261 // one way is -10 to +10, other is 0 to +1. 262 assert(consistencyRealInverse(&normalDistribution, &swapsign, -2, -1e-8, 1e-8, 4) > real.mant_dig-28); 263 writefln("normal"); 264 writefln("Normal(0)=%a invNorm=%a", normalDistribution(0.0), normalDistributionInv(real.min*real.epsilon)); 265 // assert(consistencyRealInverse(&swapsign, &normalDistribution, real.min, 1e-6) > real.mant_dig-28); 266 253 /+ 267 254 for (int i=0; i<=10; ++i) { 268 255 writefln(i/10.0, " ", normalDistributionInv(i/10.0)); … … 275 262 writefln(normalDistribution(-150)); 276 263 writefln("----------"); 264 +/ 277 265 } trunk/realtest.d
r6 r19 11 11 12 12 Params: 13 firstfunc, secondfunc Functions to be compared 14 domain A sequence of pairs of numbers giving the first and last 15 points which are valid for the function. 16 eg. (-real.infinity, real.infinity) ==> valid everywhere 17 (-real.infinity, -real.min, real.min, real.infinity) ==> valid for x!=0. 13 firstfunc = First calculation method 14 secondfunc = Second calculation method 15 16 domain = A sequence of pairs of numbers giving the first and last 17 points which are valid for the function. 18 Domain_Examples: 19 (-real.infinity, real.infinity) ==> valid everywhere 20 21 (-real.infinity, -real.min, real.min, real.infinity) ==> valid for x!=0. 18 22 Returns: 19 number of bits for which firstfunc(x) and secondfunc(x) are equal for23 The number of bits for which firstfunc(x) and secondfunc(x) are equal for 20 24 every point x in the domain. 25 21 26 -1 = at least one point is wrong by a factor of 2 or more. 22 27 */ … … 58 63 /** 59 64 Test the consistency of a real function which has an inverse. 60 Returns: the worst (minimum) value of feqrel(x, inversefunc(forwardfunc(x))) 61 for all x in the domain. 65 Equivalent to consistencyTwoFuncs(x, inversefunc(forwardfunc(x)), domain); 62 66 */ 63 67 int consistencyRealInverse(real function (real) forwardfunc, … … 74 78 } 75 79 76 // return true if x is -0.080 /// Returns true if x is -0.0 (This function is used in unit tests) 77 81 bit isNegZero(real x) 78 82 { … … 80 84 } 81 85 82 // return true if x is +0.086 /// Returns true if x is +0.0 (This function is used in unit tests) 83 87 bit isPosZero(real x) 84 88 {
