a.outの結果がおかしい件について

このQ&Aのポイント
  • SEIRモデルの解を求めるプログラムをコンパイルし、a.outの結果がおかしいです。
  • 結果が正しくない値が表示されており、期待される合計との差異が生じています。
  • どこがおかしいのかを特定するために、プログラムのコードを確認しました。
回答を見る
  • ベストアンサー

a.outの結果がおかしい件について

以下のSEIRモデルの解を求めるプログラムをコンパイルしa.outすると、 結果が 0.000000,200.000000,40.000000,30.000000,30.000000,20.000000,8.000000,12.000000,10.000000,350.000000 40.100000,275.397813,152.832528,37.778276,45.918538,0.000000,0.000000,3.615719,1.024043,516.566916 しか表示されず、またseirすべての合計は350で一定であるはずなのに516となっています。 どこがおかしいのでしょうか? 以下にプログラムを示します。 #include <stdio.h> #include <math.h> double alf=0.33, bet=0.0875, gam=0.2; ///alf:移行率,bet:感染率,gam:除外率 double f1(double t1,double a0,double a1,double a2,double a3){return -bet*a0*a2;} double f2(double t1,double a0,double a1,double a2,double a3){return bet*a0*a2-alf*a1;} double f3(double t1,double a0,double a1,double a2,double a3){return alf*a1-gam*a2;} double f4(double t1,double a0,double a1,double a2,double a3){return gam*a2;} //箱Aの関数 double g1(double t1,double b0,double b1,double b2,double b3){return -bet*b0*b2;} double g2(double t1,double b0,double b1,double b2,double b3){return bet*b0*b2-alf*b1;} double g3(double t1,double b0,double b1,double b2,double b3){return alf*b1-gam*b2;} double g4(double t1,double b0,double b1,double b2,double b3){return gam*b2;} //箱Bの関数 int main(void) { double t1,dt,t1max; double k1[4],k2[4],k3[4],k4[4],l1[4],l2[4],l3[4],l4[4],a[4],b[4],da[4],db[4] ; double (*pf[4])(double,double,double,double,double)={f1,f2,f3,f4}; double (*pg[4])(double,double,double,double,double)={g1,g2,g3,g4}; int i; //宣言 t1 = 0.0; dt = 0.1; t1max = 40.0; //時間初期値 a[0] = 200.0; a[1] = 40.0; a[2] = 30.0; a[3] = 30.0; //箱A初期値(a[0]:感受性人口、a[1]:潜伏人口、a[2]:感染人口、a[3]:隔離人口) b[0] = 20.0; b[1] = 8.0; b[2] = 12.0; b[3] = 10.0; //箱B初期値(b[0]:感受性人口、b[1]:潜伏人口、b[2]:感染人口、b[3]:隔離人口) printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",t1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); for(t1=0.0;t1<=t1max;t1+=dt) { for (i=0;i<4;i++) k1[i]=dt*pf[i](t1,a[0],a[1],a[2],a[3]); for (i=0;i<4;i++) k2[i]=dt*pf[i](t1+dt/2.0,a[0]+k1[0]/2.0,a[1]+k1[1]/2.0,a[2]+k1[2]/2.0,a[3]+k1[3]/2.0); for (i=0;i<4;i++) k3[i]=dt*pf[i](t1+dt/2.0,a[0]+k2[0]/2.0,a[1]+k2[1]/2.0,a[2]+k2[2]/2.0,a[3]+k2[3]/2.0); for (i=0;i<4;i++) k4[i]=dt*pf[i](t1+dt,a[0]+k3[0],a[1]+k3[1],a[2]+k3[2],a[3]+k3[3]); for (i=0;i<4;i++) l1[i]=dt*pg[i](t1,b[0],b[1],b[2],b[3]); for (i=0;i<4;i++) l2[i]=dt*pg[i](t1+dt/2.0,b[0]+l1[0]/2.0,b[1]+l1[1]/2.0,b[2]+l1[2]/2.0,b[3]+l1[3]/2.0); for (i=0;i<4;i++) l3[i]=dt*pg[i](t1+dt/2.0,b[0]+l2[0]/2.0,b[1]+l2[1]/2.0,b[2]+l2[2]/2.0,b[3]+l2[3]/2.0); for (i=0;i<4;i++) l4[i]=dt*pg[i](t1+dt,b[0]+l3[0],b[1]+l3[1],b[2]+l3[2],b[3]+l3[3]);} for (i=0;i<=3;i++) a[i]=a[i]+((k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i])/6.0); for (i=0;i<=3;i++) b[i]=b[i]+((l1[i]+2.0*l2[i]+2.0*l3[i]+l4[i])/6.0); //4次のルンゲクッタ da[0]=-0.8*a[0]; da[1]=-0.8*a[1]; da[2]=-0.2*a[2]; da[3]=-0.5*a[3]; //AからBへの移動量 db[0]=-b[0]; db[1]=-b[1]; db[2]=-0.7*b[2]; db[3]=-0.9*b[3]; //BからAへの移動量 if (t1 < 21.0) { //移動開始 for (i=0;i<=3;i++) { a[i]=a[i]+da[i]; b[i]=b[i]-db[i]; ////AからBへ移動後のAにおけるSEIRの数,AからBへ移動後のBにおけるSEIRの数 } } else { for (i=0;i<=3;i++) { a[i]=a[i]-da[i]; ////BからAへの移動後のAにおけるSEIRの数 b[i]=b[i]+db[i]; ////BからAへの移動後のBにおけるSEIRの数 } printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",t1+0.1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); } return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • f272
  • ベストアンサー率46% (8023/17148)
回答No.3

