#include "ncmul.h"
#include "numeric.h"
#include "power.h"
+#include "relational.h"
#include "debugmsg.h"
#include "utils.h"
bool ex::info(unsigned inf) const
{
- if (inf == info_flags::normal_form) {
-
- // Polynomials are in normal form
- if (info(info_flags::polynomial))
- return true;
-
- // polynomial^(-int) is in normal form
- if (is_ex_exactly_of_type(*this, power))
- return op(1).info(info_flags::negint);
-
- // polynomial^(int) * polynomial^(int) * ... is in normal form
- if (!is_ex_exactly_of_type(*this, mul))
- return false;
- for (unsigned i=0; i<nops(); i++) {
- if (is_ex_exactly_of_type(op(i), power)) {
- if (!op(i).op(1).info(info_flags::integer))
- return false;
- if (!op(i).op(0).info(info_flags::polynomial))
- return false;
- } else
- if (!op(i).info(info_flags::polynomial))
- return false;
- }
- return true;
- } else {
- return bp->info(inf);
- }
+ return bp->info(inf);
}
unsigned ex::nops() const
return bp->coeff(s,n);
}
-ex ex::numer(bool normalize) const
-{
- ex n;
- if (normalize && !info(info_flags::normal_form))
- n = normal();
- else
- n = *this;
-
- // polynomial
- if (n.info(info_flags::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))
- res *= n.op(i);
- }
- return res;
-}
-
-ex ex::denom(bool normalize) const
-{
- ex n;
- if (normalize && !info(info_flags::normal_form))
- n = normal();
- else
- n = *this;
-
- // polynomial
- if (n.info(info_flags::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);
- }
- return res;
-}
-
ex ex::collect(const symbol & s) const
{
GINAC_ASSERT(bp!=0);
return bp->evalf(level);
}
+/** Compute partial derivative of an expression.
+ *
+ * @param s symbol by which the expression is derived
+ * @param nth order of derivative (default 1)
+ * @return partial derivative as a new expression */
+ex ex::diff(const symbol & s, unsigned nth) const
+{
+ GINAC_ASSERT(bp!=0);
+
+ if (!nth)
+ return *this;
+ else
+ return bp->diff(s, nth);
+}
+
ex ex::subs(const lst & ls, const lst & lr) const
{
GINAC_ASSERT(bp!=0);
return (*bp)[i];
}
+/** Return operand/member at position i. */
ex ex::op(int i) const
{
debugmsg("ex op()",LOGLEVEL_MEMBER_FUNCTION);
return bp->op(i);
}
+/** Return modifyable operand/member at position i. */
ex & ex::let_op(int i)
{
debugmsg("ex let_op()",LOGLEVEL_MEMBER_FUNCTION);
return bp->let_op(i);
}
+/** Left hand side of relational expression. */
+ex ex::lhs(void) const
+{
+ debugmsg("ex lhs()",LOGLEVEL_MEMBER_FUNCTION);
+ GINAC_ASSERT(is_ex_of_type(*this,relational));
+ return (*static_cast<relational *>(bp)).lhs();
+}
+
+/** Right hand side of relational expression. */
+ex ex::rhs(void) const
+{
+ debugmsg("ex rhs()",LOGLEVEL_MEMBER_FUNCTION);
+ GINAC_ASSERT(is_ex_of_type(*this,relational));
+ return (*static_cast<relational *>(bp)).rhs();
+}
+
#ifndef INLINE_EX_CONSTRUCTORS
int ex::compare(const ex & other) const
{