commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Luc Maisonobe <Luc.Maison...@free.fr>
Subject Re: [MATH] What is the derivative of 0^x
Date Sat, 24 Aug 2013 09:24:21 GMT
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.Maisonobe@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 <gilles@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-unsubscribe@commons.apache.org>
>>>> For additional commands, e-mail: dev-help@commons.apache.org
>>>>
>>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>>
>>
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Mime
View raw message