]> www.ginac.de Git - ginac.git/blobdiff - ginac/normal.cpp
- Pearu Peterson's patch for class function giving them better support
[ginac.git] / ginac / normal.cpp
index 8ee00c8fc4cf7363cd63d1bbf953f4b62a51fc26..e9117c4d163ecb88a676c0f1dd47ec3282ceed16 100644 (file)
@@ -93,7 +93,7 @@ static struct _stat_print {
 static bool get_first_symbol(const ex &e, const symbol *&x)
 {
        if (is_ex_exactly_of_type(e, symbol)) {
-               x = static_cast<symbol *>(e.bp);
+               x = &ex_to<symbol>(e);
                return true;
        } else if (is_ex_exactly_of_type(e, add) || is_ex_exactly_of_type(e, mul)) {
                for (unsigned i=0; i<e.nops(); i++)
@@ -170,7 +170,7 @@ static void add_symbol(const symbol *s, sym_desc_vec &v)
 static void collect_symbols(const ex &e, sym_desc_vec &v)
 {
        if (is_ex_exactly_of_type(e, symbol)) {
-               add_symbol(static_cast<symbol *>(e.bp), v);
+               add_symbol(&ex_to<symbol>(e), v);
        } else if (is_ex_exactly_of_type(e, add) || is_ex_exactly_of_type(e, mul)) {
                for (unsigned i=0; i<e.nops(); i++)
                        collect_symbols(e.op(i), v);
@@ -207,7 +207,7 @@ static void get_symbol_stats(const ex &a, const ex &b, sym_desc_vec &v)
                it->ldeg_b = b.ldegree(*(it->sym));
                ++it;
        }
-       sort(v.begin(), v.end());
+       std::sort(v.begin(), v.end());
 #if 0
        std::clog << "Symbols:\n";
        it = v.begin(); itend = v.end();
@@ -322,12 +322,12 @@ numeric add::integer_content(void) const
        epvector::const_iterator itend = seq.end();
        numeric c = _num0();
        while (it != itend) {
-               GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
-               GINAC_ASSERT(is_ex_exactly_of_type(it->coeff,numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(it->rest));
+               GINAC_ASSERT(is_exactly_a<numeric>(it->coeff));
                c = gcd(ex_to<numeric>(it->coeff), c);
                it++;
        }
-       GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        c = gcd(ex_to<numeric>(overall_coeff),c);
        return c;
 }
@@ -338,11 +338,11 @@ numeric mul::integer_content(void) const
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
-               GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*it),numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(*it)));
                ++it;
        }
 #endif // def DO_GINAC_ASSERT
-       GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        return abs(ex_to<numeric>(overall_coeff));
 }
 
@@ -1228,11 +1228,11 @@ numeric add::max_coefficient(void) const
 {
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
-       GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        numeric cur_max = abs(ex_to<numeric>(overall_coeff));
        while (it != itend) {
                numeric a;
-               GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(it->rest));
                a = abs(ex_to<numeric>(it->coeff));
                if (a > cur_max)
                        cur_max = a;
@@ -1247,28 +1247,21 @@ numeric mul::max_coefficient(void) const
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
-               GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*it),numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(*it)));
                it++;
        }
 #endif // def DO_GINAC_ASSERT
-       GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        return abs(ex_to<numeric>(overall_coeff));
 }
 
 
-/** Apply symmetric modular homomorphism to a multivariate polynomial.
- *  This function is used internally by heur_gcd().
+/** Apply symmetric modular homomorphism to an expanded multivariate
+ *  polynomial.  This function is usually used internally by heur_gcd().
  *
- *  @param e  expanded multivariate polynomial
  *  @param xi  modulus
  *  @return mapped polynomial
  *  @see heur_gcd */
