J'ai écrit un algorithme rudimentaire dans Fortran 95 pour calculer le gradient d'une fonction (dont un exemple est prescrit dans le code) en utilisant des différences centrales augmentées d'une procédure connue sous le nom d'extrapolation de Richardson.Incompatibilité de type de données dans fortran
function f(n,x)
! The scalar multivariable function to be 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 the gradient of the scalar function f at x=0using a finite !
! difference approximation, with a 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 the vector x and calculate the appropriate
! derivative
do i = 1,n
! Reset step size
h = h0
! Carry out M successive central difference approximations of the derivative
do 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 do
r = 0.d0
do 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) then
dfdxi = r(k)
exit
end if
end do
gradf(i) = dfdxi
end do
! Print out the gradient
write(*,*) " "
write(*,*) " Grad(f(x)) = "
write(*,*) " "
do i = 1,n
write(*,*) gradf(i)
end do
end program gradient
En simple précision, il fonctionne bien et me donne des résultats décents. Mais lorsque je tente de changer de double précision comme indiqué dans le code, je reçois une erreur lors de la tentative de compiler affirmant que la déclaration d'affectation
d(j) = (f(n,xhup) - f(n,xhdown))/(2.d0*h)
produit une incompatibilité de type real(4)/real(8)
. J'ai essayé plusieurs déclarations différentes de double précision, ajouté chaque constante double précision appropriée dans le code avec d0
, et j'obtiens la même erreur à chaque fois. Je suis un peu perplexe quant à la façon dont la fonction f
est susceptible de produire un nombre de précision unique.
Je ne vais pas même essayer de déboguer un code Fortran qui ne dit pas 'none' implicite au sein de chaque portée. Je vous suggère d'améliorer votre code et de modifier votre question une fois que vous l'aurez fait. –