123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- %
- % Testing file for REDUCE Special Functions Package
- %
- % Chris Cannam, ZIB Berlin
- % October 1992 -> Feb 1993
- % (only some of the time, of course)
- %
- % Corrections and comments to neun@sc.zib-berlin.de
- %
- on savesfs; % just in case it's off for some reason
- off bfspace; % to provide more similarity between runs
- % with old & new bigfloats
- let {sinh (~x) => (exp(x) - exp (-x))/2 };
- % this will improve some results
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 1. Bernoulli numbers
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- off rounded;
- procedure do!*one!*bern(x);
- write ("Bernoulli ", x, " is ", bernoulli x);
- do!*one!*bern(1);
- do!*one!*bern(2);
- do!*one!*bern(3);
- do!*one!*bern(13);
- do!*one!*bern(14);
- do!*one!*bern(300);
- do!*one!*bern(-2);
- do!*one!*bern(0);
- for n := 2 step 2 until 100 do do!*one!*bern n;
- on rounded;
- precision 100;
- do!*one!*bern(1);
- do!*one!*bern(2);
- do!*one!*bern(3);
- do!*one!*bern(13);
- do!*one!*bern(14);
- do!*one!*bern(300);
- do!*one!*bern(-2);
- do!*one!*bern(0);
- do!*one!*bern(38);
- do!*one!*bern(400);
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 2. Gamma function
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- on rounded;
- off complex;
- precision 40;
- algebraic procedure wg(x);
- write ("gamma (", x, ") ==> ", gamma x);
- algebraic procedure wp(x);
- write ("-- precision ", x, ", from ", precision(x));
- wg (1/2);
- wg (3/2);
- write ("sqrt(pi)/2 ==> ", sqrt(pi)/2);
- wp(10);
- for x := 0 step 5 until 100 do
- << wg (1 + x/1000);
- wg (-1 - x/13);
- wp (8+floor(x/4)) >>;
- wg(1/1000000003);
- off rounded;
- gamma(17/2);
- gamma(-17/2);
- gamma(4);
- gamma(0);
- gamma(-4);
- gamma(-17/3);
- p := gamma(x**2) * gamma(x-y**gamma(y)) - (1/(gamma(4*(x-y))));
- y := 1/4;
- p;
- x := 3;
- p;
- y := -3/8;
- p;
- on rounded, complex;
- precision 50;
- p;
- off rounded, complex;
- clear y;
- p;
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 3. Beta function. Not very interesting
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- algebraic procedure do!*one!*beta(x,y);
- write ("Beta (", x, ",", y, ") = ", beta(x,y));
- do!*one!*beta(0,1);
- do!*one!*beta(2,-3);
- do!*one!*beta(3,2);
- do!*one!*beta(a+b,(c+d)**(b-a));
- do!*one!*beta(-3,4);
- do!*one!*beta(-3,2);
- do!*one!*beta(-3,-7.5);
- do!*one!*beta((pi * 10), exp(5));
- on rounded;
- precision 30;
- do!*one!*beta(0,1);
- do!*one!*beta(2,-3);
- do!*one!*beta(3,2);
- do!*one!*beta(a+b,(c+d)**(b-a));
- do!*one!*beta(-3,4);
- do!*one!*beta(-3,2);
- do!*one!*beta(-3,-7.5);
- do!*one!*beta((pi * 10), exp(5));
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 4. Pochhammer notation
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- off rounded;
- pochhammer(4,5);
- pochhammer(-4,5);
- pochhammer(4,-5);
- pochhammer(-4,-5);
- pochhammer(17/2,12);
- pochhammer(-17/2,12);
- pochhammer(1/3,14)*pochhammer(2/3,15);
- q := pochhammer(1/5,11)*pochhammer(2/5,11)*pochhammer(3/5,11)*
- pochhammer(1-1/5,11)*pochhammer(1,11)*pochhammer(6/5,11)*
- pochhammer(70/50,11)*pochhammer(8/5,11)*pochhammer(9/5,11);
- on complex;
- pochhammer(a+b*i,c)*pochhammer(a-b*i,c);
- a := 2;
- b := 3;
- c := 5;
- pochhammer(a+b*i,c)*pochhammer(a-b*i,c);
- off complex;
- on rounded;
- pochhammer(1/5,11)*pochhammer(2/5,11)*pochhammer(3/5,11)*
- pochhammer(1-1/5,11)*pochhammer(1,11)*pochhammer(6/5,11)*
- pochhammer(70/50,11)*pochhammer(8/5,11)*pochhammer(9/5,11);
- q;
- pochhammer(pi,floor (pi**8));
- pochhammer(-pi,floor (pi**7));
- pochhammer(1.5,floor (pi**8));
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 5. Digamma function
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- procedure do!*one!*psi(x);
- << precision (precision(0) + 4)$
- write("Psi of ", x, " is ", psi(x) ) >> ;
- clear x, y;
- z := x * ((x+y)**2 + (x**y));
- off rounded;
- do!*one!*psi(3);
- do!*one!*psi(pi);
- do!*one!*psi(1.005);
- do!*one!*psi(1.995);
- do!*one!*psi(74);
- do!*one!*psi(-1/2);
- do!*one!*psi(-3);
- do!*one!*psi(z);
- on rounded;
- precision 100;
- do!*one!*psi(3);
- do!*one!*psi(pi);
- do!*one!*psi(1.005);
- do!*one!*psi(1.995);
- do!*one!*psi(74);
- do!*one!*psi(-1/2);
- do!*one!*psi(-3);
- do!*one!*psi(z);
- precision 15;
- x := 8/3;
- y := 7/1000;
- do!*one!*psi(z);
- off rounded;
- clear x, y;
- df(psi(z), x);
- df(df(psi(z), y),x);
- int(psi(z), z);
- on rounded;
- for k := 1 step 0.1 until 2 do do!*one!*psi(k);
- off rounded;
- % PSI_SIMP.TST F.J.Wright, 2 July 1993
- on evallhseqp;
- factor psi; on rat, intstr, div; % for neater output
- % Do not try using "off mcd"!
- psi(x+m) - psi(x+m-1) = 1/(x+m-1);
- psi(x+2) - psi(x+1) + 2*psi(x) = 1/(x+1) + 2*psi(x);
- psi(x+2) + 3*psi(x) = 4*psi(x) + 1/x + 1/(x+1);
- psi(x + 1) = psi(x) + 1/x;
- psi(x + 3/2) = psi(x + 1/2) + 1/(x + 1/2);
- psi(x - 1/2) = psi(x + 1/2) - 1/(x - 1/2);
- psi((x + 3a)/a); psi(x/y + 3);
- off rat, intstr, div; on rational;
- psi(x+m) - psi(x+m-1) = 1/(x+m-1);
- psi(x+2) - psi(x+1) + 2*psi(x) = 1/(x+1) + 2*psi(x);
- psi(x+2) + 3*psi(x) = 4*psi(x) + 1/x + 1/(x+1);
- psi(x + 1) = psi(x) + 1/x;
- psi(x + 3/2) = psi(x + 1/2) + 1/(x + 1/2);
- psi(x - 1/2) = psi(x + 1/2) - 1/(x - 1/2);
- psi((x + 3a)/a); psi(x/y + 3);
- off rational;
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 6. Polygamma functions
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- procedure do!*one!*pg(n,x);
- write ("Polygamma (", n, ") of ", x, " is ", polygamma(n,x));
- off rounded;
- do!*one!*pg(1,1/2);
- do!*one!*pg(1,1);
- do!*one!*pg(1,3/2);
- do!*one!*pg(1,1.005);
- do!*one!*pg(1,1.995);
- do!*one!*pg(1,1e-10);
- do!*one!*pg(2,1.45);
- do!*one!*pg(3,1.99);
- do!*one!*pg(4,-8.2);
- do!*one!*pg(5,0);
- do!*one!*pg(6,-5);
- do!*one!*pg(7,200);
- on rounded;
- precision 100;
- do!*one!*pg(1,1/2);
- do!*one!*pg(1,1);
- do!*one!*pg(1,3/2);
- do!*one!*pg(1,1.005);
- do!*one!*pg(1,1.995);
- do!*one!*pg(1,1e-10);
- do!*one!*pg(2,1.45);
- do!*one!*pg(3,1.99);
- do!*one!*pg(4,-8.2);
- do!*one!*pg(5,0);
- do!*one!*pg(6,-5);
- do!*one!*pg(7,200);
- off rounded;
- clear x;
- % Polygamma differentiation has already
- % been tried a bit in the psi section
- df(int(int(int(polygamma(3,x),x),x),x),x);
- clear w, y, z;
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 7. Zeta function
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- procedure do!*one!*zeta(n);
- write ("Zeta of ", n, " is ", zeta n);
- off rounded;
- clear x, y, z;
- z := x * ((x+y)**5 + (x**y));
- do!*one!*zeta(0);
- for k := 4 step 2 until 35 do
- do!*one!*zeta(k);
- do!*one!*zeta(-17/3);
- do!*one!*zeta(190);
- do!*one!*zeta(300);
- do!*one!*zeta(0);
- do!*one!*zeta(-44);
- on rounded;
- clear x, y;
- for k := 3 step 3 until 36 do <<
- precision (31+k*3);
- do!*one!*zeta(k) >>;
- precision 20;
- do!*one!*zeta(-17/3);
- do!*one!*zeta(z);
- y := 3;
- x := pi;
- do!*one!*zeta(z);
- do!*one!*zeta(190);
- do!*one!*zeta(300);
- do!*one!*zeta(0);
- do!*one!*zeta(-44);
- off rounded;
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 8. Kummer functions
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- off rounded;
- t!*kummer!*a := { 1, 2.4, -1397/10 }$
- t!*kummer!*b := { 0, 1, pi, -pi, 26 }$
- for each a in t!*kummer!*a do
- for each b in t!*kummer!*a do
- for each z in t!*kummer!*a do
- << write "KummerM(", a, ",", b, ",", z, ") = ",
- kummerm(a,b,z);
- write "KummerU(", a, ",", b, ",", z, ") = ",
- kummeru(a,b,z) >>;
- on rounded;
- precision 30;
- t!*k!*c := 7;
- % To test each and every possible combination of
- % three arguments from t!*kummer!*b would take too
- % long, but we want the possibility of trying most
- % special cases. Compromise: test every seventh
- % possibility.
- for each a in t!*kummer!*b do
- for each b in t!*kummer!*b do
- for each z in t!*kummer!*b do
- << if t!*k!*c = 7
- then << write "KummerM(", a, ",", b, ",", z, ") = ",
- kummerm(a,b,z);
- write "KummerU(", a, ",", b, ",", z, ") = ",
- kummeru(a,b,z);
- t!*k!*c := 0 >>;
- t!*k!*c := t!*k!*c + 1 >>;
- off rounded;
- clear x, y, z, t!*k!*c;
- df(df(kummerM(a,b,z),z),z);
- df(kummerU(a,b,z),z);
- z := ((x^2 + y)^5) + (x^(x+y));
- df(df(kummerM(a,b,z),y),x);
- df(kummerU(a,b,z),x);
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % 9. Bessel functions
- % =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
- % Lengthy test of the Bessel functions. This isn't even
- % remotely exhaustive of the special cases -- though a
- % real person with lots of time could no doubt come up
- % with a better lot of tests than this automated rubbish.
- % Again, compromise by only actually doing one in five or
- % nine. If you want a really thorough test, you can
- % easily change this to get it; but it'll take hours to
- % run.
- clear p, q;
- hankel1(p,q);
- r := df(ws,q);
- on complex;
- r;
- p:=3/8;
- r;
- q := pi;
- r;
- on rounded;
- r;
- off complex, rounded;
- df(df(besselj(pp,qq)+rr * hankel1(pp*2,qq) *
- bessely(pp-qq,qq),qq),qq);
- % Possible values for real args
- t!*bes!*vr := { 1, pi, -pi, 26 }$
- % Possible values for real and imaginary parts of complex args
- t!*bes!*vc := { 0, 3, -41/2 }$
- array s!*bes(4)$
- s!*bes(1) := "BesselJ"$
- s!*bes(2) := "BesselY"$
- s!*bes(3) := "BesselI"$
- s!*bes(4) := "BesselK"$
- pre := 16;
- precision pre;
- preord := 10**pre;
- t!*b!*c := 3;
- algebraic procedure do!*one!*bessel(s,n,z);
- (if s = 1 then besselj(n,z)
- else if s = 2 then bessely(n,z)
- else if s = 3 then besseli(n,z)
- else besselk(n,z));
- algebraic procedure pr!*bessel(s,n,z,k);
- << if t!*b!*c = k
- then
- << on rounded;
- bes1 := do!*one!*bessel(s,n,z);
- precision(pre+5);
- bes2 := do!*one!*bessel(s,n,z);
- if bes1 neq 0
- then disc := floor abs(100*(bes2-bes1)*preord/bes1)
- else disc := 0;
- precision pre;
- write s!*bes(s), "(", n, ",", z, ") = ", bes1;
- if not numberp disc then
- << precom := !*complex;
- on complex;
- disc := disc;
- if not precom then off complex >>;
- if disc neq 0
- then write " (discrepancy ", disc, "% of one s.f.)";
- if numberp disc and disc > 200 then
- << write "***** WARNING Significant Inaccuracy.";
- write " Lower precision result:";
- write " ", bes1;
- write " Higher precision result:";
- precision(pre+5); write " ", bes2; precision pre >>;
- off rounded;
- t!*b!*c := 0 >>;
- t!*b!*c := t!*b!*c + 1 >>;
- % About to begin Bessel test. We have a list of possible
- % values, and we test every Bessel, with every value on the
- % list as both order and argument. Every Bessel is computed
- % twice, to different precisions (differing by 3), and any
- % discrepancy is reported. The value reported is the diff-
- % erence between the two computed values, expressed as a
- % percentage of the unit of the least significant displayed
- % digit. A discrepancy between 100% and 200% means that the
- % last digit of the displayed value was found to differ at
- % higher precision; values greater than 200% are cause for
- % concern. An ideal discrepancy would be between about 1%
- % and 20%; if the value is found to be zero, no discrepancy
- % is reported.
- off msg;
- for s := 1:4 do
- << write(" ... Testing ", s!*bes(s), " for real domains ... ");
- for each n in t!*bes!*vr do
- for each z in t!*bes!*vr do
- pr!*bessel(s, n, z, 5) >>;
- on complex;
- for s := 1:3 do
- << write (" ... Testing ", s!*bes(s), " for complex domains ... ");
- for each nr in t!*bes!*vc do
- for each ni in t!*bes!*vc do
- for each zr in t!*bes!*vc do
- for each zi in t!*bes!*vc do
- pr!*bessel(s, nr+ni*i, zr+zi*i, 9) >>;
- off complex;
- on msg;
- write (" ...");
- write ("Bessel test complete.");
- end;
|