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 {
<< aux << endl;
}
- if (! result) {
+ if (!result) {
cout << " passed ";
clog << "(no output)" << endl;
} else {
result += matrix_invert3();
result += matrix_misc();
- if (! result) {
+ if (!result) {
cout << " passed ";
clog << "(no output)" << endl;
} else {
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;
}
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;
// 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;
* 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;
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;
}
// 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;
// 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;
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) {
}
}
}
- if ( !passed ) {
+ if (!passed) {
clog << "One or more square roots of squares of rationals did not return exact integers" << endl;
++result;
}
result += numeric_consist3();
result += numeric_consist4();
- if ( !result ) {
+ if (!result) {
cout << " passed ";
clog << "(no output)" << endl;
} else {
result += paranoia_check7();
result += paranoia_check8();
- if (! result) {
+ if (!result) {
cout << " passed ";
clog << "(no output)" << endl;
} else {
# 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
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
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
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
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);
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
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}
@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
-@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
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
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)) {
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
{
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();
// 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);
} else {
number = 0;
}
- fct_assigned=other.fct_assigned;
+ // fct_assigned=other.fct_assigned;
}
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);
}
ex constant::evalf(int level) const
{
- if (fct_assigned) {
+ if (ef!=0) {
return ef();
} else if (number != 0) {
return *number;
// 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(). */
// 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! */
string name;
ex (*ef)();
numeric * number;
- bool fct_assigned;
+ // bool fct_assigned;
unsigned serial; //!< unique serial number for comparision
static unsigned next_serial;
};
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
//////////
$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}); \\
}
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
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
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
//////////
/** 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. */
* (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
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) */
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;