投稿者:山中和義
投稿日:2013年 3月 2日(土)10時21分14秒
|
|
|
問題
nを任意の正の整数とする。
a≧b≧0、a+2b=n
を満たす整数の組(a,b)のそれぞれに対して、積abを考える。
その積のすべての和をf(n)とすると、f(n)をnの式で表せ。
答え
a≧bなので、n=a+2b≧(1+2)bより、1≦b≦[n/3]である。
Σab
=Σ[B=1,[N/3]](N-2B)B
=NΣ[B=1,[N/3]]B - 2Σ[B=1,[N/3]]B^2
=N{x(x+1)/2} - 2{x(x+1)(2x+1)/6} ただし、x=[N/3]
=x(x+1)(3N-2-4x)/6
または
=( -4x^3+3(N-2)x^2+(3N-2)x )/6
(終り)
FOR N=1 TO 50
PRINT "N="; N
LET S=0 !a≧b≧1として考える
FOR B=1 TO INT( N/(1+2) ) !n=a+2b≧(1+2)bより
LET A=N-2*B
IF A< B THEN STOP !論理エラー
PRINT A;B !題意を満たす
LET S=S+A*B
NEXT B
PRINT "積="; S
LET X=INT(N/3) !f(n)
!!PRINT X*(X+1)*(3*N-2-4*X)/6
PRINT ( -4*X^3+3*(N-2)*X^2+(3*N-2)*X )/6
NEXT N
END
問題
nを任意の正の整数とする。
a≧b≧c≧0、a+2b+3c=n
を満たす整数の組(a,b,c)のそれぞれに対して、積abcを考える。
その積のすべての和をf(n)とすると、f(n)をnの式で表せ。
考察
類題として問題文が展開ができるので、いくつか先を見ていくと、
漸化式を用いて、
FOR n=1 TO 60
PRINT n;":"; F2(n,INT(n/3)); F3(n,INT(n/6)); F4(n,INT(n/10)); F5(n,INT(n/15))
NEXT n
END
!a+2b=n、a≧b≧0、Σab=Σ[b=1,[n/3]]b*(n-2b)
EXTERNAL FUNCTION F2(n,k) !Σ[i=1,k]i(n-2i)
LET S=0
FOR i=1 TO k
LET S=S+i*(n-2*i)
NEXT i
LET F2=S
END FUNCTION
!a+2b+3c=n、a≧b≧c≧0、Σabc=Σ[c=1,[n/6]] c*{ Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) }
EXTERNAL FUNCTION F3(n,k)
LET S=0
FOR i=1 TO k
LET x=n-3*i
LET S=S+i*(F2(x,INT(x/3)) - F2(x,i-1))
NEXT i
LET F3=S
END FUNCTION
EXTERNAL FUNCTION F4(n,k)
LET S=0
FOR i=1 TO k
LET x=n-4*i
LET S=S+i*(F3(x,INT(x/6)) - F3(x,i-1))
NEXT i
LET F4=S
END FUNCTION
EXTERNAL FUNCTION F5(n,k)
LET S=0
FOR i=1 TO k
LET x=n-5*i
LET S=S+i*(F4(x,INT(x/10)) - F4(x,i-1))
NEXT i
LET F5=S
END FUNCTION
(終り)
Σabc=Σ[c=1,[n/6]] c*{ Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) } なので、
Σ[b=c,[(n-3c)/3]] b*((n-3c)-2b) の部分を、
a+2b=n の式 f(N)=( -4x^3+3(N-2)x^2+(3N-2)x )/6
のxに、[n/3]-c と c-1 を代入して求めると、
FOR N=1 TO 60
PRINT "N="; N
LET S=0 !a≧b≧c≧1として考える
FOR C=1 TO INT( N/(1+2+3) ) !n=a+2b+3c≧(1+2+3)cより
FOR B=C TO INT( (N-3*C)/(1+2) ) !n-3c=a+2b≧(1+2)bより
LET A=N-3*C-2*B
IF A< B THEN STOP !論理エラー
PRINT A;B;C !題意を満たす
LET S=S+A*B*C
NEXT B
NEXT C
PRINT "積="; S
LET y=INT(N/6) !f(n)
LET x=INT(N/3)
PRINT y*(y+1)* ( 16*y^3 +3*(5*x-2)*y^2 +(10*x^2 +5*(5-4*N)*x -14)*y -5*x*(4*x^2 +(5-3*N)*x -N+1) +4 )/60
NEXT N
END
a+2b+3c+4d=n、a≧b≧c≧d≧0 となると、手計算では難しい。。。
|
|
|
投稿者:山中和義
投稿日:2013年 3月 4日(月)13時15分20秒
|
|
|
> No.2993[元記事へ]
> 問題
> nを任意の正の整数とする。
> a≧b≧0、a+2b=n
> を満たす整数の組(a,b)のそれぞれに対して、積abを考える。
> その積のすべての和をf(n)とすると、f(n)をnの式で表せ。
答え
A=a-bとする。a≧bより、A≧0
また、A=(n-2b)-b=n-3b ∴A+3b=n
Σ[a+2b=n,a≧b≧0]ab
=Σ[A+3b=n,A≧0,b≧0](A+b)b
3b=n-A≦nより、b≦n/3なので、
=Σ[1≦b≦[n/3]](A+b)b ただし、A=n-3b
(終り)
FOR N=1 TO 50
PRINT "N="; N
LET S=0
FOR b=1 TO INT(N/3) !b≧1として考える
LET A=N-3*b
IF A<0 THEN STOP !論理エラー
PRINT A;b !題意を満たす
LET S=S+(A+b)*b
NEXT b
PRINT "積=";S
NEXT N
END
別解 母関数
(A+b)b=Ab+b^2なので、項Abと項b^2について考える。
項Abのf(n)に対する寄与をf(n:Ab)と表す。
f(n:Ab)の母関数Σ[k=0,∞]f(k:Ab)*x^kについて
f(n:Ab)は、
p[x]=0*1+1*x+2*x^2+3*x^3+4*x^4+5*x^5+6*x^6+7*x^7+ … =x/(1-x)^2
q[x]=0*1+1*x^3+2*x^6+3*x^9+4*x^12+5*x^15+6*x^18+7*x^21+ … =x^3/(1-x^3)^2
として、積pqを展開したときのx^nの係数になる。
よって、x/(1-x)^2 * x^3/(1-x^3)^2 をマクローリン展開したときのx^nの係数になる。
同様に
f(n:b^2)は、
p[x]=1+x+x^2+x^3+x^4+x^5+x^6+x^7+ … =1/(1-x)
q[x]=0^2*1+1^2*x^3+2^2*x^6+3^2*x^9+4^2*x^12+5^2*x^15+6^2*x^18+7^2*x^21+ … =(x^6+x^3)/(1-x^3)^3
として、積pqを展開したときのx^nの係数になる。
よって、1/(1-x) * (x^6+x^3)/(1-x^3)^3 をマクローリン展開したときのx^nの係数になる。
したがって、f(n)の母関数は、
Σ[k=0,∞]f(k)*x^k
=x^4/{(1-x)^2(1-x^3)^2} + (x^6+x^3)/{(1-x)(1-x^3)^3}
=x^3(2x^3+x^2+x+1)/{(1-x)(1-x^3)^3}
これをマクローリン展開したときのx^nの係数になる。、
(終り)
!マクローリン展開
! P(x)=P(0)+{P'(0)/1!}x+{P''(0)/2!}x^2+{P'''(0)/3!}x^3+ …
!例
!P(x)=1/(1-x)=1+x+x^2+x^3+x^4+ …
!
!考察
!P(0)は、x=0を代入して、1/(1-0)=1
!P'(0)は、
! P(x)=f(x)/g(x)より、P'=(f'g-fg')/g^2なので、
! 1'(1-x)-1(1-x)'/(1-x)^2=1/(1-x)^2
! x=0を代入して、1
!P''(0)は、
! P''(x)=(P'(x))'なので、
! 上記の結果をあらためて、f(x)=f'g-fg'、g(x)=g^2と考える。上記と同じ議論を繰り返す。
!(終り)
OPTION ARITHMETIC RATIONAL !有理数モード
PUBLIC NUMERIC N !次数
LET N=50
!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!「dim a(0 to n) !係数」で定義する
DIM P(0 TO N)
DIM F(0 TO N),G(0 TO N) !p=f/g
MAT F=ZER
MAT G=ZER
DATA 6 !次数 f=x^3(2x^3+x^2+x+1)=2*x^6+x^5+x^4+x^3 ※
DATA 0,0,0,1,1,1,2 !係数 ※展開して次数が小さい方から
READ R
FOR i=0 TO R
READ F(i)
NEXT i
!!!MAT PRINT F; !debug
CALL poly_disp(F) !多項式を表示する
PRINT
DATA 10 !次数 g=(1-x)(1-x^3)^3=x^10-x^9-3x^7+3x^6+3x^4-3x^3-x+1 ※
DATA 1,-1,0,-3,3,0,3,-3,0,-1,1 !係数 ※展開して次数が小さい方から
READ R
FOR i=0 TO R
READ G(i)
NEXT i
!!!MAT PRINT G; !debug
CALL poly_disp(G) !多項式を表示する
PRINT
LET P(0)=F(0)/G(0)/FACT(0) !定数項
PRINT 0; P(0) !debug
DIM F1(0 TO N),G1(0 TO N), W1(0 TO N),W2(0 TO N),W3(0 TO N) !作業用
FOR i=1 TO N !i階微分
CALL poly_diff(F,W3) !f'g
CALL poly_mul(W3,G, W1)
!!!MAT PRINT W1; !debug
CALL poly_diff(G,W3) !fg'
CALL poly_mul(F,W3, W2)
!!!MAT PRINT W2; !debug
CALL poly_sub(W1,W2, F1) !分子 f'g-fg'
!!!MAT PRINT F1; !debug
CALL poly_mul(G,G, G1) !分母 g^2
!!!MAT PRINT G1; !debug
LET P(i)=F1(0)/G1(0)/FACT(i) !x^iの係数
PRINT i; P(i) !debug
MAT F=F1 !次へ
MAT G=G1
NEXT i
CALL poly_disp(P) !多項式を表示する
PRINT
END
!変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
!「dim a(0 to n) !係数」で定義する
!演算関連
EXTERNAL SUB poly_add(v1(),v2(), v()) !加算 v=v1+v2
OPTION ARITHMETIC RATIONAL !有理数モード
MAT v=v1+v2
END SUB
EXTERNAL SUB poly_sub(v1(),v2(), v()) !減算 v=v1-v2
OPTION ARITHMETIC RATIONAL !有理数モード
MAT v=v1-v2
END SUB
EXTERNAL SUB poly_mul(v1(),v2(), v()) !乗算 v=v1*v2
OPTION ARITHMETIC RATIONAL !有理数モード
DIM w(0 TO 2*N) !桁数は2倍になる
MAT w=ZER
FOR i=0 TO N !係数
FOR j=0 TO N
LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
NEXT j
NEXT i
FOR i=0 TO N !※下n桁をコピーする ※オーバーフローは考慮していない
LET v(i)=w(i)
NEXT i
END SUB
EXTERNAL SUB poly_diff(v1(), v()) !微分 v=v1'
OPTION ARITHMETIC RATIONAL !有理数モード
FOR i=1 TO N
LET v(i-1)=v1(i)*i
NEXT i
LET v(N)=0
END SUB
!表示関連
EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
OPTION ARITHMETIC RATIONAL !有理数モード
CALL mono_disp(A(N),N)
FOR i=N-1 TO 0 STEP -1 !次項
LET w=A(i)
IF w>0 THEN PRINT "+";
IF w<>0 OR N=0 THEN CALL mono_disp(w,i)
NEXT i
END SUB
EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
OPTION ARITHMETIC RATIONAL !有理数モード
IF k<>0 THEN !x^nで
IF ak=0 OR ak=1 THEN !係数が0,1なら
ELSEIF ak=-1 THEN !係数が-1なら
PRINT "-"; !符号
ELSE
PRINT STR$(ak);"*";
END IF
END IF
IF k=0 THEN !次数が0なら
PRINT STR$(ak);
ELSEIF k=1 THEN !次数が1なら
PRINT "X";
ELSE
IF ak<>0 THEN PRINT "X^";STR$(k); !係数が0以外なら
END IF
END SUB
|
|
|
投稿者:山中和義
投稿日:2013年 3月 5日(火)13時15分2秒
|
|
|
> No.3009[元記事へ]
> 問題
> nを任意の正の整数とする。
> a≧b≧c≧0、a+2b+3c=n
> を満たす整数の組(a,b,c)のそれぞれに対して、積abcを考える。
> その積のすべての和をf(n)とすると、f(n)をnの式で表せ。
答え
A=a-b、B=b-cとする。a≧b≧cより、A≧0、B≧0
また、A=(n-3c-2b)-b=n-3c-3b=n-3(b-c)-6c=n-3B-6c ∴A+3B+6c=n
Σ[a+2b+3c=n,a≧b≧c≧0]abc
=Σ[A+3B+6c=n,A≧0,B≧0,c≧0](A+B+c)(B+c)c
(終り)
FOR N=1 TO 50
PRINT "N="; N
LET S=0
FOR c=1 TO INT(N/6) !c≧1として考える
FOR B=0 TO INT((N-6*c)/3) !B≧0として考える
LET A=N-6*c-3*B
IF A<0 THEN STOP !論理エラー
PRINT A;B;c !題意を満たす
LET S=S+(A+B+c)*(B+c)*c
NEXT B
NEXT c
PRINT "積=";S
NEXT N
END
別解 母関数
(A+B+c)(B+c)c=(AB+B^2)c+(A+2B)c^2+c^3である。
項ABcのf(n)に対する寄与をf(n:ABc)と表す。
変数1a,A,1b,B,B^2,c,c^2,c^3に相当するxの多項式は、
1a =1+x+x^2+x^3+x^4+x^5+x^6+x^7+ … =1/(1-x)
A =0*1+1x+2x^2+3x^3+4x^4+5x^5+6x^6+7x^7+ … =x/(1-x)^2
1b =1+x^3+x^6+x^9+x^12+x^15+x^18+x^21+ … =1/(1-x^3)
B =0*1+1x^3+2x^6+3x^9+4x^12+5x^15+6x^18+7x^21+ … =x^3/(1-x^3)^2
B^2 =0^2*1+1^2x^3+2^2x^6+3^2x^9+4^2x^12+5^2x^15+6^2x^18+7^2x^21+ … =(x^6+x^3)/(1-x^3)^3
c =0*1+1x^6+2x^12+3x^18+4x^24+5x^30+6x^36+7x^42+ … =x^6/(1-x^6)^2
c^2 =0^2*1+1^2x^6+2^2x^12+3^2x^18+4^2x^24+5^2x^30+6^2x^36+7^2x^42+ … =(x^12+x^6)/(1-x^6)^3
c^3 =0^3*1+1^3x^6+2^3x^12+3^3x^18+4^3x^24+5^3x^30+6^3x^36+7^3x^42+ … =(x^18+4x^12+x^6)/(1-x^6)^4
である。
f(n:ABc)の母関数Σ[k=0,∞]f(k:ABc)*x^kについて
f(n:ABc)は、積A*B*cをマクローリン展開したときのx^nの係数になる。
同様に
f(n:B^2c)は、積1a*B^2*c
f(n:Ac^2)は、積A*1b*c^2
f(n:Bc^2)は、積1a*B*c^2
f(n:c^3)は、積1a*1b*c^3
したがって、f(n)の母関数は、
Σ[k=0,∞]f(k)*x^k
=f(n:ABc) + f(n:B^2c) + f(n:Ac^2) + 2*f(n:Bc^2) + f(n:c^3)
= x/(1-x)^2 * x^3/(1-x^3)^2 * x^6/(1-x^6)^2
+ 1/(1-x) * (x^6+x^3)/(1-x^3)^3 * x^6/(1-x^6)^2
+ x/(1-x)^2 * 1/(1-x^3) * (x^12+x^6)/(1-x^6)^3
+ 2 * { 1/(1-x) * x^3/(1-x^3)^2 * (x^12+x^6)/(1-x^6)^3 }
+ 1/(1-x) * 1/(1-x^3) * (x^18+4x^12+x^6)/(1-x^6)^4
= (6x^20+8x^19+10x^18+12x^17+13x^16+14x^15+17x^14+16x^13+15x^12+8x^11+7x^10+6x^9+3x^8+2x^7+x^6 )
/ { (1-x^3)^2 * (1-x^6)^4 }
これをマクローリン展開したときのx^nの係数になる。、
(終り)
先のマクローリン展開のプログラムでは、DATA文の箇所を、
DATA 20 !次数 f=6x^20+8x^19+10x^18+12x^17+13x^16+14x^15+17x^14+16x^13+15x^12+8x^11+7x^10+6x^9+3x^8+2x^7+x^6
DATA 0,0,0,0,0,0,1,2,3,6,7,8,15,16,17,14,13,12,10,8,6 !係数 ※展開して次数が小さい方から
DATA 30 !次数 g=x^30-2x^27-3x^24+8x^21+2x^18-12x^15+2x^12+8x^9-3x^6-2x^3+1
DATA 1,0,0,-2,0,0,-3,0,0,8,0,0,2,0,0,-12,0,0,2,0,0,8,0,0,-3,0,0,-2,0,0,1 !係数 ※展開して次数が小さい方から
とする。
|
|
|
投稿者:島村1243
投稿日:2013年 3月10日(日)09時40分8秒
|
|
|
> No.3009[元記事へ]
山中和義さんへのお返事です。
山中さんが作成された下記「マクローリン展開」プログラムを、任意関数P(x)のマクローリン展開に利用したのですが、任意関数を
DEF F(x)=....
DEF G(x)=....
DEF P(x)=F(x)/G(x)
と設定して簡単に使える様にできないでしょうか?
> !マクローリン展開
> ! P(x)=P(0)+{P'(0)/1!}x+{P''(0)/2!}x^2+{P'''(0)/3!}x^3+ …
> !例
> !P(x)=1/(1-x)=1+x+x^2+x^3+x^4+ …
> !
> !考察
> !P(0)は、x=0を代入して、1/(1-0)=1
> !P'(0)は、
> ! P(x)=f(x)/g(x)より、P'=(f'g-fg')/g^2なので、
> ! 1'(1-x)-1(1-x)'/(1-x)^2=1/(1-x)^2
> ! x=0を代入して、1
> !P''(0)は、
> ! P''(x)=(P'(x))'なので、
> ! 上記の結果をあらためて、f(x)=f'g-fg'、g(x)=g^2と考える。上記と同じ議論を繰り返す。
> !(終り)
>
> OPTION ARITHMETIC RATIONAL !有理数モード
>
> PUBLIC NUMERIC N !次数
> LET N=50
>
> !変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
> !「dim a(0 to n) !係数」で定義する
> DIM P(0 TO N)
> DIM F(0 TO N),G(0 TO N) !p=f/g
> MAT F=ZER
> MAT G=ZER
>
> DATA 6 !次数 f=x^3(2x^3+x^2+x+1)=2*x^6+x^5+x^4+x^3 ※
> DATA 0,0,0,1,1,1,2 !係数 ※展開して次数が小さい方から
> READ R
> FOR i=0 TO R
> READ F(i)
> NEXT i
> !!!MAT PRINT F; !debug
> CALL poly_disp(F) !多項式を表示する
> PRINT
>
> DATA 10 !次数 g=(1-x)(1-x^3)^3=x^10-x^9-3x^7+3x^6+3x^4-3x^3-x+1 ※
> DATA 1,-1,0,-3,3,0,3,-3,0,-1,1 !係数 ※展開して次数が小さい方から
> READ R
> FOR i=0 TO R
> READ G(i)
> NEXT i
> !!!MAT PRINT G; !debug
> CALL poly_disp(G) !多項式を表示する
> PRINT
>
>
> LET P(0)=F(0)/G(0)/FACT(0) !定数項
> PRINT 0; P(0) !debug
>
> DIM F1(0 TO N),G1(0 TO N), W1(0 TO N),W2(0 TO N),W3(0 TO N) !作業用
> FOR i=1 TO N !i階微分
>
> CALL poly_diff(F,W3) !f'g
> CALL poly_mul(W3,G, W1)
> !!!MAT PRINT W1; !debug
>
> CALL poly_diff(G,W3) !fg'
> CALL poly_mul(F,W3, W2)
> !!!MAT PRINT W2; !debug
>
> CALL poly_sub(W1,W2, F1) !分子 f'g-fg'
> !!!MAT PRINT F1; !debug
>
>
> CALL poly_mul(G,G, G1) !分母 g^2
> !!!MAT PRINT G1; !debug
>
>
> LET P(i)=F1(0)/G1(0)/FACT(i) !x^iの係数
> PRINT i; P(i) !debug
>
>
> MAT F=F1 !次へ
> MAT G=G1
> NEXT i
>
> CALL poly_disp(P) !多項式を表示する
> PRINT
>
> END
>
>
> !変数xの多項式 Σ[k=0,n]a(k)*x^k=a(n)*x^n+a(n-1)*x^(n-1)+ … +a(1)*x+a(0)
> !「dim a(0 to n) !係数」で定義する
>
> !演算関連
>
> EXTERNAL SUB poly_add(v1(),v2(), v()) !加算 v=v1+v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> MAT v=v1+v2
> END SUB
>
> EXTERNAL SUB poly_sub(v1(),v2(), v()) !減算 v=v1-v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> MAT v=v1-v2
> END SUB
>
> EXTERNAL SUB poly_mul(v1(),v2(), v()) !乗算 v=v1*v2
> OPTION ARITHMETIC RATIONAL !有理数モード
> DIM w(0 TO 2*N) !桁数は2倍になる
> MAT w=ZER
> FOR i=0 TO N !係数
> FOR j=0 TO N
> LET w(i+j)=w(i+j)+v1(i)*v2(j) !畳み込み
> NEXT j
> NEXT i
> FOR i=0 TO N !※下n桁をコピーする ※オーバーフローは考慮していない
> LET v(i)=w(i)
> NEXT i
> END SUB
>
> EXTERNAL SUB poly_diff(v1(), v()) !微分 v=v1'
> OPTION ARITHMETIC RATIONAL !有理数モード
> FOR i=1 TO N
> LET v(i-1)=v1(i)*i
> NEXT i
> LET v(N)=0
> END SUB
>
>
> !表示関連
>
> EXTERNAL SUB poly_disp(A()) !多項式を表示する a(X)=ΣAkX^k=AnX^n+An-1X^n-1+…+A1X+A0
> OPTION ARITHMETIC RATIONAL !有理数モード
> CALL mono_disp(A(N),N)
> FOR i=N-1 TO 0 STEP -1 !次項
> LET w=A(i)
> IF w>0 THEN PRINT "+";
> IF w<>0 OR N=0 THEN CALL mono_disp(w,i)
> NEXT i
> END SUB
>
> EXTERNAL SUB mono_disp(ak,k) !単項式を表示する Ak*X^k
> OPTION ARITHMETIC RATIONAL !有理数モード
> IF k<>0 THEN !x^nで
> IF ak=0 OR ak=1 THEN !係数が0,1なら
> ELSEIF ak=-1 THEN !係数が-1なら
> PRINT "-"; !符号
> ELSE
> PRINT STR$(ak);"*";
> END IF
> END IF
> IF k=0 THEN !次数が0なら
> PRINT STR$(ak);
> ELSEIF k=1 THEN !次数が1なら
> PRINT "X";
> ELSE
> IF ak<>0 THEN PRINT "X^";STR$(k); !係数が0以外なら
> END IF
> END SUB
>
>
|
|
|
投稿者:山中和義
投稿日:2013年 3月10日(日)12時28分33秒
|
|
|
> No.3012[元記事へ]
島村1243さんへのお返事です。
> DEF F(x)=....
> DEF G(x)=....
> DEF P(x)=F(x)/G(x)
> と設定して簡単に使える様にできないでしょうか?
提示したプログラムは、有理式に特化した手法です。
途中で算出される分数は、既約分数ではありませんが、厳密に微分した式になります。
よって、x=0を代入した値は誤差はありません。
一般の関数では、個々の関数に応じて微分しないといけませんので、プログラムは複雑になります。
汎用的な計算では、微分係数などで微分を近似します。したがって、誤差が累積していきます。
中点法、前進法、後退法の1,2,3次などを使えばある程度の精度は保証されますが、期待通りにはなりません。
F(X)=X/(1-X)^2の場合、係数 0,1,2,3,4,5,…
!マクローリン展開にみる数値微分の誤差と計算量 - 再帰呼び出しによるn階微分
LET A=0 !X=0 ※マクローリン展開
LET N=9 !N次近似
DIM c(0 TO N) !係数
LET c(0)=DF(A,0) !f(a)
PRINT c(0)
FOR i=1 TO N
LET c(i)=DF(A,i)/FACT(i)
PRINT c(i);"X^";STR$(i)
NEXT i
END
EXTERNAL FUNCTION F(X) !関数
!LET F=SIN(X)
!LET F=COS(X)
!LET F=EXP(X)
LET F=X/(1-X)^2 !0,1,2,3,4,5,…
!LET F=1/(1-X) !1,1,1,1,…
!LET F=(1-X)^4 !1,-4,6,-4,1,0,0,…
END FUNCTION
EXTERNAL FUNCTION DF(x,n) !f(x)のn階微分
IF n>0 THEN !微分係数から求める
LET h=1/1024
LET DF=(DF(x+h,n-1)-DF(x,n-1))/h
ELSE
LET DF=F(x)
END IF
END FUNCTION
実行結果
0
1.00195598975279 X^1
2.00881583539961 X^2
3.02355721412682 X^3
4.04920235221334 X^4
5.08883308900731 X^5
6.14561086632151 X^6
7.22195861264053 X^7
8.4220216127928 X^8
7.07402933721543 X^9
初等関数のように、n階微分がnの一般式で定義できる場合は、精度はかなり保証されます。
F(X)=SIN(X)の場合
!マクローリン展開にみる数値微分の誤差と計算量 - 再帰呼び出しによるn階微分
LET A=0 !X=0 ※マクローリン展開
LET N=9 !N次近似
DIM c(0 TO N) !係数
LET c(0)=DF(A,0) !f(a)
PRINT c(0)
FOR i=1 TO N
LET c(i)=DF(A,i)/FACT(i)
PRINT c(i);"X^";STR$(i)
NEXT i
END
EXTERNAL FUNCTION F(X) !関数
LET F=SIN(X)
!LET F=COS(X)
!LET F=EXP(X)
END FUNCTION
EXTERNAL FUNCTION DF(x,n) !f(x)のn階微分
LET DF=SIN(x+n*PI/2) !f(x)=SIN(x)
!LET DF=COS(x+n*PI/2) !f(x)=COS(x)
!LET DF=EXP(x) !f(x)=EXP(x)
END FUNCTION
実行結果
0
1 X^1
2.31321691639751E-19 X^2
-.166666666666667 X^3
-3.85536152732919E-20 X^4
8.33333333333333E-3 X^5
1.9276807636646E-21 X^6
-1.98412698412698E-4 X^7
-4.58971610396332E-23 X^8
2.75573192239859E-6 X^9
|
|
|
投稿者:島村1243
投稿日:2013年 3月10日(日)13時14分8秒
|
|
|
山中和義さんへのお返事です。
山中さん、早速のご教示有難う御座いました。
山中さんがご教示くださった
「汎用的な計算では、微分係数などで微分を近似する」方法のプログラムにF(x)=sin(x)と設定し出力したマクローリン係数と
「初等関数のように、n階微分がnの一般式で定義できる場合」の方法で出力されたF(x)=sin(x)のマクローリン係数
とを見比べると、x^5までの係数は概ね一致ですが、x^6以上の項では大きな差が出ており、任意関数を数値計算でマクローリン展開する場合は誤差の累積に注意が必要とのことが良く分かりました。
|
|
|
投稿者:しばっち
投稿日:2013年 3月12日(火)21時50分7秒
|
|
|
> No.3013[元記事へ]
再帰を使った方法より、下記の方が若干精度がいいようです
EXTERNAL FUNCTION DF(X,K)
LET H=1/1024
FOR J=0 TO K
LET S=S+(-1)^J*COMB(K,J)*F(X+(K/2-J)*H)
NEXT J
LET DF=S/(H^K)
END FUNCTION
また1000桁モードを使用して、下記のようにすればある程度は使えそうです
OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC H
LET X=0
LET N=9
LET EPS=1E-10 !'計算精度
FOR I=0 TO N
LET H=1/128
DO
LET H=H/2
LET A=DF1(X,I)
LET B=DF2(X,I)
LOOP UNTIL ABS(A - B) < EPS
LET DF=(A+B)/2
PRINT DF/FACT(I)
NEXT I
END
EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X/(1-X)^2
END FUNCTION
EXTERNAL FUNCTION DF1(X,N)
OPTION ARITHMETIC DECIMAL_HIGH
IF N>0 THEN
LET DF1=(DF1(X-2*H,N-1)-4*DF1(X-H,N-1)+3*DF1(X,N-1))/(2*H) !'3点前進法
!'LET DF1=(3*DF1(X-4*H,N-1)-16*DF1(X-3*H,N-1)+36*DF1(X-2*H,N-1)-48*DF1(X-H,N-1)+25*DF1(X,N-1))/(12*H) !'5点前進法
ELSE
LET DF1=F(X)
END IF
END FUNCTION
EXTERNAL FUNCTION DF2(X,N)
OPTION ARITHMETIC DECIMAL_HIGH
IF N>0 THEN
LET DF2=(-3*DF2(X,N-1)+4*DF2(X+H,N-1)-DF2(X+2*H,N-1))/(2*H) !'3点後退法
!'LET DF2=(-25*DF2(X,N-1)+48*DF2(X+H,N-1)-36*DF2(X+2*H,N-1)+16*DF2(X+3*H,N-1)-3*DF2(X+4*H,N-1))/(12*H) !'5点後退法
ELSE
LET DF2=F(X)
END IF
END FUNCTION
|
|
|
投稿者:島村1243
投稿日:2013年 3月13日(水)09時25分4秒
|
|
|
> No.3015[元記事へ]
しばっちさんへのお返事です。
しばっちさん、ご教示有難う御座いました。
関数 F(X)=X/(1-X)^2
についてご提示のあった二つのプロ(理屈は理解不能)を実行してみました。
---------------------------------------------------------
> 再帰を使った方法より、下記の方が若干精度がいいようです
---------------------------------------------------------
このプロの場合は結果が
0
1.00000071525602 X^1
2.00000381470259 X^2
3.00001192084544 X^3
4.00002806202375 X^4
5.00015669041249 X^5
6.01465745988539 X^6
24.1746473103899 X^7
-2263.61524295701 X^8
303480.118194826 X^9
となり、X^6の係数までは精度が高かったですが、X^7以降の係数は当てにならない結果でした。演算時間は速いので6次(必ずそう言えるか不明な点が気になるが)以下の係数には使えるようです。
----------------------------------------------------------------------
> また1000桁モードを使用して、下記のようにすればある程度は使えそうです
----------------------------------------------------------------------
上記2番目のプロは、9次までの係数が極めて高い精度で得られたので、幾らの次数まで正しい値かということを意識せず?に使えそうです。
ただし、私のコンピュータは遅い(AMD-AthlonXP2200+ 2.2GHz相当)ので8次以上の結果が出るまで5~6分必要としました。
|
|
|
投稿者:山中和義
投稿日:2013年 3月13日(水)19時05分11秒
|
|
|
> No.3014[元記事へ]
島村1243さんへのお返事です。
5次程度なら、次の連立方程式を解けば求まります。
!マクローリン展開
!f(x)=f(0)+{f'(0)/1!}x+{f''(0)/2!}x^2+{f'''(0)/3!}x^3+ …
! =f(0)+a[1]x+a[2]x^2+a[3]x^3+a[4]x^4+ …
!DEF F(X)=SIN(X)
!DEF F(X)=COS(X)
!DEF F(X)=EXP(X)
DEF F(X)=X/(1-X)^2 !0,1,2,3,4,5,…
!DEF F(X)=1/(1-X) !1,1,1,1,1,…
!DEF F(x)=(1-X)^4 !1,-4,6,-4,1,0,0,…
LET N=9 !次数
!A=
! x x^2 x^3 x^4 …
! 2x 4x^2 8x^3 16x^4 …
! 3x 9x^2 27x^3 81x^4 …
! 4x 16x^2 64x^3 256x^4 …
! :
LET x=1E-3 !x≒0
DIM A(N,N)
FOR i=1 TO N
FOR J=1 TO N
LET A(i,J)=(i*x)^J
NEXT J
NEXT i
!!!MAT PRINT A; !debug
!b=
! f( x)-f(0)
! f(2x)-f(0)
! f(3x)-f(0)
! f(4x)-f(0)
! :
DIM b(N)
LET F0=F(0)
FOR i=1 TO N
LET b(i)=F(i*x)-F0
NEXT i
DIM p(N),iA(N,N) !連立方程式Ap=bを解く
MAT iA=INV(A)
MAT p=iA*b
PRINT F(0) !各係数 定数項
MAT PRINT p; !x,x^2,x^3,…の項
END
実行結果
0
1.00000000000017 1.99999999953607 3.00000058623451 3.999024242 5.03640518 -18.75867688 1689.07931105014 -130559.084358461 2609878
|
|
|
投稿者:島村1243
投稿日:2013年 3月14日(木)13時16分45秒
|
|
|
山中和義さんへのお返事です。
山中さん、度重なるご教示有難う御座いました。
> 5次程度なら、次の連立方程式を解けば求まります。
上記プログラムの考え方も記載して頂き、私の頭でも「なるほどな~」と良く分かる計算法で感心するばかりでした。
コード中に「x=1E-3 !x≒0」の箇所が有りましたが、x=1E-2、x=1E-4、等と変えてみましたが、xを小さくすれば精度が上がると言う事でもない様ですね。
(この「x=1E-3 !x≒0」は「行列Aの高次係数が大きくなり過ぎない様にする為」という理由でしょうか?)
さてこのプログラムで「F(X)=X/(1-X)^2」を、x=1E-3のまま1000桁モードで計算させたら瞬時に9次までの高精度結果が得られました。難解な数値計算理論を使っていないのに、この方法は凄いですね。
|
|
|
投稿者:山中和義
投稿日:2013年 3月14日(木)14時20分0秒
|
|
|
> No.3018[元記事へ]
島村1243さんへのお返事です。
> コード中に「x=1E-3 !x≒0」の箇所が有りましたが、x=1E-2、x=1E-4、等と変えてみましたが、xを小さくすれば精度が上がると言う事でもない様ですね。
1E-3あたりが実用値でしょう。
> (この「x=1E-3 !x≒0」は「行列Aの高次係数が大きくなり過ぎない様にする為」という理由でしょか?)
提示したプログラムは、X=x,2x,3x,…を代入して、これを満たす補間多項式を得ます。
x=0は、0を代入するのですが、x^kがすべて0になって、行列Aが成り立ちません。
Xは、テイラー展開におけるX=aと考えることもできます。
このことは、プログラムの最後に、
!F(x)の値
LET S=F(0)
FOR i=1 TO N
LET S=S+p(i)*x^i
NEXT i
PRINT S; F(x)
を追加して、
先頭部分の関数定義とXの値を(別の関数と値でよいのですが)、
DEF F(X)=SIN(X)
LET x=PI/3
と変更して、確認できます。
|
|
|
投稿者:しばっち
投稿日:2013年 3月14日(木)21時36分13秒
|
|
|
高階微分の計算に時間がかかるのは、再帰ルーチン内で多重呼び出しを行っているためです
これを直接(10階微分まで)求めるようにすれば速くなります
(精度については注意を払う必要がある)
OPTION ARITHMETIC DECIMAL_HIGH
PUBLIC NUMERIC H
LET X=0
LET EPS=1E-20 !'精度
FOR I=1 TO 10
LET H=1/2^10
DO
LET H=H/2
SELECT CASE I
CASE 1
LET A=(-25*F(X)+48*F(X+H)-36*F(X+2*H)+16*F(X+3*H)-3*F(X+4*H))/(12*H)
LET B=(3*F(X-4*H)-16*F(X-3*H)+36*F(X-2*H)-48*F(X-H)+25*F(X))/(12*H)
CASE 2
LET A=(F(X)-2*F(X+H)+F(X+2*H))/(H^2)
LET B=(F(X-2*H)-2*F(X-H)+F(X))/(H^2)
CASE 3
LET A=(-49*F(X)+232*F(X+H)-461*F(X+2*H)+496*F(X+3*H)-307*F(X+4*H)+104*F(X+5*H)-15*F(X+6*H))/(8*H^3)
LET B=(15*F(X-6*H)-104*F(X-5*H)+307*F(X-4*H)-496*F(X-3*H)+461*F(X-2*H)-232*F(X-H)+49*F(X))/(8*H^3)
CASE 4
LET A=(F(X)-4*F(X+H)+6*F(X+2*H)-4*F(X+3*H)+F(X+4*H))/(H^4)
LET B=(F(X-4*H)-4*F(X-3*H)+6*F(X-2*H)-4*F(X-H)+F(X))/(H^4)
CASE 5
LET A=(-81*F(X)+575*F(X+H)-1790*F(X+2*H)+3195*F(X+3*H)-3580*F(X+4*H)+2581*F(X+5*H)-1170*F(X+6*H)+305*F(X+7*H)-35*F(X+8*H))/(6*H^5)
LET B=(35*F(X-8*H)-305*F(X-7*H)+1170*F(X-6*H)-2581*F(X-5*H)+3580*F(X-4*H)-3195*F(X-3*H)+1790*F(X-2*H)-575*F(X-H)+81*F(X))/(6*H^5)
CASE 6
LET A=(F(X)-6*F(X+H)+15*F(X+2*H)-20*F(X+3*H)+15*F(X+4*H)-6*F(X+5*H)+F(X+6*H))/(H^6)
LET B=(F(X-6*H)-6*F(X-5*H)+15*F(X-4*H)-20*F(X-3*H)+15*F(X-2*H)-6*F(X-H)+F(X))/(H^6)
CASE 7
LET A=(-605*F(X)+5628*F(X+H)-23583*F(X+2*H)+58632*F(X+3*H)-95802*F(X+4*H)+107520*F(X+5*H)-83958*F(X+6*H)+45048*F(X+7*H)-15897*F(X+8*H)+3332*F(X+9*H)-315*F(X+10*H))/(24*H^7)
LET B=(315*F(X-10*H)-3332*F(X-9*H)+15897*F(X-8*H)-45048*F(X-7*H)+83958*F(X-6*H)-107520*F(X-5*H)+95802*F(X-4*H)-58632*F(X-3*H)+23583*F(X-2*H)-5628*F(X-H)+605*F(X))/(24*H^7)
CASE 8
LET A=(F(X)-8*F(X+H)+28*F(X+2*H)-56*F(X+3*H)+70*F(X+4*H)-56*F(X+5*H)+28*F(X+6*H)-8*F(X+7*H)+F(X+8*H))/(H^8)
LET B=(F(X-8*H)-8*F(X-7*H)+28*F(X-6*H)-56*F(X-5*H)+70*F(X-4*H)-56*F(X-3*H)+28*F(X-2*H)-8*F(X-H)+F(X))/(H^8)
CASE 9
LET A=(-169*F(X)+1932*F(X+H)-10128*F(X+2*H)+32196*F(X+3*H)-69129*F(X+4*H)+105624*F(X+5*H)-117768*F(X+6*H)+96552*F(X+7*H)-57771*F(X+8*H)+24604*F(X+9*H)-7080*F(X+10*H)+1236*F(X+11*H)-99*F(X+12*H))/(4*H^9)
LET B=(99*F(X-12*H)-1236*F(X-11*H)+7080*F(X-10*H)-24604*F(X-9*H)+57771*F(X-8*H)-96552*F(X-7*H)+117768*F(X-6*H)-105624*F(X-5*H)+69129*F(X-4*H)-32196*F(X-3*H)+10128*F(X-2*H)-1932*F(X-H)+169*F(X))/(4*H^9)
CASE 10
LET A=(F(X)-10*F(X+H)+45*F(X+2*H)-120*F(X+3*H)+210*F(X+4*H)-252*F(X+5*H)+210*F(X+6*H)-120*F(X+7*H)+45*F(X+8*H)-10*F(X+9*H)+F(X+10*H))/(H^10)
LET B=(F(X-10*H)-10*F(X-9*H)+45*F(X-8*H)-120*F(X-7*H)+210*F(X-6*H)-252*F(X-5*H)+210*F(X-4*H)-120*F(X-3*H)+45*F(X-2*H)-10*F(X-H)+F(X))/(H^10)
END SELECT
LOOP UNTIL ABS(A - B) < EPS
LET DF=(A+B)/2
PRINT DF/FACT(I)
NEXT I
END
EXTERNAL FUNCTION F(X)
OPTION ARITHMETIC DECIMAL_HIGH
LET F=X/(1-X)^2
END FUNCTION
|
|
|
投稿者:島村1243
投稿日:2013年 3月15日(金)16時25分44秒
|
|
|
> No.3019[元記事へ]
山中和義さんへのお返事です。
山中さん、ご教示有難うございます。
> Xは、テイラー展開におけるX=aと考えることもできます。
ご指示頂いた様に、x=1E-3ではなく、x=pi/3と設定しF(x)=sin(x)について確認しましたら、ご教示のとおりになりました。
上記「Xはテーラー展開における・・・」の意味は下記で解釈すると納得出来たのですが誤りでしょうか?
X=aの近傍X=a+hに於けるF(a+h)はテイラー展開によって
F(a+h)=F(a)+F'(a)*h+F''(a)*h^2/2!+・・・
だから、これを
F(a+h)-F(a)=F'(a)*h+F''(a)*h^2/2!+・・・
と変形して「a=0,h=pi/3」と置けば、「多元連立式[A][p]=[b]を[p]について解きマクローリン係数を求めるプログラム」を利用してF(pi/3)が得られる。
|
|
|
投稿者:島村1243
投稿日:2013年 3月16日(土)14時48分27秒
|
|
|
> No.3020[元記事へ]
しばっちさんへのお返事です。
> 高階微分の計算に時間がかかるのは、再帰ルーチン内で多重呼び出しを行っているためです
> これを直接(10階微分まで)求めるようにすれば速くなります
> (精度については注意を払う必要がある)
ご教示頂いたコードを走らせて、瞬時に結果が得られることを確認しました。
どうも有難うございました。
|
|
|
戻る