7
$\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$
12
  • 2
    $\begingroup$ Looks like a logistic $\endgroup$
    – corey979
    Commented Dec 21, 2018 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$ Commented Dec 21, 2018 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
    Commented Dec 21, 2018 at 14:24
  • 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$ Commented Dec 21, 2018 at 15:06
  • 1
    $\begingroup$ This reminds me of my digital (discrete times controls course taken last century, where you can design a system with deadbeat response, i.e., a finite settling time. Might be worth a google for inspiration. $\endgroup$
    – MikeY
    Commented Dec 29, 2018 at 14:53

4 Answers 4

4
$\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$
1
  • $\begingroup$ For any interested, I think the core of this expression is basically 1/(1+E^(1/(a-1)+1/a)). $\endgroup$
    – Erhannis
    Commented Sep 1, 2022 at 21:00
8
$\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$
0
3
$\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$
2
  • $\begingroup$ I'd like to mark more than one answer as 'correct' - how do I do that? $\endgroup$ Commented Dec 27, 2018 at 10:39
  • $\begingroup$ I don't think that that is possible. $\endgroup$
    – Bill Watts
    Commented Dec 27, 2018 at 20:33
2
$\begingroup$

Try Tanh[x]

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

enter image description here

$\endgroup$
1
  • $\begingroup$ Thanks @Ulrich but this is asymptotic again... $\endgroup$ Commented Dec 21, 2018 at 22:38

Your Answer

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

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