Functions stepUp(), stepDown() and stepAny() provide smooth, S-shaped step functions that are useful for "softening" abrupt transitions between two values.
More...
|
double | SimTK::stepUp (double x) |
| Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval. More...
|
|
double | SimTK::stepDown (double x) |
| Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval. More...
|
|
double | SimTK::stepAny (double y0, double yRange, double x0, double oneOverXRange, double x) |
| Interpolate smoothly from y0 to y1 as the input argument goes from x0 to x1, with first and second derivatives zero at either end of the interval. More...
|
|
double | SimTK::dstepUp (double x) |
| First derivative of stepUp(): d/dx stepUp(x). More...
|
|
double | SimTK::dstepDown (double x) |
| First derivative of stepDown(): d/dx stepDown(x). More...
|
|
double | SimTK::dstepAny (double yRange, double x0, double oneOverXRange, double x) |
| First derivative of stepAny(): d/dx stepAny(x). More...
|
|
double | SimTK::d2stepUp (double x) |
| Second derivative of stepUp(): d^2/dx^2 stepUp(x). More...
|
|
double | SimTK::d2stepDown (double x) |
| Second derivative of stepDown(): d^2/dx^2 stepDown(x). More...
|
|
double | SimTK::d2stepAny (double yRange, double x0, double oneOverXRange, double x) |
| Second derivative of stepAny(): d^2/dx^2 stepAny(x). More...
|
|
double | SimTK::d3stepUp (double x) |
| Third derivative of stepUp(): d^3/dx^3 stepUp(x). More...
|
|
double | SimTK::d3stepDown (double x) |
| Third derivative of stepDown(): d^3/dx^3 stepDown(x). More...
|
|
double | SimTK::d3stepAny (double yRange, double x0, double oneOverXRange, double x) |
| Third derivative of stepAny(): d^3/dx^3 stepAny(x). More...
|
|
float | SimTK::stepUp (float x) |
| Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
More...
|
|
float | SimTK::stepDown (float x) |
| Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
More...
|
|
float | SimTK::stepAny (float y0, float yRange, float x0, float oneOverXRange, float x) |
| Interpolate smoothly from y0 to y1 as the input argument goes from x0 to x1, with first and second derivatives zero at either end of the interval.
More...
|
|
float | SimTK::dstepUp (float x) |
| First derivative of stepUp(): d/dx stepUp(x).
More...
|
|
float | SimTK::dstepDown (float x) |
| First derivative of stepDown(): d/dx stepDown(x).
More...
|
|
float | SimTK::dstepAny (float yRange, float x0, float oneOverXRange, float x) |
| First derivative of stepAny(): d/dx stepAny(x).
More...
|
|
float | SimTK::d2stepUp (float x) |
| Second derivative of stepUp(): d^2/dx^2 stepUp(x).
More...
|
|
float | SimTK::d2stepDown (float x) |
| Second derivative of stepDown(): d^2/dx^2 stepDown(x).
More...
|
|
float | SimTK::d2stepAny (float yRange, float x0, float oneOverXRange, float x) |
| Second derivative of stepAny(): d^2/dx^2 stepAny(x).
More...
|
|
float | SimTK::d3stepUp (float x) |
| Third derivative of stepUp(): d^3/dx^3 stepUp(x).
More...
|
|
float | SimTK::d3stepDown (float x) |
| Third derivative of stepDown(): d^3/dx^3 stepDown(x).
More...
|
|
float | SimTK::d3stepAny (float yRange, float x0, float oneOverXRange, float x) |
| Third derivative of stepAny(): d^3/dx^3 stepAny(x).
More...
|
|
double | SimTK::stepUp (int x) |
| Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval. More...
|
|
double | SimTK::stepDown (int x) |
| Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval. More...
|
|
Functions stepUp(), stepDown() and stepAny() provide smooth, S-shaped step functions that are useful for "softening" abrupt transitions between two values.
Functions that return the first three derivatives of these step functions are also provided.
y=stepUp(x) for x=0:1 returns a smooth, S-shaped step function y(x), symmetric about the midpoint x=0.5, such that y(0)=0, y(1)=1, y'(0)=y''(0)=y'(1)=y''(1)=0, where the primes indicate differentiation with respect to x. No guarantees are made about the behavior of higher derivatives except to say that y''' does exist.
y=stepDown(x) for x=0:1 is a mirror image S curve that takes y down from 1 to 0 smoothly as x goes from 0 to 1. As with stepUp() y' and y'' are 0 at both ends, but here y(0)=1 and y(1)=0.
The stepAny() function is also available to make a step function that takes y smoothly from y0 to y1 as x goes from x0 to x1.
We also provide functions that calculate the first three derivatives of stepUp(), stepDown(), and stepAny(), namely: dstepUp(), d2stepUp(), d3stepUp(), and similarly dstepDown(), dstepAny() and so on. Note again that the third derivative is not guaranteed to be well behaved.
Costs of the current implementations of these inline functions are:
The corresponding stepDown() methods cost one extra flop; the stepAny() methods cost 6 extra flops (provided you do some precalculation; see the stepAny() documentation).
◆ stepUp() [1/3]
double SimTK::stepUp |
( |
double |
x | ) |
|
|
inline |
Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | x | The control parameter, in range [0,1]. |
- Returns
- The smoothed output value, in range [0,1] but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
See the documentation for stepAny() for a discussion about how to shift and scale this function to produce arbitrary steps.
This function is overloaded for all the floating point precisions. Cost is 7 flops.
- See also
- stepDown(), stepAny()
◆ stepDown() [1/3]
double SimTK::stepDown |
( |
double |
x | ) |
|
|
inline |
Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | x | The control parameter, in range [0,1]. |
- Returns
- The smoothed output value, in range [1,0] but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
See the documentation for stepAny() for a discussion about how to shift and scale this function to produce arbitrary steps.
This function is overloaded for all the floating point precisions. Cost is 8 flops.
- See also
- stepUp(), stepAny()
◆ stepAny() [1/2]
double SimTK::stepAny |
( |
double |
y0, |
|
|
double |
yRange, |
|
|
double |
x0, |
|
|
double |
oneOverXRange, |
|
|
double |
x |
|
) |
| |
|
inline |
Interpolate smoothly from y0 to y1 as the input argument goes from x0 to x1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | y0 | The output value when x=x0. |
[in] | yRange |
The amount by which the output can change over the full interval, that is, yRange=(y1-y0) where y1 is the value of the output when x=x1. |
[in] | x0 |
The minimum allowable value for x. |
[in] | oneOverXRange | 1/xRange, where xRange is the amount by which the input variable x can change over its full interval, that is, xRange=(x1-x0) where x1 is the maximum allowable value for x. |
[in] | x |
The control parameter, in range [x0,x1]. This is often a time over which the output transition from y0 to y1 is to occur. |
- Returns
- The smoothed output value, in range [y0,y1] (where y1=y0+yRange) but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
Note that the desired curve is defined in terms of y0 and (y1-y0), and x0 and 1/(x1-x0), rather than y0,y1,x0,x1 which would make for a nicer calling signature. This is a concession to efficiency since the two ranges are likely to be unchanged during many calls to this function and can thus be precalculated. It wouldn't matter except that division is so expensive (equivalent to 15-20 floating point operations). If you aren't concerned about that (and in most cases it won't matter), you can call this function using y0,y1,x0,x1 like this:
y =
stepAny(y0,y1-y0,x0,1/(x1-x0), x);
Not counting the cost of calculating the ranges, each call to this function requires 13 flops. Calculating the ranges in the argument list as shown above raises the per-call cost to about 30 flops. However, there are many common special cases that are much simpler. For example, if y is to go from -1 to 1 while x goes from 0 to 1, then you can write:
which is still only 13 flops despite the lack of pre-calculation.
- Theory
stepUp() and stepDown() and their derivatives are defined only for arguments in the range 0 to 1. To create a general step function that smoothly interpolates from y=y0 to y1 while x goes from x0 to x1, and three derivatives, we use the stepUp() functions like this:
ooxr = 1/(x1-x0);
yr = y1-y0;
xadj = (x-x0)*ooxr
As a common special case, note that when y has a general range but x is still in [0,1], the above simplifies considerably and you can save a few flops if you want by working with stepUp() or stepDown() directly. For example, in the common case where you want y to go from -1 to 1 as x goes from 0 to 1:
It would be extremely rare for these few flops to matter at all; you should almost always choose based on what looks better and/or is less error prone instead.
◆ dstepUp() [1/2]
double SimTK::dstepUp |
( |
double |
x | ) |
|
|
inline |
First derivative of stepUp(): d/dx stepUp(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- First derivative of stepUp() at x.
◆ dstepDown() [1/2]
double SimTK::dstepDown |
( |
double |
x | ) |
|
|
inline |
First derivative of stepDown(): d/dx stepDown(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- First derivative of stepDown() at x.
◆ dstepAny() [1/2]
double SimTK::dstepAny |
( |
double |
yRange, |
|
|
double |
x0, |
|
|
double |
oneOverXRange, |
|
|
double |
x |
|
) |
| |
|
inline |
◆ d2stepUp() [1/2]
double SimTK::d2stepUp |
( |
double |
x | ) |
|
|
inline |
Second derivative of stepUp(): d^2/dx^2 stepUp(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Second derivative of stepUp() at x.
◆ d2stepDown() [1/2]
double SimTK::d2stepDown |
( |
double |
x | ) |
|
|
inline |
Second derivative of stepDown(): d^2/dx^2 stepDown(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Second derivative of stepDown() at x.
◆ d2stepAny() [1/2]
double SimTK::d2stepAny |
( |
double |
yRange, |
|
|
double |
x0, |
|
|
double |
oneOverXRange, |
|
|
double |
x |
|
) |
| |
|
inline |
Second derivative of stepAny(): d^2/dx^2 stepAny(x).
See stepAny() for parameter documentation.
- Returns
- Second derivative of stepAny() at x.
◆ d3stepUp() [1/2]
double SimTK::d3stepUp |
( |
double |
x | ) |
|
|
inline |
Third derivative of stepUp(): d^3/dx^3 stepUp(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Third derivative of stepUp() at x.
◆ d3stepDown() [1/2]
double SimTK::d3stepDown |
( |
double |
x | ) |
|
|
inline |
Third derivative of stepDown(): d^3/dx^3 stepDown(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Third derivative of stepDown() at x.
◆ d3stepAny() [1/2]
double SimTK::d3stepAny |
( |
double |
yRange, |
|
|
double |
x0, |
|
|
double |
oneOverXRange, |
|
|
double |
x |
|
) |
| |
|
inline |
Third derivative of stepAny(): d^3/dx^3 stepAny(x).
See stepAny() for parameter documentation.
- Returns
- Third derivative of stepAny() at x.
◆ stepUp() [2/3]
float SimTK::stepUp |
( |
float |
x | ) |
|
|
inline |
Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | x | The control parameter, in range [0,1]. |
- Returns
- The smoothed output value, in range [0,1] but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
See the documentation for stepAny() for a discussion about how to shift and scale this function to produce arbitrary steps.
This function is overloaded for all the floating point precisions. Cost is 7 flops.
- See also
- stepDown(), stepAny()
◆ stepDown() [2/3]
float SimTK::stepDown |
( |
float |
x | ) |
|
|
inline |
Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | x | The control parameter, in range [0,1]. |
- Returns
- The smoothed output value, in range [1,0] but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
See the documentation for stepAny() for a discussion about how to shift and scale this function to produce arbitrary steps.
This function is overloaded for all the floating point precisions. Cost is 8 flops.
- See also
- stepUp(), stepAny()
◆ stepAny() [2/2]
float SimTK::stepAny |
( |
float |
y0, |
|
|
float |
yRange, |
|
|
float |
x0, |
|
|
float |
oneOverXRange, |
|
|
float |
x |
|
) |
| |
|
inline |
Interpolate smoothly from y0 to y1 as the input argument goes from x0 to x1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | y0 | The output value when x=x0. |
[in] | yRange |
The amount by which the output can change over the full interval, that is, yRange=(y1-y0) where y1 is the value of the output when x=x1. |
[in] | x0 |
The minimum allowable value for x. |
[in] | oneOverXRange | 1/xRange, where xRange is the amount by which the input variable x can change over its full interval, that is, xRange=(x1-x0) where x1 is the maximum allowable value for x. |
[in] | x |
The control parameter, in range [x0,x1]. This is often a time over which the output transition from y0 to y1 is to occur. |
- Returns
- The smoothed output value, in range [y0,y1] (where y1=y0+yRange) but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
Note that the desired curve is defined in terms of y0 and (y1-y0), and x0 and 1/(x1-x0), rather than y0,y1,x0,x1 which would make for a nicer calling signature. This is a concession to efficiency since the two ranges are likely to be unchanged during many calls to this function and can thus be precalculated. It wouldn't matter except that division is so expensive (equivalent to 15-20 floating point operations). If you aren't concerned about that (and in most cases it won't matter), you can call this function using y0,y1,x0,x1 like this:
y =
stepAny(y0,y1-y0,x0,1/(x1-x0), x);
Not counting the cost of calculating the ranges, each call to this function requires 13 flops. Calculating the ranges in the argument list as shown above raises the per-call cost to about 30 flops. However, there are many common special cases that are much simpler. For example, if y is to go from -1 to 1 while x goes from 0 to 1, then you can write:
which is still only 13 flops despite the lack of pre-calculation.
- Theory
stepUp() and stepDown() and their derivatives are defined only for arguments in the range 0 to 1. To create a general step function that smoothly interpolates from y=y0 to y1 while x goes from x0 to x1, and three derivatives, we use the stepUp() functions like this:
ooxr = 1/(x1-x0);
yr = y1-y0;
xadj = (x-x0)*ooxr
As a common special case, note that when y has a general range but x is still in [0,1], the above simplifies considerably and you can save a few flops if you want by working with stepUp() or stepDown() directly. For example, in the common case where you want y to go from -1 to 1 as x goes from 0 to 1:
It would be extremely rare for these few flops to matter at all; you should almost always choose based on what looks better and/or is less error prone instead.
◆ dstepUp() [2/2]
float SimTK::dstepUp |
( |
float |
x | ) |
|
|
inline |
First derivative of stepUp(): d/dx stepUp(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- First derivative of stepUp() at x.
◆ dstepDown() [2/2]
float SimTK::dstepDown |
( |
float |
x | ) |
|
|
inline |
First derivative of stepDown(): d/dx stepDown(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- First derivative of stepDown() at x.
◆ dstepAny() [2/2]
float SimTK::dstepAny |
( |
float |
yRange, |
|
|
float |
x0, |
|
|
float |
oneOverXRange, |
|
|
float |
x |
|
) |
| |
|
inline |
◆ d2stepUp() [2/2]
float SimTK::d2stepUp |
( |
float |
x | ) |
|
|
inline |
Second derivative of stepUp(): d^2/dx^2 stepUp(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Second derivative of stepUp() at x.
◆ d2stepDown() [2/2]
float SimTK::d2stepDown |
( |
float |
x | ) |
|
|
inline |
Second derivative of stepDown(): d^2/dx^2 stepDown(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Second derivative of stepDown() at x.
◆ d2stepAny() [2/2]
float SimTK::d2stepAny |
( |
float |
yRange, |
|
|
float |
x0, |
|
|
float |
oneOverXRange, |
|
|
float |
x |
|
) |
| |
|
inline |
Second derivative of stepAny(): d^2/dx^2 stepAny(x).
See stepAny() for parameter documentation.
- Returns
- Second derivative of stepAny() at x.
◆ d3stepUp() [2/2]
float SimTK::d3stepUp |
( |
float |
x | ) |
|
|
inline |
Third derivative of stepUp(): d^3/dx^3 stepUp(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Third derivative of stepUp() at x.
◆ d3stepDown() [2/2]
float SimTK::d3stepDown |
( |
float |
x | ) |
|
|
inline |
Third derivative of stepDown(): d^3/dx^3 stepDown(x).
- Parameters
-
[in] | x | Control parameter in range [0,1]. |
- Returns
- Third derivative of stepDown() at x.
◆ d3stepAny() [2/2]
float SimTK::d3stepAny |
( |
float |
yRange, |
|
|
float |
x0, |
|
|
float |
oneOverXRange, |
|
|
float |
x |
|
) |
| |
|
inline |
Third derivative of stepAny(): d^3/dx^3 stepAny(x).
See stepAny() for parameter documentation.
- Returns
- Third derivative of stepAny() at x.
◆ stepUp() [3/3]
double SimTK::stepUp |
( |
int |
x | ) |
|
|
inline |
Interpolate smoothly from 0 up to 1 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | x | The control parameter, in range [0,1]. |
- Returns
- The smoothed output value, in range [0,1] but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
See the documentation for stepAny() for a discussion about how to shift and scale this function to produce arbitrary steps.
This function is overloaded for all the floating point precisions. Cost is 7 flops.
- See also
- stepDown(), stepAny() Treats int argument as a double (avoids ambiguity).
◆ stepDown() [3/3]
double SimTK::stepDown |
( |
int |
x | ) |
|
|
inline |
Interpolate smoothly from 1 down to 0 as the input argument goes from 0 to 1, with first and second derivatives zero at either end of the interval.
- Parameters
-
[in] | x | The control parameter, in range [0,1]. |
- Returns
- The smoothed output value, in range [1,0] but with first and second derivatives smoothly approaching zero as x approaches either end of its interval.
See the documentation for stepAny() for a discussion about how to shift and scale this function to produce arbitrary steps.
This function is overloaded for all the floating point precisions. Cost is 8 flops.
- See also
- stepUp(), stepAny() Treats int argument as a double (avoids ambiguity).