自動微分による微分値の計算 山中和義 2007/11/25 19:43:53 (修正1回) └続き 山中和義 2007/11/25 19:44:51 (修正1回)
Re: 自動微分による微分値の計算 |
返事を書く ノートメニュー |
山中和義 <drdlxujciw> 2007/11/25 19:44:51 ** この記事は1回修正されてます | |
続き
!●問題 ! 関数 f(x1,x2,x3)=sin(1.5*(x1+x2))/(x2*x3) のとき、x1=x2=x3=1における関数値、偏微分係数は? !●数値微分の場合(前進差分) DEF f(x1,x2,x3)=SIN(1.5*(x1+x2))/(x2*x3) !関数を定義する LET N=3 !変数の数 LET xx1=1 LET xx2=1 LET xx3=1 LET d=1E-8 ! PRINT f(xx1,xx2,xx3), !f PRINT (f(xx1+d,xx2,xx3)-f(xx1,xx2,xx3))/d, !∂f/∂x1 PRINT (f(xx1,xx2+d,xx3)-f(xx1,xx2,xx3))/d, !∂f/∂x2 PRINT (f(xx1,xx2,xx3+d)-f(xx1,xx2,xx3))/d !∂f/∂x3 !●自動微分の場合 !x1=[1,1,0,0] ※[x1, ∂x1/∂x1, ∂x1/∂x2, ∂x1/∂x3] !x2=[1,0,1,0] !x3=[1,0,0,1] DIM x1(N+1),x2(N+1),x3(N+1) !変数の定義 DATA 1,1,0,0 MAT READ x1 DATA 1,0,1,0 MAT READ x2 DATA 1,0,0,1 MAT READ x3 !関数値、偏微分値がすぐにわかるような関数同士の四則演算、合成の形に分解する。 ! v1=x1+x2 ! v2=1.5*v1 ! v3=sin(v2) ! v4=x2*x3 ! v5=v3/v4 ! !※式を手コンパイルで求める。 !多言語(C++など)では、オペランドのオーバーロード(演算子の多重定義)機能で実現する。 !v1=x1+x2=[1,1,0,0]+[1,0,1,0]=[2,1,1,0] DIM v1(N+1) CALL DiffAdd(x1,x2, v1) MAT PRINT v1 !v2=1.5*v1=[1.5,0,0,0]*[2,1,1,0]=[3,1.5,1.5,0] DIM c15(N+1) !定数1.5 CALL DiffSetConst(1.5, c15) DIM v2(N+1) CALL DiffMul(c15,v1, v2) !!!MAT v2=1.5*v1でも可 MAT PRINT v2 !v3=sin(v2)=[sin(v2),(∂sin(v2)/∂v2)*(∂v2/∂x1),(∂sin(v2)/∂v2)*(∂v2/∂x2),(∂sin(v2)/∂v2)*(∂v2/∂x3)]=[sin(3),1.5*cos(3),1.5*cos(3),0] DIM v3(N+1) !LET v3(1)=SIN(FxVal(v2)) !LET dfx=DFxVal("SIN",v2) !※∂sin(v2)/∂v2 !LET v3(2)=dfx*1.5 !※∂v2/∂x1=∂{1.5*(x1+x2)}/∂x1=1.5 !LET v3(3)=dfx*1.5 !LET v3(4)=dfx*0 CALL DiffCompo("SIN",v2, v3) !v4=x2*x3=[1,0,1,0]*[1,0,0,1]=[1,0,1,1] DIM v4(N+1) CALL DiffMul(x2,x3, v4) MAT PRINT v4 !v5=v3/v4 DIM v5(N+1) CALL DiffDiv(v3,v4, v5) MAT PRINT v5 !確認 PRINT SIN(3),1.5*COS(3),1.5*COS(3)-SIN(3),-SIN(3) END |