-ex ex::smod(const numeric &xi) const
-{
-       GINAC_ASSERT(bp!=0);
-       return bp->smod(xi);
-}
-
 ex basic::smod(const numeric &xi) const
 {
        return *this;
@@ -1286,13 +1279,13 @@ ex add::smod(const numeric &xi) const
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
-               GINAC_ASSERT(!is_ex_exactly_of_type(it->rest,numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(it->rest));
                numeric coeff = GiNaC::smod(ex_to<numeric>(it->coeff), xi);
                if (!coeff.is_zero())
                        newseq.push_back(expair(it->rest, coeff));
                it++;
        }
-       GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        numeric coeff = GiNaC::smod(ex_to<numeric>(overall_coeff), xi);
        return (new add(newseq,coeff))->setflag(status_flags::dynallocated);
 }
@@ -1303,12 +1296,12 @@ ex mul::smod(const numeric &xi) const
        epvector::const_iterator it = seq.begin();
        epvector::const_iterator itend = seq.end();
        while (it != itend) {
-               GINAC_ASSERT(!is_ex_exactly_of_type(recombine_pair_to_ex(*it),numeric));
+               GINAC_ASSERT(!is_exactly_a<numeric>(recombine_pair_to_ex(*it)));
                it++;
        }
 #endif // def DO_GINAC_ASSERT
        mul * mulcopyp = new mul(*this);
-       GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
+       GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
        mulcopyp->overall_coeff = GiNaC::smod(ex_to<numeric>(overall_coeff),xi);
        mulcopyp->clearflag(status_flags::evaluated);
        mulcopyp->clearflag(status_flags::hash_calculated);
@@ -1831,7 +1824,7 @@ ex sqrfree_parfrac(const ex & a, const symbol & x)
        // Factorize denominator and compute cofactors
        exvector yun = sqrfree_yun(denom, x);
 //clog << "yun factors: " << exprseq(yun) << endl;
-       int num_yun = yun.size();
+       unsigned num_yun = yun.size();
        exvector factor; factor.reserve(num_yun);
        exvector cofac; cofac.reserve(num_yun);
        for (unsigned i=0; i<num_yun; i++) {
@@ -1849,7 +1842,7 @@ ex sqrfree_parfrac(const ex & a, const symbol & x)
                        }
                }
        }
-       int num_factors = factor.size();
+       unsigned num_factors = factor.size();
 //clog << "factors  : " << exprseq(factor) << endl;
 //clog << "cofactors: " << exprseq(cofac) << endl;
 
@@ -1857,7 +1850,7 @@ ex sqrfree_parfrac(const ex & a, const symbol & x)
        int max_denom_deg = denom.degree(x);
        matrix sys(max_denom_deg + 1, num_factors);
        matrix rhs(max_denom_deg + 1, 1);
