]> www.ginac.de Git - ginac.git/blobdiff - ginac/diff.cpp
- Banned exZERO(), exONE(), exMINUSHALF() and all this from the interface.
[ginac.git] / ginac / diff.cpp
index 167d4939fe5fe5a510db386b164f9f292382bfec..ae85b5556a27d5a67ebcbfce09151210dba64d0e 100644 (file)
 #include "relational.h"
 #include "series.h"
 #include "symbol.h"
+#include "utils.h"
 
+#ifndef NO_GINAC_NAMESPACE
 namespace GiNaC {
+#endif // ndef NO_GINAC_NAMESPACE
 
 /** Default implementation of ex::diff(). It prints and error message and returns a fail object.
  *  @see ex::diff */
@@ -52,7 +55,7 @@ ex basic::diff(symbol const & s) const
  *  @see ex::diff */
 ex numeric::diff(symbol const & s) const
 {
-    return exZERO();
+    return _ex0();
 }
 
 
@@ -63,9 +66,9 @@ ex numeric::diff(symbol const & s) const
 ex symbol::diff(symbol const & s) const
 {
     if (compare_same_type(s)) {
-        return exZERO();
+        return _ex0();
     } else {
-        return exONE();
+        return _ex1();
     }
 }
 
@@ -74,7 +77,7 @@ ex symbol::diff(symbol const & s) const
  *  @see ex::diff */
 ex constant::diff(symbol const & s) const
 {
-    return exZERO();
+    return _ex0();
 }
 
 /** Implementation of ex::diff() for multiple differentiation of a symbol.
@@ -90,13 +93,13 @@ ex symbol::diff(symbol const & s, unsigned nth) const
             return s;
             break;
         case 1:
-            return exONE();
+            return _ex1();
             break;
         default:
-            return exZERO();
+            return _ex0();
         }
     } else {
-        return exONE();
+        return _ex1();
     }
 }
 
@@ -105,7 +108,7 @@ ex symbol::diff(symbol const & s, unsigned nth) const
  *  @see ex::diff */
 ex indexed::diff(symbol const & s) const
 {
-        return exZERO();
+        return _ex0();
 }
 
 
@@ -149,7 +152,7 @@ ex mul::diff(symbol const & s) const
  *  @see ex::diff */
 ex ncmul::diff(symbol const & s) const
 {
-    return exZERO();
+    return _ex0();
 }
 
 
@@ -159,7 +162,7 @@ ex power::diff(symbol const & s) const
 {
     if (exponent.info(info_flags::real)) {
         // D(b^r) = r * b^(r-1) * D(b) (faster than the formula below)
-        return mul(mul(exponent, power(basis, exponent - exONE())), basis.diff(s));
+        return mul(mul(exponent, power(basis, exponent - _ex1())), basis.diff(s));
     } else {
         // D(b^e) = b^e * (D(e)*ln(b) + e*D(b)/b)
         return mul(power(basis, exponent),
@@ -175,17 +178,22 @@ ex power::diff(symbol const & s) const
 ex function::diff(symbol const & s) const
 {
     exvector new_seq;
-
-    if (serial == function_index_Order) {
-
+    
+    if (serial==function_index_Order) {
         // Order Term function only differentiates the argument
         return Order(seq[0].diff(s));
-
     } else {
-
         // Chain rule
+        ex arg_diff;
         for (unsigned i=0; i!=seq.size(); i++) {
-            new_seq.push_back(mul(pdiff(i), seq[i].diff(s)));
+            arg_diff = seq[i].diff(s);
+            // We apply the chain rule only when it makes sense.  This is not
+            // just for performance reasons but also to allow functions to
+            // throw when differentiated with respect to one of its arguments
+            // without running into trouble with our automatic full
+            // differentiation:
+            if (!arg_diff.is_zero())
+                new_seq.push_back(mul(pdiff(i), arg_diff));
         }
     }
     return add(new_seq);
@@ -226,18 +234,20 @@ ex series::diff(symbol const & s) const
 
 ex ex::diff(symbol const & s, unsigned nth) const
 {
-    ASSERT(bp!=0);
+    GINAC_ASSERT(bp!=0);
 
-    if ( nth==0 ) {
+    if (nth==0) {
         return *this;
     }
 
     ex ndiff = bp->diff(s);
-    while ( nth>1 ) {
+    while (nth>1) {
         ndiff = ndiff.diff(s);
         --nth;
     }
     return ndiff;
 }
 
+#ifndef NO_GINAC_NAMESPACE
 } // namespace GiNaC
+#endif // ndef NO_GINAC_NAMESPACE