root/trunk/mathextra/testconsistency.d

Revision 80, 4.4 kB (checked in by Don Clugston, 2 years ago)

Updated realtest to use new-style delegates from DMD 0.162.

Line 
1 /**
2  Test consistency of all of the statistical functions which have inverses.
3  These tests are really tough -- most will fail on machines which don't have
4  80-bit reals.
5 */
6 module mathextra.testconsistency;
7
8 import std.stdio;
9 import mathextra.realtest;
10
11 import mathextra.mathstat;
12 import mathextra.mathspecial;
13
14
15 version (testetcgamma) {
16 import mathextra.etcgamma;
17 alias mathextra.etcgamma.tgamma gamma;
18 alias mathextra.etcgamma.lgamma loggamma;
19 } else {
20 import std.math; // for lgamma, tgamma
21 alias std.math.tgamma gamma;
22 alias std.math.lgamma loggamma;
23 }
24
25 import mathextra.complex;
26 // do this just so it will compile.
27  real cosh(real x) { return std.math.cosh(x); }
28  real sinh(real x) { return std.math.sinh(x); }
29  real sin(real x) { return std.math.sin(x); }
30  real cos(real x) { return std.math.cos(x); }
31  real exp(real x) { return std.math.exp(x); }
32  real log(real x) { return std.math.log(x); }
33  real acos(real x) { return std.math.acos(x); }
34  real asin(real x) { return std.math.asin(x); }
35  real atan(real x) { return std.math.atan(x); }
36
37 // -------------------------------
38 // Tests of standard mathematical functions
39 // -------------------------------
40
41 unittest { // lgamma and tgamma
42
43     writefln("CONSISTENCY TESTS OF STANDARD FUNCTIONS");
44    
45     static real logabsgamma(real x)
46     {
47      // For poles, gamma(x) returns nan, but loggamma() returns infinity.
48       if (x<0 && x==floor(x)) return real.infinity;
49       return log(fabs(gamma(x)));
50     }
51
52   // Check that loggamma(x) = log(gamma(x)) provided x is not -1, -2, -3, ...
53
54 // Test some high-precision values (50 decimal digits)
55     const real SQRT_PI = 1.77245385090551602729816748334114518279754945612238L;
56     assert(feqrel(gamma(0.5L), SQRT_PI) == real.mant_dig);
57
58 //  assert(consistencyTwoFuncs(&loggamma, &logabsgamma, -1000, 1700) > real.mant_dig-7);
59   assert(
60     consistencyTwoFuncs(
61         (real x) { return exp(loggamma(x)); },
62         (real x) { if (x<0 && x==floor(x)) return real.infinity;
63                    return fabs(gamma(x)); },
64        -2000, real.infinity)
65        > real.mant_dig-16);
66 }
67
68 // x*exp(x). Used only for testing
69 real productExp(real x)
70 {
71  return x*exp(x);
72 }
73
74 unittest { // productLog, productLog_1
75  assert(isNegZero(productLog(-0.0)));
76  assert(isPosZero(productLog(0.0)));
77  assert( consistencyRealInverse(&productLog, &productExp,
78         -1/E, double.max) >= double.mant_dig);
79  assert( consistencyRealInverse(&productExp, &productLog,-1, 11000)
80         >= real.mant_dig-3);
81 /+       
82  assert( consistencyRealInverse(&productLog_1, &productExp,
83         -1/E, -real.epsilon) >= double.mant_dig);
84  assert( consistencyRealInverse(&productExp, &productLog_1,
85     log(real.epsilon), -1) >= double.mant_dig);
86 +/    
87 }
88
89 unittest { // cosh, acosh
90   assert( consistencyRealUnity( (real x){ return cosh(acosh(x)); }, 1, double.max)
91              >= double.mant_dig);
92   assert( consistencyRealUnity( (real x){ return acosh(cosh(x)); }, 1, log(real.max)*(1-real.epsilon))
93              >= real.mant_dig-1);
94 }
95
96 unittest { // sinh, asinh
97      assert( consistencyRealUnity((real x){ return sinh(asinh(x)); }, -double.max, double.max) >= double.mant_dig);
98      assert( consistencyRealUnity((real x){ return sinh(asinh(x)); },-1, 1) >= real.mant_dig-2);
99      assert( consistencyRealUnity((real x){ return asinh(sinh(x));},
100              -log(real.max)*(1+real.epsilon), log(real.max)*(1-real.epsilon)
101              )>= double.mant_dig);
102 }
103
104 unittest { // tanh, atanh
105  assert( consistencyRealInverse(&atanh, &tanh, -1, 1)
106          >= real.mant_dig-2);
107  assert( consistencyRealInverse(&tanh, &atanh, -1,1)
108          >= real.mant_dig-2);       
109 }
110
111
112 unittest { // tan, atan
113  assert( consistencyRealInverse(&atan, &tan, -PI_2, PI_2)
114          >= real.mant_dig-1);
115  assert( consistencyRealInverse(&tan, &atan, -PI_2*(1-real.epsilon), PI_2*(1-real.epsilon))
116          >= real.mant_dig-2);
117 }
118 /+
119 // Sin and cos require absolute accuracy tests.
120
121 unittest { // cos, acos
122 writefln("cos");
123 //writefln(-PI_2, "  ", cos(-PI_2), "  ", acos(cos(PI_2*2)));
124 writefln(-PI_2, "  %a", cos(0x1p-63), "  ", cos(acos(PI)));
125 //writefln(-PI_2, "  ", acos(-2), "  ", acos(cos(-1)));
126  assert( consistencyRealInverse(&acos, &cos, 0x1p-64, 1)
127          >= real.mant_dig-1);
128         
129 /*         
130  assert( consistencyRealInverse(&cos, &acos, -PI_2*(1-real.epsilon), PI_2*(1-real.epsilon))
131          >= real.mant_dig-2);
132 */         
133 }
134 +/
Note: See TracBrowser for help on using the browser.