]> www.ginac.de Git - ginac.git/blobdiff - ginac/basic.cpp
documentation update
[ginac.git] / ginac / basic.cpp
index 90b9c1452baa6828788f51764275e161db2fbcd3..92bd16053d8e921d35b3b26ee323545bd100e7ae 100644 (file)
@@ -134,7 +134,7 @@ void basic::print(const print_context & c, unsigned level) const
                c.s << "[" << class_name() << " object]";
 }
 
-/** Little wrapper arount print to be called within a debugger.
+/** Little wrapper around print to be called within a debugger.
  *  This is needed because you cannot call foo.print(cout) from within the
  *  debugger because it might not know what cout is.  This method can be
  *  invoked with no argument and it will simply print to stdout.
@@ -146,7 +146,7 @@ void basic::dbgprint(void) const
        std::cerr << std::endl;
 }
 
-/** Little wrapper arount printtree to be called within a debugger.
+/** Little wrapper around printtree to be called within a debugger.
  *
  *  @see basic::dbgprint
  *  @see basic::printtree */
@@ -221,16 +221,32 @@ bool basic::has(const ex & other) const
 {
        GINAC_ASSERT(other.bp!=0);
        lst repl_lst;
-       if (match(*other.bp, repl_lst)) return true;
-       if (nops()>0) {
-               for (unsigned i=0; i<nops(); i++)
-                       if (op(i).has(other))
-                               return true;
-       }
+       if (match(*other.bp, repl_lst))
+               return true;
+       for (unsigned i=0; i<nops(); i++)
+               if (op(i).has(other))
+                       return true;
        
        return false;
 }
 
+/** Construct new expression by applying the specified function to all
+ *  sub-expressions (one level only, not recursively). */
+ex basic::map(map_function & f) const
+{
+       unsigned num = nops();
+       if (num == 0)
+               return *this;
+
+       basic *copy = duplicate();
+       copy->setflag(status_flags::dynallocated);
+       copy->clearflag(status_flags::hash_calculated);
+       ex e(*copy);
+       for (unsigned i=0; i<num; i++)
+               e.let_op(i) = f(e.op(i));
+       return e.eval();
+}
+
 /** Return degree of highest power in object s. */
 int basic::degree(const ex & s) const
 {
@@ -249,7 +265,7 @@ ex basic::coeff(const ex & s, int n) const
        return n==0 ? *this : _ex0();
 }
 
-/** Sort expression in terms of powers of some object(s).
+/** Sort expanded expression in terms of powers of some object(s).
  *  @param s object(s) to sort in
  *  @param distributed recursive or distributed form (only used when s is a list) */
 ex basic::collect(const ex & s, bool distributed) const
@@ -347,6 +363,19 @@ ex basic::evalf(int level) const
        return *this;
 }
 
+/** Function object to be applied by basic::evalm(). */
+struct evalm_map_function : public map_function {
+       ex operator()(const ex & e) { return GiNaC::evalm(e); }
+} fcn;
+/** Evaluate sums, products and integer powers of matrices. */
+ex basic::evalm(void) const
+{
+       if (nops() == 0)
+               return *this;
+       else
+               return map(fcn);
+}
+
 /** Perform automatic symbolic evaluations on indexed expression that
  *  contains this object as the base expression. */
 ex basic::eval_indexed(const basic & i) const
@@ -407,7 +436,7 @@ bool basic::match(const ex & pattern, lst & repl_lst) const
 {
 /*
        Sweet sweet shapes, sweet sweet shapes,
-       Thats the key thing, right right.
+       That's the key thing, right right.
        Feed feed face, feed feed shapes,
        But who is the king tonight?
        Who is the king tonight?
@@ -707,6 +736,7 @@ void basic::ensure_if_modifiable(void) const
 {
        if (this->refcount>1)
                throw(std::runtime_error("cannot modify multiply referenced object"));
+       clearflag(status_flags::hash_calculated);
 }
 
 //////////