問題2.34 Hornerの方法についての補足

SICP読書会でHornerの方法を実装する問題をやったあと、これが何の役に立つのか?という話をしたのだけど、いまいちな説明だったように思うので文章で補足してみる。
前提知識は、以下3つくらいのつもり。

Hornerの方法とは何か

Hornerの方法とは、一元n次多項式を計算するときの簡単な(計算量の少ない)算法である。

という多項式の値は次のように計算してもよいはずだ。

これがHornerの方法である。
さて、計算量が少ないと言ったが、どの程度少ないのであろうか。
まず馬鹿正直にを計算してみよう。
を計算するのに、n回の足し算が必要である。
次に馬鹿正直にk次の項:を計算するには(k+1)回の掛け算が必要だ。
従って、n次多項式を計算するには、
回の掛け算が必要になる。

であるが、Σの計算は前提知識としていないので、Σの公式に頼らず計算する。を逆順に書いても総和は変わらないので、

各項を縦に足すと、



である。
以上によりの計算量オーダーはとなる*1。

一方、Hornerの方法を使う場合、自明にn回の掛け算とn回の足し算が必要なので、計算量オーダーはとなる。もちろんこれはよりもかなり早い。

他方、馬鹿正直にk次の項でk+1回の掛け算を行わず、逐次平方してやることによりk次の項の計算オーダーをで評価することもできる。
この場合、掛け算のオーダーは、


これの評価はちょっと悩むが、なので、


と大雑把に上限と下限を見積もってやることはできる。従って逐次平方する場合の計算オーダーはであるが、これはより大きく、よりは小さい。

何の役に立つか?

たとえば、ハッシュテーブルを実装するには文字列からハッシュ値を求める必要があり、ハッシュ値を求めるハッシュ関数として使うことができる。
これについては以前、Cでハッシュテーブルを作ってみたで書いたのでそちらを参照のこと。(これはつまり、長さnの文字列をx進数の多倍長整数とみなして、その値を求めるのに、n次多項式の値を求めるHornerの方法を使えるということである)
なお、文字列の情報を切り捨てないハッシュ関数は、文字列の長さをnとすれば少なくとものオーダーになると考えられるので、Hornerの方法によるハッシュ関数は計算オーダーとしては比較的素性がよいものと言える気がする。

*1:固定長の整数や浮動小数点数演算のように加算乗算のコストが一定な場合。以下同じ