-       for (unsigned i=0; i<=max_denom_deg; i++) {
+       for (int i=0; i<=max_denom_deg; i++) {
                for (unsigned j=0; j<num_factors; j++)
                        sys(i, j) = cofac[j].coeff(x, i);
                rhs(i, 0) = red_numer.coeff(x, i);
@@ -1918,7 +1911,7 @@ static ex replace_with_symbol(const ex &e, lst &sym_lst, lst &repl_lst)
 /** Create a symbol for replacing the expression "e" (or return a previously
  *  assigned symbol). An expression of the form "symbol == expression" is added
  *  to repl_lst and the symbol is returned.
- *  @see ex::to_rational */
+ *  @see basic::to_rational */
 static ex replace_with_symbol(const ex &e, lst &repl_lst)
 {
        // Expression already in repl_lst? Then return the assigned symbol
@@ -2037,7 +2030,7 @@ static ex frac_cancel(const ex &n, const ex &d)
        // as defined by get_first_symbol() is made positive)
        const symbol *x;
        if (get_first_symbol(den, x)) {
-               GINAC_ASSERT(is_ex_exactly_of_type(den.unit(*x),numeric));
+               GINAC_ASSERT(is_exactly_a<numeric>(den.unit(*x)));
                if (ex_to<numeric>(den.unit(*x)).is_negative()) {
                        num *= _ex_1();
                        den *= _ex_1();
@@ -2066,12 +2059,12 @@ ex add::normal(lst &sym_lst, lst &repl_lst, int level) const
        dens.reserve(seq.size()+1);
        epvector::const_iterator it = seq.begin(), itend = seq.end();
        while (it != itend) {
-               ex n = recombine_pair_to_ex(*it).bp->normal(sym_lst, repl_lst, level-1);
+               ex n = ex_to<basic>(recombine_pair_to_ex(*it)).normal(sym_lst, repl_lst, level-1);
                nums.push_back(n.op(0));
                dens.push_back(n.op(1));
                it++;
        }
-       ex n = overall_coeff.bp->normal(sym_lst, repl_lst, level-1);
+       ex n = ex_to<numeric>(overall_coeff).normal(sym_lst, repl_lst, level-1);
        nums.push_back(n.op(0));
        dens.push_back(n.op(1));
        GINAC_ASSERT(nums.size() == dens.size());
@@ -2125,12 +2118,12 @@ ex mul::normal(lst &sym_lst, lst &repl_lst, int level) const
        ex n;
        epvector::const_iterator it = seq.begin(), itend = seq.end();
        while (it != itend) {
-               n = recombine_pair_to_ex(*it).bp->normal(sym_lst, repl_lst, level-1);
+               n = ex_to<basic>(recombine_pair_to_ex(*it)).normal(sym_lst, repl_lst, level-1);
                num.push_back(n.op(0));
                den.push_back(n.op(1));
                it++;
        }
-       n = overall_coeff.bp->normal(sym_lst, repl_lst, level-1);
+       n = ex_to<numeric>(overall_coeff).normal(sym_lst, repl_lst, level-1);
        num.push_back(n.op(0));
        den.push_back(n.op(1));
 
@@ -2152,8 +2145,8 @@ ex power::normal(lst &sym_lst, lst &repl_lst, int level) const
                throw(std::runtime_error("max recursion level reached"));
 
        // Normalize basis and exponent (exponent gets reassembled)
-       ex n_basis = basis.bp->normal(sym_lst, repl_lst, level-1);
-       ex n_exponent = exponent.bp->normal(sym_lst, repl_lst, level-1);
+       ex n_basis = ex_to<basic>(basis).normal(sym_lst, repl_lst, level-1);
+       ex n_exponent = ex_to<basic>(exponent).normal(sym_lst, repl_lst, level-1);
        n_exponent = n_exponent.op(0) / n_exponent.op(1);
 
        if (n_exponent.info(info_flags::integer)) {
@@ -2233,7 +2226,7 @@ ex ex::normal(int level) const
        lst sym_lst, repl_lst;
 
        ex e = bp->normal(sym_lst, repl_lst, level);
-       GINAC_ASSERT(is_ex_of_type(e, lst));
+       GINAC_ASSERT(is_a<lst>(e));
 
        // Re-insert replaced symbols
        if (sym_lst.nops() > 0)
@@ -2254,7 +2247,7 @@ ex ex::numer(void) const
        lst sym_lst, repl_lst;
 
        ex e = bp->normal(sym_lst, repl_lst, 0);
-       GINAC_ASSERT(is_ex_of_type(e, lst));
+       GINAC_ASSERT(is_a<lst>(e));
 
        // Re-insert replaced symbols
        if (sym_lst.nops() > 0)
@@ -2274,7 +2267,7 @@ ex ex::denom(void) const
        lst sym_lst, repl_lst;
 
        ex e = bp->normal(sym_lst, repl_lst, 0);
-       GINAC_ASSERT(is_ex_of_type(e, lst));
+       GINAC_ASSERT(is_a<lst>(e));
 
        // Re-insert replaced symbols
        if (sym_lst.nops() > 0)
@@ -2294,7 +2287,7 @@ ex ex::numer_denom(void) const
        lst sym_lst, repl_lst;
 
        ex e = bp->normal(sym_lst, repl_lst, 0);
-       GINAC_ASSERT(is_ex_of_type(e, lst));
+       GINAC_ASSERT(is_a<lst>(e));
 
        // Re-insert replaced symbols
        if (sym_lst.nops() > 0)
@@ -2304,9 +2297,20 @@ ex ex::numer_denom(void) const
 }
 
 
-/** Default implementation of ex::to_rational(). It replaces the object with a
- *  temporary symbol.
- *  @see ex::to_rational */
+/** Rationalization of non-rational functions.
+ *  This function converts a general expression to a rational polynomial
+ *  by replacing all non-rational subexpressions (like non-rational numbers,
+ *  non-integer powers or functions like sin(), cos() etc.) to temporary
+ *  symbols. This makes it possible to use functions like gcd() and divide()
+ *  on non-rational functions by applying to_rational() on the arguments,
+ *  calling the desired function and re-substituting the temporary symbols
+ *  in the result. To make the last step possible, all temporary symbols and
+ *  their associated expressions are collected in the list specified by the
+ *  repl_lst parameter in the form {symbol == expression}, ready to be passed
+ *  as an argument to ex::subs().
+ *
+ *  @param repl_lst collects a list of all temporary symbols and their replacements
+ *  @return rationalized expression */
 ex basic::to_rational(lst &repl_lst) const
 {
        return replace_with_symbol(*this, repl_lst);
@@ -2314,8 +2318,7 @@ ex basic::to_rational(lst &repl_lst) const
 
 
 /** Implementation of ex::to_rational() for symbols. This returns the
- *  unmodified symbol.
- *  @see ex::to_rational */
+ *  unmodified symbol. */
 ex symbol::to_rational(lst &repl_lst) const
 {
        return *this;
@@ -2324,8 +2327,7 @@ ex symbol::to_rational(lst &repl_lst) const
 
 /** Implementation of ex::to_rational() for a numeric. It splits complex
  *  numbers into re+I*im and replaces I and non-rational real numbers with a
- *  temporary symbol.
- *  @see ex::to_rational */
+ *  temporary symbol. */
 ex numeric::to_rational(lst &repl_lst) const
 {
        if (is_real()) {
@@ -2343,8 +2345,7 @@ ex numeric::to_rational(lst &repl_lst) const
 
 
 /** Implementation of ex::to_rational() for powers. It replaces non-integer
- *  powers by temporary symbols.
- *  @see ex::to_rational */
+ *  powers by temporary symbols. */
 ex power::to_rational(lst &repl_lst) const
 {
        if (exponent.info(info_flags::integer))
@@ -2354,8 +2355,7 @@ ex power::to_rational(lst &repl_lst) const
 }
 
 
-/** Implementation of ex::to_rational() for expairseqs.
- *  @see ex::to_rational */
+/** Implementation of ex::to_rational() for expairseqs. */
 ex expairseq::to_rational(lst &repl_lst) const
 {
        epvector s;
@@ -2374,24 +2374,4 @@ ex expairseq::to_rational(lst &repl_lst) const
 }
 
 
-/** Rationalization of non-rational functions.
- *  This function converts a general expression to a rational polynomial
- *  by replacing all non-rational subexpressions (like non-rational numbers,
- *  non-integer powers or functions like sin(), cos() etc.) to temporary
- *  symbols. This makes it possible to use functions like gcd() and divide()
- *  on non-rational functions by applying to_rational() on the arguments,
- *  calling the desired function and re-substituting the temporary symbols
- *  in the result. To make the last step possible, all temporary symbols and
- *  their associated expressions are collected in the list specified by the
- *  repl_lst parameter in the form {symbol == expression}, ready to be passed
- *  as an argument to ex::subs().
- *
- *  @param repl_lst collects a list of all temporary symbols and their replacements
- *  @return rationalized expression */
-ex ex::to_rational(lst &repl_lst) const
-{
-       return bp->to_rational(repl_lst);
-}
-
-
 } // namespace GiNaC