]> www.ginac.de Git - ginac.git/blobdiff - ginac/normal.cpp
- archive file format is a little more compact (stores property name and type
[ginac.git] / ginac / normal.cpp
index f57e4f0dbb60b31c3fc7bb053b905881ffee24f2..28ea9e6c1ff0d18f573094f58d38e6da00fe80d1 100644 (file)
@@ -47,9 +47,9 @@
 #include "symbol.h"
 #include "utils.h"
 
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC
 
 // If comparing expressions (ex::compare()) is fast, you can set this to 1.
 // Some routines like quo(), rem() and gcd() will then return a quick answer
@@ -224,20 +224,25 @@ static numeric lcm_of_coefficients_denominators(const ex &e)
  *  @param e  multivariate polynomial (need not be expanded)
  *  @param lcm  LCM to multiply in */
 
-static ex multiply_lcm(const ex &e, const ex &lcm)
+static ex multiply_lcm(const ex &e, const numeric &lcm)
 {
        if (is_ex_exactly_of_type(e, mul)) {
                ex c = _ex1();
-               for (int i=0; i<e.nops(); i++)
-                       c *= multiply_lcm(e.op(i), lcmcoeff(e.op(i), _num1()));
+               numeric lcm_accum = _num1();
+               for (unsigned i=0; i<e.nops(); i++) {
+                       numeric op_lcm = lcmcoeff(e.op(i), _num1());
+                       c *= multiply_lcm(e.op(i), op_lcm);
+                       lcm_accum *= op_lcm;
+               }
+               c *= lcm / lcm_accum;
                return c;
        } else if (is_ex_exactly_of_type(e, add)) {
                ex c = _ex0();
-               for (int i=0; i<e.nops(); i++)
+               for (unsigned i=0; i<e.nops(); i++)
                        c += multiply_lcm(e.op(i), lcm);
                return c;
        } else if (is_ex_exactly_of_type(e, power)) {
-               return pow(multiply_lcm(e.op(0), pow(lcm, 1/e.op(1))), e.op(1));
+               return pow(multiply_lcm(e.op(0), lcm.power(ex_to_numeric(e.op(1)).inverse())), e.op(1));
        } else
                return e * lcm;
 }
@@ -939,11 +944,11 @@ ex basic::smod(const numeric &xi) const
 
 ex numeric::smod(const numeric &xi) const
 {
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
     return GiNaC::smod(*this, xi);
-#else // ndef NO_GINAC_NAMESPACE
+#else // ndef NO_NAMESPACE_GINAC
     return ::smod(*this, xi);
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC
 }
 
 ex add::smod(const numeric &xi) const
@@ -954,21 +959,21 @@ ex add::smod(const numeric &xi) const
     epvector::const_iterator itend = seq.end();
     while (it != itend) {
         GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
         numeric coeff = GiNaC::smod(ex_to_numeric(it->coeff), xi);
-#else // ndef NO_GINAC_NAMESPACE
+#else // ndef NO_NAMESPACE_GINAC
         numeric coeff = ::smod(ex_to_numeric(it->coeff), xi);
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC
         if (!coeff.is_zero())
             newseq.push_back(expair(it->rest, coeff));
         it++;
     }
     GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
     numeric coeff = GiNaC::smod(ex_to_numeric(overall_coeff), xi);
-#else // ndef NO_GINAC_NAMESPACE
+#else // ndef NO_NAMESPACE_GINAC
     numeric coeff = ::smod(ex_to_numeric(overall_coeff), xi);
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC
     return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
 }
 
@@ -984,11 +989,11 @@ ex mul::smod(const numeric &xi) const
 #endif // def DO_GINAC_ASSERT
     mul * mulcopyp=new mul(*this);
     GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
     mulcopyp->overall_coeff = GiNaC::smod(ex_to_numeric(overall_coeff),xi);
-#else // ndef NO_GINAC_NAMESPACE
+#else // ndef NO_NAMESPACE_GINAC
     mulcopyp->overall_coeff = ::smod(ex_to_numeric(overall_coeff),xi);
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC
     mulcopyp->clearflag(status_flags::evaluated);
     mulcopyp->clearflag(status_flags::hash_calculated);
     return mulcopyp->setflag(status_flags::dynallocated);
@@ -1104,7 +1109,7 @@ factored_a:
                ex g = _ex1();
                ex acc_ca = _ex1();
                ex part_b = b;
-               for (int i=0; i<a.nops(); i++) {
+               for (unsigned i=0; i<a.nops(); i++) {
                        ex part_ca, part_cb;
                        g *= gcd(a.op(i), part_b, &part_ca, &part_cb, check_args);
                        acc_ca *= part_ca;
@@ -1122,7 +1127,7 @@ factored_b:
                ex g = _ex1();
                ex acc_cb = _ex1();
                ex part_a = a;
-               for (int i=0; i<b.nops(); i++) {
+               for (unsigned i=0; i<b.nops(); i++) {
                        ex part_ca, part_cb;
                        g *= gcd(part_a, b.op(i), &part_ca, &part_cb, check_args);
                        acc_cb *= part_cb;
@@ -1395,7 +1400,7 @@ static ex frac_cancel(const ex &n, const ex &d)
 {
     ex num = n;
     ex den = d;
-    ex pre_factor = _ex1();
+    numeric pre_factor = _num1();
 
     // Handle special cases where numerator or denominator is 0
     if (num.is_zero())
@@ -1409,8 +1414,8 @@ static ex frac_cancel(const ex &n, const ex &d)
 
     // Bring numerator and denominator to Z[X] by multiplying with
     // LCM of all coefficients' denominators
-    ex num_lcm = lcm_of_coefficients_denominators(num);
-    ex den_lcm = lcm_of_coefficients_denominators(den);
+    numeric num_lcm = lcm_of_coefficients_denominators(num);
+    numeric den_lcm = lcm_of_coefficients_denominators(den);
        num = multiply_lcm(num, num_lcm);
        den = multiply_lcm(den, den_lcm);
     pre_factor = den_lcm / num_lcm;
@@ -1568,6 +1573,6 @@ ex ex::normal(int level) const
         return e;
 }
 
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC