#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 */
* @see ex::diff */
ex numeric::diff(symbol const & s) const
{
- return exZERO();
+ return _ex0();
}
ex symbol::diff(symbol const & s) const
{
if (compare_same_type(s)) {
- return exZERO();
+ return _ex0();
} else {
- return exONE();
+ return _ex1();
}
}
* @see ex::diff */
ex constant::diff(symbol const & s) const
{
- return exZERO();
+ return _ex0();
}
/** Implementation of ex::diff() for multiple differentiation of a symbol.
return s;
break;
case 1:
- return exONE();
+ return _ex1();
break;
default:
- return exZERO();
+ return _ex0();
}
} else {
- return exONE();
+ return _ex1();
}
}
* @see ex::diff */
ex indexed::diff(symbol const & s) const
{
- return exZERO();
+ return _ex0();
}
* @see ex::diff */
ex ncmul::diff(symbol const & s) const
{
- return exZERO();
+ return _ex0();
}
{
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),
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);
epvector new_seq;
epvector::const_iterator it = seq.begin(), itend = seq.end();
- //!! coeff might depend on var
+ // FIXME: coeff might depend on var
while (it != itend) {
if (is_order_function(it->rest)) {
new_seq.push_back(expair(it->rest, it->coeff - 1));
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