]> www.ginac.de Git - ginac.git/blobdiff - ginac/basic.cpp
documentation update
[ginac.git] / ginac / basic.cpp
index c899d19f1659c2641d3b4048108bf5b90019c5f7..a2e10f715531d286c0d3fef0a0a13a4e5cc8d18a 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 */
@@ -213,24 +213,40 @@ ex basic::operator[](int i) const
        return op(i);
 }
 
-/** Search ocurrences.  An object  'has' an expression if it is the expression
+/** Search ocurrences.  An object 'has' an expression if it is the expression
  *  itself or one of the children 'has' it.  As a consequence (according to
  *  the definition of children) given e=x+y+z, e.has(x) is true but e.has(x+y)
- *  is false. */
+ *  is false.  The expression can also contain wildcards. */
 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_func 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,15 @@ ex basic::evalf(int level) const
        return *this;
 }
 
+/** Evaluate sums, products and integer powers of matrices. */
+ex basic::evalm(void) const
+{
+       if (nops() == 0)
+               return *this;
+       else
+               return map(GiNaC::evalm);
+}
+
 /** Perform automatic symbolic evaluations on indexed expression that
  *  contains this object as the base expression. */
 ex basic::eval_indexed(const basic & i) const
@@ -405,7 +430,22 @@ bool basic::contract_with(exvector::iterator self, exvector::iterator other, exv
  *  is added to repl_lst. */
 bool basic::match(const ex & pattern, lst & repl_lst) const
 {
-//clog << "match " << *this << " with " << pattern << ", repl_lst = " << repl_lst << endl;
+/*
+       Sweet sweet shapes, sweet sweet shapes,
+       That's the key thing, right right.
+       Feed feed face, feed feed shapes,
+       But who is the king tonight?
+       Who is the king tonight?
+       Pattern is the thing, the key thing-a-ling,
+       But who is the king of pattern?
+       But who is the king, the king thing-a-ling,
+       Who is the king of Pattern?
+       Bog is the king, the king thing-a-ling,
+       Bog is the king of Pattern.
+       Ba bu-bu-bu-bu bu-bu-bu-bu-bu-bu bu-bu
+       Bog is the king of Pattern.
+*/
+
        if (is_ex_exactly_of_type(pattern, wildcard)) {
 
                // Wildcard matches anything, but check whether we already have found
@@ -458,7 +498,7 @@ ex basic::subs(const lst & ls, const lst & lr, bool no_pattern) const
                for (unsigned i=0; i<ls.nops(); i++) {
                        lst repl_lst;
                        if (match(*ls.op(i).bp, repl_lst))
-                               return lr.op(i).bp->subs(repl_lst, true); // avoid recursion when re-substituting the wildcards
+                               return lr.op(i).bp->subs(repl_lst, true); // avoid infinite recursion when re-substituting the wildcards
                }
        }
 
@@ -692,6 +732,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);
 }
 
 //////////