MathGroup Archive 2008

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Problems with differentiating Piecewise functions


On 28 Mar 2008, at 09:16, hlovatt wrote:
> On Mar 28, 12:18 am, Andrzej Kozlowski <a... at mimuw.edu.pl> wrote:
>> On 26 Mar 2008, at 10:55, hlovatt wrote:
>>
>>> If I set up a piecewise function and differentiate it:
>>
>>> In[112]:= pw1 = Piecewise[{{x^2, x <= 0}, {x, x > 0}}]
>>
>>> Out[112]= \[Piecewise] {
>>> {x^2, x <= 0},
>>> {x, x > 0}
>>> }
>>
>>> In[113]:= pw1 /. x -> 0
>>
>>> Out[113]= 0
>>
>>> In[114]:= pw1d = D[pw1, x]
>>
>>> Out[114]= \[Piecewise] {
>>> {2 x, x < 0},
>>> {1, x > 0},
>>> {Indeterminate, \!\(\*
>>>    TagBox["True",
>>>     "PiecewiseDefault",
>>>     AutoDelete->False,
>>>     DeletionWarning->True]\)}
>>> }
>>
>>> In[115]:= pw1d /. x -> 0
>>
>>> Out[115]= Indeterminate
>>
>>> Then at the joins between the pieces I get Indeterminate values,
>>> because the limit x <= 0 has become x < 0 after differentiation.  
>>> Does
>>> anyone know a solution to this problem?
>>
>>> Thanks,
>>
>>> Howard.
>>
>>  What do you mean by "a solution to this problem"? You have a
>> function that is not differentiable at 0 and you would like it's
>> derivative to have a value there? You can't expect a "solution to a
>> problem" when you do not tell us what is the problem (except the fact
>> that not all functions are differentiable - but that's life).
>> Note that is your pieceise function is actually differentiable than
>> the derivative is defined everywhere:
>>
>> pw2 = Piecewise[{{x^2, x <= 0}, {x^3, x > 0}}];
>>
>> pw2d = D[pw2, x]
>> Piecewise[{{2*x, x < 0}, {0, x == 0}}, 3*x^2]
>>
>> This is also as it should be. What else would you expect?
>>
>> Andrzej Kozlowski
>
> Thanks to everyone who replied. I have to apologise for the bad
> example that I posted (I simplified my problem by cutting and pasting
> an example from the help file to keep the post short). I am actually
> fitting cubic splines and the functions are continuous up to the
> second derivative (at least to the accuracy of machine precision). A
> better example is:
>
> In[54]:= pw[x_] :=
> Piecewise[{{0.+ 0.007508378277320685 x + 7.561460342471517*10^-7 x^3,
>     x < 50}, {-4.8729206849430454*10^-6 (-125.76959597633721 +
>       x) (1148.1044516606876- 47.50636365246156 x + x^2), 50 <= x}}]
>
> In[55]:= pw[x]
>
> Out[55]= \[Piecewise] {
>  {0.+ 0.00750838 x + 7.56146*10^-7 x^3, x < 50},
>  {-4.87292*10^-6 (-125.77 + x) (1148.1- 47.5064 x + x^2), 50 <= x}
> }
>
> In[56]:= pw[50]
>
> Out[56]= 0.469937
>
> In[57]:= pw[50 + 10^-30]
>
> Out[57]= 0.469937
>
> In[58]:= pw[50 - 10^-30]
>
> Out[58]= 0.469937
>
> In[60]:= pw'[x]
>
> Out[60]= \[Piecewise] {
>  {0.00750838+ 2.26844*10^-6 x^2, x < 50},
>  {-4.87292*10^-6 (-125.77 + x) (-47.5064 + 2 x) -
>    4.87292*10^-6 (1148.1- 47.5064 x + x^2), x > 50},
>  {Indeterminate, \!\(\*
>     TagBox["True",
>      "PiecewiseDefault",
>      AutoDelete->False,
>      DeletionWarning->True]\)}
> }
>
> In[61]:= pw'[50]
>
> Out[61]= Indeterminate
>
> In[62]:= pw'[50 + 10^-30]
>
> Out[62]= 0.0131795
>
> In[63]:= pw'[50 - 10^-30]
>
> Out[63]= 0.0131795
>
> Also if you Plot pw or pw' you get an annoying gap in the plot at the
> join (but strangely not pw''). My guess is that Mathematica is too
> pedantic about machine precision and is treating each piece as an
> algebraic equation. However this does not explain why Plot behaves
> funnily and doesn't help if you are trying to do numerical analysis.
>

You are violating one of the most fundamental principles of computer  
algebra: do not mix approximate numbers with symbolic computation.  
More correctly, such "mixing" requires a great deal of care and  
symbolic algebraic techniques that can deal with approximate numbers  
(and even more so with machine precision input) are still in their  
infancy. (In fact Mathematica is one of the few systems that make it  
to some extent possible). In your case the symbolic technique you are  
using is differentiation of a piecewise function, and this cannot be  
reliably combined with numerical precision input.

The answer to your problem is simple. Switch from using a mixture of  
symbolic methods and approximate input to a purely numeric setting.  
The best way to do this, I think, is by using FunctionInterpolation.  
So what you need to do is this:

pw[x_] :=
  Piecewise[{{0. + 0.007508378277320685 x + 7.561460342471517*10^-7 x^3,
     x < 50}, {-4.8729206849430454*10^-6 (-125.76959597633721 +
        x) (1148.1044516606876 - 47.50636365246156 x + x^2), 50 <= x}}]

f = FunctionInterpolation[pw[x], {x, 0, 80}];

Plot[f[x], {x, 40, 60}]

shows a continuous curve

Plot[f'[x], {x, 40, 60}]

shows an almost smooth curve, with a slight "kink" at the break point.  
One could probably play with the options to FunctionInterpolation to  
"smoothen" it.

Andrzej Kozlowski


  • Prev by Date: Re: Re: Problems with differentiating Piecewise functions
  • Next by Date: Re: Re: Problems with differentiating Piecewise functions
  • Previous by thread: Re: Re: Problems with differentiating Piecewise functions
  • Next by thread: Re: Re: Problems with differentiating Piecewise functions