A short note on the generalized “smoothstep” function.

August 29, 2017

The Wikipedia page on Renderman’s “smoothstep” function,

\mathrm{smoothstep}(x)=3x^2-2x^3

features an entry on higher-order generalizations of this function, where each succeeding member has more of its higher order derivatives being set to zero at the endpoints 0 and 1.

Among other things, a formula for these generalized functions is presented, which I find rather unwieldy. I have thus written this short entry to present a much conceptually simpler formula.

One can use e.g. confluent divided differences to derive the following (IMNSHO cleaner) formula for n-th order smoothstep \mathrm{S}_n(x):

\displaystyle \mathrm{S}_n(x)=x^{n+1}\sum\limits_{k=0}^n\binom{n+k}{k}(1-x)^k

Here is a Mathematica demonstration of this identity for the first 21 members:

And @@ Table[InterpolatingPolynomial[{PadRight[{{0}, 0}, n + 2],
                                      PadRight[{{1}, 1}, n + 2]}, x] ==
             x^(n + 1) Sum[Binomial[n + k, k] (1 - x)^k, {k, 0, n}]
             // Simplify, {n, 0, 20}]

which should yield True.

In implementations for other languages (e.g. C++, JavaScript), one would want to use a suitable modification of Horner’s rule to evaluate the polynomial factor expressed in terms of 1-x, as well as exploiting the recurrence

\dbinom{n+k+1}{k+1}=\left(1+\dfrac{n}{k+1}\right)\dbinom{n+k}{k}

for generating the coefficients.

Advertisements

FNV hashing in Mathematica

May 4, 2012

I recently needed to do Fowler/Noll/Vo hashing in Mathematica. I figured other people might have a need for this hash function as well, so here’s my Mathematica implementation:

(* FNV hash parameters: bit length, FNV prime, FNV offset *)
$FNVData = Append[#, Function[{bi, pr},
Fold[BitXor[Mod[pr #1, 2^bi], #2] &, 0,
ToCharacterCode["chongo /\\../\\"]]] @@ #] & /@ Transpose[{2^Range[5, 10],
2^(8 Quotient[2^Range[5, 10] + 5, 12]) + 2^8 +
Map[FromDigits[#, 16] &,
{"93", "B3", "3B", "63", "57", "8D"}]}];


FNV[dat_String, bi : _Integer : 32, shift : (0 | 1) : 1] := With[{k = IntegerExponent[bi, 2] - 4},
Fold[BitXor[Mod[$FNVData[[k, 2]] #1, 2^bi], #2] &,
shift $FNVData[[k, 3]], ToCharacterCode[dat]]] /;
32 <= bi <= 1024 && BitAnd[bi, bi - 1] == 0

I made sure to provide for both shift-1 and shift-0 versions in the implementation (though as mentioned on the FNV page, FNV-1 is what should be preferred). The FNV page has a few suggestions to extend FNV hashing to bit lengths that are not a power of two, but I did not bother with them. (Maybe somebody else can try!) It should not be too hard to modify the code to do FNV-1a hashing.


questions, questions

August 13, 2010

I really should be getting around to posting something with actual mathematical content in this blog, but for now I’m slowly working through my backlog of my “dumb questions”; and there were quite a lot of them scattered around in my handwritten notes and an assorted bunch of my Mathematica notebook experiments. Thus far, my technique of asking my dumb questions at MathOverflow (and to a lesser extent at “Math Underflow“) seems to be working: if they get downvoted, then they’re definitely dumb.

In at least two separate occasions, some of the answers I got led me to useful new ideas, though not necessarily related to the original question(s) I asked. I guess that’s something. :)

Once I sort myself out, I’ll start posting about my experiments.

Happy trails!

\Jan