arXiv探訪

興味の赴くままに数学するだけ

Smoothstep関数

多項式は単純に見えるが奥が深い。今回紹介するSmoothstep関数を用いると、代数的な式で点同士を(程よく)滑らかに繋ぐことができる。線型補間(Linear Interpolation)では変化が急すぎて辛いときに便利で、ゲーム等で用いられる地形生成などを陰で支えている。*1

定義

一般に定義してもいいが、正規化したものだけを考える。整数{ k\ge 0 }に対して{ 2k+1 }次のSmoothstep関数とは、{ f(0)=0, f(1)=1 }なる多項式{ f }であって

{ f^{(1)}(0)=\dotsb =f^{(k)}(0)=f^{(1)}(1)=\dotsb = f^{(k)}(1)=0 }

を満たすものを言う。以下に{ k }が小さいときの具体的な式を挙げれば

{ \displaystyle \begin{align*} k=0 &\qquad f(x)=x \\ k=1 &\qquad f(x)=-2x^{3}+3x^{2} \\ k=2 &\qquad f(x)=6x^{5}-15x^{4}+10x^{3} \\ k=3 &\qquad f(x)=-20x^{7}+70x^{6}-84x^{5}+35x^{4} \\ k=4 &\qquad f(x)=70x^{9}-315x^{8}+540x^{7}-420x^{6}+126x^{5} \\ \vdots &\qquad \vdots \end{align*} }

となる。特に{ k=0 }のときは線型補間そのものなので、この拡張だと思っても良い。

f:id:mathmathniconico:20160228014545p:plain

愚直に計算してみる

取りあえず{ f(0)=f^{(1)}(0)=\dotsb =f^{(k)}(0)=0 }なので、{ f(x)=x^{k+1}g(x) }と書き直す。

{ g(x)=b_{k}(x-1)^{k}+b_{k-1}(x-1)^{k-1}+\dotsb + b_{0} }

と展開すれば、まず{ 1=f(1)=g(1)=b_{0} }である。また{ 1\le n\le k }に対しライプニッツ則より

{ \displaystyle f^{(n)}(x)=\sum_{j=0}^{n}\frac{n!}{j!(n-j)!}(k+1)_{j}x^{k+1-j}g^{(n-j)}(x) }

となる。ただし{ (k+1)_{j} }はポッホハンマー記号で、{ (\alpha)_{0}:=1, (\alpha)_{m}:=\alpha (\alpha-1)\dotsm (\alpha-m+1) }と定める。{ x=1 }と置けば二項係数を用いて

{ \displaystyle 0=\sum_{j=0}^{n}\frac{(k+1)_{j}}{j!}b_{n-j}=\sum_{j=0}^{n} \,_{k+1}C_{j}\cdot b_{n-j} }

を得る。行列で書き下せば、

{ \displaystyle \left( \begin{matrix} _{k+1}C_{0} & _{k+1}C_{1} & \dots & _{k+1}C_{k-1} & _{k+1}C_{k} \\ & _{k+1}C_{0} & \dots & _{k+1}C_{k-2}& _{k+1}C_{k-1} \\ & & & \vdots & \vdots \\ & & & _{k+1}C_{0} & _{k+1}C_{1} \\ & & &  & _{k+1}C_{0} \end{matrix} \right) \left( \begin{matrix} b_{k} \\ b_{k-1} \\ \vdots \\ b_{1} \\ b_{0} \end{matrix} \right)=\left( \begin{matrix} 0 \\ 0 \\ \vdots \\ 0 \\ 1 \end{matrix} \right) }

となる。微妙に見たことありそうで無いが、逆行列は小さい順に

