De retour de la fonction d'incompatibilité de type
Je suis d'essayer de recoder un vieux C++ programme en Fortran pour faire usage de LAPACK (je suis conscient que C++ n'ont LAPACK++, mais je vais avoir beaucoup de mal à l'installer, donc j'ai abandonné).
A l'origine, je n'ai aucun problème à la compilation, mais c'était quand j'ai eu toutes les variables déclarées comme REAL
. Quand j'ai commencé à coder la section du programme requis LAPACK, j'ai trouvé que tous les paramètres passés à DSYEV
doivent être DOUBLE PRECISION
. J'ai donc essayé de tout changer à la double précision (y compris le changement de tous codés en dur nombres double précision homologues, c'est à dire 0.0 -> 0.0D0) Maintenant, quand j'essaie de compiler, j'obtiens l'erreur suivante pour toutes les fonctions et sous-routines que j'ai écrit:
Error: Return type mismatch of function <function> at (1) (REAL(4)/REAL(8))
Je ne sais pas d'où ça vient, comme tout dans le programme a été modifié pour la double précision.
Par exemple, j'ai déclaré la suivante:
double precision :: alpha(3),d(3),zeta1,zeta2
double precision :: A1(3),A2(3),D1(3),D2(3)
double precision :: PI
PI = 3.14159265359D0
alpha = (/0.109818D0, 0.405771D0, 2.22766D0/)
d = (/0.444635D0, 0.535328D0, 0.154329D0 /)
do 10 i=1,3
A1(i) = alpha(i)*zeta1**2.0D0
A2(i) = alpha(i)*zeta2**2.0D0
D1(i) = d(i)*(2.0D0*A1(i)/PI)**(3.0D0/4.0D0)
D2(i) = d(i)*(2.0D0*A2(i)/PI)**(3.0D0/4.0D0)
10 continue
Et la fonction:
subroutine createS(S,A1,A2,D1,D2,r)
double precision A1(3),A2(3),D1(3),D2(3)
double precision r
double precision S(2,2)
integer :: i,j
S(1,1) = 1.0D0
S(2,2) = 1.0D0
do 80 i=1,3
do 90 j=1,3
S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)
90 continue
80 continue
S(2,1) = S(1,2)
return
end
double precision function getS(a,b,r)
double precision :: PI
double precision a,b,r
double precision :: S
PI = 3.14159265359D0
S = (PI/(a+b))**1.5D0
S = S*dexp(-(a*b*r*r)/(a+b))
getS = S
return
end
Et puis j'ai l'erreur
HFSTO3G.f:85.28:
S(1,2) = S(1,2) + getS(A1(i),A2(j),r)*D1(i)*D2(j)
1
Error: Return type mismatch of function 'gets' at (1) (REAL(4)/REAL(8))
Je suis en utilisant gfortran à compiler. Pourrait-il être le problème? Je ne suis pas nouvelle à la programmation, mais les nouvelles de Fortran. Pas de programmation de ce en Fortran n'est pas une option.
- il y a aussi d'autres bibliothèques en C++ qui ne l'algèbre linéaire, pour n'en citer une alternative 🙂
Vous devez vous connecter pour publier un commentaire.
Avez-vous mis votre sous-routines et fonctions dans un module et
use
ce module? Sinon, probablement ce qui se passe c'est que vous avez de typage implicite est dans le sous-programme crée comme une simple précision réel, mais il retourne en fait un double précision. Une autre suggestion: utilisez toujoursimplicit none
pour trouver variable non déclarée. Dans le cas où vous oubliez d'inclureimplicit none
dans votre code source, gfortran fournit les options du compilateur-fimplicit-none
. Typage implicite est pernicieuse et probablement continué en Fortran pour soutenir le code de legs.P. S.
double precision
est aussi obsolète, mais beaucoup moins risqué que de typage implicite. Si vous avez une version récente de gfortran vous pouvez utiliser les éléments suivants:Voir le gfortran manuel.
EDIT: Le
implicit none
changé le type de obtient à partir de la réalité(4) (par typage implicite) à l'inconnu (pas de type déclaré, typage implicite désactivé). Si vous placez les procédures dans un module, ils "savent" des uns et des autres types: la fonction retourne et les types d'argument. Cela va corriger ce bug. Il aide également le compilateur trouver d'autres bugs mais permettant de vérifier la cohérence des arguments entre l'appel et les arguments de la procédure. Voir Utilisation correcte des modules, fonctions et sous-routines en fortran et Le calcul du produit vectoriel de deux vecteurs en Fortran 90 pour des exemples.Vous n'êtes pas déclarer
getS
une fonction dans la sous-routinecreateS
. Vous devez ajouterdouble precision, external :: getS
dans vos déclarations de variables de la sous-routinecreateS
.external
moderne Fortran. Si la fonction est en Fortran et vous avez le code source, de le mettre dans un module etuse
ce module. Si il est dans une autre langue ou dans une bibliothèque et que vous n'avez pas le code source, puis à rédiger uninterface
déclaration pour elle. À la fois l'interface et le module va vous donner l'argument de la vérification de la cohérence. Une interface explicite est nécessaire d'utiliser de nombreuses fonctionnalités "avancées" du Fortran >=90.contains
au sein de la sous-routinecreateS
).remplacer double précision avec: