Hi!
I am using some functions/subroutines from Numerical Recipes without any change.
Program contains only one calculation of gammp (incomplete gamma func.)
Code example (transcribed from NR):
CONTAINS
FUNCTION gammp(a,x)
! uses gser, gcf
END FUNCTION gammp
SUBROUTINE gser(gamser,a,x,gln)
! uses gammln
END SUBROUTINE gser
SUBROUTINE gcf(gammcf,a,x,gln)
! uses gammln
END SUBROUTINE gcf
FUNCTION gammln(xx)
REAL :: gammln,xx
END FUNCTION gammln
As You can see, function gammln is clearly defined.
But ifort (or MS linker) returns this error:
-out:gamma.exe
-subsystem:console
gamma.obj
gamma.obj : error LNK2019: unresolved external symbol _GAMMLN referenced in function _MAIN__
gamma.exe : fatal error LNK1120: 1 unresolved externals
PS: I am using ifort from command line.
I am using some functions/subroutines from Numerical Recipes without any change.
Program contains only one calculation of gammp (incomplete gamma func.)
Code example (transcribed from NR):
CONTAINS
FUNCTION gammp(a,x)
! uses gser, gcf
END FUNCTION gammp
SUBROUTINE gser(gamser,a,x,gln)
! uses gammln
END SUBROUTINE gser
SUBROUTINE gcf(gammcf,a,x,gln)
! uses gammln
END SUBROUTINE gcf
FUNCTION gammln(xx)
REAL :: gammln,xx
END FUNCTION gammln
As You can see, function gammln is clearly defined.
But ifort (or MS linker) returns this error:
-out:gamma.exe
-subsystem:console
gamma.obj
gamma.obj : error LNK2019: unresolved external symbol _GAMMLN referenced in function _MAIN__
gamma.exe : fatal error LNK1120: 1 unresolved externals
PS: I am using ifort from command line.
連結已複製
6 回應
This "Contains" is part of main source file, i have not created module.
Source file:
Program Gamma
IMPLICIT NONE
REAL :: T, base, integral
Print*, "T = "
READ*, T
Print*, "base = "
READ*, base
integral = gammp(base, t)
Print*, integral
READ(*,*)
CONTAINS
FUNCTION gammp(a,x)
REAL a,gammp,x
REAL gammcf,gamser,gln
if(x.lt.0..or.a.le.0.)pause 'bad arguments in gammp'
if(x.lt.a+1.)then
call gser(gamser,a,x,gln)
gammp=gamser
else
call gcf(gammcf,a,x,gln)
gammp=1.-gammcf
endif
return
END FUNCTION gammp
SUBROUTINE gser(gamser,a,x,gln)
INTEGER ITMAX
REAL a,gamser,gln,x,EPS
PARAMETER (ITMAX=100,EPS=3.e-7)
INTEGER n
REAL ap,del,sum,gammln
gln=gammln(a)
if(x.le.0.)then
if(x.lt.0.)pause 'x gamser=0.
return
endif
ap=a
sum=1./a
del=sum
do n=1,ITMAX
ap=ap+1.
del=del*x/ap
sum=sum+del
if(abs(del).lt.abs(sum)*EPS)goto 1
enddo
pause 'a too large, ITMAX too small in gser'
1 gamser=sum*exp(-x+a*log(x)-gln)
return
END SUBROUTINE gser
SUBROUTINE gcf(gammcf,a,x,gln)
INTEGER ITMAX
REAL a,gammcf,gln,x,EPS,FPMIN
PARAMETER (ITMAX=100,EPS=3.e-7,FPMIN=1.e-30)
INTEGER i
REAL an,b,c,d,del,h,gammln
gln=gammln(a)
b=x+1.-a
c=1./FPMIN
d=1./b
h=d
do i=1,ITMAX
an=-i*(i-a)
b=b+2.
d=an*d+b
if(abs(d).lt.FPMIN)d=FPMIN
c=b+an/c
if(abs(c).lt.FPMIN)c=FPMIN
d=1./d
del=d*c
h=h*del
if(abs(del-1.).lt.EPS)goto 2
enddo
pause 'a too large, ITMAX too small in gcf'
2 gammcf=exp(-x+a*log(x)-gln)*h
return
END SUBROUTINE gcf
FUNCTION gammln(xx)
REAL :: gammln,xx
INTEGER j
DOUBLE PRECISION ser,stp,tmp,x,y,cof(6)
SAVE cof,stp
DATA cof,stp/76.18009172947146d0,-86.50532032941677d0,24.01409824083091d0, &
-1.231739572450155d0,.1208650973866179d-2,-.5395239384953d-5,2.5066282746310005d0/
x=xx
y=x
tmp=x+5.5d0
tmp=(x+0.5d0)*log(tmp)-tmp
ser=1.000000000190015d0
do j=1,6
y=y+1.d0
ser=ser+cof(j)/y
enddo
gammln=tmp+log(stp*ser/x)
return
END FUNCTION gammln
END Program
Source file:
Program Gamma
IMPLICIT NONE
REAL :: T, base, integral
Print*, "T = "
READ*, T
Print*, "base = "
READ*, base
integral = gammp(base, t)
Print*, integral
READ(*,*)
CONTAINS
FUNCTION gammp(a,x)
REAL a,gammp,x
REAL gammcf,gamser,gln
if(x.lt.0..or.a.le.0.)pause 'bad arguments in gammp'
if(x.lt.a+1.)then
call gser(gamser,a,x,gln)
gammp=gamser
else
call gcf(gammcf,a,x,gln)
gammp=1.-gammcf
endif
return
END FUNCTION gammp
SUBROUTINE gser(gamser,a,x,gln)
INTEGER ITMAX
REAL a,gamser,gln,x,EPS
PARAMETER (ITMAX=100,EPS=3.e-7)
INTEGER n
REAL ap,del,sum,gammln
gln=gammln(a)
if(x.le.0.)then
if(x.lt.0.)pause 'x gamser=0.
return
endif
ap=a
sum=1./a
del=sum
do n=1,ITMAX
ap=ap+1.
del=del*x/ap
sum=sum+del
if(abs(del).lt.abs(sum)*EPS)goto 1
enddo
pause 'a too large, ITMAX too small in gser'
1 gamser=sum*exp(-x+a*log(x)-gln)
return
END SUBROUTINE gser
SUBROUTINE gcf(gammcf,a,x,gln)
INTEGER ITMAX
REAL a,gammcf,gln,x,EPS,FPMIN
PARAMETER (ITMAX=100,EPS=3.e-7,FPMIN=1.e-30)
INTEGER i
REAL an,b,c,d,del,h,gammln
gln=gammln(a)
b=x+1.-a
c=1./FPMIN
d=1./b
h=d
do i=1,ITMAX
an=-i*(i-a)
b=b+2.
d=an*d+b
if(abs(d).lt.FPMIN)d=FPMIN
c=b+an/c
if(abs(c).lt.FPMIN)c=FPMIN
d=1./d
del=d*c
h=h*del
if(abs(del-1.).lt.EPS)goto 2
enddo
pause 'a too large, ITMAX too small in gcf'
2 gammcf=exp(-x+a*log(x)-gln)*h
return
END SUBROUTINE gcf
FUNCTION gammln(xx)
REAL :: gammln,xx
INTEGER j
DOUBLE PRECISION ser,stp,tmp,x,y,cof(6)
SAVE cof,stp
DATA cof,stp/76.18009172947146d0,-86.50532032941677d0,24.01409824083091d0, &
-1.231739572450155d0,.1208650973866179d-2,-.5395239384953d-5,2.5066282746310005d0/
x=xx
y=x
tmp=x+5.5d0
tmp=(x+0.5d0)*log(tmp)-tmp
ser=1.000000000190015d0
do j=1,6
y=y+1.d0
ser=ser+cof(j)/y
enddo
gammln=tmp+log(stp*ser/x)
return
END FUNCTION gammln
END Program
Get rid of
Explanation: when you "glue together" different routines into single scope (as internal routines within the PROGRAM), you provide explicit interface, i.e. all other routines now "know" what GAMLN is. However, the (re)declaration "REAL GAMLN" says "ignore the neighboring GAMLN, there's another external GAMLN that you should use". Obviously, there isn't... thus the "unresolved external".
That's a common error when you "glue together" old F77 code into MODULEs or as internal routines: these FUNCTIONs were "bound" by EXTERNAL or REAL/INTEGER declarations, but once the code is merged, they become a burden.
REAL ... gamlndeclarations in routines other than gamln.
Explanation: when you "glue together" different routines into single scope (as internal routines within the PROGRAM), you provide explicit interface, i.e. all other routines now "know" what GAMLN is. However, the (re)declaration "REAL GAMLN" says "ignore the neighboring GAMLN, there's another external GAMLN that you should use". Obviously, there isn't... thus the "unresolved external".
That's a common error when you "glue together" old F77 code into MODULEs or as internal routines: these FUNCTIONs were "bound" by EXTERNAL or REAL/INTEGER declarations, but once the code is merged, they become a burden.