やりたいことが,よくわからないが... AからBへ移動とかBからAへの移動というのは,一体いつ移動するの?21日までは各タイムステップでAからBへ移動して,その後は各タイムステップでBからAへ移動するのだろうか? もしそうなら #include <stdio.h> #include <math.h> double alf=0.33, bet=0.0875, gam=0.2; ///alf:移行率,bet:感染率,gam:除外率 double f1(double t1,double a0,double a1,double a2,double a3){return -bet*a0*a2;} double f2(double t1,double a0,double a1,double a2,double a3){return bet*a0*a2-alf*a1;} double f3(double t1,double a0,double a1,double a2,double a3){return alf*a1-gam*a2;} double f4(double t1,double a0,double a1,double a2,double a3){return gam*a2;} //箱Aの関数 double g1(double t1,double b0,double b1,double b2,double b3){return -bet*b0*b2;} double g2(double t1,double b0,double b1,double b2,double b3){return bet*b0*b2-alf*b1;} double g3(double t1,double b0,double b1,double b2,double b3){return alf*b1-gam*b2;} double g4(double t1,double b0,double b1,double b2,double b3){return gam*b2;} //箱Bの関数 int main(void) { double t1,dt,t1max; double k1[4],k2[4],k3[4],k4[4],l1[4],l2[4],l3[4],l4[4],a[4],b[4],da[4],db[4] ; double (*pf[4])(double,double,double,double,double)={f1,f2,f3,f4}; double (*pg[4])(double,double,double,double,double)={g1,g2,g3,g4}; int i; //宣言 t1 = 0.0; dt = 0.1; t1max = 40.0; //時間初期値 a[0] = 200.0; a[1] = 40.0; a[2] = 30.0; a[3] = 30.0; //箱A初期値(a[0]:感受性人口、a[1]:潜伏人口、a[2]:感染人口、a[3]:隔離人口) b[0] = 20.0; b[1] = 8.0; b[2] = 12.0; b[3] = 10.0; //箱B初期値(b[0]:感受性人口、b[1]:潜伏人口、b[2]:感染人口、b[3]:隔離人口) printf("%4.2f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f\n",t1+0.1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); for(t1=0.0;t1<=t1max;t1+=dt) { for (i=0;i<4;i++) k1[i]=dt*pf[i](t1,a[0],a[1],a[2],a[3]); for (i=0;i<4;i++) k2[i]=dt*pf[i](t1+dt/2.0,a[0]+k1[0]/2.0,a[1]+k1[1]/2.0,a[2]+k1[2]/2.0,a[3]+k1[3]/2.0); for (i=0;i<4;i++) k3[i]=dt*pf[i](t1+dt/2.0,a[0]+k2[0]/2.0,a[1]+k2[1]/2.0,a[2]+k2[2]/2.0,a[3]+k2[3]/2.0); for (i=0;i<4;i++) k4[i]=dt*pf[i](t1+dt,a[0]+k3[0],a[1]+k3[1],a[2]+k3[2],a[3]+k3[3]); for (i=0;i<4;i++) l1[i]=dt*pg[i](t1,b[0],b[1],b[2],b[3]); for (i=0;i<4;i++) l2[i]=dt*pg[i](t1+dt/2.0,b[0]+l1[0]/2.0,b[1]+l1[1]/2.0,b[2]+l1[2]/2.0,b[3]+l1[3]/2.0); for (i=0;i<4;i++) l3[i]=dt*pg[i](t1+dt/2.0,b[0]+l2[0]/2.0,b[1]+l2[1]/2.0,b[2]+l2[2]/2.0,b[3]+l2[3]/2.0); for (i=0;i<4;i++) l4[i]=dt*pg[i](t1+dt,b[0]+l3[0],b[1]+l3[1],b[2]+l3[2],b[3]+l3[3]); for (i=0;i<=3;i++) a[i]=a[i]+((k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i])/6.0); for (i=0;i<=3;i++) b[i]=b[i]+((l1[i]+2.0*l2[i]+2.0*l3[i]+l4[i])/6.0); //4次のルンゲクッタ da[0]=-0.8*a[0]; da[1]=-0.8*a[1]; da[2]=-0.2*a[2]; da[3]=-0.5*a[3]; //AからBへの移動量 db[0]=-b[0]; db[1]=-b[1]; db[2]=-0.7*b[2]; db[3]=-0.9*b[3]; //BからAへの移動量 if (t1 < 21.0) { //移動開始 for (i=0;i<=3;i++) { a[i]=a[i]+da[i]; b[i]=b[i]-da[i]; ////AからBへ移動後のAにおけるSEIRの数,AからBへ移動後のBにおけるSEIRの数 } } else { for (i=0;i<=3;i++) { a[i]=a[i]-db[i]; ////BからAへの移動後のAにおけるSEIRの数 b[i]=b[i]+db[i]; ////BからAへの移動後のBにおけるSEIRの数 } } printf("%4.2f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f,%10.6f\n",t1+0.1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); } return 0; } こんな感じだろう。

fujiya1234
質問者

お礼

いつもお世話になっております。エラーなく正常に動きました! Aを例えば駅、Bを学校とし、ある時間(放課後)を過ぎると逆にBからAへ行くような シュミレーションをしてみたのですが、いかがでしょうか? また質問させていただいた際には是非ご回答いただけると幸いです。 ありがとうございました。

その他の回答 (2)

  • chie65535
  • ベストアンサー率43% (8525/19382)
回答No.2

