简体   繁体   中英

Different results for similar C and Fortran code

This is an observation from a homework (past deadline) for which we had to use Eulers explicit scheme to investigate a predator-prey model. I compare the Fortran and C code (given below), and I cannot explain why there is a difference in the result, when I compare the Fortran code and the C code.

C code:

#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;
}

Now the Fortran version, the initialization parameters are exactly identical to the C version above.

! 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

Now the results, snapshot of results from C code:

   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

Results from Fortran code:

       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

Why do I see this divergence? I am using gfortran (v4.7.2), and running this on my laptop having Arch Linux on Intel i7.

EDIT:

This is the fix.

REAL FUNCTION FR(R,F,alpha)
    REAL, VALUE :: F,alpha
    REAL, VALUE :: R

    R = 2*R - alpha*R*F
FR = R
END FUNCTION FR

Note the VALUE for pointer-disassociation.

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

In FF , pass F by reference. In FR , pass R by reference. Update F and R like the fortran code does.

edit : Yup, what @JimLewis said.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM