2012年5月8日火曜日

学校の課題でベッセル(Bessel)関数 0次をC言語でプログラミングして、x→∞ にし...

学校の課題でベッセル(Bessel)関数 0次をC言語でプログラミングして、x→∞ にしたときのV0(x)の値を求めろと課題を出されました。

#include <stdio.h>

#include <math.h>



main()

{

double k=1,a2,a3,f,b;

int kurikaeshi=10; //kurikaeshiはk→∞の範囲

double k1[90],c1[90],s,e,a1[90],b1[90],l1[90],f1[90],x,end[90],j;

int i,a,a4;





k1[0] = 1;

a1[0] = 1;

c1[0] = 1;

for(x=2.00;x<kurikaeshi;x+0.01){



//階乗する分母の式----------------------------------------------------------



for(i=0;i<kurikaeshi;i++){

if(i == 0) k1[i] = 1;

else{

k=k*i;

k1[i] = k * k;}

// printf("k! * k! = %e \n",k1[i]);





//----分子の計算------------------------------------------------------------

if(i == 0) a1[i] = 1,f1[i] = 1;

else{

a = pow(-1,i);

a1[i] = a;

f1[i] = a1[i] / k1[i];

}

// printf("k=%d (-1)^k / k!*k! = %e \n",i,f1[i]);



//----(x/2)^2k--------------------------------------------------------------

if(x == 0) a3 = 1.0;

else{ if(i == 0 ) a3 = 1.0;

else{

a2 = x / 2.0;

a4 = 2 * i;

a3 = pow(a2,a4);

}}

c1[i] = a3;

// printf("(x/2)^2k = %e \n",c1[i]);





//----最後手前の計算------------------------------------------------------------

if(i == 0) l1[i] = 1;

else{

b = f1[i] * c1[i];

l1[i] = b + l1[i-1];

}

printf("x=%e k=%d %e \n\n",x,i,l1[i]);



j = l1[i];

while(fabs(j) < fabs(j) * 1e-25) {

end[i] = j;

printf("☆ x=0 y=%e \n",end[i]);

}

}





}

return 0;

}



と記述してみたのですが上手く計算されず途中でエラーとなってしまいます。

どうか解決する方法を教えてはもらえませんか?

お願いします。



参考URLはhttp://www8.plala.or.jp/randomism/besselj/ です。

0次なのでn=0 で計算しています。







//_ベッセル関数:



//_試作品です:(級数計算を改善)

/*******************************

J0(x)は自前の関数Bess0で求めるようにしました。

テストメインでは、

① J0(x)の零点付近の様子を確かめ

② 適切な区間を指定して二分探索法で求めます

最後に、printfでの出力がついています。

*******************************/

// 二分探索法について、3行の簡潔な手順説明がここにあります↓

// http://epp.eps.nagoya-u.ac.jp/~sirono/suti02/lect1203/lect1203.html

// 他の話題もありますが、大きく二分探索法と出ていますので見つけ易いです。



#include_<stdio.h>

#include_<math.h>



double_Bess0(___//_J0(x)_を計算し、戻り値で返す

____double_x,_______//[i]_独立変数

____double_eps,_____//[i]_打ち切り誤差

____int_max,________//[i]_級数項数の上限

____int*_lp)________//[o]_計算した項数

{

____int_____k;

____double__fct,_dJ,_J0;



____k_=_0;_J0_=_1;

____dJ_=_1;_fct_=_-pow(x/2,2.);

____do_{

________if_(_++k_>_max_)_break;

________dJ_*=_fct/(k*k);

________J0_+=_dJ;

____}_while_(_fabs(dJ)_>_eps_);

____*lp_=_k;

____return_J0;

}

