floating point - Data type mismatch in fortran -
i've written rudimentary algorithm in fortran 95 calculate gradient of function (an example of prescribed in code) using central differences augmented procedure known richardson extrapolation.
function f(n,x) ! scalar multivariable function differentiated  integer :: n real(kind = kind(1d0)) :: x(n), f  f = x(1)**5.d0 + cos(x(2)) + log(x(3)) - sqrt(x(4))  end function f !=====! !=====! !=====!  program gradient !==============================================================================! ! calculates gradient of scalar function f @ x=0using finite        ! ! difference approximation, low order richardson extrapolation.         ! !==============================================================================!  parameter (n = 4, m = 25) real(kind = kind(1d0)) :: x(n), xhup(n), xhdown(n), d(m), r(m), dfdxi, h0, h, gradf(n)  h0 = 1.d0 x  = 3.d0  ! loop through each component of vector x , calculate appropriate ! derivative = 1,n ! reset step size h = h0      ! carry out m successive central difference approximations of derivative j = 1,m         xhup = x         xhdown = x         xhup(i) = xhup(i) + h         xhdown(i) = xhdown(i) - h         d(j) = ( f(n,xhup) - f(n,xhdown) ) / (2.d0*h)     h = h / 2.d0     end      r = 0.d0     k = 3,m      r(k) = ( 64.d0*d(k) - 20.d0*d(k-1) + d(k-2) ) / 45.d0         if ( abs(r(k) - r(k-1)) < 0.0001d0 )         dfdxi = r(k)             exit         end if     end      gradf(i) = dfdxi end  ! print out gradient write(*,*) " " write(*,*) " grad(f(x)) = " write(*,*) " " = 1,n     write(*,*) gradf(i) end  end program gradient   in single precision runs fine , gives me decent results. when try change double precision shown in code, error when trying compile claiming assignment statement
d(j) = ( f(n,xhup) - f(n,xhdown) ) / (2.d0*h)   is producing type mismatch real(4)/real(8).  have tried several different declarations of double precision, appended every appropriate double precision constant in code d0, , same error every time.  i'm little stumped how function f possibly producing single precision number.
the problem f not explicitely defined in main program, therefore implicitly assumed of single precision, type real(4) gfortran.
i agree comment of high performance mark, should use implicit none in fortran code, make sure object explicitely declared. way, have obtained more appropriate error message f not being explicitely defined.
also, consider 2 more things:
define function within module , import module in main program. practice define subroutines/functions within modules only, compiler can make checks on number , type of arguments, when invoke function.
you (again in module) introduce constant precicision , use everywhere, kind of real must specified. taking example below, changing line
integer, parameter :: dp = kind(1.0d0)into
integer, parameter :: dp = kind(1.0)you change real variables double single precision. note
_dpsuffix literal constants instead ofd0suffix, automatically adjust precision well.module accuracy implicit none integer, parameter :: dp = kind(1.0d0) end module accuracy module myfunc use accuracy implicit none contains function f(n,x) integer :: n real(dp) :: x(n), f f = 0.5_dp * x(1)**5 + cos(x(2)) + log(x(3)) - sqrt(x(4)) end function f end module myfunc program gradient use myfunc implicit none real(dp) :: x(n), xhup(n), xhdown(n), d(m), r(m), dfdxi, h0, h, gradf(n) : end program gradient
Comments
Post a Comment