>しか表示されず、 プログラムの波括弧の対応がおかしいので「初期値」と「最終結果」のみしか表示されません。 貴方は「t1が0から40.1まで0.1刻みで401回分、表示される筈」でプログラムを書いたつもりですが、そうなってはいません。 >またseirすべての合計は350で一定であるはずなのに516となっています。 感染が進むうち「出生」と「死亡」が発生するので、最終結果が「人口増加」で終わっただけの話です。 このプログラムでは「各種パラメータの設定値」により「全員死滅して終わり」になったり、「出生よりも感染による死亡が多くなり人口減少して終わり」になったり、「出生と感染による死亡が釣り合って人口が変わらずに終わり」になったり、「感染による死亡よりも出生が多くなり人口増加して終わり」になったりします。 >どこがおかしいのでしょうか? 「波括弧の位置」がおかしいです。 以下のプログラムと見比べて下さい(「波括弧」を追加しただけです) #include <stdio.h> #include <math.h> double alf=0.33, bet=0.0875, gam=0.2; ///alf:移行率,bet:感染率,gam:除外率 double f1(double t1,double a0,double a1,double a2,double a3){return -bet*a0*a2;} double f2(double t1,double a0,double a1,double a2,double a3){return bet*a0*a2-alf*a1;} double f3(double t1,double a0,double a1,double a2,double a3){return alf*a1-gam*a2;} double f4(double t1,double a0,double a1,double a2,double a3){return gam*a2;} //箱Aの関数 double g1(double t1,double b0,double b1,double b2,double b3){return -bet*b0*b2;} double g2(double t1,double b0,double b1,double b2,double b3){return bet*b0*b2-alf*b1;} double g3(double t1,double b0,double b1,double b2,double b3){return alf*b1-gam*b2;} double g4(double t1,double b0,double b1,double b2,double b3){return gam*b2;} //箱Bの関数 int main(void) {  double t1,dt,t1max;  double k1[4],k2[4],k3[4],k4[4],l1[4],l2[4],l3[4],l4[4],a[4],b[4],da[4],db[4] ;  double (*pf[4])(double,double,double,double,double)={f1,f2,f3,f4};  double (*pg[4])(double,double,double,double,double)={g1,g2,g3,g4};  int i; //宣言  t1 = 0.0;  dt = 0.1;  t1max = 40.0; //時間初期値  a[0] = 200.0;  a[1] = 40.0;  a[2] = 30.0;  a[3] = 30.0; //箱A初期値(a[0]:感受性人口、a[1]:潜伏人口、a[2]:感染人口、a[3]:隔離人口)  b[0] = 20.0;  b[1] = 8.0;  b[2] = 12.0;  b[3] = 10.0; //箱B初期値(b[0]:感受性人口、b[1]:潜伏人口、b[2]:感染人口、b[3]:隔離人口)  printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",t1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]);  for(t1=0.0;t1<=t1max;t1+=dt) {   for (i=0;i<4;i++) k1[i]=dt*pf[i](t1,a[0],a[1],a[2],a[3]);   for (i=0;i<4;i++) k2[i]=dt*pf[i](t1+dt/2.0,a[0]+k1[0]/2.0,a[1]+k1[1]/2.0,a[2]+k1[2]/2.0,a[3]+k1[3]/2.0);   for (i=0;i<4;i++) k3[i]=dt*pf[i](t1+dt/2.0,a[0]+k2[0]/2.0,a[1]+k2[1]/2.0,a[2]+k2[2]/2.0,a[3]+k2[3]/2.0);   for (i=0;i<4;i++) k4[i]=dt*pf[i](t1+dt,a[0]+k3[0],a[1]+k3[1],a[2]+k3[2],a[3]+k3[3]);   for (i=0;i<4;i++) l1[i]=dt*pg[i](t1,b[0],b[1],b[2],b[3]);   for (i=0;i<4;i++) l2[i]=dt*pg[i](t1+dt/2.0,b[0]+l1[0]/2.0,b[1]+l1[1]/2.0,b[2]+l1[2]/2.0,b[3]+l1[3]/2.0);   for (i=0;i<4;i++) l3[i]=dt*pg[i](t1+dt/2.0,b[0]+l2[0]/2.0,b[1]+l2[1]/2.0,b[2]+l2[2]/2.0,b[3]+l2[3]/2.0);   for (i=0;i<4;i++) l4[i]=dt*pg[i](t1+dt,b[0]+l3[0],b[1]+l3[1],b[2]+l3[2],b[3]+l3[3]);}   for (i=0;i<=3;i++) a[i]=a[i]+((k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i])/6.0);   for (i=0;i<=3;i++) b[i]=b[i]+((l1[i]+2.0*l2[i]+2.0*l3[i]+l4[i])/6.0); //4次のルンゲクッタ   da[0]=-0.8*a[0];   da[1]=-0.8*a[1];   da[2]=-0.2*a[2];   da[3]=-0.5*a[3]; //AからBへの移動量   db[0]=-b[0];   db[1]=-b[1];   db[2]=-0.7*b[2];   db[3]=-0.9*b[3]; //BからAへの移動量   if (t1 < 21.0) { //移動開始    for (i=0;i<=3;i++) {     a[i]=a[i]+da[i];     b[i]=b[i]-db[i]; ////AからBへ移動後のAにおけるSEIRの数,AからBへ移動後のBにおけるSEIRの数    }   } else {    for (i=0;i<=3;i++) {     a[i]=a[i]-da[i]; ////BからAへの移動後のAにおけるSEIRの数     b[i]=b[i]+db[i]; ////BからAへの移動後のBにおけるSEIRの数    }   }   printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",t1+0.1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]);  }  return 0; }

fujiya1234
質問者

お礼

printfがelse内に入ってましたね。 ありがとうございました。

  • maiko0333
  • ベストアンサー率19% (840/4403)
回答No.1

間違いっちゅうかdouble を使う限り、小数点以下の数字は近似値にしかなりませんよ。

