Numerical differentiation in Fortran

时间:2017-04-24 17:22:31

标签: function fortran

My code doesn't compile, I keep having the message ta5p =(f(x+2.d0*h)-2.d0*f(x+h)+2.d0*f(x-h))/(2.d0*(h**3)) 1 Error: Function 'f' at (1) has no IMPLICIT type and Incompatible ranks 0 and 1 in assignment at (1)

I need to create a program that computes the difference (o(i) i = 1,n) between the exact derivative and the numerical derivative. That was applied for some higher-order methods, that are indicated in my program as s2p,t2p, s3p, s5p, ss3p, ss5p and ta5p. The first, second and third derivative are defined as df, d2f and d4f, respectively. I tried to use functions in this so my loop remains organized, which made my program really big.

The input is a table "tab1_in.dat" that informs, on the first line, the number of different values (n) of h, a constant in numerical differentiation, and on second line, what are the values of h.

Here is the code

   program numerical differentiation
      implicit none
      integer i, n
      real*8 h(100), o(7)
      real*8, parameter :: x0 = 1.d0/3.d0 
      open(10,file = "tab1_in.dat")
      read(10,*)n        !receives the number of different values of h
      read(10,*) (h(i), i = 1,n)  !receive the values of h
      do i = 1,n
     !Calculates the deviation between the two types of differentiation

         o(1) = df(x0) - f2p(x0, h(k))
         o(2) = df(x0) - t2p(x0, h(k))
         o(3) = df(x0) - s3p(x0, h(k))
         o(4) = df(x0) - s5p(x0, h(k))
         o(5) = d2f(x0) - ss3p(x0, h(k))
         o(6) = d2f(x0) - ss5p(x0, h(k))
         o(7) = d3f(x0) - ta5p(x0, h(k))
         write(*,*) o(1),o(2),o(3),o(4),o(5),o(6),o(7)
      end do

      contains      
      real*8 Function f(x)  !the function that is being analyzed
      real*8 x
           f = (exp(4.d0*x))*(dcos(x/2.d0))
      end function f

      real*8 Function df(x) !first derivative of f(x)
      real*8 x
           df = (exp(4.d0*x))*(dcos(x/2.d0))
           df = 4.d0*df - (1.d0/2.d0)*(exp(4.d0*x))*dsin(x/2.d0)
      end function df

      real*8 Function d2f(x) !second derivative of f(x)
      real*8 x
           d2f = (exp(4.d0*x))*(dcos(x/2.d0))
           d2f = (63.d0/4.d0)*d2f - 4.d0*exp((4.d0*x))*dsin(x/2.d0)
      end function d3f

      real*8 Function d3f(x)    !third derivative of f(x)
      real*8 x
           d3f = 61.d0*(exp(4.d0*x))*[dcos(x/2.d0))
           d3f = d3f - (191.d0/8.d0)*(exp(4.d0*x))*dsin(x/2.d0)
      end function d3f
       !higher-order of numerical derivative
      real*8 Function f2p(x,h)
      real*8 x, h
           f2p = (f(x + h)/h) - (f(x)/h)
      end function f2p

      real*8 function t2p(x,h)
      real*8 x, h
           t2p = (f(x) - f(x - h))/h
      end function t2p

      real*8 function s3p(x,h)
     real*8 x, h
           s3p = (f(x + h) - f(x - h))/(2.d0*h)
      end function s3p

      real*8 function s5p(x,h)
      real*8 x,h
           s5p=(f(x+2.d0*h)-8.d0*f(x+h)+8.d0*f(x-h)-f(x2.d0*h))/(12.d0*h)
      end function s5p

      real*8 function ss3p(x,h)
      real*8 x,h
           ss3p = (f(x+h)-2.d0*f(x)+f(x-h))/(h**2.d0)
      end function ss3p

      real*8 function ss5p(x,h)
      real*8 x,h
           ss5p =(-f(x+2.d0*h)+16.d0*f(x+h)-30.d0*f(x))/(12.d0*(h**2.d0))
           ss5p = ss5p+(16.d0*f(x+h)-f(x-2.d0*h))/(12.d0*(h**2.d0))
      end function ss5p

      real*8 function ta5p(x,h)
      real*8 x,h
           ta5p =(f(x+2.d0*h)-2.d0*f(x+h)+2.d0*f(x-h))/(2.d0*(h**3))
           ta5p = ta5p + (-f(x-2.d0*h))/(2.d0*(h**3))
      end function ta5p
   end program numerical differentiation

1 个答案:

答案 0 :(得分:0)

事实证明,我在编辑器vi的水平方向上使用了太多空间,因此它甚至没有显示警告该问题的橙色。

有趣的是我制作了另一个代码,但这两个代码的结果不同。在我的第二个代码中,我在循环之前定义了x = 1/3的精确导数,然后,在循环内我定义了数值导数,也用于x = 1/3,仅使用函数f(x)相同它是上面写的方式。所以我的逻辑出了问题,我需要弄明白。无论如何,谢谢你的帮助。