X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=check%2Fcheck_inifcns.cpp;h=81497cb9e0d1dabd2e939bee5c628b04d060e4d4;hp=b9e1f9f8a4f8eb1fa8ccc57e4790963359509c8a;hb=c77b5c8466b3d0a007146b435c4635ccf3fbf373;hpb=27d8eeed808afec4b319cea040d62365b65d49bc diff --git a/check/check_inifcns.cpp b/check/check_inifcns.cpp index b9e1f9f8..81497cb9 100644 --- a/check/check_inifcns.cpp +++ b/check/check_inifcns.cpp @@ -4,7 +4,7 @@ * functions. */ /* - * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2003 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,163 +24,190 @@ #include "checks.h" /* Some tests on the sine trigonometric function. */ -static unsigned inifcns_check_sin(void) +static unsigned inifcns_check_sin() { - unsigned result = 0; - bool errorflag = false; - - // sin(n*Pi) == 0? - errorflag = false; - for (int n=-10; n<=10; ++n) { - if (sin(n*Pi).eval() != numeric(0) || - !sin(n*Pi).eval().info(info_flags::integer)) - errorflag = true; - } - if (errorflag) { - // we don't count each of those errors - clog << "sin(n*Pi) with integer n does not always return exact 0" - << endl; - ++result; - } - - // sin((n+1/2)*Pi) == {+|-}1? - errorflag = false; - for (int n=-10; n<=10; ++n) { - if (!sin((n+numeric(1,2))*Pi).eval().info(info_flags::integer) || - !(sin((n+numeric(1,2))*Pi).eval() == numeric(1) || - sin((n+numeric(1,2))*Pi).eval() == numeric(-1))) - errorflag = true; - } - if (errorflag) { - clog << "sin((n+1/2)*Pi) with integer n does not always return exact {+|-}1" - << endl; - ++result; - } - - // compare sin((q*Pi).evalf()) with sin(q*Pi).eval().evalf() at various - // points. E.g. if sin(Pi/10) returns something symbolic this should be - // equal to sqrt(5)/4-1/4. This routine will spot programming mistakes - // of this kind: - errorflag = false; - ex argument; - numeric epsilon(double(1e-8)); - for (int n=-340; n<=340; ++n) { - argument = n*Pi/60; - if (abs(sin(evalf(argument))-evalf(sin(argument)))>epsilon) { - clog << "sin(" << argument << ") returns " - << sin(argument) << endl; - errorflag = true; - } - } - if (errorflag) { - ++result; - } - - return result; + unsigned result = 0; + bool errorflag = false; + + // sin(n*Pi) == 0? + errorflag = false; + for (int n=-10; n<=10; ++n) { + if (sin(n*Pi).eval() != numeric(0) || + !sin(n*Pi).eval().info(info_flags::integer)) + errorflag = true; + } + if (errorflag) { + // we don't count each of those errors + clog << "sin(n*Pi) with integer n does not always return exact 0" + << endl; + ++result; + } + + // sin((n+1/2)*Pi) == {+|-}1? + errorflag = false; + for (int n=-10; n<=10; ++n) { + if (!sin((n+numeric(1,2))*Pi).eval().info(info_flags::integer) || + !(sin((n+numeric(1,2))*Pi).eval() == numeric(1) || + sin((n+numeric(1,2))*Pi).eval() == numeric(-1))) + errorflag = true; + } + if (errorflag) { + clog << "sin((n+1/2)*Pi) with integer n does not always return exact {+|-}1" + << endl; + ++result; + } + + // compare sin((q*Pi).evalf()) with sin(q*Pi).eval().evalf() at various + // points. E.g. if sin(Pi/10) returns something symbolic this should be + // equal to sqrt(5)/4-1/4. This routine will spot programming mistakes + // of this kind: + errorflag = false; + ex argument; + numeric epsilon(double(1e-8)); + for (int n=-340; n<=340; ++n) { + argument = n*Pi/60; + if (abs(sin(evalf(argument))-evalf(sin(argument)))>epsilon) { + clog << "sin(" << argument << ") returns " + << sin(argument) << endl; + errorflag = true; + } + } + if (errorflag) + ++result; + + return result; } /* Simple tests on the cosine trigonometric function. */ -static unsigned inifcns_check_cos(void) +static unsigned inifcns_check_cos() { - unsigned result = 0; - bool errorflag; - - // cos((n+1/2)*Pi) == 0? - errorflag = false; - for (int n=-10; n<=10; ++n) { - if (cos((n+numeric(1,2))*Pi).eval() != numeric(0) || - !cos((n+numeric(1,2))*Pi).eval().info(info_flags::integer)) - errorflag = true; - } - if (errorflag) { - clog << "cos((n+1/2)*Pi) with integer n does not always return exact 0" - << endl; - ++result; - } - - // cos(n*Pi) == 0? - errorflag = false; - for (int n=-10; n<=10; ++n) { - if (!cos(n*Pi).eval().info(info_flags::integer) || - !(cos(n*Pi).eval() == numeric(1) || - cos(n*Pi).eval() == numeric(-1))) - errorflag = true; - } - if (errorflag) { - clog << "cos(n*Pi) with integer n does not always return exact {+|-}1" - << endl; - ++result; - } - - // compare cos((q*Pi).evalf()) with cos(q*Pi).eval().evalf() at various - // points. E.g. if cos(Pi/12) returns something symbolic this should be - // equal to 1/4*(1+1/3*sqrt(3))*sqrt(6). This routine will spot - // programming mistakes of this kind: - errorflag = false; - ex argument; - numeric epsilon(double(1e-8)); - for (int n=-340; n<=340; ++n) { - argument = n*Pi/60; - if (abs(cos(evalf(argument))-evalf(cos(argument)))>epsilon) { - clog << "cos(" << argument << ") returns " - << cos(argument) << endl; - errorflag = true; - } - } - if (errorflag) { - ++result; - } - - return result; + unsigned result = 0; + bool errorflag; + + // cos((n+1/2)*Pi) == 0? + errorflag = false; + for (int n=-10; n<=10; ++n) { + if (cos((n+numeric(1,2))*Pi).eval() != numeric(0) || + !cos((n+numeric(1,2))*Pi).eval().info(info_flags::integer)) + errorflag = true; + } + if (errorflag) { + clog << "cos((n+1/2)*Pi) with integer n does not always return exact 0" + << endl; + ++result; + } + + // cos(n*Pi) == 0? + errorflag = false; + for (int n=-10; n<=10; ++n) { + if (!cos(n*Pi).eval().info(info_flags::integer) || + !(cos(n*Pi).eval() == numeric(1) || + cos(n*Pi).eval() == numeric(-1))) + errorflag = true; + } + if (errorflag) { + clog << "cos(n*Pi) with integer n does not always return exact {+|-}1" + << endl; + ++result; + } + + // compare cos((q*Pi).evalf()) with cos(q*Pi).eval().evalf() at various + // points. E.g. if cos(Pi/12) returns something symbolic this should be + // equal to 1/4*(1+1/3*sqrt(3))*sqrt(6). This routine will spot + // programming mistakes of this kind: + errorflag = false; + ex argument; + numeric epsilon(double(1e-8)); + for (int n=-340; n<=340; ++n) { + argument = n*Pi/60; + if (abs(cos(evalf(argument))-evalf(cos(argument)))>epsilon) { + clog << "cos(" << argument << ") returns " + << cos(argument) << endl; + errorflag = true; + } + } + if (errorflag) + ++result; + + return result; } /* Simple tests on the tangent trigonometric function. */ -static unsigned inifcns_check_tan(void) +static unsigned inifcns_check_tan() { - unsigned result = 0; - bool errorflag; - - // compare tan((q*Pi).evalf()) with tan(q*Pi).eval().evalf() at various - // points. E.g. if tan(Pi/12) returns something symbolic this should be - // equal to 2-sqrt(3). This routine will spot programming mistakes of - // this kind: - errorflag = false; - ex argument; - numeric epsilon(double(1e-8)); - for (int n=-340; n<=340; ++n) { - if (!(n%30) && (n%60)) // skip poles - ++n; - argument = n*Pi/60; - if (abs(tan(evalf(argument))-evalf(tan(argument)))>epsilon) { - clog << "tan(" << argument << ") returns " - << tan(argument) << endl; - errorflag = true; - } - } - if (errorflag) { - ++result; - } - - return result; + unsigned result = 0; + bool errorflag; + + // compare tan((q*Pi).evalf()) with tan(q*Pi).eval().evalf() at various + // points. E.g. if tan(Pi/12) returns something symbolic this should be + // equal to 2-sqrt(3). This routine will spot programming mistakes of + // this kind: + errorflag = false; + ex argument; + numeric epsilon(double(1e-8)); + for (int n=-340; n<=340; ++n) { + if (!(n%30) && (n%60)) // skip poles + ++n; + argument = n*Pi/60; + if (abs(tan(evalf(argument))-evalf(tan(argument)))>epsilon) { + clog << "tan(" << argument << ") returns " + << tan(argument) << endl; + errorflag = true; + } + } + if (errorflag) + ++result; + + return result; } -unsigned check_inifcns(void) +/* Simple tests on the dilogarithm function. */ +static unsigned inifcns_check_Li2() { - unsigned result = 0; + // NOTE: this can safely be removed once CLN supports dilogarithms and + // checks them itself. + unsigned result = 0; + bool errorflag; + + // check the relation Li2(z^2) == 2 * (Li2(z) + Li2(-z)) numerically, which + // should hold in the entire complex plane: + errorflag = false; + ex argument; + numeric epsilon(double(1e-16)); + for (int n=0; n<200; ++n) { + argument = numeric(20.0*rand()/(RAND_MAX+1.0)-10.0) + + numeric(20.0*rand()/(RAND_MAX+1.0)-10.0)*I; + if (abs(Li2(pow(argument,2))-2*Li2(argument)-2*Li2(-argument)) > epsilon) { + clog << "Li2(z) at z==" << argument + << " failed to satisfy Li2(z^2)==2*(Li2(z)+Li2(-z))" << endl; + errorflag = true; + } + } + + if (errorflag) + ++result; + + return result; +} + +unsigned check_inifcns() +{ + unsigned result = 0; - cout << "checking consistency of symbolic functions" << flush; - clog << "---------consistency of symbolic functions:" << endl; - - result += inifcns_check_sin(); cout << '.' << flush; - result += inifcns_check_cos(); cout << '.' << flush; - result += inifcns_check_tan(); cout << '.' << flush; - - if (!result) { - cout << " passed " << endl; - clog << "(no output)" << endl; - } else { - cout << " failed " << endl; - } - - return result; + cout << "checking consistency of symbolic functions" << flush; + clog << "---------consistency of symbolic functions:" << endl; + + result += inifcns_check_sin(); cout << '.' << flush; + result += inifcns_check_cos(); cout << '.' << flush; + result += inifcns_check_tan(); cout << '.' << flush; + result += inifcns_check_Li2(); cout << '.' << flush; + + if (!result) { + cout << " passed " << endl; + clog << "(no output)" << endl; + } else { + cout << " failed " << endl; + } + + return result; }