Le 23/08/2013 19:20, Ajo Fod a écrit : > Hello, Hi Ajo,
> > This shows one way of interpreting the derivative for strictly +ve numbers. > > public static void main(final String[] args) { > final double x = 1d; > DerivativeStructure dsA = new DerivativeStructure(1, 1, 0, x); > System.out.println("Derivative of |a|^x wrt x"); > for (int p = 10; p < 21; p++) { > double a; > if (p < 20) { > a = 1d / Math.pow(2d, p); > } else { > a = 0d; > } > final DerivativeStructure a_ds = new DerivativeStructure(1, 1, > a); > final DerivativeStructure out = a_ds.pow(dsA); > final double calc = (Math.pow(a, x + EPS) - Math.pow(a, x)) / > EPS; > System.out.format("Derivative@%f=%f %f\n", a, calc, > out.getPartialDerivative(new int[]{1})); > } > } > > At this point I"m explicitly substituting the rule that derivative(|a|^x) = > 0 for |a|=0. Yes, but this fails for x = 0, as the limit of the finite difference is -infinity and not 0. You can build your own function which explicitly assumes a is constant and takes care of special values as follows: public static DerivativeStructure aToX(final double a, final DerivativeStructure x) { final double lnA = (a == 0 && x.getValue() == 0) ? Double.NEGATIVE_INFINITY : FastMath.log(a); final double[] function = new double[1 + x.getOrder()]; function[0] = FastMath.pow(a, x.getValue()); for (int i = 1; i < function.length; ++i) { function[i] = lnA * function[i - 1]; } return x.compose(function); } This will work and provides derivatives to any order for almost any values of a and x, including a=0, x=1 as in your exemple, but also slightly better for a=0, x=0. However, it still has an important drawback: it won't compute the n-th order derivative correctly for a=0, x=0 and n > 1. It will provide NaN for these higher order derivatives instead of +/-infinity according to parity of n. This is a known problem that we already encountered when dealing with rootN. Here is an extract of a comment in the test case testRootNSingularity, where similar NaN appears instead of +/- infinity. The dsZero instance in the comment is simple the x parameter of the function, as a derivativeStructure with value 0.0 and depending on itself (dsZero = new DerivativeStructure(1, maxOrder, 0, 0.0)): // the following checks shows a LIMITATION of the current implementation // we have no way to tell dsZero is a pure linear variable x = 0 // we only say: "dsZero is a structure with value = 0.0, // first derivative = 1.0, second and higher derivatives = 0.0". // Function composition rule for second derivatives is: // d2[f(g(x))]/dx2 = f''(g(x)) * [g'(x)]^2 + f'(g(x)) * g''(x) // when function f is the nth root and x = 0 we have: // f(0) = 0, f'(0) = +infinity, f''(0) = -infinity (and higher // derivatives keep switching between +infinity and -infinity) // so given that in our case dsZero represents g, we have g(x) = 0, // g'(x) = 1 and g''(x) = 0 // applying the composition rules gives: // d2[f(g(x))]/dx2 = f''(g(x)) * [g'(x)]^2 + f'(g(x)) * g''(x) // = -infinity * 1^2 + +infinity * 0 // = -infinity + NaN // = NaN // if we knew dsZero is really the x variable and not the identity // function applied to x, we would not have computed f'(g(x)) * g''(x) // and we would have found that the result was -infinity and not NaN Hope this helps Luc > > Thanks, > Ajo. > > > > On Fri, Aug 23, 2013 at 9:39 AM, Luc Maisonobe <luc.maison...@free.fr>wrote: > >> Hi Ajo, >> >> Le 23/08/2013 17:48, Ajo Fod a écrit : >>> Try this and I'm happy to explain if necessary: >>> >>> public class Derivative { >>> >>> public static void main(final String[] args) { >>> DerivativeStructure dsA = new DerivativeStructure(1, 1, 0, 1d); >>> System.out.println("Derivative of constant^x wrt x"); >>> for (int a = -3; a < 3; a++) { >> >> We have chosen the classical definition which implies c^x is not defined >> for real r and negative c. >> >> Our implementation is based on the decomposition c^r = exp(r * ln(c)), >> so the NaN comes from the logarithm when c <= 0. >> >> Noe also that as explained in the documentation here: >> < >> http://commons.apache.org/proper/commons-math/userguide/analysis.html#a4.7_Differentiation >>> , >> there are no concepts of "constants" and "variables" in this framework, >> so we cannot draw a line between c^r as seen as a univariate function of >> r, or as a univariate function of c, or as a bivariate function of c and >> r, or even as a pentavariate function of p1, p2, p3, p4, p5 with both c >> and r being computed elsewhere from p1...p5. So we don't make special >> cases for the case c = 0 for example. >> >> Does this explanation make sense to you? >> >> best regards, >> Luc >> >> >>> final DerivativeStructure a_ds = new DerivativeStructure(1, >> 1, >>> a); >>> final DerivativeStructure out = a_ds.pow(dsA); >>> System.out.format("Derivative@%d=%f\n", a, >>> out.getPartialDerivative(new int[]{1})); >>> } >>> } >>> } >>> >>> >>> >>> On Fri, Aug 23, 2013 at 7:59 AM, Gilles <gil...@harfang.homelinux.org >>> wrote: >>> >>>> On Fri, 23 Aug 2013 07:17:35 -0700, Ajo Fod wrote: >>>> >>>>> Seems like the DerivativeCompiler returns NaN. >>>>> >>>>> IMHO it should return 0. >>>>> >>>> >>>> What should be 0? And Why? >>>> >>>> >>>> >>>>> Is this worthy of an issue? >>>>> >>>> >>>> As is, no. >>>> >>>> Gilles >>>> >>>> >>>>> Thanks, >>>>> -Ajo >>>>> >>>> >>>> >>>> >> ------------------------------**------------------------------**--------- >>>> To unsubscribe, e-mail: dev-unsubscribe@commons.**apache.org< >> dev-unsubscr...@commons.apache.org> >>>> For additional commands, e-mail: dev-h...@commons.apache.org >>>> >>>> >>> >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org >> For additional commands, e-mail: dev-h...@commons.apache.org >> >> > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org