subs() performs "syntactic substitution" as in Maple; you can substitute
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 5 Apr 2001 21:02:26 +0000 (21:02 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 5 Apr 2001 21:02:26 +0000 (21:02 +0000)
any object by any other object (even numerics) but only when the object
subs() is called on exactly matches an object on the left-hand side of the
substitution list; expairseq still doesn't substitute its numeric coefficients
so substituting numerics will not replace them in all occurences (this
shouldn't matter, though)

ginac/basic.cpp
ginac/container.pl
ginac/expairseq.cpp
ginac/function.pl
ginac/indexed.cpp
ginac/indexed.h
ginac/power.cpp
ginac/symbol.cpp
ginac/symbol.h
ginac/tensor.cpp
ginac/tensor.h

index 1b3882590b708f7ea0e7fdb4fd0cfd3eaae17a95..c4e17cd5eaccbd64cc0833e7c8b5c09464d3cfe6 100644 (file)
 #include "symbol.h"
 #include "lst.h"
 #include "ncmul.h"
-#include "idx.h"
-#include "indexed.h"
-#include "tensor.h"
-#include "function.h"
 #include "archive.h"
 #include "utils.h"
 #include "debugmsg.h"
@@ -341,10 +337,17 @@ bool basic::contract_with(exvector::iterator self, exvector::iterator other, exv
        return false;
 }
 
-/** Substitute a set of symbols by arbitrary expressions. The ex returned
+/** Substitute a set of objects by arbitrary expressions. The ex returned
  *  will already be evaluated. */
 ex basic::subs(const lst & ls, const lst & lr) const
 {
+       GINAC_ASSERT(ls.nops() == lr.nops());
+
+       for (unsigned i=0; i<ls.nops(); i++) {
+               if (is_equal(*ls.op(i).bp))
+                       return lr.op(i);
+       }
+
        return *this;
 }
 
@@ -466,11 +469,11 @@ ex basic::expand(unsigned options) const
 
 // public
 
-/** Substitute objects (symbols, indices, tensors, functions, indexed) in
- *  expression and return the result as a new expression.  There are two
- *  valid types of replacement arguments: 1) a relational like object==ex
- *  and 2) a list of relationals lst(object1==ex1,object2==ex2,...), which
- *  is converted to subs(lst(object1,object2,...),lst(ex1,ex2,...)). */
+/** Substitute objects in an expression (syntactic substitution) and return
+ *  the result as a new expression.  There are two valid types of
+ *  replacement arguments: 1) a relational like object==ex and 2) a list of
+ *  relationals lst(object1==ex1,object2==ex2,...), which is converted to
+ *  subs(lst(object1,object2,...),lst(ex1,ex2,...)). */
 ex basic::subs(const ex & e) const
 {
        if (e.info(info_flags::relation_equal)) {
@@ -482,20 +485,14 @@ ex basic::subs(const ex & e) const
        lst ls;
        lst lr;
        for (unsigned i=0; i<e.nops(); i++) {
-               if (!e.op(i).info(info_flags::relation_equal)) {
+               ex r = e.op(i);
+               if (!r.info(info_flags::relation_equal)) {
                        throw(std::invalid_argument("basic::subs(ex): argument must be a list or equations"));
                }
-               ex s = e.op(i).op(0);
-               ex r = e.op(i).op(1);
-               if (!is_ex_of_type(s, symbol) && !is_ex_of_type(s, idx) &&
-                   !is_ex_of_type(s, tensor) && !is_ex_of_type(s, function) &&
-                       !is_ex_of_type(s, indexed)) {
-                       throw(std::invalid_argument("basic::subs(ex): lhs must be a symbol, idx, tensor, function or indexed"));
-               }
-               ls.append(s);
-               lr.append(r);
+               ls.append(r.op(0));
+               lr.append(r.op(1));
        }
-       return subs(ls,lr);
+       return subs(ls, lr);
 }
 
 /** Compare objects to establish canonical ordering.
index 571330f982ebde9f0f34a5b80132ea4ff05f94d2..1a591ab304d50917487ea411c2c67fce5ea48853 100755 (executable)
@@ -502,9 +502,9 @@ ex ${CONTAINER}::derivative(const symbol & s) const
 ex ${CONTAINER}::subs(const lst & ls, const lst & lr) const
 {
        ${STLT} * vp=subschildren(ls,lr);
-       if (vp==0) {
-               return *this;
-       }
+       if (vp==0)
+               return inherited::subs(ls, lr);
+
        return this${CONTAINER}(vp);
 }
 
index 43754ea2dfc1ee16fb670d8259743923449c1a43..09a38af5931c14922e42761e2e1b016e6e5ef193 100644 (file)
@@ -337,7 +337,7 @@ ex expairseq::subs(const lst &ls, const lst &lr) const
 {
        epvector *vp = subschildren(ls,lr);
        if (vp==0)
-               return *this;
+               return inherited::subs(ls, lr);
        
        return thisexpairseq(vp,overall_coeff);
 }
index f6e7b33276ea306d6bd6c7df7d2a46d26962c539..b36df872337b225da8534ed867741009e6d92347 100755 (executable)
@@ -345,7 +345,6 @@ public:
        ex evalf(int level=0) const;
        unsigned calchash(void) const;
        ex series(const relational & r, int order, unsigned options = 0) const;
-       ex subs(const lst & ls, const lst & lr) const;
        ex thisexprseq(const exvector & v) const;
        ex thisexprseq(exvector * vp) const;
 protected:
@@ -822,19 +821,6 @@ ${series_switch_statement}
        throw(std::logic_error("function::series(): invalid nparams"));
 }
 
-ex function::subs(const lst & ls, const lst & lr) const
-{
-       GINAC_ASSERT(ls.nops() == lr.nops());
-
-       for (unsigned i=0; i<ls.nops(); i++) {
-               if (is_ex_of_type(ls.op(i), function) &&
-                   compare_same_type(ex_to_function(ls.op(i)))==0)
-                       return lr.op(i);
-       }
-
-       return inherited::subs(ls, lr);
-}
-
 // protected
 
 
index c530c1f4479e4d1e012208c77c40cf6b143a29c0..5277bf89ab3a584d42fafb28b0a5ef02c5321eb3 100644 (file)
@@ -369,19 +369,6 @@ ex indexed::coeff(const ex & s, int n) const
                return n==0 ? ex(*this) : _ex0();
 }
 
-ex indexed::subs(const lst & ls, const lst & lr) const
-{
-       GINAC_ASSERT(ls.nops() == lr.nops());
-
-       for (unsigned i=0; i<ls.nops(); i++) {
-               if (is_ex_of_type(ls.op(i), indexed) &&
-                   compare_same_type(ex_to_indexed(ls.op(i)))==0)
-                       return lr.op(i);
-       }
-
-       return inherited::subs(ls, lr);
-}
-
 ex indexed::thisexprseq(const exvector & v) const
 {
        return indexed(symmetry, v);
index 5b3497820eec60b1e37b44f3ee18e4c19b04b2a6..e98375d38165d56610fe1e72a111e8412f705711 100644 (file)
@@ -159,7 +159,6 @@ public:
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
        ex coeff(const ex & s, int n = 1) const;
-       ex subs(const lst & ls, const lst & lr) const;
        exvector get_free_indices(void) const;
 
 protected:
index f5d877e65a5baef61dc29f2f67c415b855038acd..c2885565f701fad473b58c3125ab2119d245b8b9 100644 (file)
@@ -476,7 +476,7 @@ ex power::subs(const lst & ls, const lst & lr) const
 
        if (are_ex_trivially_equal(basis,subsed_basis)&&
                are_ex_trivially_equal(exponent,subsed_exponent)) {
-               return *this;
+               return inherited::subs(ls, lr);
        }
        
        return power(subsed_basis, subsed_exponent);
index 8547ffefede2f3059f9f38ec6eabd7496c42ac83..09e4192b689cdf27ed3f6fb5c52958bdb44011e7 100644 (file)
@@ -221,19 +221,6 @@ ex symbol::eval(int level) const
        }
 }
 
-ex symbol::subs(const lst & ls, const lst & lr) const
-{
-       GINAC_ASSERT(ls.nops() == lr.nops());
-
-       for (unsigned i=0; i<ls.nops(); i++) {
-               if (is_ex_exactly_of_type(ls.op(i),symbol)) {
-                       if (compare_same_type(ex_to_symbol(ls.op(i)))==0)
-                               return lr.op(i);
-               }
-       }
-       return *this;
-}
-
 // protected
 
 /** Implementation of ex::diff() for single differentiation of a symbol.
index 16dcab0cd8b308bf027a96e6800f08d28680cadc..c147c89f2ddcdabec0ce5fa630c617605135be60 100644 (file)
@@ -86,7 +86,6 @@ public:
        ex series(const relational & s, int order, unsigned options = 0) const;
        ex normal(lst &sym_lst, lst &repl_lst, int level = 0) const;
        ex to_rational(lst &repl_lst) const;
-       ex subs(const lst & ls, const lst & lr) const;
 protected:
        ex derivative(const symbol & s) const;
        int compare_same_type(const basic & other) const;
index b53d6f7d0edb519a8ddee3ed6f5bd02855547971..c7a68bf2c1f602c57b311be4899cbdb20e17b083 100644 (file)
@@ -166,18 +166,6 @@ DEFAULT_PRINT(tensmetric, "g")
 DEFAULT_PRINT(minkmetric, "eta")
 DEFAULT_PRINT(tensepsilon, "eps")
 
-ex tensor::subs(const lst & ls, const lst & lr) const
-{
-       GINAC_ASSERT(ls.nops() == lr.nops());
-
-       for (unsigned i=0; i<ls.nops(); i++) {
-               if (is_ex_of_type(ls.op(i), tensor) &&
-                   compare_same_type(ex_to_tensor(ls.op(i)))==0)
-                       return lr.op(i);
-       }
-       return *this;
-}
-
 /** Automatic symbolic evaluation of an indexed delta tensor. */
 ex tensdelta::eval_indexed(const basic & i) const
 {
index ac991d5f666f5e47d621e1829bdf5f3bd4b2c048..65c86c45bd5c703407980f390683f2a017f57a92 100644 (file)
@@ -40,8 +40,6 @@ protected:
        tensor(unsigned ti);
 
        // functions overriding virtual functions from bases classes
-public:
-       ex subs(const lst & ls, const lst & lr) const;
 protected:
        unsigned return_type(void) const { return return_types::noncommutative_composite; }
 };