]> www.ginac.de Git - ginac.git/blobdiff - ginac/basic.cpp
- Make diff() care for evaluating stuff.
[ginac.git] / ginac / basic.cpp
index 89186ad9815cf479dc20defbdd9b56909354a27b..cf69c42cd2263dcfb722790ff65a7e2bacd4d8f6 100644 (file)
@@ -35,9 +35,9 @@
 #include "utils.h"
 #include "debugmsg.h"
 
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
 namespace GiNaC {
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC
 
 GINAC_IMPLEMENT_REGISTERED_CLASS(basic, void)
 
@@ -293,6 +293,32 @@ ex basic::subs(const lst & ls, const lst & lr) const
     return *this;
 }
 
+/** Default interface of nth derivative ex::diff(s, n).  It should be called
+ *  instead of ::derivative(s) for first derivatives and for nth derivatives it
+ *  just recurses down.
+ *
+ *  @param s symbol to differentiate in
+ *  @param nth order of differentiation
+ *  @see ex::diff */
+ex basic::diff(const symbol & s, unsigned nth) const
+{
+    // trivial: zeroth derivative
+    if (!nth)
+        return ex(*this);
+    
+    // evaluate unevalueted *this before differentiating
+    if (!(flags & status_flags::evaluated))
+        return ex(*this).diff(s, nth);
+    
+    ex ndiff = derivative(s);
+    while (!ndiff.is_zero() &&    // stop differentiating zeros
+           nth>1) {
+        ndiff = ndiff.diff(s);
+        --nth;
+    }
+    return ndiff;
+}
+
 exvector basic::get_indices(void) const
 {
     return exvector(); // return an empty exvector
@@ -305,6 +331,15 @@ ex basic::simplify_ncmul(const exvector & v) const
 
 // protected
 
+/** Default implementation of ex::diff(). It simply throws an error message.
+ *
+ *  @exception logic_error (differentiation not supported by this type)
+ *  @see ex::diff */
+ex basic::derivative(const symbol & s) const
+{
+    throw(std::logic_error("differentiation not supported by this type"));
+}
+
 int basic::compare_same_type(const basic & other) const
 {
     return compare_pointers(this, &other);
@@ -349,6 +384,7 @@ ex basic::expand(unsigned options) const
     return this->setflag(status_flags::expanded);
 }
 
+
 //////////
 // non-virtual functions in this class
 //////////
@@ -491,6 +527,6 @@ const type_info & typeid_basic=typeid(some_basic);
 
 int max_recursion_level=1024;
 
-#ifndef NO_GINAC_NAMESPACE
+#ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
-#endif // ndef NO_GINAC_NAMESPACE
+#endif // ndef NO_NAMESPACE_GINAC