2
$\begingroup$

I've defined a smooth step function given as

f[x_] = Piecewise[{
    {y0, x<x0-dx/2},
    {y0+1/2(y1-y0)(1-Cos[Pi*x/dx]), x<x0+dx/2},
    {y0, True}
}];

This function is differentiable everywhere, and Mathematica can correctly calculate it with exact values. However, if numerical values are substituted in x0 or dx, derivative at boundary points become undeterminate.

I'm aware that this exact same question has been asked before in here, but the solution presented there does not satisfy me - I don't want to define the derivative as its own function, since I need to be able to calculate also derivatives of products

D[f[x]*g[x,t], x]

since they appear in the differential equation I'm trying to solve numerically. One solution would be to expand the derivatives and then substitute separately defined f'[x] to appropriate places, but I don't want to do this since the equations are already quite messy. Furthermore, if I wanted to solve the differential equation for continuous piecewise function which isn't differentiable at boundary points, I'd still like to be able to solve it numerically without errors.

Forcing Mathematica to take one-sided derivatives at boundary points would solve both of these problems. So my question is whether this is possible.

EDIT:

I'm getting closer to the solution, thanks to Jack LaVigne who suggested in the comments to use Limit. So I defined following functions (hopefully self-explanatory):

SetAttributes[oneSidedD, HoldAll];
oneSidedD[f_, t_, dir_] := Module[{x},
   Limit[D[f, t], t -> x, Direction -> dir] /. x -> t
  ]

SetAttributes[rD, HoldAll];
SetAttributes[lD, HoldAll];
rD[f_, t_] := oneSidedD[f, t, +1];
lD[f_, t_] := oneSidedD[f, t, -1];

To check this works I defined simplest piecewise function I could imagine

in:  f[x_] = Piecewise[{{0, t < 0}, {t, True}}];
in:  D[f[x],x] // InputForm
out: Piecewise[{{0, t < 0}, {1, t > 0}}, Indeterminate]
in:  lD[f[x],x] // InputForm
out: Piecewise[{{1, t >= 0}}, 0]

Everything seems to work correcly, until I try to differentiate a product with some general function, I get this:

in:  lD[f[t]*h[t], t] // InputForm
out: h[t]*Piecewise[{{0, t < 0}, {1, t > 0}}, Indeterminate] + Piecewise[{{0, t < 0}}, t]*Derivative[1][h][t]

The output seems to be in form $h[t]f'[t] + f[t]h'[t]$ and oddly it seems to fail to take the left-limit of $f'[t]$ correctly, even though before it didn't have any problem with it. Even if I define the product as its own function, the problem doesn't disappear:

in:  q[t_] = PiecewiseExpand[f[t]*h[t]];
in:  lD[q[t],t] // InputForm
out: Piecewise[{{0, t < 0}, {h[t] + t*Derivative[1][h][t], t > 0}}, Indeterminate]

However, in this case I'm not sure if now this fails because $\lim_{x \to 0-}h[x]$ is not guaranteed to exist. Whatever the case, I can't find a workaround for this.

$\endgroup$
3
  • $\begingroup$ Your function f[x_] is invalid, for starters you write Cos(Pi*x/dx), and you have an extra comma at the end of the list. $\endgroup$
    – C. E.
    Jul 25, 2017 at 8:41
  • $\begingroup$ Oh, sorry, syntax error. I used special characters in my actual code and they didn't appear correctly in here, so I rewrote the function here and made a mistake. EDIT: Fixed $\endgroup$
    – user51299
    Jul 25, 2017 at 9:52
  • $\begingroup$ Good question. I don't think Mathematica supports one sided derivatives. However Limit will accept a direction and might be helpful. $\endgroup$ Jul 25, 2017 at 14:20

1 Answer 1

2
$\begingroup$

First, express the piecewise function with UnitStep. This can be achieved easily with the help of the undocumented function Simplify`PWToUnitStep:

Clear[y0, y1, x0, dx]
x0 = 2; dx = 1/10;
f[x_] = Piecewise[{{y0, x < x0 - dx/2}, {y0 + 1/2 (y1 - y0) (1 - Cos[Pi*x/dx]), 
     x < x0 + dx/2}, {y0, True}}] // Simplify`PWToUnitStep

Then, remove those Piecewise[…, Indeterminate] after differentiation. If you don't like UnitStep, add a Simplify:

D[f[x], x]
% /. HoldPattern@Piecewise[__] :> 0
% // Simplify

Mathematica graphics

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.