- changed behaviour of numeric::is_rational() and added numeric::is_cinteger()
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Fri, 10 Dec 1999 20:23:46 +0000 (20:23 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Fri, 10 Dec 1999 20:23:46 +0000 (20:23 +0000)
  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

19 files changed:
check/expand_subs.cpp
check/lsolve_onedim.cpp
check/matrix_checks.cpp
check/normalization.cpp
check/numeric_consist.cpp
check/paranoia_check.cpp
doc/reference/DoxyfileHTML
doc/tutorial/classhierarchy.fig
doc/tutorial/ginac.texi
doc/tutorial/version.texi
ginac/add.cpp
ginac/basic.cpp
ginac/constant.cpp
ginac/constant.h
ginac/expairseq.cpp
ginac/function.pl
ginac/mul.cpp
ginac/numeric.cpp
ginac/numeric.h

index 4d78708..109978f 100644 (file)
@@ -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 {
index be113c2..d1c19f7 100644 (file)
@@ -44,7 +44,7 @@ unsigned lsolve_onedim(void)
              << aux << endl;
     }
     
-    if (! result) {
+    if (!result) {
         cout << " passed ";
         clog << "(no output)" << endl;
     } else {
index 3da30af..7bce787 100644 (file)
@@ -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 {
index bf761ff..7ce1e5d 100644 (file)
@@ -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;
 }
index d6a3ffc..6008849 100644 (file)
@@ -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 {
index b42225c..3eb4185 100644 (file)
@@ -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 {
index d9260e2..c465b30 100644 (file)
@@ -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
index d093f8e..4df411c 100644 (file)
@@ -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
index 028f264..5a7ad9d 100644 (file)
@@ -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
 
index 468f23d..027c1b4 100644 (file)
@@ -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
index 553b827..c3f5619 100644 (file)
@@ -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<mul *>(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<mul *>(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
 {
index 96fa259..c2b4ce1 100644 (file)
@@ -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();
index 12e9dde..cc02515 100644 (file)
@@ -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(). */
index 04fdc50..4d95d57 100644 (file)
@@ -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;
 };
index 8a9c095..ec88239 100644 (file)
@@ -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
 //////////
index b55845a..a55daa4 100755 (executable)
@@ -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}); \\
 }
index 9155b1a..aea28d6 100644 (file)
@@ -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<numeric &>(*(*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<numeric &>(*(*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_position<seq.size(); current_position++) {
-        ex const & expanded_ex=recombine_pair_to_ex(seq[current_position]).expand(options);
-        if (is_ex_exactly_of_type(expanded_ex,add)) {
-            positions_of_adds[number_of_adds]=current_position;
-            add const & expanded_addref=ex_to_add(expanded_ex);
-            number_of_add_operands[number_of_adds]=expanded_addref.seq.size();
-            number_of_expanded_terms *= expanded_addref.seq.size();
-            number_of_adds++;
-        }
-        sub_expanded_seq.push_back(expanded_ex);
-    }
-
-    exvector distrseq;
-    distrseq.reserve(number_of_expanded_terms);
-
-    intvector k;
-    k.resize(number_of_adds);
-    
-    int l;
-    for (l=0; l<number_of_adds; l++) {
-        k[l]=0;
-    }
-
-    while (1) {
-        exvector term;
-        term=sub_expanded_seq;
-        for (l=0; l<number_of_adds; l++) {
-            add const & addref=ex_to_add(sub_expanded_seq[positions_of_adds[l]]);
-            term[positions_of_adds[l]]=addref.recombine_pair_to_ex(addref.seq[k[l]]);
-        }
-        distrseq.push_back((new mul(term))->setflag(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
 //////////
index 4ab0c17..9f7cb6e 100644 (file)
@@ -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) */ 
index b7acbce..168651d 100644 (file)
@@ -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;