3
$\begingroup$

I have a smooth step function given by the piecewise function

smoothstep[x_] := Piecewise[{{0, x <= -(1/2)}, 
   {-20*(x + 1/2)^7 + 70*(x + 1/2)^6 - 84*(x + 1/2)^5 + 
       35*(x + 1/2)^4, -(1/2) < x < 1/2}, {1, x >= 1/2}}]
Plot[smoothstep[x], {x, -1, 1}]

enter image description here

I'd very much like to find a non-piecewise expression for this - i.e., a single algebraic expression (which I realise will likely contain infinities).

Is it possible to use Mathematica to find such an expression? I tried obtaining an approximation with

interp = InterpolatingPolynomial[{{-10, 0}, 
   {-9, 0, 0}*{-8, 0, 0}, {-7, 0, 0}*{-6, 0, 0}, {-5, 0, 0}, 
   {-4, 0, 0}, {-3, 0, 0}, {-2, 0, 0}, {-1, 0, 0}, {0, 1/2}, 
   {1, 1, 0}, {2, 1, 0}, {3, 1, 0}, {4, 1, 0}, {5, 1, 0}, 
   {6, 1, 0}, {7, 1, 0}, {8, 1, 0}, {9, 1, 0}, {10, 1, 0}}, x]

but it produces a nonsense-plot:

enter image description here

Suggestions? Or can it simply not be done?

UPDATE

Both @Michael and @Thies provide excellent answers below. I have ticked @Michael's because it is more comprehensive, but both are correct and useful.

$\endgroup$
  • 2
    $\begingroup$ Looks like a logistic $\endgroup$ – corey979 Dec 21 '18 at 13:19
  • $\begingroup$ the difference is that logistic curves tend towards 0 and 1 rather than actually reaching those values at a specified value of x - hence the fact that the smooth step is piecewise... $\endgroup$ – Richard Burke-Ward Dec 21 '18 at 14:07
  • 1
    $\begingroup$ How smooth do you want your curve to be? How many derivatives should be continuous? Can you have a curve that is not piecewise but is actually equal to 0 and 1 away from the step? $\endgroup$ – Hugh Dec 21 '18 at 14:24
  • $\begingroup$ Ideally infinitely differentiable, and about as smooth as the piecewisesmoothstep function I gave in the OP. It doesn't have to be that curve, though... And I don't know the answer to whether it's possible. That's the main reason I'm asking the question! Thanks for your thought and input. $\endgroup$ – Richard Burke-Ward Dec 21 '18 at 15:00
  • 1
    $\begingroup$ I think you want a bump function, a function with compact support that is infinitely differentiable. Even more suiting seems to be a smooth function or Mollified version of a unit step. The article about smooth functions also has an example of a smooth unit step. I can write an answer if you need more details. $\endgroup$ – Thies Heidecke Dec 21 '18 at 15:06
2
$\begingroup$

Here's an "algebraic expression" using the same sort of smooth ($C^\infty$) transition function as @Thies's:

Plot[
 1/4 (2 + (-2 + 4 x)/
     Sqrt[(1 - 2 x)^2] + ((1 + 
         Sqrt[(-1 + 2 x)^2]/(1 - 2 x)) (1 + (1 + 2 x)/
          Sqrt[(1 + 2 x)^2]))/(1 + E^((8 x)/(-1 + 4 x^2)))),
 {x, -1, 1}]

enter image description here

Like @Thies's, it's not Mathematica-lly differentiable at the points where the function transitions to a constant, even though it is mathematically infinitely differentiable there. This is due to the way derivatives of Piecewise[] are handled in @Thies's and because mine has a divide-by-zero error.


Addendum. The only way I've figured out how to get a function that Mathematica will yield a symbolic derivative at the transition points is by overriding the differentiation operator. To make it numerically and symbolically efficient requires some work:

