积分方法梯形的计算

时间:2016-03-12 18:37:53

标签: fortran openmp integral

我已经有了当前的代码,但它仍然无效。如果代码正确,请帮助我编译它。我曾尝试过这样编译:

  

gfortran trap.f -fopenmp

PROGRAM TRAP
USE OMP_LIB
DOUBLE PRECISION INTEG, TMPINT  
DOUBLE PRECISION A, B      
PARAMETER (A=3.0, B=7.0)  
INTEGER N      
PARAMETER (N=10)
DOUBLE PRECISION H         
DOUBLE PRECISION X
INTEGER I
DOUBLE PRECISION F         
H = (B-A)/N
INTEG = 0.0
TMPINT = 0.0
!$omp parallel firstprivate(X, TMPINT) shared(INTEG)
!$omp do
DO 10 I=1,N-1,1
X=A+I*H
TMPINT = TMPINT + F(X)
10   CONTINUE
!$omp end do
!$omp critical
INTEG = INTEG + TMPINT
!$omp end critical
!$omp end parallel 
NTEG = (INTEG+(F(A)+F(B))/2.0)*H
PRINT *, "WITH N=", N, "INTEGRAL=", INTEG
END
FUNCTION F(X)
DOUBLE PRECISION X
F = X / (X + 1) * EXP(-X + 2)
END

编译器提出以下问题:

[http://i.stack.imgur.com/QPknv.png][1]

[http://i.stack.imgur.com/GYkmN.png][2]

2 个答案:

答案 0 :(得分:1)

你的程序有一个后缀.f,所以gfortran假定代码是固定格式的,并且抱怨许多语句都是"无法分类"。要解决此问题,请将文件名更改为trap.f90并编译为gfortran -fopenmp trap.f90以采用自由格式。还有其他问题:一个是函数F(X)的返回类型与主程序中声明的类型不匹配,因此F(X)需要修改为

FUNCTION F(X)
implicit none                     !<--- this is always recommended
DOUBLE PRECISION X, F             !<--- add F here
F = X / (X + 1) * EXP(-X + 2)
END

另一个问题是NTEG可能是INTEG的拼写错误,因此应将其修改为

INTEG = (INTEG+(F(A)+F(B))/2.0)*H

(如果我们在主程序中有implicit none,则自动检测到这一点)。现在运行代码,例如8个线程,给出

$ OMP_NUM_THREADS=8 ./a.out
WITH N=          10 INTEGRAL=  0.28927708626319770

虽然exact result是0.28598 ...增加N的价值,我们可以确认协议变得更好:

WITH N=         100 INTEGRAL=  0.28602065571967972
WITH N=        1000 INTEGRAL=  0.28598803555916535
WITH N=       10000 INTEGRAL=  0.28598770935198736
WITH N=      100000 INTEGRAL=  0.28598770608991503
顺便说一下,使用reduction子句来做同样的事情可能更容易,例如:

INTEG = 0.0

!$omp parallel do reduction(+ : integ) private(x)                                   
DO I = 1, N-1                                                                       
    X = A + I * H
    INTEG = INTEG + F( X )
ENDDO
!$omp end parallel do                                                               

INTEG = (INTEG+(F(A)+F(B))/2.0)*H

答案 1 :(得分:0)

您的代码采用固定格式(.f)。因此,您必须按固定格式的规则进行编码:每行的前六个字符具有特殊含义,除非您在第一个位置,行继续(第六个位置)或语句标签{中指定注释,否则应为空白{1}}。

如果您相应地格式化代码,编译器会抱怨10的返回值不匹配。由于您不使用F(X),因此类型由函数的第一个字母定义,implicit none映射到(单精度)实数。因此,您需要明确指定返回类型。

然后代码如下:

F

[请注意,我也将 PROGRAM TRAP USE OMP_LIB DOUBLE PRECISION INTEG, TMPINT DOUBLE PRECISION A, B PARAMETER (A=3.0, B=7.0) INTEGER N PARAMETER (N=10) DOUBLE PRECISION H DOUBLE PRECISION X INTEGER I DOUBLE PRECISION F H = (B-A)/N INTEG = 0.0 TMPINT = 0.0 c$omp parallel firstprivate(X, TMPINT) shared(INTEG) c$omp do DO 10 I=1,N-1,1 X=A+I*H TMPINT = TMPINT + F(X) 10 CONTINUE c$omp end do c$omp critical INTEG = INTEG + TMPINT c$omp end critical c$omp end parallel INTEG = (INTEG+(F(A)+F(B))/2.0)*H PRINT *, "WITH N=", N, "INTEGRAL=", INTEG END DOUBLE PRECISION FUNCTION F(X) DOUBLE PRECISION X F = X / (X + 1) * EXP(-X + 2) END 行修改为NTAG =,因为我认为这是有意的。我没有检查代码的有效性。 ]