]> www.ginac.de Git - ginac.git/commitdiff
let_op() is no longer the default implementation of op(). Rationale: let_op()
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 20 Feb 2003 17:50:43 +0000 (17:50 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 20 Feb 2003 17:50:43 +0000 (17:50 +0000)
needs to clear status_flags::hash_calculated, otherwise we could end up with
equal objects that have different hash values. But clearing hash_calculated
on a read-only op() access would be inefficient. let_op() is now only
implemented by lst and matrix.

ginac/basic.cpp
ginac/container.pl
ginac/expairseq.cpp
ginac/expairseq.h
ginac/exprseq_suppl.cpp
ginac/idx.cpp
ginac/idx.h
ginac/matrix.cpp
ginac/matrix.h
ginac/pseries.cpp
ginac/pseries.h

index 9fd739822db5ec257a68efe2f2b0e67e592147ce..702379309da2417a5bb8271012e538ad9cef27d0 100644 (file)
@@ -179,12 +179,13 @@ unsigned basic::nops() const
 /** Return operand/member at position i. */
 ex basic::op(int i) const
 {
-       return (const_cast<basic *>(this))->let_op(i);
+       throw(std::runtime_error(std::string("op() not implemented by ") + class_name()));
 }
 
 /** Return modifyable operand/member at position i. */
 ex & basic::let_op(int i)
 {
+       ensure_if_modifiable();
        throw(std::runtime_error(std::string("let_op() not implemented by ") + class_name()));
 }
 
index c30342d9ca397ce998b278ddfecde6c0f44c5caf..84c0a49deec17be2264833fc055a35dc269dddaf 100755 (executable)
@@ -106,12 +106,29 @@ END_OF_SORT_IMPLEMENTATION
 }
 
 if ($let_op) {
-       $LET_OP_IMPLEMENTATION=<<END_OF_LET_OP_IMPLEMENTATION
+       $LET_OP_DEFINITION=<<END_OF_LET_OP_DEFINITION;
+       ex & let_op(int i);
+END_OF_LET_OP_DEFINITION
+
+       $LET_OP_IMPLEMENTATION=<<END_OF_LET_OP_IMPLEMENTATION;
+ex ${CONTAINER}::op(int i) const
+{
+       GINAC_ASSERT(i>=0);
+       GINAC_ASSERT(i<nops());
+
+       ${STLT}::const_iterator it=seq.begin();
+       for (int j=0; j<i; j++) {
+               ++it;
+       }
+       return *it;
+}
+
 ex & ${CONTAINER}::let_op(int i)
 {
        GINAC_ASSERT(i>=0);
        GINAC_ASSERT(i<nops());
 
+       ensure_if_modifiable();
        ${STLT}::iterator it=seq.begin();
        for (int j=0; j<i; j++) {
                ++it;
@@ -120,6 +137,7 @@ ex & ${CONTAINER}::let_op(int i)
 }
 END_OF_LET_OP_IMPLEMENTATION
 } else {
+       $LET_OP_DEFINITION="";
        $LET_OP_IMPLEMENTATION="// ${CONTAINER}::let_op() will be implemented by user elsewhere";
 }
 
@@ -238,7 +256,8 @@ public:
        unsigned precedence(void) const {return 10;}
        bool info(unsigned inf) const;
        unsigned nops() const;
-       ex & let_op(int i);
+       ex op(int i) const;
+${LET_OP_DEFINITION}
        ex map(map_function & f) const;
        ex eval(int level=0) const;
        ex subs(const lst & ls, const lst & lr, unsigned options = 0) const;
index 228da90c6c61419d915a815599e4bdc039abdc1d..5c3c2fe7810720cfb07f7e26a3a135914be3c078 100644 (file)
@@ -292,11 +292,6 @@ ex expairseq::op(int i) const
        return overall_coeff;
 }
 
-ex & expairseq::let_op(int i)
-{
-       throw(std::logic_error("let_op not defined for expairseq and derived classes (add, mul, ...)"));
-}
-
 ex expairseq::map(map_function &f) const
 {
        epvector *v = new epvector;
index 559ca1e8b7d281f6b281640f024e937ce6cfe550..add8a8f9d27d89c20480165203c4bc4338c4692a 100644 (file)
@@ -91,7 +91,6 @@ public:
        bool info(unsigned inf) const;
        unsigned nops() const;
        ex op(int i) const;
-       ex & let_op(int i);
        ex map(map_function & f) const;
        ex eval(int level=0) const;
        ex to_rational(lst &repl_lst) const;
index 29bb549ad61caa66e07d0fc747a48966390ff57b..e348853c71aaf774d4e65a9cce45f7eae48e8909 100644 (file)
@@ -33,11 +33,11 @@ bool exprseq::info(unsigned inf) const
        return basic::info(inf);
 }
 
