]> www.ginac.de Git - ginac.git/commitdiff
map() doesn't allocate a new object unless necessary
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 10 Jun 2004 02:17:13 +0000 (02:17 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 10 Jun 2004 02:17:13 +0000 (02:17 +0000)
ginac/basic.cpp
ginac/idx.cpp
ginac/power.cpp
ginac/relational.cpp

index 038cd7b571fdb6e93aca0f38569add33e6b9fc0f..b9689851b6a63bf2de8bba0a1b7eeb84c3f8ea7c 100644 (file)
@@ -307,12 +307,23 @@ ex basic::map(map_function & f) const
        if (num == 0)
                return *this;
 
-       basic *copy = duplicate();
-       copy->setflag(status_flags::dynallocated);
-       copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
-       for (size_t i=0; i<num; i++)
-               copy->let_op(i) = f(copy->op(i));
-       return *copy;
+       basic *copy = NULL;
+       for (size_t i=0; i<num; i++) {
+               const ex & o = op(i);
+               const ex & n = f(o);
+               if (!are_ex_trivially_equal(o, n)) {
+                       if (copy == NULL)
+                               copy = duplicate();
+                       copy->let_op(i) = n;
+               }
+       }
+
+       if (copy) {
+               copy->setflag(status_flags::dynallocated);
+               copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
+               return *copy;
+       } else
+               return *this;
 }
 
 /** Return degree of highest power in object s. */
@@ -781,7 +792,7 @@ unsigned basic::calchash() const
 struct expand_map_function : public map_function {
        unsigned options;
        expand_map_function(unsigned o) : options(o) {}
-       ex operator()(const ex & e) { return expand(e, options); }
+       ex operator()(const ex & e) { return e.expand(options); }
 };
 
 /** Expand expression, i.e. multiply it out and return the result as a new
index 1aba28bf302c0c20abe672a718761bcc0c798fd5..c95c07c72fc87ef01655d157ef256e21a587bf78 100644 (file)
@@ -242,11 +242,16 @@ ex idx::op(size_t i) const
 
 ex idx::map(map_function & f) const
 {
-       idx *copy = duplicate();
-       copy->setflag(status_flags::dynallocated);
-       copy->clearflag(status_flags::hash_calculated);
-       copy->value = f(value);
-       return *copy;
+       const ex &mapped_value = f(value);
+       if (are_ex_trivially_equal(value, mapped_value))
+               return *this;
+       else {
+               idx *copy = duplicate();
+               copy->setflag(status_flags::dynallocated);
+               copy->clearflag(status_flags::hash_calculated);
+               copy->value = mapped_value;
+               return *copy;
+       }
 }
 
 /** Returns order relation between two indices of the same type. The order
index aa0b082a7970b45faa10f4f06716e3bcae279c7b..309d529a69cffebb3825f96e2d1bcd13e6ff0916 100644 (file)
@@ -246,7 +246,14 @@ ex power::op(size_t i) const
 
 ex power::map(map_function & f) const
 {
-       return (new power(f(basis), f(exponent)))->setflag(status_flags::dynallocated);
+       const ex &mapped_basis = f(basis);
+       const ex &mapped_exponent = f(exponent);
+
+       if (!are_ex_trivially_equal(basis, mapped_basis)
+        || !are_ex_trivially_equal(exponent, mapped_exponent))
+               return (new power(mapped_basis, mapped_exponent))->setflag(status_flags::dynallocated);
+       else
+               return *this;
 }
 
 int power::degree(const ex & s) const
index 87acde42fe24b89e975167da4dd243716d411fe3..86e2c2e8399bde1fbea5eb4db966e69aa2870f27 100644 (file)
@@ -164,7 +164,14 @@ ex relational::op(size_t i) const
 
 ex relational::map(map_function & f) const
 {
-       return (new relational(f(lh), f(rh), o))->setflag(status_flags::dynallocated);
+       const ex &mapped_lh = f(lh);
+       const ex &mapped_rh = f(rh);
+
+       if (!are_ex_trivially_equal(lh, mapped_lh)
+        || !are_ex_trivially_equal(rh, mapped_rh))
+               return (new relational(mapped_lh, mapped_rh, o))->setflag(status_flags::dynallocated);
+       else
+               return *this;
 }
 
 ex relational::eval(int level) const