これは、捕食者と被食者のモデルを調査するためにオイラーの明示的なスキームを使用しなければならなかった宿題(過去の締め切り)からの観察です。FortranコードとCコード(以下を参照)を比較しましたが、FortranコードとCコードを比較すると、結果に違いがある理由を説明できません。
Cコード:
#include <stdio.h>
//Functions for Euler Explicit
float FR(float R,float F,float alpha)
{
return (2*R - alpha*R*F);
}
float FF(float R,float F,float alpha)
{
return (-F + alpha*R*F);
}
int main()
{
int N;
float alpha,initR,initF,bigR,h;
/* Data Setup */
alpha = 0.001;
initR = 15;
initF = 22;
N = 50;
bigR = 400;
h = 0.01;
float R0,F0,R1,F1;
int i;
R0 = initR;
F0 = initF;
for (i = 0; i < N; i++)
{
R1 = R0 + h*FR(R0,F0,alpha);
F1 = F0 + h*FF(R0,F0,alpha);
printf("%d\t%f\t%f\n",i,R1,F1);
R0 = R1;
F0 = F1;
}
return 0;
}
現在、Fortranバージョンでは、初期化パラメーターは上記のCバージョンとまったく同じです。
! EULER EXPLICIT
SUBROUTINE eulers_explicit (initR,initF,N,alpha,h)
IMPLICIT NONE
REAL :: R0,F0,R1,F1,initF,initR,alpha,h
INTEGER I,N
R0 = initR
F0 = initF
DO I=1,N
R1 = R0 + h*FR(R0,F0,alpha)
F1 = F0 + h*FF(R0,F0,alpha)
PRINT *,I,R1,F1
R0 = R1
F0 = F1
END DO
END SUBROUTINE eulers_explicit
! EULER EXPLICIT
REAL FUNCTION FR(R,F,alpha)
REAL, INTENT(IN) :: F,alpha
REAL, INTENT(INOUT) :: R
R = 2*R - alpha*R*F
FR = R
END FUNCTION FR
REAL FUNCTION FF(R,F,alpha)
REAL, INTENT(IN) :: R,alpha
REAL, INTENT(INOUT) :: F
F = -F + alpha*R*F
FF = F
END FUNCTION FF
PROGRAM solve
USE usual_routines
IMPLICIT NONE
INTEGER :: N
REAL :: alpha,initR,initF,h
alpha = 0.001
initR = 15
initF = 22
N = 50
h = 0.01
PRINT *, "Eulers explicit method: "
CALL eulers_explicit (initR,initF,N,alpha,h)
END PROGRAM solve
結果、Cコードからの結果のスナップショット:
0 15.296700 21.783300
1 15.599301 21.568800
2 15.907923 21.356476
3 16.222683 21.146309
4 16.543707 20.938276
5 16.871117 20.732357
6 17.205042 20.528532
7 17.545610 20.326778
8 17.892956 20.127077
9 18.247213 19.929407
10 18.608521 19.733749
Fortranコードの結果:
0 29.9666996 -21.5607319
1 61.1852989 20.4571381
2 122.330109 -18.1591854
3 249.350449 13.8127756
4 500.209259 -7.04162502
5 1013.98022 -2.80275159E-02
6 2048.26880 -2.91000959E-02
7 4137.56299 -9.10123810E-02
8 8358.25781 -0.668782473
9 16889.3262 -10.6198158
10 34297.5977 -353.508148
なぜこの相違が見られるのですか?私はgfortran(v4.7.2)を使用しており、Inteli7上にArchLinuxを搭載したラップトップでこれを実行しています。
編集:
これは修正です。
REAL FUNCTION FR(R,F,alpha)
REAL, VALUE :: F,alpha
REAL, VALUE :: R
R = 2*R - alpha*R*F
FR = R
END FUNCTION FR
VALUE
ポインタの関連付け解除に注意してください。