类似的C和Fortran代码的结果不同

时间:2013-03-26 21:48:48

标签: c fortran numerical-methods

这是一个家庭作业(过去的截止日期)的观察,我们不得不使用欧拉显式方案来研究捕食者 - 猎物模型。我比较了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),并在我的笔记本电脑上使用英特尔i7上的Arch Linux运行。

编辑:

这是修复。

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

2 个答案:

答案 0 :(得分:7)

FORTRAN子程序FF和FR修改它们的参数,而C等效 不要。

答案 1 :(得分:3)

FF中,通过引用传递F。在FR中,通过引用传递R。像fortran代码一样更新FR

编辑:是的,@JimLewis说的是什么。