組立除法の(意外な)使い道
・関数値 - 記数法の計算、平均変化率、定積分
・微分係数 - 多項式のテイラー展開、ニュートン法による代数方程式の求根
これらを用いるシーンで利用できる。
その一例をコーディングしてみました。
!●記数法の計算
LET N=5 !桁数
DATA 1,1,0,1,0,1 !2進法 110101
DIM A2(0 TO N),Q2(0 TO N)
FOR i=N TO 0 STEP -1
READ A2(i)
NEXT i
CALL poly_divByLin(A2,2, Q2,R) !p(x)/(x-2)
PRINT R !10進法
!●多項式のテイラー展開
LET N=4 !次数
DATA 1,-2,-20,23,13 !x^4-2*x^3-20*x^2+23*x+13
DATA 5 !x=a
DIM A(0 TO N) !係数
FOR i=N TO 0 STEP -1
READ A(i)
NEXT i
READ v
DIM Q(0 TO N),AA(0 TO N) !作業用
MAT AA=A
FOR i=0 TO N-1 !Σf[k](a)/k!*(x-a)^k
CALL poly_divByLin(AA,v, Q,R) !k階微分係数 ※<----------
PRINT R;" * ( x -";v;") ^";i
MAT AA=Q !次へ
NEXT i
PRINT Q(0);" * ( x -";v;") ^";N
!●代数方程式の根をニュートン法で求める(関数値、微分係数)
LET cEps=1e-10 !精度 ※要調整
LET N=3 !次数
DATA 1,-2,0,-9 !x^3-2*x^2-9=(x-3)*(x^2+x+3)
LET Xk=2 !近似根
DIM A3(0 TO N),Q3(0 TO N),QQ3(0 TO N)
FOR i=N TO 0 STEP -1
READ A3(i)
NEXT i
LET iter=200 !反復回数
FOR k=1 TO iter
CALL poly_divByLin(A3,Xk, Q3,f) !関数値※<----------
CALL poly_divByLin(Q3,Xk, QQ3,df) !微分係数 ※<----------
LET WXk=Xk-f/df !Xk+1=Xk-f(Xk)/f'(Xk)
IF ABS(WXk-Xk)<=ABS(Xk)*cEps THEN EXIT FOR !収束すれば終了
LET Xk=WXk !次へ
NEXT k
IF k>iter THEN
PRINT iter;"回では収束しません。"
STOP
END IF
PRINT USING "## ##.###############": k,Xk
END
!補助ルーチン
!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!演算関連
EXTERNAL FUNCTION poly_degree(A()) !次数を得る
FOR i=UBOUND(A) TO 1 STEP -1
IF A(i)<>0 THEN EXIT FOR !係数が0でない最初の位置
NEXT i
LET poly_degree=i
END FUNCTION
EXTERNAL SUB poly_divByLin(A(),v, Q(),R) !多項式a(x)をx-αで割ったときの商q(x)と余りrを求める
MAT Q=ZER
LET s=0
FOR i=poly_degree(A) TO 0 STEP -1 !ホーナーの方法
LET Q(i)=s !※「係数にxを掛けて次の係数を加える」が組立除法になる
LET s=s*v+A(i) !(…(((An*X+An-1)*X+An-2)*X+An-3)*X+…+A1)*X+A0
NEXT i
LET R=s
END SUB