-ex & exprseq::let_op(int i)
+ex exprseq::op(int i) const
 {
        GINAC_ASSERT(i>=0);
        GINAC_ASSERT(i<nops());
-       
+
        return seq[i];
 }
 
index 2cd3eae6a34b8e92024c79f652a86d6cf79cb53d..2323c29cf8480e3bd8e6870ee43be8dcb3d6ec41 100644 (file)
@@ -275,12 +275,21 @@ unsigned idx::nops() const
        return 1;
 }
 
-ex & idx::let_op(int i)
+ex idx::op(int i) const
 {
        GINAC_ASSERT(i == 0);
        return value;
 }
 
+ex idx::map(map_function & f) const
+{
+       idx *copy = static_cast<idx *>(duplicate());
+       copy->setflag(status_flags::dynallocated);
+       copy->clearflag(status_flags::hash_calculated);
+       copy->value = f(value);
+       return *copy;
+}
+
 /** Returns order relation between two indices of the same type. The order
  *  must be such that dummy indices lie next to each other. */
 int idx::compare_same_type(const basic & other) const
index fe7b51944aa29f60ac9e9aed00cbc9fe1dc553bf..7fc743b5ce906aee837a0b0371ea73739bb60068 100644 (file)
@@ -51,7 +51,8 @@ public:
        void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        unsigned nops() const;
-       ex & let_op(int i);
+       ex op(int i) const;
+       ex map(map_function & f) const;
        ex evalf(int level = 0) const;
        ex subs(const lst & ls, const lst & lr, unsigned options = 0) const;
 
index 57cd8894bab85d1aa17d60fd28b615c878b08b7b..67d99c97a43167cc1e7e4e513a46bda814b735d6 100644 (file)
@@ -199,11 +199,21 @@ unsigned matrix::nops() const
 }
 
 /** returns matrix entry at position (i/col, i%col). */
+ex matrix::op(int i) const
+{
+       GINAC_ASSERT(i>=0);
+       GINAC_ASSERT(i<nops());
+       
+       return m[i];
+}
+
+/** returns writable matrix entry at position (i/col, i%col). */
 ex & matrix::let_op(int i)
 {
        GINAC_ASSERT(i>=0);
        GINAC_ASSERT(i<nops());
        
+       ensure_if_modifiable();
        return m[i];
 }
 
index 5eb816bb1aeb1c1cfbb839670ed6f9d855026635..7fabe7099d0bdcd9e33a2f42f499307aba4a261e 100644 (file)
@@ -45,6 +45,7 @@ public:
 public:
        void print(const print_context & c, unsigned level = 0) const;
        unsigned nops() const;
+       ex op(int i) const;
        ex & let_op(int i);
        ex eval(int level=0) const;
        ex evalm(void) const {return *this;}
index 6077fd72c003208b3c990cd83831ce754f62e969..33b9cfdc83fc3d7d128bb009be75d60455b5846f 100644 (file)
@@ -264,12 +264,8 @@ ex pseries::op(int i) const
 {
        if (i < 0 || unsigned(i) >= seq.size())
                throw (std::out_of_range("op() out of range"));
-       return seq[i].rest * power(var - point, seq[i].coeff);
-}
 
-ex & pseries::let_op(int i)
-{
-       throw (std::logic_error("let_op() not defined for pseries"));
+       return seq[i].rest * power(var - point, seq[i].coeff);
 }
 
 /** Return degree of highest power of the series.  This is usually the exponent
index 37ac579633456ffa21b2756ff087a33c27f5ce98..17ae934a0f250bb464a8cf151bc5be368748352b 100644 (file)
@@ -46,7 +46,6 @@ public:
        unsigned precedence(void) const {return 38;} // for clarity just below add::precedence
        unsigned nops(void) const;
        ex op(int i) const;
-       ex & let_op(int i);
        int degree(const ex &s) const;
        int ldegree(const ex &s) const;
        ex coeff(const ex &s, int n = 1) const;