{ \displaystyle \begin{align*} \left( \begin{matrix} 1 & 2 \\ & 1 \end{matrix} \right)^{-1} &=\left( \begin{matrix} 1 & -2 \\ & 1 \end{matrix} \right), \\ \left( \begin{matrix} 1 & 3 & 3 \\ & 1 & 3 \\ & & 1 \end{matrix} \right)^{-1} &=\left( \begin{matrix} 1 & -3 & 6 \\ & 1 & -3 \\ & & 1 \end{matrix} \right), \\ 
\left( \begin{matrix} 1 & 4 & 6 & 4 \\ & 1 & 4 & 6 \\ & & 1 & 4 \\ & & & 1\end{matrix} \right)^{-1} &=\left( \begin{matrix} 1 & -4 & 10 & -20 \\ & 1 & -4 & 10 \\ & & 1 & -4 \\ & & & 1 \end{matrix} \right), \\ \left( \begin{matrix} 1 & 5 & 10 & 10 & 5 \\ & 1 & 5 & 10 & 10 \\ & & 1 & 5 & 10 \\ & & & 1 & 5 \\ & & & & 1 \end{matrix} \right)^{-1} &=\left( \begin{matrix} 1 & -5 & 15 & -35 & 70 \\ & 1 & -5 & 15 & -35 \\ & & 1 & -5 & 15 \\ & & & 1 & -5 \\ & & & & 1 \end{matrix} \right), \dotsc \end{align*} }

と計算できる。一番右上の数字が求めたい{ f }の最高次係数にちゃんとなっていることを確認できる。次は予想なので誰か証明して下さい。

予想 { b_{n} }は、組{ p=(p_{i}) }{ n }の分割({ p_{i}\ge 0, \sum p_{i}=n })全体を動くとき、

{ \displaystyle (-1)^{|p|}\prod_{i} \, _{k+1}C_{p_{i}} }

の総和となる。

例えば{ k=4, n=4 }のとき、{ n }の分割は{ (4), (3, 1), (2, 2), (2, 1, 1), (1, 1, 1, 1) }であり、その重複度は{ 1, 2, 1, 3, 1 }なので

{ b_{4}=-C_{4}+2C_{3}C_{1}+C_{2}^{2}-3C_{2}C_{1}^{2}+C_{1}^{4}=-5+100+100-750+625=70 }

を得る。({ C_{j}:=\, _{5}C_{j} }

積分表示を求めてみる

明示的に{ f }を表示することが難しくても、積分表示を求めることは簡単にでき、多項式なので頑張れば計算もできる。条件より{ f^{(1)}(x)=ax^{k}(x-1)^{k} }と表すことが出来る。よってこれを積分して

{ \displaystyle f(x)=a\int_{0}^{x}t^{k}(t-1)^{k}\mathrm{d}t+b }

が求める積分表示である。ベータ関数{ B(p, q) }を思い出せば

{ \displaystyle \begin{align*} \int_{0}^{1}t^{k}(t-1)^{k}\mathrm{d}t =& (-1)^{k}\int_{0}^{1}t^{k}(1-t)^{k}\mathrm{d}t =(-1)^{k}B(k+1, k+1) \\ =& (-1)^{k}\frac{\Gamma (2k+2)}{\Gamma (k+1)\Gamma (k+1)}=(-1)^{k}\frac{(2k+1)!}{(k!)^{2}} \end{align*} }

が分かる。{ f(0)=0, f(1)=1 }より

{ \displaystyle f(x)=(-1)^{k}\frac{(k!)^{2}}{(2k+1)!}\int_{0}^{x}t^{k}(t-1)^{k}\mathrm{d}t }

が従う。

ちなみに、この表示から適当な{ k }に対し

{ \displaystyle f^{(1)}(x)=(-1)^{k}\frac{(k!)^{2}}{(2k+1)!}x^{k}(x-1)^{k}, f^{(2)}(x)=(-1)^{k}\frac{(k!)^{2}}{(2k+1)!}x^{k-1}(x-1)^{k-1}(2x-1) }

が分かるので、{ f }の増減等は直ぐに分かる。特に{ f^{(1)} }{ \frac{1}{2} }を中心とした偶関数になるので、

{ \displaystyle 2f\left(\frac{1}{2}\right) = 2\int_{0}^{\frac{1}{2}}f^{(1)}(t)\mathrm{d}t=\int_{0}^{1}f^{(1)}(t)\mathrm{d}t=f(1)=1 }

つまり{ f(\frac{1}{2})=\frac{1}{2} }を得る。

参考文献

グラフはhttp://graph.tk/で生成しました。

*1:関係あるかどうかは分からないが、Minecraftが類似物の多い中でも流行った理由の一つに、自然な地形生成の良さがあったのではないかなぁと個人的には思う。