From: Richard Kreckel Date: Fri, 10 Dec 1999 20:23:46 +0000 (+0000) Subject: - changed behaviour of numeric::is_rational() and added numeric::is_cinteger() X-Git-Tag: release_0-5-0~96 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=b0265215a51a081d20fe68475e080716afc2d45a;ds=sidebyside - changed behaviour of numeric::is_rational() and added numeric::is_cinteger() and numeric::is_crational() which work for complex numbers now - added default ctor for constant to please CInt - documentation reflects the changes for upcoming 0.4.1 --- diff --git a/check/expand_subs.cpp b/check/expand_subs.cpp index 4d78708b..109978fa 100644 --- a/check/expand_subs.cpp +++ b/check/expand_subs.cpp @@ -86,11 +86,11 @@ unsigned expand_subs(void) cout << "checking commutative expansion and substitution..." << flush; clog << "---------commutative expansion and substitution:" << endl; - + result += expand_subs1(); result += expand_subs2(); - - if (! result) { + + if (!result) { cout << " passed "; clog << "(no output)" << endl; } else { diff --git a/check/lsolve_onedim.cpp b/check/lsolve_onedim.cpp index be113c2d..d1c19f78 100644 --- a/check/lsolve_onedim.cpp +++ b/check/lsolve_onedim.cpp @@ -44,7 +44,7 @@ unsigned lsolve_onedim(void) << aux << endl; } - if (! result) { + if (!result) { cout << " passed "; clog << "(no output)" << endl; } else { diff --git a/check/matrix_checks.cpp b/check/matrix_checks.cpp index 3da30af8..7bce7872 100644 --- a/check/matrix_checks.cpp +++ b/check/matrix_checks.cpp @@ -230,7 +230,7 @@ unsigned matrix_checks(void) result += matrix_invert3(); result += matrix_misc(); - if (! result) { + if (!result) { cout << " passed "; clog << "(no output)" << endl; } else { diff --git a/check/normalization.cpp b/check/normalization.cpp index bf761ffe..7ce1e5dc 100644 --- a/check/normalization.cpp +++ b/check/normalization.cpp @@ -30,106 +30,107 @@ static symbol x("x"), y("y"), z("z"); static unsigned check_normal(const ex &e, const ex &d) { - ex en = e.normal(); - if (en.compare(d) != 0) { - clog << "normal form of " << e << " is " << en << " (should be " << d << ")" << endl; - return 1; - } - return 0; + ex en = e.normal(); + if (en.compare(d) != 0) { + clog << "normal form of " << e << " erroneously returned " + << en << " (should be " << d << ")" << endl; + return 1; + } + return 0; } static unsigned normal1(void) { - unsigned result = 0; - ex e, d; - - // Expansion - e = pow(x, 2) - (x+1)*(x-1) - 1; - d = exZERO(); - result += check_normal(e, d); - - // Expansion inside functions - e = sin(x*(x+1)-x) + 1; - d = sin(pow(x, 2)) + 1; - result += check_normal(e, d); - - // Fraction addition - e = numeric(2)/x + y/3; - d = (x*y/3 + 2) / x; - result += check_normal(e, d); - - // Fraction addition - e = pow(x, -1) + x/(x+1); - d = (pow(x, 2)+x+1)/(x*(x+1)); - result += check_normal(e, d); - - // Fraction cancellation - e = (pow(x, 2) - pow(y, 2)) / pow(x-y, 3); - d = (x + y) / (pow(x, 2) + pow(y, 2) - x * y * 2); - result += check_normal(e, d); - - // Fraction cancellation - e = (pow(x, -1) + x) / (pow(x , 2) * 2 + 2); - d = pow(x * 2, -1); - result += check_normal(e, d); - - // Distribution of powers - e = pow(x/y, 2); - d = pow(x, 2) / pow(y, 2); - result += check_normal(e, d); - - // Distribution of powers (integer, distribute) and fraction addition - e = pow(pow(x, -1) + x, 2); - d = pow(pow(x, 2) + 1, 2) / pow(x, 2); - result += check_normal(e, d); - - // Distribution of powers (non-integer, don't distribute) and fraction addition - e = pow(pow(x, -1) + x, numeric(1)/2); - d = pow((pow(x, 2) + 1) / x, numeric(1)/2); - result += check_normal(e, d); - - // Replacement of functions with temporary symbols and fraction cancellation - e = pow(sin(x), 2) - pow(cos(x), 2); - e /= sin(x) + cos(x); - d = sin(x) - cos(x); - result += check_normal(e, d); - - // Replacement of non-integer powers with temporary symbols - e = (pow(numeric(2), numeric(1)/2) * x + x) / x; - d = pow(numeric(2), numeric(1)/2) + 1; - result += check_normal(e, d); - - // Replacement of complex numbers with temporary symbols - e = (x + y + x*I + y*I) / (x + y); - d = 1 + I; - result += check_normal(e, d); - - e = (pow(x, 2) + pow(y, 2)) / (x + y*I); - d = e; - result += check_normal(e, d); - - // More complex rational function - e = (pow(x-y*2,4)/pow(pow(x,2)-pow(y,2)*4,2)+1)*(x+y*2)*(y+z)/(pow(x,2)+pow(y,2)*4); - d = (y*2 + z*2) / (x + y*2); - result += check_normal(e, d); - - return result; + unsigned result = 0; + ex e, d; + + // Expansion + e = pow(x, 2) - (x+1)*(x-1) - 1; + d = exZERO(); + result += check_normal(e, d); + + // Expansion inside functions + e = sin(x*(x+1)-x) + 1; + d = sin(pow(x, 2)) + 1; + result += check_normal(e, d); + + // Fraction addition + e = numeric(2)/x + y/3; + d = (x*y/3 + 2) / x; + result += check_normal(e, d); + + // Fraction addition + e = pow(x, -1) + x/(x+1); + d = (pow(x, 2)+x+1)/(x*(x+1)); + result += check_normal(e, d); + + // Fraction cancellation + e = (pow(x, 2) - pow(y, 2)) / pow(x-y, 3); + d = (x + y) / (pow(x, 2) + pow(y, 2) - x * y * 2); + result += check_normal(e, d); + + // Fraction cancellation + e = (pow(x, -1) + x) / (pow(x , 2) * 2 + 2); + d = pow(x * 2, -1); + result += check_normal(e, d); + + // Distribution of powers + e = pow(x/y, 2); + d = pow(x, 2) / pow(y, 2); + result += check_normal(e, d); + + // Distribution of powers (integer, distribute) and fraction addition + e = pow(pow(x, -1) + x, 2); + d = pow(pow(x, 2) + 1, 2) / pow(x, 2); + result += check_normal(e, d); + + // Distribution of powers (non-integer, don't distribute) and fraction addition + e = pow(pow(x, -1) + x, numeric(1)/2); + d = pow((pow(x, 2) + 1) / x, numeric(1)/2); + result += check_normal(e, d); + + // Replacement of functions with temporary symbols and fraction cancellation + e = pow(sin(x), 2) - pow(cos(x), 2); + e /= sin(x) + cos(x); + d = sin(x) - cos(x); + result += check_normal(e, d); + + // Replacement of non-integer powers with temporary symbols + e = (pow(numeric(2), numeric(1)/2) * x + x) / x; + d = pow(numeric(2), numeric(1)/2) + 1; + result += check_normal(e, d); + + // Replacement of complex numbers with temporary symbols + e = (x + y + x*I + y*I) / (x + y); + d = 1 + I; + result += check_normal(e, d); + + e = (pow(x, 2) + pow(y, 2)) / (x + y*I); + d = e; + result += check_normal(e, d); + + // More complex rational function + e = (pow(x-y*2,4)/pow(pow(x,2)-pow(y,2)*4,2)+1)*(x+y*2)*(y+z)/(pow(x,2)+pow(y,2)*4); + d = (y*2 + z*2) / (x + y*2); + result += check_normal(e, d); + + return result; } unsigned normalization(void) { - unsigned result = 0; - - cout << "checking rational function normalization..." << flush; - clog << "---------rational function normalization:" << endl; - - result += normal1(); - - if (!result) { - cout << " passed "; - clog << "(no output)" << endl; - } else { - cout << " failed "; - } - return result; + unsigned result = 0; + + cout << "checking rational function normalization..." << flush; + clog << "---------rational function normalization:" << endl; + + result += normal1(); + + if (!result) { + cout << " passed "; + clog << "(no output)" << endl; + } else { + cout << " failed "; + } + return result; } diff --git a/check/numeric_consist.cpp b/check/numeric_consist.cpp index d6a3ffca..60088493 100644 --- a/check/numeric_consist.cpp +++ b/check/numeric_consist.cpp @@ -37,47 +37,54 @@ static unsigned numeric_consist1(void) numeric test_int2(5); numeric test_rat1 = test_int1; test_rat1 /= test_int2; test_rat1 = -test_rat1; // -42/5 + numeric test_crat = test_rat1+I*test_int2; // 5*I-42/5 symbol a("a"); ex e1, e2; - if ( !test_int1.is_integer() ) { + if (!test_int1.is_integer()) { clog << test_int1 << " erroneously not recognized as integer" << endl; ++result; } - if ( !test_int1.is_rational() ) { + if (!test_int1.is_rational()) { clog << test_int1 << " erroneously not recognized as rational" << endl; ++result; } - if ( !test_rat1.is_rational() ) { + if (!test_rat1.is_rational()) { clog << test_rat1 << " erroneously not recognized as rational" << endl; ++result; } - if ( test_rat1.is_integer() ) { + if (test_rat1.is_integer()) { clog << test_rat1 << " erroneously recognized as integer" << endl; ++result; } + if (!test_crat.is_crational()) { + clog << test_crat + << " erroneously not recognized as complex rational" << endl; + ++result; + } + int i = numeric(1984).to_int(); - if ( i-1984 ) { + if (i-1984) { clog << "conversion of " << i << " from numeric to int failed" << endl; ++result; } e1 = test_int1; - if ( !e1.info(info_flags::posint) ) { + if (!e1.info(info_flags::posint)) { clog << "expression " << e1 << " erroneously not recognized as positive integer" << endl; ++result; } e2 = test_int1 + a; - if ( ex_to_numeric(e2).is_integer() ) { + if (ex_to_numeric(e2).is_integer()) { clog << "expression " << e2 << " erroneously recognized as integer" << endl; ++result; @@ -86,15 +93,15 @@ static unsigned numeric_consist1(void) // The next two were two actual bugs in CLN till June, 12, 1999: test_rat1 = numeric(3)/numeric(2); test_rat1 += test_rat1; - if ( !test_rat1.is_integer() ) { + if (!test_rat1.is_integer()) { clog << "3/2 + 3/2 erroneously not integer 3 but instead " << test_rat1 << endl; ++result; } test_rat1 = numeric(3)/numeric(2); numeric test_rat2 = test_rat1 + numeric(1); // 5/2 - test_rat2 -= test_rat1; // 1 - if ( !test_rat2.is_integer() ) { + test_rat2 -= test_rat1; // 1 + if (!test_rat2.is_integer()) { clog << "5/2 - 3/2 erroneously not integer 1 but instead " << test_rat2 << endl; ++result; @@ -124,7 +131,7 @@ static unsigned numeric_consist1(void) * calculating expt(a,b) if b is a rational and a a nonnegative integer. * Implementing a workaround sadly introduced another bug on May 28th 1999 * that was fixed on May 31st. The workaround turned out to be stupid and - * the bug was finally killed in CLN on September 2nd. */ + * the original bug in CLN was finally killed on September 2nd. */ static unsigned numeric_consist2(void) { unsigned result = 0; @@ -134,27 +141,27 @@ static unsigned numeric_consist2(void) ex three = numeric(3); // The hang in this code was the reason for the original workaround - if ( pow(two,two/three) == 42 ) { + if (pow(two,two/three)==42) { clog << "pow(2,2/3) erroneously returned 42" << endl; ++result; // cannot happen } // Actually, this used to raise a FPE after introducing the workaround - if ( two*zero != zero ) { + if (two*zero!=zero) { clog << "2*0 erroneously returned " << two*zero << endl; ++result; } // And this returned a cl_F due to the implicit call of numeric::power() ex six = two*three; - if ( !six.info(info_flags::integer) ) { + if (!six.info(info_flags::integer)) { clog << "2*3 erroneously returned the non-integer " << six << endl; ++result; } // The fix in the workaround left a whole which was fixed hours later... ex another_zero = pow(zero,numeric(1)/numeric(2)); - if ( another_zero.compare(exZERO()) ) { + if (another_zero.compare(exZERO())) { clog << "pow(0,1/2) erroneously returned" << another_zero << endl; ++result; } @@ -175,50 +182,50 @@ static unsigned numeric_consist3(void) // These overloaded routines indeed need to be checked separately since // internally they might be doing something completely different: a = 23; b = 4; calc_rem = irem(a, b); - if ( calc_rem != 3 ) { + if (calc_rem != 3) { clog << "irem(" << a << "," << b << ") erroneously returned " << calc_rem << endl; ++result; } a = 23; b = -4; calc_rem = irem(a, b); - if ( calc_rem != 3 ) { + if (calc_rem != 3) { clog << "irem(" << a << "," << b << ") erroneously returned " << calc_rem << endl; ++result; } a = -23; b = 4; calc_rem = irem(a, b); - if ( calc_rem != -3 ) { + if (calc_rem != -3) { clog << "irem(" << a << "," << b << ") erroneously returned " << calc_rem << endl; ++result; } a = -23; b = -4; calc_rem = irem(a, b); - if ( calc_rem != -3 ) { + if (calc_rem != -3) { clog << "irem(" << a << "," << b << ") erroneously returned " << calc_rem << endl; ++result; } // and now the overloaded irem(a,b,q): a = 23; b = 4; calc_rem = irem(a, b, calc_quo); - if ( calc_rem != 3 || calc_quo != 5 ) { + if (calc_rem != 3 || calc_quo != 5) { clog << "irem(" << a << "," << b << ",q) erroneously returned " << calc_rem << " with q=" << calc_quo << endl; ++result; } a = 23; b = -4; calc_rem = irem(a, b, calc_quo); - if ( calc_rem != 3 || calc_quo != -5 ) { + if (calc_rem != 3 || calc_quo != -5) { clog << "irem(" << a << "," << b << ",q) erroneously returned " << calc_rem << " with q=" << calc_quo << endl; ++result; } a = -23; b = 4; calc_rem = irem(a, b, calc_quo); - if ( calc_rem != -3 || calc_quo != -5 ) { + if (calc_rem != -3 || calc_quo != -5) { clog << "irem(" << a << "," << b << ",q) erroneously returned " << calc_rem << " with q=" << calc_quo << endl; ++result; } a = -23; b = -4; calc_rem = irem(a, b, calc_quo); - if ( calc_rem != -3 || calc_quo != 5 ) { + if (calc_rem != -3 || calc_quo != 5) { clog << "irem(" << a << "," << b << ",q) erroneously returned " << calc_rem << " with q=" << calc_quo << endl; ++result; @@ -228,50 +235,50 @@ static unsigned numeric_consist3(void) // These overloaded routines indeed need to be checked separately since // internally they might be doing something completely different: a = 23; b = 4; calc_quo = iquo(a, b); - if ( calc_quo != 5 ) { + if (calc_quo != 5) { clog << "iquo(" << a << "," << b << ") erroneously returned " << calc_quo << endl; ++result; } a = 23; b = -4; calc_quo = iquo(a, b); - if ( calc_quo != -5 ) { + if (calc_quo != -5) { clog << "iquo(" << a << "," << b << ") erroneously returned " << calc_quo << endl; ++result; } a = -23; b = 4; calc_quo = iquo(a, b); - if ( calc_quo != -5 ) { + if (calc_quo != -5) { clog << "iquo(" << a << "," << b << ") erroneously returned " << calc_quo << endl; ++result; } a = -23; b = -4; calc_quo = iquo(a, b); - if ( calc_quo != 5 ) { + if (calc_quo != 5) { clog << "iquo(" << a << "," << b << ") erroneously returned " << calc_quo << endl; ++result; } // and now the overloaded iquo(a,b,r): a = 23; b = 4; calc_quo = iquo(a, b, calc_rem); - if ( calc_quo != 5 || calc_rem != 3 ) { + if (calc_quo != 5 || calc_rem != 3) { clog << "iquo(" << a << "," << b << ",r) erroneously returned " << calc_quo << " with r=" << calc_rem << endl; ++result; } a = 23; b = -4; calc_quo = iquo(a, b, calc_rem); - if ( calc_quo != -5 || calc_rem != 3 ) { + if (calc_quo != -5 || calc_rem != 3) { clog << "iquo(" << a << "," << b << ",r) erroneously returned " << calc_quo << " with r=" << calc_rem << endl; ++result; } a = -23; b = 4; calc_quo = iquo(a, b, calc_rem); - if ( calc_quo != -5 || calc_rem != -3 ) { + if (calc_quo != -5 || calc_rem != -3) { clog << "iquo(" << a << "," << b << ",r) erroneously returned " << calc_quo << " with r=" << calc_rem << endl; ++result; } a = -23; b = -4; calc_quo = iquo(a, b, calc_rem); - if ( calc_quo != 5 || calc_rem != -3 ) { + if (calc_quo != 5 || calc_rem != -3) { clog << "iquo(" << a << "," << b << ",r) erroneously returned " << calc_quo << " with r=" << calc_rem << endl; ++result; @@ -294,10 +301,11 @@ static unsigned numeric_consist4(void) passed = false; } } - if ( !passed ) { + if (!passed) { clog << "One or more square roots of squares of integers did not return exact integers" << endl; ++result; } + // square roots of squares of rationals: passed = true; for (int num=0; num<41; ++num) { @@ -307,7 +315,7 @@ static unsigned numeric_consist4(void) } } } - if ( !passed ) { + if (!passed) { clog << "One or more square roots of squares of rationals did not return exact integers" << endl; ++result; } @@ -327,7 +335,7 @@ unsigned numeric_consist(void) result += numeric_consist3(); result += numeric_consist4(); - if ( !result ) { + if (!result) { cout << " passed "; clog << "(no output)" << endl; } else { diff --git a/check/paranoia_check.cpp b/check/paranoia_check.cpp index b42225ca..3eb4185c 100644 --- a/check/paranoia_check.cpp +++ b/check/paranoia_check.cpp @@ -241,7 +241,7 @@ unsigned paranoia_check(void) result += paranoia_check7(); result += paranoia_check8(); - if (! result) { + if (!result) { cout << " passed "; clog << "(no output)" << endl; } else { diff --git a/doc/reference/DoxyfileHTML b/doc/reference/DoxyfileHTML index d9260e29..c465b30a 100644 --- a/doc/reference/DoxyfileHTML +++ b/doc/reference/DoxyfileHTML @@ -128,7 +128,7 @@ SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. -INLINE_SOURCES = YES +INLINE_SOURCES = NO # If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen # will only generate file names in lower case letters. If set to diff --git a/doc/tutorial/classhierarchy.fig b/doc/tutorial/classhierarchy.fig index d093f8e6..4df411c9 100644 --- a/doc/tutorial/classhierarchy.fig +++ b/doc/tutorial/classhierarchy.fig @@ -9,26 +9,6 @@ Single 1200 2 5 1 1 2 0 7 100 0 -1 4.000 0 0 1 0 1896.500 2807.128 791 579 1973 321 3002 579 1 1 1.00 68.57 137.14 -6 4853 2533 5779 2790 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 4853 2533 5779 2533 5779 2790 4853 2790 4853 2533 -4 1 0 99 0 0 14 0.0000 4 150 555 5316 2739 matrix\001 --6 -6 4853 2070 5779 2327 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 4853 2070 5779 2070 5779 2327 4853 2327 4853 2070 -4 1 0 99 0 0 14 0.0000 4 150 705 5316 2276 numeric\001 --6 -6 4853 1607 5779 1864 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 4853 1607 5779 1607 5779 1864 4853 1864 4853 1607 -4 1 0 99 0 0 14 0.0000 4 135 735 5316 1813 constant\001 --6 -6 585 2019 1099 2276 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 585 2019 1099 2019 1099 2276 585 2276 585 2019 -4 1 0 99 0 0 14 0.0000 4 150 315 842 2224 add\001 --6 6 996 1144 2025 1401 2 2 0 1 0 7 100 0 20 0.000 0 0 -1 0 0 5 2025 1144 996 1144 996 1401 2025 1401 2025 1144 @@ -39,75 +19,100 @@ Single 3053 630 3876 630 3876 887 3053 887 3053 630 4 1 0 99 0 0 14 0.0000 4 150 450 3465 836 basic\001 -6 -6 225 463 739 720 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 225 463 739 463 739 720 225 720 225 463 -4 1 0 99 0 0 14 0.0000 4 105 210 482 668 ex\001 --6 -6 2160 1498 2880 1755 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 2160 1498 2880 1498 2880 1755 2160 1755 2160 1498 -4 1 0 99 0 0 14 0.0000 4 150 555 2520 1704 power\001 --6 -6 4860 1119 5786 1376 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 4860 1119 5786 1119 5786 1376 4860 1376 4860 1119 -4 1 0 99 0 0 14 0.0000 4 195 615 5323 1324 symbol\001 --6 6 2340 1935 3195 2205 2 2 0 1 0 7 100 0 20 0.000 0 0 -1 0 0 5 2340 1948 3195 1948 3195 2205 2340 2205 2340 1948 4 1 0 99 0 0 14 0.0000 4 150 690 2764 2154 exprseq\001 -6 -6 1350 2019 1864 2276 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 +6 2565 2925 3510 3195 +2 2 0 1 0 7 100 0 20 0.000 0 0 -1 0 0 5 + 2565 2925 3510 2925 3510 3195 2565 3195 2565 2925 +4 1 0 99 0 0 14 0.0000 4 150 675 3034 3131 indexed\001 +-6 +6 3060 3645 3420 3735 +1 4 0 1 0 0 100 0 20 0.000 1 0.0000 3127 3690 23 23 3104 3690 3150 3690 +1 4 0 1 0 0 100 0 20 0.000 1 0.0000 3263 3690 23 23 3240 3690 3286 3690 +1 4 0 1 0 0 100 0 20 0.000 1 0.0000 3397 3690 23 23 3374 3690 3420 3690 +-6 +6 4410 3600 4770 3690 +1 4 0 1 0 0 100 0 20 0.000 1 0.0000 4477 3645 23 23 4454 3645 4500 3645 +1 4 0 1 0 0 100 0 20 0.000 1 0.0000 4613 3645 23 23 4590 3645 4636 3645 +1 4 0 1 0 0 100 0 20 0.000 1 0.0000 4747 3645 23 23 4724 3645 4770 3645 +-6 +6 585 1980 1125 2295 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 585 2019 1099 2019 1099 2276 585 2276 585 2019 +4 1 0 99 0 0 14 0.0000 4 150 315 842 2224 add\001 +-6 +6 225 450 765 720 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 225 463 739 463 739 720 225 720 225 463 +4 1 0 99 0 0 14 0.0000 4 105 210 482 668 ex\001 +-6 +6 1350 1980 1890 2295 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 1350 2019 1864 2019 1864 2276 1350 2276 1350 2019 4 1 0 99 0 0 14 0.0000 4 150 315 1607 2224 mul\001 -6 6 1305 2520 2025 2790 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 1305 2533 2025 2533 2025 2790 1305 2790 1305 2533 4 1 0 99 0 0 14 0.0000 4 150 525 1672 2739 ncmul\001 -6 -6 1530 2925 2475 3195 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 1530 2925 2475 2925 2475 3195 1530 3195 1530 2925 -4 1 0 99 0 0 14 0.0000 4 150 690 1999 3131 function\001 +6 1485 2880 2430 3150 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 1485 2880 2430 2880 2430 3150 1485 3150 1485 2880 +4 1 0 99 0 0 14 0.0000 4 150 690 1954 3086 function\001 +-6 +6 1845 3510 2520 3780 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 1845 3510 2520 3510 2520 3780 1845 3780 1845 3510 +4 1 0 99 0 0 14 0.0000 4 195 585 2179 3716 isospin\001 +-6 +6 2565 3510 3060 3780 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 2565 3510 3060 3510 3060 3780 2565 3780 2565 3510 +4 1 0 99 0 0 14 0.0000 4 150 435 2809 3716 color\001 +-6 +6 3555 3465 4365 3780 +1 2 0 1 0 30 100 0 20 0.000 1 0.0000 3960 3622 405 157 3555 3622 4365 3622 +4 1 0 99 0 0 14 0.0000 4 150 690 3960 3690 coloridx\001 +-6 +6 3600 2880 4275 3195 +1 2 0 1 0 30 100 0 20 0.000 1 0.0000 3937 3037 337 157 3600 3037 4274 3037 +4 1 0 99 0 0 14 0.0000 4 150 255 3960 3105 idx\001 +-6 +6 3780 2250 4320 2520 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 3806 2263 4320 2263 4320 2520 3806 2520 3806 2263 +4 1 0 99 0 0 14 0.0000 4 150 195 4063 2468 lst\001 +-6 +6 2160 1485 2880 1755 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 2160 1498 2880 1498 2880 1755 2160 1755 2160 1498 +4 1 0 99 0 0 14 0.0000 4 150 555 2520 1704 power\001 -6 6 4725 2970 5445 3240 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 4725 2970 5445 2970 5445 3240 4725 3240 4725 2970 4 1 0 99 0 0 14 0.0000 4 150 510 5059 3176 series\001 -6 -6 4005 2655 4545 2925 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 4031 2668 4545 2668 4545 2925 4031 2925 4031 2668 -4 1 0 99 0 0 14 0.0000 4 150 195 4288 2873 lst\001 --6 -6 3240 2340 3825 2610 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 3240 2340 3825 2340 3825 2610 3240 2610 3240 2340 -4 1 0 99 0 0 14 0.0000 4 150 255 3529 2546 idx\001 --6 -6 2565 2925 3510 3195 -2 2 0 1 0 7 100 0 20 0.000 0 0 -1 0 0 5 - 2565 2925 3510 2925 3510 3195 2565 3195 2565 2925 -4 1 0 99 0 0 14 0.0000 4 150 675 3034 3131 indexed\001 +6 4815 2520 5805 2790 +2 2 0 1 0 30 100 0 20 0.000 0 0 -1 0 0 5 + 4853 2533 5779 2533 5779 2790 4853 2790 4853 2533 +4 1 0 99 0 0 14 0.0000 4 150 555 5316 2739 matrix\001 -6 -6 1935 3510 2610 3780 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 1935 3510 2610 3510 2610 3780 1935 3780 1935 3510 -4 1 0 99 0 0 14 0.0000 4 195 585 2269 3716 isospin\001 +6 4770 1980 5760 2340 +1 2 0 1 0 30 100 0 20 0.000 1 0.0000 5287 2182 473 158 4814 2182 5760 2182 +4 1 0 99 0 0 14 0.0000 4 150 705 5310 2250 numeric\001 -6 -6 2700 3510 3285 3780 -2 2 0 1 0 3 100 0 20 0.000 0 0 -1 0 0 5 - 2700 3510 3285 3510 3285 3780 2700 3780 2700 3510 -4 1 0 99 0 0 14 0.0000 4 150 435 2989 3716 color\001 +6 4770 1530 5760 1890 +1 2 0 1 0 30 100 0 20 0.000 1 0.0000 5287 1732 473 158 4814 1732 5760 1732 +4 1 0 99 0 0 14 0.0000 4 135 735 5310 1800 constant\001 -6 -6 3375 3645 3735 3735 -1 4 0 1 0 0 100 0 20 0.000 1 0.0000 3442 3690 23 23 3419 3690 3465 3690 -1 4 0 1 0 0 100 0 20 0.000 1 0.0000 3578 3690 23 23 3555 3690 3601 3690 -1 4 0 1 0 0 100 0 20 0.000 1 0.0000 3712 3690 23 23 3689 3690 3735 3690 +6 4770 1080 5760 1440 +1 2 0 1 0 30 100 0 20 0.000 1 0.0000 5287 1282 473 158 4814 1282 5760 1282 +4 1 0 99 0 0 14 0.0000 4 195 615 5310 1350 symbol\001 -6 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 @@ -144,19 +149,22 @@ Single 2430 2250 1935 2475 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 - 3599 937 4230 2610 + 3599 937 4005 2205 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 - 2610 2295 2160 2880 + 2610 2295 2160 2835 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 2835 2295 2970 2880 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 - 3510 945 3528 2300 + 3330 945 3780 2880 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 2655 3240 2295 3465 2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 1 1 1.00 60.00 120.00 - 2970 3240 2970 3465 + 2835 3240 2835 3465 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 0 1 2 + 1 1 1.00 60.00 120.00 + 3870 3240 3870 3465 diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 028f2647..5a7ad9df 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -360,9 +360,9 @@ polynomials): 3*y^2+x^2 @end example -You can differentiate functions and expand them as Taylor or -Laurent series (the third argument of series is the evaluation point, -the fourth defines the order): +You can differentiate functions and expand them as Taylor or Laurent +series (the third argument of @code{series} is the evaluation point, the +fourth defines the order): @example > diff(tan(x),x); @@ -371,6 +371,9 @@ tan(x)^2+1 x-1/6*x^3+Order(x^4) > series(1/tan(x),x,0,4); x^(-1)-1/3*x+Order(x^2) +> series(gamma(2*sin(x)-2),x,Pi/2,6); +-(x-1/2*Pi)^(-2)+(-1/12*Pi^2-1/2*EulerGamma^2-1/240)*(x-1/2*Pi)^2 +-EulerGamma-1/12+Order((x-1/2*Pi)^3) @end example If you ever wanted to convert units in C or C++ and found this @@ -675,8 +678,9 @@ implement its own arithmetic. To give an idea about what kinds of symbolic composits may be built we have a look at the most important classes in the class hierarchy. The -dashed line symbolizes a "points to" or "handles" relationship while the -solid lines stand for "inherits from" relationship in the class +oval classes are atomic ones and the squared classes are containers. +The dashed line symbolizes a "points to" or "handles" relationship while +the solid lines stand for "inherits from" relationship in the class hierarchy: @image{classhierarchy} @@ -912,9 +916,13 @@ following table. @item @code{.is_prime()} @tab object is a prime integer (probabilistic primality test) @item @code{.is_rational()} -@tab object is an exact rational number (integers are rational, too, as are complex extensions like @math{2/3+7/2*I}) +@tab object is an exact rational number (integers are rational, too) @item @code{.is_real()} @tab object is a real integer, rational or float (i.e. is not complex) +@item @code{.is_cinteger()} +@tab object is a (complex) integer, such as @math{2-3*I} +@item @code{.is_crational()} +@tab object is an exact (complex) rational number (such as @math{2/3+7/2*I}) @end multitable @end cartouche diff --git a/doc/tutorial/version.texi b/doc/tutorial/version.texi index 468f23de..027c1b4a 100644 --- a/doc/tutorial/version.texi +++ b/doc/tutorial/version.texi @@ -1,3 +1,3 @@ -@set UPDATED 30 November 1999 -@set EDITION 0.4.0 -@set VERSION 0.4.0 +@set UPDATED 10 December 1999 +@set EDITION 0.4.1 +@set VERSION 0.4.1 diff --git a/ginac/add.cpp b/ginac/add.cpp index 553b8272..c3f56191 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -218,170 +218,6 @@ ex add::coeff(symbol const & s, int const n) const return (new add(coeffseq))->setflag(status_flags::dynallocated); } -/* -ex add::eval(int level) const -{ - // simplifications: +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric()) - // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize) - // +(...,x,0) -> +(...,x) - // +(x) -> x - // +() -> 0 - - debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION); - - epvector newseq=seq; - epvector::iterator it1,it2; - - // +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric()) - it2=newseq.end()-1; - it1=it2-1; - while ((newseq.size()>=2)&&is_exactly_of_type(*(*it1).rest.bp,numeric)&& - is_exactly_of_type(*(*it2).rest.bp,numeric)) { - *it1=expair(ex_to_numeric((*it1).rest).mul(ex_to_numeric((*it1).coeff)) - .add(ex_to_numeric((*it2).rest).mul(ex_to_numeric((*it2).coeff))),exONE()); - newseq.pop_back(); - it2=newseq.end()-1; - it1=it2-1; - } - - if ((newseq.size()>=1)&&is_exactly_of_type(*(*it2).rest.bp,numeric)) { - // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize) - *it2=expair(ex_to_numeric((*it2).rest).mul(ex_to_numeric((*it2).coeff)),exONE()); - // +(...,x,0) -> +(...,x) - if (ex_to_numeric((*it2).rest).compare(0)==0) { - newseq.pop_back(); - } - } - - if (newseq.size()==0) { - // +() -> 0 - return exZERO(); - } else if (newseq.size()==1) { - // +(x) -> x - return recombine_pair_to_ex(*(newseq.begin())); - } - - return (new add(newseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); -} -*/ - -/* -ex add::eval(int level) const -{ - // simplifications: +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric()) - // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize) - // +(...,x,0) -> +(...,x) - // +(x) -> x - // +() -> 0 - - debugmsg("add eval",LOGLEVEL_MEMBER_FUNCTION); - - if ((level==1)&&(flags & status_flags::evaluated)) { -#ifdef DO_GINAC_ASSERT - for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) { - GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,add)); - GINAC_ASSERT(!(is_ex_exactly_of_type((*cit).rest,numeric)&& - (ex_to_numeric((*cit).coeff).compare(numONE())!=0))); - } -#endif // def DO_GINAC_ASSERT - return *this; - } - - epvector newseq; - epvector::iterator it1,it2; - bool seq_copied=false; - - epvector * evaled_seqp=evalchildren(level); - if (evaled_seqp!=0) { - // do more evaluation later - return (new add(evaled_seqp))->setflag(status_flags::dynallocated); - } - -#ifdef DO_GINAC_ASSERT - for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) { - GINAC_ASSERT(!is_ex_exactly_of_type((*cit).rest,add)); - GINAC_ASSERT(!(is_ex_exactly_of_type((*cit).rest,numeric)&& - (ex_to_numeric((*cit).coeff).compare(numONE())!=0))); - } -#endif // def DO_GINAC_ASSERT - - if (flags & status_flags::evaluated) { - return *this; - } - - expair const & last_expair=*(seq.end()-1); - expair const & next_to_last_expair=*(seq.end()-2); - int seq_size = seq.size(); - - // +(...,x,c1,c2) -> +(...,x,c1+c2) (c1, c2 numeric()) - if ((!seq_copied)&&(seq_size>=2)&& - is_ex_exactly_of_type(last_expair.rest,numeric)&& - is_ex_exactly_of_type(next_to_last_expair.rest,numeric)) { - newseq=seq; - seq_copied=true; - it2=newseq.end()-1; - it1=it2-1; - } - while (seq_copied&&(newseq.size()>=2)&& - is_ex_exactly_of_type((*it1).rest,numeric)&& - is_ex_exactly_of_type((*it2).rest,numeric)) { - *it1=expair(ex_to_numeric((*it1).rest).mul(ex_to_numeric((*it1).coeff)) - .add_dyn(ex_to_numeric((*it2).rest).mul(ex_to_numeric((*it2).coeff))),exONE()); - newseq.pop_back(); - it2=newseq.end()-1; - it1=it2-1; - } - - // +(...,(c1,c2)) -> (...,(c1*c2,1)) (normalize) - if ((!seq_copied)&&(seq_size>=1)&& - (is_ex_exactly_of_type(last_expair.rest,numeric))&& - (ex_to_numeric(last_expair.coeff).compare(numONE())!=0)) { - newseq=seq; - seq_copied=true; - it2=newseq.end()-1; - } - if (seq_copied&&(newseq.size()>=1)&& - (is_ex_exactly_of_type((*it2).rest,numeric))&& - (ex_to_numeric((*it2).coeff).compare(numONE())!=0)) { - *it2=expair(ex_to_numeric((*it2).rest).mul_dyn(ex_to_numeric((*it2).coeff)),exONE()); - } - - // +(...,x,0) -> +(...,x) - if ((!seq_copied)&&(seq_size>=1)&& - (is_ex_exactly_of_type(last_expair.rest,numeric))&& - (ex_to_numeric(last_expair.rest).is_zero())) { - newseq=seq; - seq_copied=true; - it2=newseq.end()-1; - } - if (seq_copied&&(newseq.size()>=1)&& - (is_ex_exactly_of_type((*it2).rest,numeric))&& - (ex_to_numeric((*it2).rest).is_zero())) { - newseq.pop_back(); - } - - // +() -> 0 - if ((!seq_copied)&&(seq_size==0)) { - return exZERO(); - } else if (seq_copied&&(newseq.size()==0)) { - return exZERO(); - } - - // +(x) -> x - if ((!seq_copied)&&(seq_size==1)) { - return recombine_pair_to_ex(*(seq.begin())); - } else if (seq_copied&&(newseq.size()==1)) { - return recombine_pair_to_ex(*(newseq.begin())); - } - - if (!seq_copied) return this->hold(); - - return (new add(newseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); -} -*/ - ex add::eval(int level) const { // simplifications: +(;c) -> c @@ -480,37 +316,6 @@ ex add::thisexpairseq(epvector * vp, ex const & oc) const return (new add(vp,oc))->setflag(status_flags::dynallocated); } -/* -expair add::split_ex_to_pair(ex const & e) const -{ - if (is_ex_exactly_of_type(e,mul)) { - mul const & mulref=ex_to_mul(e); - GINAC_ASSERT(mulref.seq.size()>1); - ex const & lastfactor_rest=(*(mulref.seq.end()-1)).rest; - ex const & lastfactor_coeff=(*(mulref.seq.end()-1)).coeff; - if (is_ex_exactly_of_type(lastfactor_rest,numeric) && - ex_to_numeric(lastfactor_coeff).is_equal(numONE())) { - epvector s=mulref.seq; - //s.pop_back(); - //return expair((new mul(s,1))->setflag(status_flags::dynallocated), - // lastfactor); - mul * mulp=static_cast(mulref.duplicate()); -#ifdef EXPAIRSEQ_USE_HASHTAB - mulp->remove_hashtab_entry(mulp->seq.end()-1); -#endif // def EXPAIRSEQ_USE_HASHTAB - mulp->seq.pop_back(); -#ifdef EXPAIRSEQ_USE_HASHTAB - mulp->shrink_hashtab(); -#endif // def EXPAIRSEQ_USE_HASHTAB - mulp->clearflag(status_flags::evaluated); - mulp->clearflag(status_flags::hash_calculated); - return expair(mulp->setflag(status_flags::dynallocated),lastfactor_rest); - } - } - return expair(e,exONE()); -} -*/ - expair add::split_ex_to_pair(ex const & e) const { if (is_ex_exactly_of_type(e,mul)) { @@ -526,45 +331,6 @@ expair add::split_ex_to_pair(ex const & e) const return expair(e,exONE()); } -/* -expair add::combine_ex_with_coeff_to_pair(ex const & e, - ex const & c) const -{ - GINAC_ASSERT(is_ex_exactly_of_type(c,numeric)); - if (is_ex_exactly_of_type(e,mul)) { - mul const & mulref=ex_to_mul(e); - GINAC_ASSERT(mulref.seq.size()>1); - ex const & lastfactor_rest=(*(mulref.seq.end()-1)).rest; - ex const & lastfactor_coeff=(*(mulref.seq.end()-1)).coeff; - if (is_ex_exactly_of_type(lastfactor_rest,numeric) && - ex_to_numeric(lastfactor_coeff).is_equal(numONE())) { - //epvector s=mulref.seq; - //s.pop_back(); - //return expair((new mul(s,1))->setflag(status_flags::dynallocated), - // ex_to_numeric(lastfactor).mul_dyn(ex_to_numeric(c))); - mul * mulp=static_cast(mulref.duplicate()); -#ifdef EXPAIRSEQ_USE_HASHTAB - mulp->remove_hashtab_entry(mulp->seq.end()-1); -#endif // def EXPAIRSEQ_USE_HASHTAB - mulp->seq.pop_back(); -#ifdef EXPAIRSEQ_USE_HASHTAB - mulp->shrink_hashtab(); -#endif // def EXPAIRSEQ_USE_HASHTAB - mulp->clearflag(status_flags::evaluated); - mulp->clearflag(status_flags::hash_calculated); - if (are_ex_trivially_equal(c,exONE())) { - return expair(mulp->setflag(status_flags::dynallocated),lastfactor_rest); - } else if (are_ex_trivially_equal(lastfactor_rest,exONE())) { - return expair(mulp->setflag(status_flags::dynallocated),c); - } - return expair(mulp->setflag(status_flags::dynallocated), - ex_to_numeric(lastfactor_rest).mul_dyn(ex_to_numeric(c))); - } - } - return expair(e,c); -} -*/ - expair add::combine_ex_with_coeff_to_pair(ex const & e, ex const & c) const { diff --git a/ginac/basic.cpp b/ginac/basic.cpp index 96fa259d..c2b4ce15 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -294,28 +294,9 @@ ex basic::subs(ex const & e) const return subs(ls,lr); } -// compare functions to sort expressions canonically -// all compare functions return: -1 for *this less than other, 0 equal, 1 greater - -/* -int basic::compare(basic const & other) const -{ - const type_info & typeid_this = typeid(*this); - const type_info & typeid_other = typeid(other); - - if (typeid_this==typeid_other) { - return compare_same_type(other); - } - - // special rule: sort numeric() to end - if (typeid_this==typeid_numeric) return 1; - if (typeid_other==typeid_numeric) return -1; - - // otherwise: sort according to type_info order (arbitrary, but well defined) - return typeid_this.before(typeid_other) ? -1 : 1; -} -*/ - +/** Compare objects to establish canonical order. + * All compare functions return: -1 for *this less than other, 0 equal, + * 1 greater. */ int basic::compare(basic const & other) const { unsigned hash_this = gethash(); diff --git a/ginac/constant.cpp b/ginac/constant.cpp index 12e9dde4..cc025153 100644 --- a/ginac/constant.cpp +++ b/ginac/constant.cpp @@ -38,6 +38,13 @@ namespace GiNaC { // public +constant::constant() : + basic(TINFO_constant), name(""), ef(0), + number(0), serial(next_serial++) +{ + debugmsg("constant default constructor",LOGLEVEL_CONSTRUCT); +} + constant::~constant() { debugmsg("constant destructor",LOGLEVEL_DESTRUCT); @@ -63,7 +70,7 @@ void constant::copy(constant const & other) } else { number = 0; } - fct_assigned=other.fct_assigned; + // fct_assigned=other.fct_assigned; } void constant::destroy(bool call_parent) @@ -81,14 +88,15 @@ void constant::destroy(bool call_parent) constant::constant(string const & initname, ex (*efun)()) : basic(TINFO_constant), name(initname), ef(efun), - number(0), fct_assigned(true), serial(next_serial++) + // number(0), fct_assigned(true), serial(next_serial++) + number(0), serial(next_serial++) { debugmsg("constant constructor from string, function",LOGLEVEL_CONSTRUCT); } constant::constant(string const & initname, numeric const & initnumber) : basic(TINFO_constant), name(initname), ef(0), - number(new numeric(initnumber)), fct_assigned(false), serial(next_serial++) + number(new numeric(initnumber)), /* fct_assigned(false),*/ serial(next_serial++) { debugmsg("constant constructor from string, numeric",LOGLEVEL_CONSTRUCT); } @@ -107,7 +115,7 @@ basic * constant::duplicate() const ex constant::evalf(int level) const { - if (fct_assigned) { + if (ef!=0) { return ef(); } else if (number != 0) { return *number; @@ -156,7 +164,7 @@ unsigned constant::next_serial=0; // global constants ////////// -const constant some_constant("",0); +const constant some_constant; type_info const & typeid_constant=typeid(some_constant); /** Pi. (3.14159...) Diverts straight into CLN for evalf(). */ diff --git a/ginac/constant.h b/ginac/constant.h index 04fdc50a..4d95d570 100644 --- a/ginac/constant.h +++ b/ginac/constant.h @@ -41,6 +41,7 @@ class constant : public basic // default constructor, destructor, copy constructor assignment operator and helpers public: + constant(); ~constant(); constant(constant const & other); // constant const & operator=(constant const & other); /* it's pervert! */ @@ -77,7 +78,7 @@ private: string name; ex (*ef)(); numeric * number; - bool fct_assigned; + // bool fct_assigned; unsigned serial; //!< unique serial number for comparision static unsigned next_serial; }; diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 8a9c0952..ec882394 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -1540,75 +1540,6 @@ epvector * expairseq::subschildren(lst const & ls, lst const & lr) const return 0; // nothing has changed } -/* -epvector expairseq::subschildren(lst const & ls, lst const & lr) const -{ - epvector s; - s.reserve(seq.size()); - - for (epvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) { - s.push_back(split_ex_to_pair((*it).rest.subs(ls,lr),(*it).coeff)); - } - return s; -} -*/ - -/* -void expairseq::sort(epviter first, epviter last, expair_is_less comp) -{ - if (first != last) { - introsort_loop(first, last, lg(last - first) * 2, comp); - __final_insertion_sort(first, last, comp); - } -} - -ptrdiff_t expairseq::lg(ptrdiff_t n) -{ - ptrdiff_t k; - for (k = 0; n > 1; n >>= 1) ++k; - return k; -} - -void expairseq::introsort_loop(epviter first, epviter last, - ptrdiff_t depth_limit, expair_is_less comp) -{ - while (last - first > stl_threshold) { - if (depth_limit == 0) { - partial_sort(first, last, last, comp); - return; - } - --depth_limit; - epviter cut = unguarded_partition(first, last, - expair(__median(*first, *(first + (last - first)/2), - *(last - 1), comp)), comp); - introsort_loop(cut, last, depth_limit, comp); - last = cut; - } -} - -epviter expairseq::unguarded_partition(epviter first, epviter last, - expair pivot, expair_is_less comp) -{ - while (1) { - while (comp(*first, pivot)) ++first; - --last; - while (comp(pivot, *last)) --last; - if (!(first < last)) return first; - iter_swap(first, last); - ++first; - } -} - -void expairseq::partial_sort(epviter first, epviter middle, epviter last, - expair_is_less comp) { - make_heap(first, middle, comp); - for (RandomAccessIterator i = middle; i < last; ++i) - if (comp(*i, *first)) - __pop_heap(first, middle, i, T(*i), comp, distance_type(first)); - sort_heap(first, middle, comp); -} -*/ - ////////// // static member variables ////////// diff --git a/ginac/function.pl b/ginac/function.pl index b55845a3..a55daa47 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -44,7 +44,7 @@ END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE $declare_function_macro_no_namespace=generate( <<'END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE','ex const & p${N}','p${N}'); #define DECLARE_FUNCTION_${N}P(NAME) \\ -extern unsigned function_index_##NAME; \\ +extern const unsigned function_index_##NAME; \\ inline function NAME(${SEQ1}) { \\ return function(function_index_##NAME, ${SEQ2}); \\ } diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 9155b1a9..aea28d63 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -246,227 +246,6 @@ ex mul::coeff(symbol const & s, int const n) const return exZERO(); } -/* -ex mul::eval(int level) const -{ - // simplifications: *(...,x,(c1,1),(c2,1)) -> *(...,x,(c1*c2,1)) (c1, c2 numeric(), move pairs to end first) - // *(...,x,1) -> *(...,x) - // *(...,x,0) -> 0 - // *(+(x,y,...),(c,1)) -> *(+(*(x,c),*(y,c),...)) (c numeric()) - // *(x) -> x - // *() -> 1 - - debugmsg("mul eval",LOGLEVEL_MEMBER_FUNCTION); - - if ((level==1)&&(flags & status_flags::evaluated)) { -#ifdef DO_GINAC_ASSERT - for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) { - GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul))|| - (!(ex_to_numeric((*cit).coeff).is_integer()))); - } - - // test if all numerics were moved to the end and - // all numerics with coeff 1 to the very end - if (seq.size()!=0) { - epvector::const_iterator cit=seq.end(); - bool all_coeff_1=true; - bool all_numeric=true; - do { - cit--; - if (is_ex_exactly_of_type((*cit).rest,numeric)) { - GINAC_ASSERT(all_numeric); - if ((*cit).coeff.is_equal(exONE())) { - GINAC_ASSERT(all_coeff_1); - } else { - all_coeff_1=false; - } - } else { - all_numeric=false; - } - } while (cit!=seq.begin()); - } -#endif // def DO_GINAC_ASSERT - return *this; - } - - epvector newseq; - epvector::iterator it1,it2; - bool seq_copied=false; - - epvector * evaled_seqp=evalchildren(level); - if (evaled_seqp!=0) { - // do more evaluation later - return (new mul(evaled_seqp))->setflag(status_flags::dynallocated); - } - - // combine pairs with coeff 1 (all numerics should be at end, assert below) - if (seq.size()>1) { - // count number of pairs with coeff 1 - unsigned num_coeff_1=0; - bool still_numeric=true; - epvector::const_iterator cit=seq.end(); - unsigned first_pos; - unsigned second_pos; - do { - cit--; - if (is_ex_exactly_of_type((*cit).rest,numeric)) { - if ((*cit).coeff.is_equal(exONE())) { - num_coeff_1++; - } - } else { - still_numeric=false; - } - } while ((cit!=seq.begin())&&still_numeric); - if (num_coeff_1>1) { - newseq=seq; - - } - - -#ifdef DO_GINAC_ASSERT - for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) { - GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul))|| - (!(ex_to_numeric((*cit).coeff).is_integer()))); - } - - // test if all numerics were moved to the end and - // all numerics with coeff 1 to the very end - if (seq.size()!=0) { - epvector::const_iterator cit=seq.end(); - bool all_coeff_1=true; - bool all_numeric=true; - do { - cit--; - if (is_ex_exactly_of_type((*cit).rest,numeric)) { - GINAC_ASSERT(all_numeric); - if ((*cit).coeff.is_equal(exONE())) { - GINAC_ASSERT(all_coeff_1); - } else { - all_coeff_1=false; - } - } else { - all_numeric=false; - } - } while (cit!=seq.begin()); - } -#endif // def DO_GINAC_ASSERT - - if (flags & status_flags::evaluated) { - return *this; - } - - expair const & last_expair=*(seq.end()-1); - expair const & next_to_last_expair=*(seq.end()-2); - int seq_size = seq.size(); - - // *(...,x,(c1,1),(c2,1)) -> *(...,x,(c1*c2,1)) (c1, c2 numeric()) - if ((!seq_copied) && (seq_size>=2) && - is_ex_exactly_of_type(last_expair.rest,numeric) && - ex_to_numeric(last_expair.coeff).is_equal(numONE()) && - is_ex_exactly_of_type(next_to_last_expair.rest,numeric) && - ex_to_numeric(next_to_last_expair.coeff).is_equal(numONE()) ) { - newseq=seq; - seq_copied=true; - it2=newseq.end()-1; - it1=it2-1; - } - while (seq_copied && (newseq.size()>=2) && - is_ex_exactly_of_type((*it1).rest,numeric) && - ex_to_numeric((*it1).coeff).is_equal(numONE()) && - is_ex_exactly_of_type((*it2).rest,numeric) && - ex_to_numeric((*it2).coeff).is_equal(numONE()) ) { - *it1=expair(ex_to_numeric((*it1).rest).mul_dyn(ex_to_numeric((*it2).rest)),exONE()); - newseq.pop_back(); - it2=newseq.end()-1; - it1=it2-1; - } - - // *(...,x,1) -> *(...,x) - if ((!seq_copied) && (seq_size>=1) && - (is_ex_exactly_of_type(last_expair.rest,numeric)) && - (ex_to_numeric(last_expair.rest).compare(numONE())==0)) { - newseq=seq; - seq_copied=true; - it2=newseq.end()-1; - } - if (seq_copied && (newseq.size()>=1) && - (is_ex_exactly_of_type((*it2).rest,numeric)) && - (ex_to_numeric((*it2).rest).compare(numONE())==0)) { - newseq.pop_back(); - it2=newseq.end()-1; - } - - // *(...,x,0) -> 0 - if ((!seq_copied) && (seq_size>=1) && - (is_ex_exactly_of_type(last_expair.rest,numeric)) && - (ex_to_numeric(last_expair.rest).is_zero())) { - return exZERO(); - } - if (seq_copied && (newseq.size()>=1) && - (is_ex_exactly_of_type((*it2).rest,numeric)) && - (ex_to_numeric((*it2).rest).is_zero())) { - return exZERO(); - } - - // *(+(x,y,...),c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +()) - if ((!seq_copied) && (seq_size==2) && - is_ex_exactly_of_type(next_to_last_expair.rest,add) && - is_ex_exactly_of_type(last_expair.rest,numeric) && - ex_to_numeric(last_expair.coeff).is_equal(numONE()) && - (ex_to_numeric(next_to_last_expair.coeff).compare(numONE())==0)) { - add const & addref=ex_to_add(next_to_last_expair.rest); - epvector distrseq; - distrseq.reserve(addref.seq.size()); - for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) { - distrseq.push_back(addref.combine_pair_with_coeff_to_pair(*cit, - last_expair.rest)); - } - // special treatment for the last element if it is numeric (to - // avoid terms like (2/3)*(3/2)) is no longer necessary, this - // is handled in add::combine_pair_with_coeff_to_pair() - return (new add(distrseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); - } - if (seq_copied && (newseq.size()==2) && - is_ex_exactly_of_type(newseq[0].rest,add) && - is_ex_exactly_of_type(newseq[1].rest,numeric) && - ex_to_numeric(newseq[1].coeff).is_equal(numONE()) && - (ex_to_numeric(newseq[0].coeff).compare(numONE())==0)) { - add const & addref=ex_to_add(newseq[0].rest); - epvector distrseq; - distrseq.reserve(addref.seq.size()); - for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) { - distrseq.push_back(addref.combine_pair_with_coeff_to_pair(*cit, - newseq[1].rest)); - } - // special treatment for the last element if it is numeric (to - // avoid terms like (2/3)*(3/2)) is no longer necessary, this - // is handled in add::combine_pair_with_coeff_to_pair() - return (new add(distrseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); - } - - // *() -> 1 - if ((!seq_copied) && (seq_size==0)) { - return exONE(); - } else if (seq_copied && (newseq.size()==0)) { - return exONE(); - } - - // *(x) -> x - if ((!seq_copied) && (seq_size==1)) { - return recombine_pair_to_ex(*(seq.begin())); - } else if (seq_copied && (newseq.size()==1)) { - return recombine_pair_to_ex(*(newseq.begin())); - } - - if (!seq_copied) return this->hold(); - - return (new mul(newseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); -} -*/ - ex mul::eval(int level) const { // simplifications *(...,x;0) -> 0 @@ -536,79 +315,6 @@ ex mul::eval(int level) const return this->hold(); } -/* -ex mul::eval(int level) const -{ - // simplifications: *(...,x,c1,c2) -> *(...,x,c1*c2) (c1, c2 numeric()) - // *(...,(c1,c2)) -> (...,(c1^c2,1)) (normalize) - // *(...,x,1) -> +(...,x) - // *(...,x,0) -> 0 - // *(+(x,y,...),c) -> *(+(*(x,c),*(y,c),...)) (c numeric()) - // *(x) -> x - // *() -> 1 - - debugmsg("mul eval",LOGLEVEL_MEMBER_FUNCTION); - - epvector newseq=seq; - epvector::iterator it1,it2; - - // *(...,x,c1,c2) -> *(...,x,c1*c2) (c1, c2 numeric()) - it2=newseq.end()-1; - it1=it2-1; - while ((newseq.size()>=2)&&is_exactly_of_type(*(*it1).rest.bp,numeric)&& - is_exactly_of_type(*(*it2).rest.bp,numeric)) { - *it1=expair(ex_to_numeric((*it1).rest).power(ex_to_numeric((*it1).coeff)) - .mul(ex_to_numeric((*it2).rest).power(ex_to_numeric((*it2).coeff))),exONE()); - newseq.pop_back(); - it2=newseq.end()-1; - it1=it2-1; - } - - if ((newseq.size()>=1)&&is_exactly_of_type(*(*it2).rest.bp,numeric)) { - // *(...,(c1,c2)) -> (...,(c1^c2,1)) (normalize) - *it2=expair(ex_to_numeric((*it2).rest).power(ex_to_numeric((*it2).coeff)),exONE()); - // *(...,x,1) -> *(...,x) - if (static_cast(*(*it2).rest.bp).compare(numONE())==0) { - newseq.pop_back(); - it2=newseq.end()-1; - } - } - - // *(...,x,0) -> 0 - if ((newseq.size()>=1)&&is_exactly_of_type(*(*it2).rest.bp,numeric)) { - if (static_cast(*(*it2).rest.bp).is_zero()==0) { - return exZERO(); - } - } - - // *(+(x,y,...),c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +()) - if ((newseq.size()==2)&&is_ex_exactly_of_type(newseq[0].rest,add)&& - is_ex_exactly_of_type(newseq[1].rest,numeric)&& - (ex_to_numeric(newseq[0].coeff).compare(numONE())==0)) { - add const & addref=ex_to_add(newseq[0].rest); - numeric const & numref=ex_to_numeric(newseq[1].rest); - epvector distrseq; - distrseq.reserve(addref.seq.size()); - for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) { - distrseq.push_back(expair((*cit).rest,ex_to_numeric((*cit).coeff).mul(numref))); - } - return (new add(distrseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); - } - - if (newseq.size()==0) { - // *() -> 1 - return exONE(); - } else if (newseq.size()==1) { - // *(x) -> x - return recombine_pair_to_ex(*newseq.begin()); - } - - return (new mul(newseq,1))->setflag(status_flags::dynallocated | - status_flags::evaluated ); -} -*/ - exvector mul::get_indices(void) const { // return union of indices of factors @@ -895,66 +601,6 @@ ex mul::expand(unsigned options) const status_flags::expanded); } -/* -ex mul::expand(unsigned options) const -{ - exvector sub_expanded_seq; - intvector positions_of_adds; - intvector number_of_add_operands; - - sub_expanded_seq.resize(seq.size()); - positions_of_adds.resize(seq.size()); - number_of_add_operands.reserve(seq.size()); - - int number_of_adds=0; - int number_of_expanded_terms=1; - for (unsigned current_position=0; current_positionsetflag(status_flags::dynallocated | - status_flags::expanded)); - - // increment k[] - l=number_of_adds-1; - while ((l>=0)&&((++k[l])>=number_of_add_operands[l])) { - k[l]=0; - l--; - } - if (l<0) break; - } - - return (new add(distrseq))->setflag(status_flags::dynallocated | - status_flags::expanded); -} -*/ - ////////// // new virtual functions which can be overridden by derived classes ////////// diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index 4ab0c175..9f7cb6ec 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -594,7 +594,7 @@ bool numeric::is_negative(void) const /** True if object is a non-complex integer. */ bool numeric::is_integer(void) const { - return (bool)instanceof(*value, cl_I_ring); // -> CLN + return instanceof(*value, cl_I_ring); // -> CLN } /** True if object is an exact integer greater than zero. */ @@ -638,20 +638,13 @@ bool numeric::is_prime(void) const * (denominator may be unity). */ bool numeric::is_rational(void) const { - if (instanceof(*value, cl_RA_ring)) { - return true; - } else if (!is_real()) { // complex case, handle Q(i): - if ( instanceof(realpart(*value), cl_RA_ring) && - instanceof(imagpart(*value), cl_RA_ring) ) - return true; - } - return false; + return instanceof(*value, cl_RA_ring); } /** True if object is a real integer, rational or float (but not complex). */ bool numeric::is_real(void) const { - return (bool)instanceof(*value, cl_R_ring); // -> CLN + return instanceof(*value, cl_R_ring); // -> CLN } bool numeric::operator==(numeric const & other) const @@ -664,6 +657,34 @@ bool numeric::operator!=(numeric const & other) const return (*value != *other.value); // -> CLN } +/** True if object is element of the domain of integers extended by I, i.e. is + * of the form a+b*I, where a and b are integers. */ +bool numeric::is_cinteger(void) const +{ + if (instanceof(*value, cl_I_ring)) + return true; + else if (!is_real()) { // complex case, handle n+m*I + if (instanceof(realpart(*value), cl_I_ring) && + instanceof(imagpart(*value), cl_I_ring)) + return true; + } + return false; +} + +/** True if object is an exact rational number, may even be complex + * (denominator may be unity). */ +bool numeric::is_crational(void) const +{ + if (instanceof(*value, cl_RA_ring)) + return true; + else if (!is_real()) { // complex case, handle Q(i): + if (instanceof(realpart(*value), cl_RA_ring) && + instanceof(imagpart(*value), cl_RA_ring)) + return true; + } + return false; +} + /** Numerical comparison: less. * * @exception invalid_argument (complex inequality) */ diff --git a/ginac/numeric.h b/ginac/numeric.h index b7acbcea..168651d4 100644 --- a/ginac/numeric.h +++ b/ginac/numeric.h @@ -187,6 +187,8 @@ public: bool is_prime(void) const; bool is_rational(void) const; bool is_real(void) const; + bool is_cinteger(void) const; + bool is_crational(void) const; bool operator==(numeric const & other) const; bool operator!=(numeric const & other) const; bool operator<(numeric const & other) const;