#include "ncmul.h"
#include "numeric.h"
#include "power.h"
+#include "debugmsg.h"
+#include "utils.h"
+
+#ifndef NO_GINAC_NAMESPACE
+namespace GiNaC {
+#endif // ndef NO_GINAC_NAMESPACE
//////////
// default constructor, destructor, copy constructor assignment operator and helpers
#ifndef INLINE_EX_CONSTRUCTORS
-ex::ex() : bp(exZERO().bp)
+ex::ex() : bp(ex0().bp)
{
debugmsg("ex default constructor",LOGLEVEL_CONSTRUCT);
- ASSERT(exZERO().bp!=0);
- ASSERT(exZERO().bp->flags & status_flags::dynallocated);
- ASSERT(bp!=0);
+ GINAC_ASSERT(ex0().bp!=0);
+ GINAC_ASSERT(ex0().bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
++bp->refcount;
}
ex::~ex()
{
debugmsg("ex destructor",LOGLEVEL_DESTRUCT);
- ASSERT(bp!=0);
- ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
if (--bp->refcount == 0) {
delete bp;
}
ex::ex(ex const & other) : bp(other.bp)
{
debugmsg("ex copy constructor",LOGLEVEL_CONSTRUCT);
- ASSERT(bp!=0);
- ASSERT((bp->flags) & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT((bp->flags) & status_flags::dynallocated);
++bp->refcount;
}
ex const & ex::operator=(ex const & other)
{
debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);
- ASSERT(bp!=0);
- ASSERT(bp->flags & status_flags::dynallocated);
- ASSERT(other.bp!=0);
- ASSERT(other.bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(other.bp!=0);
+ GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
++other.bp->refcount;
basic * tmpbp=other.bp;
if (--bp->refcount==0) {
// public
+/** Swap the contents of two expressions. */
void ex::swap(ex & other)
{
debugmsg("ex swap",LOGLEVEL_MEMBER_FUNCTION);
- ASSERT(bp!=0);
- ASSERT(bp->flags & status_flags::dynallocated);
- ASSERT(other.bp!=0);
- ASSERT(other.bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(other.bp!=0);
+ GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
basic * tmpbp=bp;
bp=other.bp;
other.bp=tmpbp;
}
+/** Output formatted to be useful as ginsh input. */
+void ex::print(ostream & os, unsigned upper_precedence) const
+{
+ debugmsg("ex print",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ bp->print(os,upper_precedence);
+}
+
+void ex::printraw(ostream & os) const
+{
+ debugmsg("ex printraw",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ os << "ex(";
+ bp->printraw(os);
+ os << ")";
+}
+
+void ex::printtree(ostream & os, unsigned indent) const
+{
+ debugmsg("ex printtree",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ // os << "refcount=" << bp->refcount << " ";
+ bp->printtree(os,indent);
+}
+
+/** Print expression as a C++ statement. The output looks like
+ * "<type> <var_name> = <expression>;". The "type" parameter has an effect
+ * on how number literals are printed.
+ *
+ * @param os output stream
+ * @param type variable type (one of the csrc_types)
+ * @param var_name variable name to be printed */
+void ex::printcsrc(ostream & os, unsigned type, const char *var_name) const
+{
+ debugmsg("ex print csrc", LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ switch (type) {
+ case csrc_types::ctype_float:
+ os << "float ";
+ break;
+ case csrc_types::ctype_double:
+ os << "double ";
+ break;
+ case csrc_types::ctype_cl_N:
+ os << "cl_N ";
+ break;
+ }
+ os << var_name << " = ";
+ bp->printcsrc(os, type, 0);
+ os << ";\n";
+}
+
+/** Little wrapper arount print to be called within a debugger. */
+void ex::dbgprint(void) const
+{
+ debugmsg("ex dbgprint",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ bp->dbgprint();
+}
+
+/** Little wrapper arount printtree to be called within a debugger. */
+void ex::dbgprinttree(void) const
+{
+ debugmsg("ex dbgprinttree",LOGLEVEL_PRINT);
+ GINAC_ASSERT(bp!=0);
+ bp->dbgprinttree();
+}
+
bool ex::info(unsigned inf) const
{
if (inf == info_flags::normal_form) {
int ex::nops() const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->nops();
}
ex ex::expand(unsigned options) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->expand(options);
}
bool ex::has(ex const & other) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->has(other);
}
int ex::degree(symbol const & s) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->degree(s);
}
int ex::ldegree(symbol const & s) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->ldegree(s);
}
ex ex::coeff(symbol const & s, int const n) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->coeff(s,n);
}
// something^(-int)
if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
- return exONE();
+ return _ex1();
// something^(int) * something^(int) * ...
if (!is_ex_exactly_of_type(n, mul))
return n;
- ex res = exONE();
+ ex res = _ex1();
for (int 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);
// polynomial
if (n.info(info_flags::polynomial))
- return exONE();
+ return _ex1();
// something^(-int)
if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
// something^(int) * something^(int) * ...
if (!is_ex_exactly_of_type(n, mul))
- return exONE();
- ex res = exONE();
+ return _ex1();
+ ex res = _ex1();
for (int 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);
ex ex::collect(symbol const & s) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->collect(s);
}
ex ex::eval(int level) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->eval(level);
}
ex ex::evalf(int level) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->evalf(level);
}
ex ex::subs(lst const & ls, lst const & lr) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->subs(ls,lr);
}
ex ex::subs(ex const & e) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->subs(e);
}
exvector ex::get_indices(void) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->get_indices();
}
ex ex::simplify_ncmul(exvector const & v) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->simplify_ncmul(v);
}
ex ex::operator[](ex const & index) const
{
debugmsg("ex operator[ex]",LOGLEVEL_OPERATOR);
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return (*bp)[index];
}
ex ex::operator[](int const i) const
{
debugmsg("ex operator[int]",LOGLEVEL_OPERATOR);
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return (*bp)[i];
}
ex ex::op(int const i) const
{
debugmsg("ex op()",LOGLEVEL_MEMBER_FUNCTION);
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->op(i);
}
{
debugmsg("ex let_op()",LOGLEVEL_MEMBER_FUNCTION);
makewriteable();
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->let_op(i);
}
#ifndef INLINE_EX_CONSTRUCTORS
int ex::compare(ex const & other) const
{
- ASSERT(bp!=0);
- ASSERT(other.bp!=0);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(other.bp!=0);
if (bp==other.bp) {
// special case: both expression point to same basic, trivially equal
return 0;
#ifndef INLINE_EX_CONSTRUCTORS
bool ex::is_equal(ex const & other) const
{
- ASSERT(bp!=0);
- ASSERT(other.bp!=0);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(other.bp!=0);
if (bp==other.bp) {
// special case: both expression point to same basic, trivially equal
return true;
unsigned ex::return_type(void) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->return_type();
}
unsigned ex::return_type_tinfo(void) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->return_type_tinfo();
}
unsigned ex::gethash(void) const
{
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
return bp->gethash();
}
void ex::makewriteable()
{
debugmsg("ex makewriteable",LOGLEVEL_MEMBER_FUNCTION);
- ASSERT(bp!=0);
- ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
if (bp->refcount > 1) {
basic * bp2=bp->duplicate();
++bp2->refcount;
--bp->refcount;
bp=bp2;
}
- ASSERT(bp->refcount == 1);
+ GINAC_ASSERT(bp->refcount == 1);
}
void ex::construct_from_basic(basic const & other)
{
- if ( (other.flags & status_flags::evaluated)==0 ) {
+ if ((other.flags & status_flags::evaluated)==0) {
// cf. copy constructor
ex const & tmpex = other.eval(1); // evaluate only one (top) level
bp = tmpex.bp;
- ASSERT(bp!=0);
- ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
++bp->refcount;
if ((other.flags & status_flags::dynallocated)&&(other.refcount==0)) {
delete &const_cast<basic &>(other);
bp=other.duplicate();
bp->setflag(status_flags::dynallocated);
}
- ASSERT(bp!=0);
+ GINAC_ASSERT(bp!=0);
// bp->clearflag(status_flags::evaluated);
++bp->refcount;
}
- ASSERT(bp!=0);
- ASSERT(bp->flags & status_flags::dynallocated);
+ GINAC_ASSERT(bp!=0);
+ GINAC_ASSERT(bp->flags & status_flags::dynallocated);
}
//////////
// global functions
//////////
-ex const & exZERO(void)
-{
- static ex * eZERO=new ex(numZERO());
- return *eZERO;
-}
-
-ex const & exONE(void)
-{
- static ex * eONE=new ex(numONE());
- return *eONE;
-}
-
-ex const & exTWO(void)
-{
- static ex * eTWO=new ex(numTWO());
- return *eTWO;
-}
-
-ex const & exTHREE(void)
-{
- static ex * eTHREE=new ex(numTHREE());
- return *eTHREE;
-}
-
-ex const & exMINUSONE(void)
-{
- static ex * eMINUSONE=new ex(numMINUSONE());
- return *eMINUSONE;
-}
-
-ex const & exHALF(void)
-{
- static ex * eHALF=new ex(ex(1)/ex(2));
- return *eHALF;
-}
+// none
-ex const & exMINUSHALF(void)
-{
- static ex * eMINUSHALF=new ex(numeric(-1,2));
- return *eMINUSHALF;
-}
+#ifndef NO_GINAC_NAMESPACE
+} // namespace GiNaC
+#endif // ndef NO_GINAC_NAMESPACE