- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Are both the main program and GAMMLN in the same source file?
- What is that CONTAINS statement part of?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Given that you show a CONTAINS, I assume that this source defines a MODULE. That means you must add a USE of that module name in your program that calls GAMMLN.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PS: Compilation without line
"integral = gammp(base, t)" returns no error message.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank You, problem solved!

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page