如何通过双重集成解决方案

时间:2019-05-02 10:21:47

标签: fortran gfortran fortran90 fortran95

此双重积分的解决方案是-0.083,但在最终的汇编中,它显示为-Infinity。看来错误很简单,但我真的找不到它。

我一直在模块部分中进行特殊搜索,但看不到为什么它显示为-Infinity。例如,如果您更改它们之间的两个函数(f2中的x和f1中的x ^ 2),则积分的解决方案为0.083,并且代码给出正确的答案。 annyone可以找到错误吗?非常感谢。

module funciones

contains

function f(x,y)

implicit none

real*8:: x,y,f

f=2d0*x*y

end function

function f1(x)

real*8::x,f1

f1=x

end function


function f2(x)

real*8::x,f2

f2=x**2d0

end function

function g(x,c,d,h)

implicit none

integer::m,j

real*8::x,y,c,d,k,s,h,g

m=nint(((d-c)/h)+1d0)

k=(d-c)/dble(m)

s=0.

do j=1d0,m-1d0

y=c+dble(j)*k

s=s+f(x,y)

end do

g=k*(0.5d0*(f(x,c)+f(x,d))+s)

return

end function


subroutine trapecio(a,b,n,integral)

implicit none

integer::n,i

real*8::a,b,c,d,x,h,s,a1,a2,b1,b2,integral

h=(b-a)/dble(n)

s=0d0

do i=1d0,n-1d0

x=a+dble(i)*h

c=f1(x)

d=f2(x)

s=s+g(x,c,d,h)

end do


a1=f1(a)

a2=f2(a)

b1=f1(b)

b2=f2(b)

integral=h*(0.5d0*g(a,a1,a2,h)+0.5d0*g(b,b1,b2,h)+s)

end subroutine

end module



program main

use funciones

implicit none

integer::n,i

real*8::a,b,c,d,x,s,h,integral

print*, "introduzca los valores de a, b y n"

read(*,*) a, b, n

call trapecio (a,b,n,integral)

print*,integral

end program

主程序很简单,只需调用子例程并使用该模块即可。它还会打印最终结果。

1 个答案:

答案 0 :(得分:0)

首先,如评论中所述:您的问题尚不清楚。您使用哪些输入参数abn?期望得到什么结果?

除此之外:您发布的代码使用了不赞成使用的功能,非标准类型和错误的代码样式。 一些一般性提示:

  • real*8是非标准的Fortran。请改用real(real64)。 real64必须由use :: iso_fotran_env, only: real64.
  • 导入 do循环中的
  • 非整数表达式(do i=1d0,n-1d0)在现代Fortran中已删除。改用整数。
  • 代码应设置空格和缩进格式
  • print*,应替换为write(*,*)
  • 代码应始终使用英文名称
  • 在模块的开头而不是对每个功能都写implicit none
  • 使用语句privatepubliconly来使模块/程序接口更清晰
  • 如果要转换为类型real,请使用函数REAL代替DBLE
  • 我更喜欢使用result
  • 来定义更简洁的函数
  • 使用intent关键字:intent(in)将变量作为const引用传递。
  • 主程序中的变量c,d,x,s,h未使用。编译警告以检测未使用的变量。

这是根据我的建议更改的代码:

module funciones
use :: iso_fortran_env, only: real64
implicit none

private
public :: trapecio, r8

   integer, parameter :: r8 = real64

contains
   function f(x,y) result(value)
      real(r8), intent(in) :: x,y
      real(r8) :: value

      value = 2._r8*x*y
   end function

   function f1(x) result(value)
      real(r8), intent(in) :: x
      real(r8) :: value

      value = x
   end function

   function f2(x) result(value)
      real(r8), intent(in) :: x
      real(r8) :: value

      value = x**2._r8
   end function

   function g(x,c,d,h) result(value)
      real(r8), intent(in) :: x, c, d, h
      real(r8) :: value

      real(r8) :: y, k, s
      integer :: m, j

      m = NINT(((d-c)/h)+1._r8)
      k = (d-c)/REAL(m, r8)
      s = 0._r8
      do j = 1, m-1
         y = c + REAL(j,r8)*k
         s = s + f(x,y)
      end do

      value = k*(0.5_r8*(f(x,c)+f(x,d))+s)
   end function

   subroutine trapecio(a, b, n, integral)
      real(r8), intent(in) :: a, b
      integer, intent(in) :: n
      real(r8), intent(out) :: integral

      integer :: i
      real(r8) :: c, d, x, h, s, a1, a2, b1, b2
      h = (b-a)/REAL(n,r8)
      s = 0._r8

      do i = 1, n-1
         x = a + REAL(i,r8)*h
         c = f1(x)
         d = f2(x)
         s = s + g(x,c,d,h)
      end do

      a1 = f1(a)
      a2 = f2(a)
      b1 = f1(b)
      b2 = f2(b)
      integral = h*(0.5_r8*g(a,a1,a2,h) + 0.5_r8*g(b,b1,b2,h) + s)
   end subroutine
end module

program main
   use funciones, only: trapecio, r8

   implicit none

   integer :: n,i
   real(r8) :: a,b,integral

   write(*,*) "introduzca los valores de a, b y n"
   read(*,*) a, b, n
   call trapecio (a,b,n,integral)
   write(*,*) integral
end program