ynの値を直接計算する方法を考える。
ynについては、以下のような式が成り立つ。
(1) y2n=2ynyn+1−ayn2 (2) y2n+1=yn+12+byn2 (3) y2n+2=ayn+12+2bynyn+1
n番目と n+1番目から2n番目、2n+1番目、2n+2番目が生成されるということで、
以前、べき乗計算のときに使った、nを2進数に展開して、各桁のビットに応じて処理を行う、
という手法が使えそうである。
23を例に考えてみよう。
奇数番目を生成する式は、(2)しかない。
y23=y12+y11
つまり、12番目と11番目を計算しておく必要がある。
次に、11番目は奇数番目なので、生成する式は、(2)しかない。
y11=y6+y5
12番目をこの6番目と5番目から生成するには、(3)の式を使えばよい。
次に、5番目は奇数番目なので、生成する式は、(2)しかない。
y5=y3+y2
6番目をこの3番目と2番目から生成するには、(3)の式を使えばよい。
次に、3番目は奇数番目なので、生成する式は、(2)しかない。
y3=y2+y1
2番目は、0番目と1番目から生成されるが、(1)式より、2番目と1番目からも計算できる。
以上の流れをまとめると、以下のようになる。
w0:0→(2)→1→(1)→2→(2)→5→(2)→11→(2)→23 w1:1→(3)→2→(2)→3→(3)→6→(3)→12→(3)→24
23=(10111)2と、式の選択を見比べると、以下のアルゴリズムでn番目を求められることがわかる。
プログラムは以下のとおり。
10 ' lucas sequence 20 ' y(0)=0, y(1)=1, y(n+1)=ay(n)+by(n-1) 30 fnYn1(N) 40 local I,A,B,W0,W1,Y0,Y1 50 dim W%(len(N)) 60 if N=0 then return(0) 70 if N=1 then return(1) 80 I=0 90 while N>0 100 inc I:W%(I)=N@2:N=N\2 110 wend 120 W%(0)=I 130 ' 140 A=1:B=1:Y0=0:Y1=1 150 for I=W%(0) to 1 step -1 160 if W%(I)=1 then W0=Y1^2+B*Y0^2:W1=A*Y1^2+2*B*Y0*Y1 170 if W%(I)=0 then W0=2*Y0*Y1-A*Y0^2:W1=Y1^2+B*Y0^2 180 Y0=W0:Y1=W1 190 next I 200 return(Y0)
0番目、1番目に対する例外処理は不要である。
また、UBASICでは、bit(i,n)により、nを2進展開したときの最下位からi番目のビットを取得できる。
これらを使って書き直すと以下のようになる。
10 ' lucas sequence 20 ' y(0)=0, y(1)=1, y(n+1)=ay(n)+by(n-1) 30 fnYn2(N) 40 local I,A,B,W0,W1,Y0,Y1 50 dim W%(len(N)) 60 A=1:B=1:Y0=0:Y1=1 70 for I=len(N)-1 to 0 step -1 80 if bit(I,N)=1 then W0=Y1^2+B*Y0^2:W1=A*Y1^2+2*B*Y0*Y1 90 if bit(I,N)=0 then W0=2*Y0*Y1-A*Y0^2:W1=Y1^2+B*Y0^2 100 Y0=W0:Y1=W1 110 next I 120 return(Y0)
前 | この章の目次 | 次 |
---|