使用梯形或辛普森统计的积分计算

时间:2014-12-01 17:21:16

标签: fortran integration numerical-analysis

基本上,作业说"找到f(x)= 0的解决方案...."。其中f(x)=积分(1 / sqrt(2 * pi))exp(-t ^ 2/2)dt从x = 0到x-0.45。对不起,我找不到如何把积分放在这里。

我的教授。给了我们一些如何开始的提示。

start x
do i = 1,2,3...
    fp = 1/sqrt(2*pi)exp(-x^2/2)
    f  = use trap,or simpson's rule to find the integration than subtract 0.45
    x = x - (f/fp)
end do 

这是我做的事情

program main
implicit none

integer :: n, k, i
double precision :: h, a, fp, f, x1, x2, pi, blub, integ, e, dx, j, m

a = 0
n = 25
x1 = 0.5
pi = 4.0d0 * atan(1.0d0)

do i = 1, n
    e = exp((-x1)**2.0d0/2.0d0)
    print*, e

    fp = (1.0d0/sqrt(2.0d0 * pi))* e

    !start of the trapezoid
    dx = (x1-a)/n  !find dx by subtracting starting point from endpoint and divide by number of steps taken
    m = (blub(a) + blub(x1))/2 !find the mean value of the integral


    j = 0
        do k=1, n-1
            h = i
            j = j + blub(h) !calculate the each step of the integral from one to n and add all together. 
        end do

    integ = dx*(m+j) !result of the trapezoid method

    print*, "integ: ", integ
    f = integ - 0.45
    a = x1
    x1 = a - (f/fp)
    print*, "x1: ",x1
    print*, "a: ",a
    print*, "f: ",f
    print*, "fp: ", fp
    print*, (x1-a)/n
end do

stop
end 

double precision function blub (x)
double precision :: x

blub(x) = (1.0d0/sqrt(2.0d0 * (4.0d0 * atan(1.0d0))))*exp((-x)**2.0d0/2.0d0)

return
end

我做了所有的印刷,以找出我的错误可能在哪里。我意识到我的dx基于x1小于n而变小。因为我的整数变成了一个数字,其中e ^ -310对0.45几乎没有影响,因此我的f保持不变,并且混淆x1 ......

如果有人能向我解释如何解决这个错误,那真是太棒了。

编辑:我确定我在梯形部分犯了一个错误,我只是不知道在哪里。 f应该随着每个循环而改变,但dx如此小以防止这种情况。

1 个答案:

答案 0 :(得分:2)

其中一个错误是这个。我并不认为它是唯一的一个:

double precision function blub (x)
double precision :: x

blub(x) = (1.0d0/sqrt(2.0d0 * (4.0d0 * atan(1.0d0))))*exp((-x)**2.0d0/2.0d0)

return
end

如果您使用gfortran -Wall -std=f95 -c fun.f90进行编译,则会获得

fun.f90:5.76:

lub(x) = (1.0d0/sqrt(2.0d0 * (4.0d0 * atan(1.0d0))))*exp((-x)**2.0d0/2.0d0)
                                                                           1
Warning: Obsolescent feature: Statement function at (1)
fun.f90:1.30:

double precision function blub (x)
                              1
Warning: Return value of function 'blub' at (1) not set

这可以提醒你一些奇怪的事情正在发生。实际上,您已在原始函数内创建了一个新的语句函数(一个过时的Fortran特性),而不是给它正确的值。你应该使用:

double precision function blub (x)
  implicit none
  double precision, intent(in) :: x

  blub = (1 / sqrt(8 * atan(1.0d0))) * exp((-x)**2 / 2)
end function

您可以忘记在return之前放置的stop结束end。没有理由使用它们。

我建议你使用更多的调试编译器标志,例如-g -fbacktrace -fcheck=all,并将所有函数和子程序放入模块中或将它们设置为内部(使用contains)。