関連するQ&A

  • 2次元配列を関数の引数にする方法について

    以下のプログラムはSEIRモデル(https://ja.wikipedia.org/wiki/SEIR%E3%83%A2%E3%83%87%E3%83%AB)を2つたて、それらを相互作用させたときのA,Bそれぞれの解をルンゲクッタ法を用いて求めています。 ここで一次元配列a[i],b[j]を2次元配列a[2][4](i:領域A,B,j:SEIR)とし使用した場合、 関数の定義のところなどどのように書けばよいのでしょうか? C言語初心者でして、お見苦しい点多々あると思いますが、何卒ご教示お願いします。。。 #include <stdio.h> #include <math.h> double alf=0.05, bet=0.005, gam=0.05; ///alf:移行率,bet:感染率,gam:除外率 double f1(double t1,double a0,double a1,double a2,double a3){return -bet*a0*a2;} double f2(double t1,double a0,double a1,double a2,double a3){return bet*a0*a2-alf*a1;} double f3(double t1,double a0,double a1,double a2,double a3){return alf*a1-gam*a2;} double f4(double t1,double a0,double a1,double a2,double a3){return gam*a2;} //箱Aの関数 double g1(double t1,double b0,double b1,double b2,double b3){return -bet*b0*b2;} double g2(double t1,double b0,double b1,double b2,double b3){return bet*b0*b2-alf*b1;} double g3(double t1,double b0,double b1,double b2,double b3){return alf*b1-gam*b2;} double g4(double t1,double b0,double b1,double b2,double b3){return gam*b2;} //箱Bの関数 int main(void) { double t1,dt,t1max; double k1[4],k2[4],k3[4],k4[4],l1[4],l2[4],l3[4],l4[4],a[4],b[4],da[4],db[4] ; double (*pf[4])(double,double,double,double,double)={f1,f2,f3,f4}; double (*pg[4])(double,double,double,double,double)={g1,g2,g3,g4}; int i; //宣言 t1 = 0.0; dt = 0.1; t1max = 20.0; //時間初期値 a[0] = 2000.0; a[1] = 300.0; a[2] = 400.0; a[3] = 300.0; //箱A初期値(a[0]:感受性人口、a[1]:潜伏人口、a[2]:感染人口、a[3]:隔離人口) b[0] = 1000.0; b[1] = 200.0; b[2] = 300.0; b[3] = 500.0; //箱B初期値(b[0]:感受性人口、b[1]:潜伏人口、b[2]:感染人口、b[3]:隔離人口) printf("%4.2f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f\n",t1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); for(t1=0.0;t1<=t1max;t1+=dt) { for (i=0;i<4;i++) k1[i]=dt*pf[i](t1,a[0],a[1],a[2],a[3]); for (i=0;i<4;i++) k2[i]=dt*pf[i](t1+dt/2.0,a[0]+k1[0]/2.0,a[1]+k1[1]/2.0,a[2]+k1[2]/2.0,a[3]+k1[3]/2.0); for (i=0;i<4;i++) k3[i]=dt*pf[i](t1+dt/2.0,a[0]+k2[0]/2.0,a[1]+k2[1]/2.0,a[2]+k2[2]/2.0,a[3]+k2[3]/2.0); for (i=0;i<4;i++) k4[i]=dt*pf[i](t1+dt,a[0]+k3[0],a[1]+k3[1],a[2]+k3[2],a[3]+k3[3]); for (i=0;i<4;i++) l1[i]=dt*pg[i](t1,b[0],b[1],b[2],b[3]); for (i=0;i<4;i++) l2[i]=dt*pg[i](t1+dt/2.0,b[0]+l1[0]/2.0,b[1]+l1[1]/2.0,b[2]+l1[2]/2.0,b[3]+l1[3]/2.0); for (i=0;i<4;i++) l3[i]=dt*pg[i](t1+dt/2.0,b[0]+l2[0]/2.0,b[1]+l2[1]/2.0,b[2]+l2[2]/2.0,b[3]+l2[3]/2.0); for (i=0;i<4;i++) l4[i]=dt*pg[i](t1+dt,b[0]+l3[0],b[1]+l3[1],b[2]+l3[2],b[3]+l3[3]); for (i=0;i<=3;i++) a[i]=a[i]+((k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i])/6.0); for (i=0;i<=3;i++) b[i]=b[i]+((l1[i]+2.0*l2[i]+2.0*l3[i]+l4[i])/6.0); //4次のルンゲクッタ da[0]=-0.05*a[0]; da[1]=-0.05*a[1]; da[2]=-0.01*a[2]; da[3]=-0.05*a[3]; //AからBへの移動量 db[0]=-0.05*b[0]; db[1]=-0.05*b[1]; db[2]=-0.02*b[2]; db[3]=-0.05*b[3]; //BからAへの移動量 if (t1 < 15.0) { //移動開始 for (i=0;i<=3;i++) { a[i]=a[i]+da[i]; b[i]=b[i]-da[i]; ////AからBへ移動後のAにおけるSEIRの数,AからBへ移動後のBにおけるSEIRの数 } } else { for (i=0;i<=3;i++) { a[i]=a[i]-db[i]; ////BからAへの移動後のAにおけるSEIRの数 b[i]=b[i]+db[i]; ////BからAへの移動後のBにおけるSEIRの数 } } printf("%4.2f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f,%10.3f\n",t1+0.1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); } return 0; }

  • コンパイルエラーの原因と対策について。

    以下のプログラムは、SEIRモデルをルンゲクッタ法を使いA,Bそれぞれについて解を求めているのですが、 どうしてもコンパイルエラーが出てしまいます。 字数制限でエラー内容は書けませんがご希望があれば補足いたします。 原因と改良すべき点をご教示お願いします。 #include <stdio.h> #include <math.h> #define alf 0.33 #define bet 0.0875 #define gam 0.2 double f1(double t1,double a[0],double a[1],double a[2],double a[3]); double f2(double t1,double a[0],double a[1],double a[2],double a[3]); double f3(double t1,double a[0],double a[1],double a[2],double a[3]); double f4(double t1,double a[0],double a[1],double a[2],double a[3]); //箱Aの関数 double g1(double t1,double b[0],double b[1],double b[2],double b[3]); double g2(double t1,double b[0],double b[1],double b[2],double b[3]); double g3(double t1,double b[0],double b[1],double b[2],double b[3]); double g4(double t1,double b[0],double b[1],double b[2],double b[3]); //箱Bの関数 int main(void) { double t1,dt,t1max; double k1[4],k2[4],k3[4],k4[4],l1[4],l2[4],l3[4],l4[4],a[4],b[4],da[4],db[4] ; double (*pf[4])(double,double,double,double,double)={f1,f2,f3,f4}; double (*pg[4])(double,double,double,double,double)={g1,g2,g3,g4}; int i; //宣言 t1 = 0.0; dt = 0.1; t1max = 40.0; //時間初期値 a[0] = 200.0; a[1] = 40.0; a[2] = 30.0; a[3] = 30.0; //箱A初期値(a[0]:感受性人口、a[1]:潜伏人口、a[2]:感染人口、a[3]:隔離人口) b[0] = 20.0; b[1] = 8.0; b[2] = 12.0; b[3] = 10.0; //箱B初期値(b[0]:感受性人口、b[1]:潜伏人口、b[2]:感染人口、b[3]:隔離人口) printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",t1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); for(t1=0.0;t1<=t1max;t1+=dt) { for (i=0;i<4;i++) k1[i]=dt*pf[i](t1,a[0],a[1],a[2],a[3]); for (i=0;i<4;i++) k2[i]=dt*pf[i](t1+dt/2.0,a[0]+k1[0]/2.0,a[1]+k1[1]/2.0,a[2]+k1[2]/2.0,a[3]+k1[3]/2.0); for (i=0;i<4;i++) k3[i]=dt*pf[i](t1+dt/2.0,a[0]+k2[0]/2.0,a[1]+k2[1]/2.0,a[2]+k2[2]/2.0,a[3]+k2[3]/2.0); for (i=0;i<4;i++) k4[i]=dt*pf[i](t1+dt,a[0]+k3[0],a[1]+k3[1],a[2]+k3[2],a[3]+k3[3]); for (i=0;i<4;i++) l1[i]=dt*pg[i](t1,b[0],b[1],b[2],b[3]); for (i=0;i<4;i++) l2[i]=dt*pg[i](t1+dt/2.0,b[0]+l1[0]/2.0,b[1]+l1[1]/2.0,b[2]+l1[2]/2.0,b[3]+l1[3]/2.0); for (i=0;i<4;i++) l3[i]=dt*pg[i](t1+dt/2.0,b[0]+l2[0]/2.0,b[1]+l2[1]/2.0,b[2]+l2[2]/2.0,b[3]+l2[3]/2.0); for (i=0;i<4;i++) l4[i]=dt*pg[i](t1+dt,b[0]+l3[0],b[1]+l3[1],b[2]+l3[2],b[3]+l3[3]);} for (i=0;i<=3;i++) a[i]=a[i]+((k1[i]+2.0*k2[i]+2.0*k3[i]+k4[i])/6.0); for (i=0;i<=3;i++) b[i]=b[i]+((l1[i]+2.0*l2[i]+2.0*l3[i]+l4[i])/6.0); //4次のルンゲクッタ da[0]=-0.8*a[0]; da[1]=-0.8*a[1]; da[2]=-0.2*a[2]; da[3]=-0.5*a[3]; //AからBへの移動量 db[0]=-b[0]; db[1]=-b[1]; db[2]=-0.7*b[2]; db[3]=-0.9*b[3]; //BからAへの移動量 if (t1 < 21.0) { //移動開始 for (i=0;i<=3;i++) { a[i]=a[i]+da[i]; b[i]=b[i]-db[i]; ////AからBへ移動後のAにおけるSEIRの数,AからBへ移動後のBにおけるSEIRの数 } } else { for (i=0;i<=3;i++) { a[i]=a[i]-da[i]; ////BからAへの移動後のAにおけるSEIRの数 b[i]=b[i]+db[i]; ////BからAへの移動後のBにおけるSEIRの数 } printf("%f,%f,%f,%f,%f,%f,%f,%f,%f,%f\n",t1+0.1,a[0],a[1],a[2],a[3],b[0],b[1],b[2],b[3],a[0]+a[1]+a[2]+a[3]+b[0]+b[1]+b[2]+b[3]); } return 0; } double f1(double t1,double a[0],double a[1],double a[2],double a[3]) { double r; r=-bet*a[0]*a[2]; return r; } double f2(double t1,double a[0],double a[1],double a[2],double a[3]) { double r; r=bet*a[0]*a[2]-alf*a[1]; return r; } double f3(double t1,double a[0],double a[1],double a[2],double a[3]) { double r; r=alf*a[1]-gam*a[2]; return r; } double f4(double t1,double a[0],double a[1],double a[2],double a[3]) { double r; r=gam*a[2]; return r; } double g1(double t1,double b[0],double b[1],double b[2],double b[3]) { double r; r=-bet*b[0]*b[2]; return r; } double g2(double t1,double b[0],double b[1],double b[2],double b[3]) { double r; r=bet*b[0]*b[2]-alf*b[1]; return r; } double g3(double t1,double b[0],double b[1],double b[2],double b[3]) { double r; r=alf*b[1]-gam*b[2]; return r; } double g4(double t1,double b[0],double b[1],double b[2],double b[3]) { double r; r=gam*b[2]; return r; }

  • 配列を用いたC言語プログラミングについて

    以下のルンゲクッタ法を用いたプログラムに配列などを使いさらに短くしたいのですが どのような方法が有りますか? #include <stdio.h> #include <math.h> double f1(double t1,double w,double x,double y,double z); double f2(double t1,double w,double x,double y,double z); double f3(double t1,double w,double x,double y,double z); double f4(double t1,double w,double x,double y,double z); //箱Aの関数 double g1(double t1,double a,double b,double c,double d); double g2(double t1,double a,double b,double c,double d); double g3(double t1,double a,double b,double c,double d); double g4(double t1,double a,double b,double c,double d); //箱Bの関数 int main(void) { double t1,w,x,y,z,a,b,c,d,dt,t1max,t2max,lam,gam,lat,dw,dx,dy,dz,da,db,dc,dd ; double k1[4],k2[4],k3[4],k4[4],l1[4],l2[4],l3[4],l4[4] ; ///宣言 t1 = 0.0; dt = 0.3; t1max = 40.0; //時間初期値 w = 200.0; x = 40.0; y = 30.0; z = 30.0; ///箱A初期値(w:感受性人口、x:潜伏人口、y:感染人口、z:隔離人口) a = 20.0; b = 8.0; c = 12.0; d = 10.0; ///箱B初期値(a:感受性人口、b:潜伏人口、c:感染人口,d:隔離人口) for(t1=0.0;t1<=t1max;t1+=dt) { k1[0]=dt*f1(t1,w,x,y,z); k1[1]=dt*f2(t1,w,x,y,z); k1[2]=dt*f3(t1,w,x,y,z); k1[3]=dt*f4(t1,w,x,y,z); k2[0]=dt*f1(t1+dt/2.0,w+k1[0]/2.0,x+k1[1]/2.0,y+k1[2]/2.0,z+k1[3]/2.0); k2[1]=dt*f2(t1+dt/2.0,w+k1[0]/2.0,x+k1[1]/2.0,y+k1[2]/2.0,z+k1[3]/2.0); k2[2]=dt*f3(t1+dt/2.0,w+k1[0]/2.0,x+k1[1]/2.0,y+k1[2]/2.0,z+k1[3]/2.0); k2[3]=dt*f4(t1+dt/2.0,w+k1[0]/2.0,x+k1[1]/2.0,y+k1[2]/2.0,z+k1[3]/2.0); k3[0]=dt*f1(t1+dt/2.0,w+k2[0]/2.0,x+k2[1]/2.0,y+k2[2]/2.0,z+k2[3]/2.0); k3[1]=dt*f2(t1+dt/2.0,w+k2[0]/2.0,x+k2[1]/2.0,y+k2[2]/2.0,z+k2[3]/2.0); k3[2]=dt*f3(t1+dt/2.0,w+k2[0]/2.0,x+k2[1]/2.0,y+k2[2]/2.0,z+k2[3]/2.0); k3[3]=dt*f4(t1+dt/2.0,w+k2[0]/2.0,x+k2[1]/2.0,y+k2[2]/2.0,z+k2[3]/2.0); k4[0]=dt*f1(t1+dt,w+k3[0],x+k3[1],y+k3[2],z+k3[3]); k4[1]=dt*f2(t1+dt,w+k3[0],x+k3[1],y+k3[2],z+k3[3]); k4[2]=dt*f3(t1+dt,w+k3[0],x+k3[1],y+k3[2],z+k3[3]); k4[3]=dt*f4(t1+dt,w+k3[0],x+k3[1],y+k3[2],z+k3[3]); ///箱Aルンゲクッタ l1[0]=dt*g1(t1,a,b,c,d); l1[1]=dt*g2(t1,a,b,c,d); l1[2]=dt*g3(t1,a,b,c,d); l1[3]=dt*g4(t1,a,b,c,d); l2[0]=dt*g1(t1+dt/2.0,a+l1[0]/2.0,b+l1[1]/2.0,c+l1[2]/2.0,d+l1[3]/2.0); l2[1]=dt*g2(t1+dt/2.0,a+l1[0]/2.0,b+l1[1]/2.0,c+l1[2]/2.0,d+l1[3]/2.0); l2[2]=dt*g3(t1+dt/2.0,a+l1[0]/2.0,b+l1[1]/2.0,c+l1[2]/2.0,d+l1[3]/2.0); l2[3]=dt*g4(t1+dt/2.0,a+l1[0]/2.0,b+l1[1]/2.0,c+l1[2]/2.0,d+l1[3]/2.0); l3[0]=dt*g1(t1+dt/2.0,a+l2[0]/2.0,b+l2[1]/2.0,c+l2[2]/2.0,d+l2[3]/2.0); l3[1]=dt*g2(t1+dt/2.0,a+l2[0]/2.0,b+l2[1]/2.0,c+l2[2]/2.0,d+l2[3]/2.0); l3[2]=dt*g3(t1+dt/2.0,a+l2[0]/2.0,b+l2[1]/2.0,c+l2[2]/2.0,d+l2[3]/2.0); l3[3]=dt*g4(t1+dt/2.0,a+l2[0]/2.0,b+l2[1]/2.0,c+l2[2]/2.0,d+l2[3]/2.0); l4[0]=dt*g1(t1+dt,a+l3[0],b+l3[1],c+l3[2],d+l3[3]); l4[1]=dt*g2(t1+dt,a+l3[0],b+l3[1],c+l3[2],d+l3[3]); l4[2]=dt*g3(t1+dt,a+l3[0],b+l3[1],c+l3[2],d+l3[3]); l4[3]=dt*g4(t1+dt,a+l3[0],b+l3[1],c+l3[2],d+l3[3]); ///箱Bルンゲクッタ w=w+((k1[0]+2.0*k2[0]+2.0*k3[0]+k4[0])/6.0); x=x+((k1[1]+2.0*k2[1]+2.0*k3[1]+k4[1])/6.0); y=y+((k1[2]+2.0*k2[2]+2.0*k3[2]+k4[2])/6.0); z=z+((k1[3]+2.0*k2[3]+2.0*k3[3]+k4[3])/6.0); a=a+((l1[0]+2.0*l2[0]+2.0*l3[0]+l4[0])/6.0); b=b+((l1[1]+2.0*l2[1]+2.0*l3[1]+l4[1])/6.0); c=c+((l1[2]+2.0*l2[2]+2.0*l3[2]+l4[2])/6.0); d=d+((l1[3]+2.0*l2[3]+2.0*l3[3]+l4[3])/6.0); } return 0; }

  • 大学のC言語の課題で

    ルンゲクッタ法を用いたバネの単振動を解析する課題をやっています。以下の部分まで作ったのですが、 どうしても最後のほうがわかりません。 関数fとf2のreturn やメイン関数を変更すればいいとおもうのですが、どうやっても満足な結果が得られません。どなたか詳しい方教えてもらえない? #include<stdio.h> #include<math.h> double f(double t,double y1) { return y1; } double f2(double t2,double y2) { double w=5.0,k=0.5; return -w*w*f(t2,y2)-2.0*k*y2; } int main(void) { int count,bunkatu,npr; double t_0,T; double k1,k2,k3,k4; double y,t,dt,dt_2,dt_6; t_0 = 0.0; T=10.0; bunkatu=2000; npr=1000; y=1.0; printf("\n# [t_0,T]=[%6.4lf,%6.4lf] N=%d\n",t_0,T,bunkatu); t=t_0; dt=(T-t_0)/(double)bunkatu; dt_2=dt/2.0; dt_6=dt/6.0; for(count=0;count <=bunkatu;count++) { if(count %(bunkatu/npr)==0) printf("\n %5.2lf %10.5f",t,y); k1=f2(t,y); k2=f(t+dt_2,y+k1*dt_2); k3=f(t+dt_2,y+k2*dt_2); k4=f(t+dt,y+k3*dt); y+=(k1+2.0*k2+2.0*k3+k4)*dt_6; t+=dt; } printf("\n"); return 0; }

  • ルンゲクッタ法で数値解析(C言語)

    コンピュータ(プログラミング)のカテゴリに投稿しようかとも考えましたが、物理学に関する数値計算ということなので、物理学のカテゴリに投稿しました。 単振動や減衰振動、そして強制振動などを数値解析したいと思い、ルンゲクッタ法を使いシミュレートしてみようとしています。ルンゲクッタ法という方法を全く知らなかったので、インターネットや図書館で調べたのですが、どうしても分からないことろがあるので質問することにしました。 書籍やネットの情報を参考にしながら、単振動の場合を数値解析してみました(C言語を使って)。この単振動はうまくできたのですが、どうしても、その先の、減衰振動の数値解析がうまくいかないので、困っています。 ---- #include <stdio.h> double f1(double t,double x,double v); double f2(double t,double x,double v); int main() { double t,x,v,dt,tmax; double k1[2],k2[2],k3[2],k4[2]; x=1.0; //位置の初期値 v=0.0; //速度の初期値 dt=0.01; //刻み幅 tmax=500.0; //繰り返し最大回数 FILE *output; output=fopen("output.dat","w"); for(t=0;t<tmax;t+=dt) { k1[0]=dt*f1(t,x,v); k1[1]=dt*f2(t,x,v); k2[0]=dt*f1(t+dt/2.0,x+k1[0]/2.0,v+k1[1]/2.0); k2[1]=dt*f2(t+dt/2.0,x+k1[0]/2.0,v+k1[1]/2.0); k3[0]=dt*f1(t+dt/2.0,x+k2[0]/2.0,v+k2[1]/2.0); k3[1]=dt*f2(t+dt/2.0,x+k2[0]/2.0,v+k2[1]/2.0); k4[0]=dt*f1(t+dt,x+k3[0],v+k3[1]); k4[1]=dt*f2(t+dt,x+k3[0],v+k3[1]); x=x+(k1[0]+2.0*k2[0]+2.0*k3[0]+k4[0])/6.0; v=v+(k1[1]+2.0*k2[1]+2.0*k3[1]+k4[1])/6.0; fprintf(output,"%f %f %f\n",t,x,v); } fclose(output); return 0; } double f1(double t,double x,double v) { return v; } double f2(double t,double x,double v) { return (-x); } ---- このソースは単振動のもので、減衰振動のときは、最後の方の ---- double f1(double t,double x,double v) { return v; } double f2(double t,double x,double v) { return (-x); ---- の部分が変わるのだと思うのですが、よく分かりません。 減衰振動は、mx"=-kx-rx'で表されるので、この式を変形(?)したものが、入るのかな、という予想程度にしか分かりません。 ソースをどのように変えれば減衰振動を解析できるのでしょうか。 どなたか詳しい方、教えてください。お願いします。

  • ルンゲクッタのプロクラム実行できません

    プログラムの実行ができません。 どこを直したらよいのか教えて下さい。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <math.h> double *dvector(long i,long j); void free_dvector(double *a,long i); double func(double x,double y); double *rk4(double y0,double a,double b, int n,double(*f)()); int main(void) { double *y,h,a=0.0, b=1.0, y0=1.0; int i,n; printf("分割数を入力して下さい------->"); scanf("%d",&n); y=dvector(0,n); y=rk4(y0,a,b,n,func); h=(b-a)/n; for(i=0;i<=n;i++) { printf("x=%f \t y=%f \n",a+i*h,y[i]); } return 0; } double *rk4(double y0,double a, double b,int n,double (*f)()) { double k1,k2,k3,k4,h,*y,x; int i; y=dvector(0,n); h=(b-a)/n; y[0]=y0; x=a; for(i=0;i<n;i++) { k1=f(x,y[i]); k2=f(x+h/2.0,y[i]+h*k1/2.0); k3=f(x+h/2.0,y[i]+h*k2/2.0); k4=f(x+h,y[i]+h*k3); y[i+1]=y[i]+h/6.0*(k1+2.0*k2+2.0*k3+k4); x +=h; } return y; free_dvector(y,0); }

  • 微分方程式(ルンゲ=クッタ)がうまくいきません

    C言語で物体の自由落下運動(空気抵抗を考慮する)を微分方程式を用いて解かなければならないのですが、どうしてもグラフの形が曲線になりません。どこが間違っているのか指摘お願いします。 空気抵抗を考慮しているので、落下速度はどんどんある一定の値に近づいていくはずなのですが、グラフは直線になってしまいます。いろいろと方法を試しましたがどれも外れました。 写真は赤が今の状態(間違っています)、黒が理想形です。 ここではルンゲ=クッタ法を使用しています。 #include <stdio.h> #include <math.h> double yd(double t,double y){ double m = 50.0; 質量 double g = 9.8; 重力加速度 double k = 0.01; 空気抵抗の定数係数 double a= g - ((k *y)/m); 運動方程式 return(a); } double runge(double t,double y,double h){ double k1,k2,k3,k4,r; double h2 = h / 2.0; k1 = yd(t,y); k2 = yd(t+h2,y+(h2*k1)); k3 = yd(t+h2,y+(h2*k2)); k4 = yd(t+h,y+(h*k3)); a = y + (h/6.0) * ((k1 + (2.0 * k2) + (2.0 * k3) + k4)); return(a); } void main(){ double y = 0.0; double h = 0.001; double t = 0.0; int i; for(i = 0; i < 1000; i++){ t += h; y = runge(t,y,h); printf("%f %f\n",t,y); } }

  • Javaプログラムのフローチャートについて

    下に記述したのは4次のルンゲクッタ法のJavaによるプログラム例です。このプログラムの簡単なフローチャートを作成してプレゼンしたいのですが、作成した経験がなく、本等をみてもいまいちわかりません。どなたかご教授いただきたく、お願い申し上げます。 // 2階常微分方程式に対する Runge-Kutta 法による積分メソッド public void Runge_Kutta(double x[], double y[]){ double xi, vi, k1, k2, k3, k4, l1, l2, l3, l4; for(int i = 0; i < iMax-1; i++){ xi = x[i]; vi=y[i]; k1 = dt*vi; l1 = dt*fun(vi, xi); k2 = dt*(vi+0.5*l1); l2 = dt*fun(vi+0.5*l1, xi+0.5*k1); k3 = dt*(vi+0.5*l2); l3 = dt*fun(vi+0.5*l2, xi+0.5*k2); k4 = dt*(vi+l3); l4 = dt*fun(vi+l3, xi+k3); x[i+1] = xi+(k1+2.0*(k2+k3)+k4)/6.0; y[i+1] = vi+(l1+2.0*(l2+l3)+l4)/6.0; if(y[i] < ymin){ Max=i; break;} if(Math.abs(y[i+1]-y[i]) < diff && Math.abs(x[i+1]-x[i])< diff){Max=i; break;} } }

    • ベストアンサー
    • Java
  • セグメントエラー

    #include <stdio.h> #define S 10.0 #define L 10.0 void solve(int m,double a[][10],double f[]); main() { double t,me[10][10],fe[10]; int i,x; t=(S*L)/420; me[0][0]=t*156;me[0][1]=t*22*L;me[0][2]=t*54;me[0][3]=t*(-13)*L; me[1][0]=me[0][1];me[1][1]=t*4*L*L;me[1][2]=t*13*L;me[1][3]=t*(-3)*L*L; me[2][0]=me[0][2];me[2][1]-me[1][2];me[2][2]=t*156;me[2][3]=t*(-22)*L; me[3][0]=me[0][3];me[3][1]=me[1][3];me[2][3]=me[3][2];me[3][3]=t*4*L*L; for(i=0;i<4;i++){ fe[i]=1.0; } x=4; solve(x,me,fe); } void solve(int m,double a[][10],double f[]) { /* m=number of unknowns */ int i,j,k; double aa; /* forward elimination */ for(i=0;i<m-1;i++){ for(j=i+1;j<m;j++){ aa=a[j][i]/a[i][i]; f[j]-=aa*f[i]; for(k=i+1;k<m;j++){ a[j][k]-=aa*a[i][k]; } } } /* backward substitution */ f[m-1]/=a[m-1][m-1]; for(i=m-2;i>=0;i--){ for(j=i+1;j<m;j++){ f[i]-=a[i][j]*f[j]; } f[i]/=a[i][i]; } } 以上のようなプログラムについて、コンパイルはできるのですが、実行時に「セグメントエラー」と出てしまいます。たぶん配列の引渡しに原因があるようなのですが、どなたか詳しい原因(対処法)をご教授願いたいと思います。

  • お初に質問させていただきます。最近、Excelのマクロを始め、下のよう

    お初に質問させていただきます。最近、Excelのマクロを始め、下のようなユーザー定義関数を作成し無事動作を確認しました。そして、他の方法で実測した任意の時刻における値との差の二乗の総和が最小になるようにK(1),K(2)の値を最適化したいと思い、最小二乗の総和をワークシート上に計算し、Excelのツールのソルバーを用いて最適化を試みました。しかし、「最適解は見つかりました」と出るのですが、値に全く変化はなく最適化できていません。ユーザー定義関数を含むとソルバーは使えないのですか?もし何か解決法があれば教えてください。私が使っているExcelはExcel 2003です。 Public Function RK1(成分, 時刻かける20) As Double Application.Volatile Dim Koc As Double, Kco As Double, Eo As Integer, Ec As Integer, Y0(2) As Double Dim Y(2) As Double, K1(4) As Double, K2(4) As Double, K3(4) As Double Dim K4(4) As Double, T As Double Dim K(2) As Double, DelY(2) As Double Dim Tt(1500) As Double, TV(2, 1500) As Double For I = 1 To 2 Y0(I) = Cells(3 + I, 2).Value Const nn As Integer = 20 dx = 1# / nn T = 0# K(1) = Cells(2, 2).Value K(2) = Cells(3, 2).Value Next I For J = 1 To 300 Y(1) = Y0(1) Y(2) = Y0(2) K1(1) = F1(T, Y(1), Y(2)) * dx K1(2) = F2(T, Y(1), Y(2)) * dx ' Y(1) = Y0(1) + 0.5 * K1(1) Y(2) = Y0(2) + 0.5 * K1(2) K2(1) = F1(T, Y(1), Y(2)) * dx K2(2) = F2(T, Y(1), Y(2)) * dx ' Y(1) = Y0(1) + 0.5 * K2(1) Y(2) = Y0(2) + 0.5 * K2(2) K3(1) = F1(T, Y(1), Y(2)) * dx K3(2) = F2(T, Y(1), Y(2)) * dx ' Y(1) = Y0(1) + K3(1) Y(2) = Y0(2) + K3(2) K4(1) = F1(T, Y(1), Y(2)) * dx K4(2) = F2(T, Y(1), Y(2)) * dx ' DelY(1) = (K1(1) + 2# * K2(1) + 2# * K3(1) + K4(1)) / 6# DelY(2) = (K1(2) + 2# * K2(2) + 2# * K3(2) + K4(2)) / 6# T = T + dx Y0(1) = Y0(1) + DelY(1) Y0(2) = Y0(2) + DelY(2) Tt(J) = T TV(1, J) = Y0(1) TV(2, J) = Y0(2) Next J RK1 = TV(成分, 時刻かける20) End Function Function F1(T, a, b) Dim K(2) As Double Eo = Cells(7, 2).Value Ec = Cells(8, 2).Value K(1) = Cells(2, 2).Value K(2) = Cells(3, 2).Value F1 = (-K(1) * a + K(2) * b) * (1 - 10 ^ (-(Eo * a + Ec * b))) / (Eo * a + Ec * b) End Function Function F2(T, a, b) Dim K(2) As Double Eo = Cells(7, 2).Value Ec = Cells(8, 2).Value K(1) = Cells(2, 2).Value K(2) = Cells(3, 2).Value F2 = (K(1) * a - K(2) * b) * (1 - 10 ^ (-(Eo * a + Ec * b))) / (Eo * a + Ec * b) End Function