return bp->coeff(s,n);
}
-ex ex::numer(bool normalize) const
-{
- ex n;
- if (normalize)
- n = normal();
- else
- n = *this;
-
- // number
- if (is_ex_exactly_of_type(n, numeric))
- return ex_to_numeric(n).numer();
-
- // polynomial
- if (n.info(info_flags::cinteger_polynomial))
- return n;
-
- // something^(-int)
- if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
- return _ex1();
-
- // something^(int) * something^(int) * ...
- if (!is_ex_exactly_of_type(n, mul))
- return n;
- ex res = _ex1();
- for (unsigned i=0; i<n.nops(); i++) {
- if (is_ex_exactly_of_type(n.op(i), power) && n.op(i).op(1).info(info_flags::negint)) {
- // something^(-int) belongs to the denominator
- } else if (is_ex_exactly_of_type(n.op(i), numeric)) {
- res *= ex_to_numeric(n.op(i)).numer();
- } else {
- res *= n.op(i);
- }
- }
- return res;
-}
-
-ex ex::denom(bool normalize) const
-{
- ex n;
- if (normalize)
- n = normal();
- else
- n = *this;
-
- // number
- if (is_ex_exactly_of_type(n, numeric))
- return ex_to_numeric(n).denom();
-
- // polynomial
- if (n.info(info_flags::cinteger_polynomial))
- return _ex1();
-
- // something^(-int)
- if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
- return power(n.op(0), -(n.op(1)));
-
- // something^(int) * something^(int) * ...
- if (!is_ex_exactly_of_type(n, mul))
- return _ex1();
- ex res = _ex1();
- for (unsigned i=0; i<n.nops(); i++) {
- if (is_ex_exactly_of_type(n.op(i), power) && n.op(i).op(1).info(info_flags::negint)) {
- res *= power(n.op(i), -1);
- } else if (is_ex_exactly_of_type(n.op(i), numeric)) {
- res *= ex_to_numeric(n.op(i)).denom();
- } else {
- // everything else belongs to the numerator
- }
- }
- return res;
-}
-
ex ex::collect(const symbol & s) const
{
GINAC_ASSERT(bp!=0);
ex coeff(const symbol & s, int n=1) const;
ex lcoeff(const symbol & s) const { return coeff(s, degree(s)); }
ex tcoeff(const symbol & s) const { return coeff(s, ldegree(s)); }
- ex numer(bool normalize = true) const;
- ex denom(bool normalize = true) const;
+ ex numer(void) const;
+ ex denom(void) const;
ex unit(const symbol &x) const;
ex content(const symbol &x) const;
numeric integer_content(void) const;
inline ex coeff(const ex & thisex, const symbol & s, int n=1)
{ return thisex.coeff(s, n); }
-inline ex numer(const ex & thisex, bool normalize = true)
-{ return thisex.numer(normalize); }
+inline ex numer(const ex & thisex)
+{ return thisex.numer(); }
-inline ex denom(const ex & thisex, bool normalize = true)
-{ return thisex.denom(normalize); }
+inline ex denom(const ex & thisex)
+{ return thisex.denom(); }
inline ex normal(const ex & thisex, int level=0)
{ return thisex.normal(level); }
* @see ex::normal */
ex power::normal(lst &sym_lst, lst &repl_lst, int level) const
{
- if (exponent.info(info_flags::posint)) {
- // Integer powers are distributed
- ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
- return (new lst(power(n.op(0), exponent), power(n.op(1), exponent)))->setflag(status_flags::dynallocated);
- } else if (exponent.info(info_flags::negint)) {
- // Integer powers are distributed
- ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
- return (new lst(power(n.op(1), -exponent), power(n.op(0), -exponent)))->setflag(status_flags::dynallocated);
- } else {
- // Non-integer powers are replaced by temporary symbol (after normalizing basis)
- ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
- return (new lst(replace_with_symbol(power(n.op(0) / n.op(1), exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
+ // Normalize basis
+ ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
+
+ if (exponent.info(info_flags::integer)) {
+
+ if (exponent.info(info_flags::positive)) {
+
+ // (a/b)^n -> {a^n, b^n}
+ return (new lst(power(n.op(0), exponent), power(n.op(1), exponent)))->setflag(status_flags::dynallocated);
+
+ } else if (exponent.info(info_flags::negint)) {
+
+ // (a/b)^-n -> {b^n, a^n}
+ return (new lst(power(n.op(1), -exponent), power(n.op(0), -exponent)))->setflag(status_flags::dynallocated);
+ }
+
+ } else {
+ if (exponent.info(info_flags::positive)) {
+
+ // (a/b)^z -> {sym((a/b)^z), 1}
+ return (new lst(replace_with_symbol(power(n.op(0) / n.op(1), exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
+
+ } else {
+
+ if (n.op(1).is_equal(_ex1())) {
+
+ // a^-x -> {1, sym(a^x)}
+ return (new lst(_ex1(), replace_with_symbol(power(n.op(0), -exponent), sym_lst, repl_lst)))->setflag(status_flags::dynallocated);
+
+ } else {
+
+ // (a/b)^-x -> {(b/a)^x, 1}
+ return (new lst(replace_with_symbol(power(n.op(1) / n.op(0), -exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
+ }
+ }
}
}
return e.op(0) / e.op(1);
}
+/** Numerator of an expression. If the expression is not of the normal form
+ * "numerator/denominator", it is first converted to this form and then the
+ * numerator is returned.
+ *
+ * @see ex::normal
+ * @return numerator */
+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));
+
+ // Re-insert replaced symbols
+ if (sym_lst.nops() > 0)
+ return e.op(0).subs(sym_lst, repl_lst);
+ else
+ return e.op(0);
+}
+
+/** Denominator of an expression. If the expression is not of the normal form
+ * "numerator/denominator", it is first converted to this form and then the
+ * denominator is returned.
+ *
+ * @see ex::normal
+ * @return denominator */
+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));
+
+ // Re-insert replaced symbols
+ if (sym_lst.nops() > 0)
+ return e.op(1).subs(sym_lst, repl_lst);
+ else
+ return e.op(1);
+}
+
#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
#endif // ndef NO_NAMESPACE_GINAC