void_main(){

____int_____iter,_loop,_maxlp=1000;

____double__x,_J0,_eps=1.e-12;

____double__xa,_xb,_Ja,_Jb;



____printf("1.0<x<3.0_でのJ0(x)の分布\n");

____printf("_x_________N___J0\n");

____for(x=1.;x<=3.;x+=0.5)_{

________J0_=_Bess0(_x,_eps,_maxlp,_&loop_);

________printf("%f_%3d_%9f\n",x,loop,J0);

____}

____printf("\n");

____printf("1.0<x<3.0_でのJ0(x)=0の根(J0(x)の零点)\n");

____xa_=_1.0;

____xb_=_3.0;

____Ja_=_Bess0(_xa,_eps,_maxlp,_&loop_);

____Jb_=_Bess0(_xb,_eps,_maxlp,_&loop_);

____iter_=_1;

____do_{____//_Binary_search_for_J0(x)_=_0.

________x__=_0.5*(xa+xb);

________J0_=_Bess0(_x,_eps,_maxlp,_&loop_);

________printf("trial_%2d:_at_x=%f,_J0=%9.1e\n",iter,x,J0);

________if_(_fabs(J0)_<_eps_)_break;

________if_(_J0*Ja_>=_0_)_xa_=_x;

________else______________xb_=_x;

____}_while_(_++iter_<_maxlp_);

____printf("\n");

____if(_iter_<_maxlp_)_{

________printf("Converged_at_%dth_trial_of_half_way_search.\n",iter);

________printf("J0(x)_=_%15.12f,_at_x_=_%15.12f\n",J0,x);

____}

____return;

}



実行結果:



1.0<x<3.0_でのJ0(x)の分布

_x_________N___J0

1.000000___8__0.765198

1.500000___9__0.511828

2.000000__10__0.223891 <=== ここまでプラス

2.500000__11_-0.048384 <=== ここからマイナス

3.000000__12_-0.260052



2分探索法での経過: <== 逐次近似の経過は普通出力しない、出すのは勝手

1.0<x<3.0_でのJ0(x)=0の根(J0(x)の零点)

trial__1:_at_x=2.000000,_J0=_2.2e-001

trial__2:_at_x=2.500000,_J0=-4.8e-002

trial__3:_at_x=2.250000,_J0=_8.3e-002

trial__4:_at_x=2.375000,_J0=_1.6e-002

trial__5:_at_x=2.437500,_J0=-1.7e-002

trial__6:_at_x=2.406250,_J0=-7.4e-004

trial__7:_at_x=2.390625,_J0=_7.4e-003

trial__8:_at_x=2.398438,_J0=_3.3e-003

trial__9:_at_x=2.402344,_J0=_1.3e-003

trial_10:_at_x=2.404297,_J0=_2.7e-004

trial_11:_at_x=2.405273,_J0=-2.3e-004

trial_12:_at_x=2.404785,_J0=_2.1e-005

trial_13:_at_x=2.405029,_J0=-1.1e-004

trial_14:_at_x=2.404907,_J0=-4.2e-005

trial_15:_at_x=2.404846,_J0=-1.1e-005

trial_16:_at_x=2.404816,_J0=_5.1e-006

trial_17:_at_x=2.404831,_J0=-2.8e-006

trial_18:_at_x=2.404823,_J0=_1.2e-006

trial_19:_at_x=2.404827,_J0=-8.1e-007

trial_20:_at_x=2.404825,_J0=_1.8e-007

trial_21:_at_x=2.404826,_J0=-3.1e-007

trial_22:_at_x=2.404826,_J0=-6.7e-008

trial_23:_at_x=2.404825,_J0=_5.6e-008

trial_24:_at_x=2.404826,_J0=-5.5e-009

trial_25:_at_x=2.404826,_J0=_2.5e-008

trial_26:_at_x=2.404826,_J0=_1.0e-008

trial_27:_at_x=2.404826,_J0=_2.3e-009

trial_28:_at_x=2.404826,_J0=-1.6e-009

trial_29:_at_x=2.404826,_J0=_3.5e-010

trial_30:_at_x=2.404826,_J0=-6.2e-010

trial_31:_at_x=2.404826,_J0=-1.3e-010

trial_32:_at_x=2.404826,_J0=_1.1e-010

trial_33:_at_x=2.404826,_J0=-1.4e-011

trial_34:_at_x=2.404826,_J0=_4.7e-011

trial_35:_at_x=2.404826,_J0=_1.7e-011

trial_36:_at_x=2.404826,_J0=_1.6e-012

trial_37:_at_x=2.404826,_J0=-5.9e-012

trial_38:_at_x=2.404826,_J0=-2.2e-012

trial_39:_at_x=2.404826,_J0=-2.8e-013



Converged_at_39th_trial_of_half_way_search.

J0(x)_=_-0.000000000000,_at_x_=__2.404825557696 <=== J0(x)はほぼゼロ

0 件のコメント:

コメントを投稿