ClearAll[smoothstep,
  ss0, dss, idss,(* internal aux fns (smoothstep, derivative, internal derivative *)
  smoothstepExpand];
Block[{x},   (* because x is evaluated in some definitions *)
 ss0[x_] := 1/(1 + Exp[2/(2 x + 1) - 2/(1 - 2 x)]);  (* base expression *)
 dss[0, x_] = Piecewise[{  (* complete base function *)
    {ss0[x], -1/2 < x < 1/2},
    {1, x >= 1/2}}];
 smoothstep[x_?NumericQ] = dss[0, x];  (* function, limited to eval on numerical input *)
 (* idss[n,x] is the general n-th derivative, which has the form of an 
    inactivated Sum[] in terms of a DifferenceRoot[];
    idss[] is numerically unstable near x==1/2, but when simplified, behaves better;
    hence in dss[] below, which calls idss[], one sees Simplify@Activate@idss[n,y] *)
 idss[n_, x_] = Piecewise[{{D[ss0[x], {x, n}], -1/2 < x < 1/2}}];
 dss[n_, x_] := Block[{y},  (* called internally for a specific positive integer n *)
   dss[n, y_] = Simplify@Activate@idss[n, y]; (* memoize simplified symbolic derivative *)
   dss[n, x]];
 Derivative[n_Integer?Positive][smoothstep][x_?NumericQ] :=
   dss[n, x];  (* evaluate derivative at numeric input *)
 smoothstepExpand[expr_] := 
  expr /. {  (* expand smoothstep[], smoothstep'[] etc. into Piecewise expressions *)
    HoldPattern[smoothstep[x_]] :> dss[0, x],
    HoldPattern[Derivative[n_Integer?Positive][smoothstep][x0_]] :> 
     dss[n, x0]}
 ]

Plot[
 {smoothstep[x], smoothstep'[x]},
 {x, -1, 1}]

enter image description here

$\endgroup$
6
$\begingroup$

You want a smooth function or bump function, a function with compact support which is infinitely differentiable. An example for a smooth unit step given in the Wikipedia article is

f[x_] := Boole[x > 0] Exp[-1/x]
g[x_] := f[x] / (f[x] + f[1-x])

Plot[g[x], {x, -0.1, 1.1}]

smooth step

An equivalent definition is

g[x]//PiecewiseExpand//FullSimplify

Piecewise[{
  {0, x <= 0},
  {1/(1+Exp[1/x - 1/(1-x)]), 0 < x < 1},
  {1, True}}
]
$\endgroup$
2
$\begingroup$

Try Tanh[x]

Plot[{smoothstep[x], (1 + Tanh[x 5])/2}, {x, -1, 1}]

enter image description here

$\endgroup$
  • $\begingroup$ Thanks @Ulrich but this is asymptotic again... $\endgroup$ – Richard Burke-Ward Dec 21 '18 at 22:38
1
$\begingroup$

I don't know know if you like this any better, but I'm not sure what you have against Piecewise. You can convert to UnitStep with:

smoothstep[x_] =  Simplify`PWToUnitStep@ Piecewise[{{0, 
     x <= -(1/2)}, {-20*(x + 1/2)^7 + 70*(x + 1/2)^6 - 
      84*(x + 1/2)^5 + 35*(x + 1/2)^4, -(1/2) < x < 1/2}, {1,  x >= 1/2}}]
(*1/16 (-(320 x^7) + 336 x^5 - 140 x^3 + 35 x + 8) (1 -  UnitStep[-x - 1/2]) (1 - UnitStep[x - 1/2]) + UnitStep[x - 1/2]*)

The plots of the function and its derivatives look the same as original.

$\endgroup$
  • $\begingroup$ I'd like to mark more than one answer as 'correct' - how do I do that? $\endgroup$ – Richard Burke-Ward Dec 27 '18 at 10:39
  • $\begingroup$ I don't think that that is possible. $\endgroup$ – Bill Watts Dec 27 '18 at 20:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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