For Programmers: Free Programming Magazines  


Home > Archive > Fortran > April 2005 > Using .f files with .f90 codes: Symbol Referencing error









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Using .f files with .f90 codes: Symbol Referencing error
student

2005-04-22, 3:57 am


Hi!

I am trying to call a function inside a .f file using a subroutine
inside a .f90 file. However, i get a symbol referencing error while
compilation. can anyone help me sort that out?

the subroutine source is as follows:

INCLUDE 'matrixoperations.f90'

SUBROUTINE gibbsnorm(X,mean,varcov,sample)
use matrix
IMPLICIT NONE
REAL, DIMENSION(:) :: mean,X
REAL, DIMENSION(:,:) :: varcov
REAL, DIMENSION(size(mean,1)), INTENT(OUT) :: sample
REAL, DIMENSION (size(mean,1),size(mean,1)) :: delta
REAL :: av,sd
INTEGER :: m,i,j,k
REAL, EXTERNAL :: gennor

IF (size(mean,1)/=size(X,1)) THEN
WRITE (*,*) "Error in gibbs sampler procedure: The dimension of
the initial
value matrix is not the same as the mean matrix!!"
STOP
end IF


IF (size(varcov,1)/=size(varcov,2)) THEN
WRITE(*,*) "Error in gibbs sampler procedure: The
variance-covariance matrix is
not square!!"
STOP
end IF

IF (size(mean,1)/=size(varcov,1)) THEN
WRITE (*,*) "Error in gibbs sampler procedure: The dimension of
variance-covariance matrix is not the same as the mean matrix!"
STOP
end IF

m = size(mean,1)


delta = inv(varcov) !inverse of the variance-covariance matrix


DO k = 1,5 ! throw away the first 4 samples from the Gibbs' scheme
DO i = 1,m
av = mean(i)
sd = 1/delta(i,i) ! variance of the conditional distribution of
the i-th
variable given the rest


!! Calculation of the mean of the conditional distribution follows

DO j = 1,m
av = av -
(X(i)-mean(i))*(delta(i,k)+delta(k,i))/(2*delta(k,k))
end DO
av = av + (X(k)-mean(k))! mean of the conditional distribution
of the i-th
variable given the rest


X(i)=gennor(av,sd) ! sampling from the conditional density, and
updating value
end DO
end DO

DO i = 1,m
sample(i) = X(i) !save the fifth sample
end DO

end SUBROUTINE gibbsnorm




the .f file content is as follows:

REAL FUNCTION gennor(av,sd)
C***************************************
*******************************
C
C REAL FUNCTION GENNOR( AV, SD )
C
C GENerate random deviate from a NORmal distribution
C
C
C Function
C
C
C Generates a single random deviate from a normal distribution
C with mean, AV, and standard deviation, SD.
C
C
C Arguments
C
C
C AV --> Mean of the normal distribution.
C REAL AV
C
C SD --> Standard deviation of the normal distribution.
C REAL SD
C JJV (SD >= 0)
C
C GENNOR <-- Generated normal deviate.
C REAL GENNOR
C
C
C Method
C
C
C Renames SNORM from TOMS as slightly modified by BWB to use RANF
C instead of SUNIF.
C
C For details see:
C Ahrens, J.H. and Dieter, U.
C Extensions of Forsythe's Method for Random
C Sampling from the Normal Distribution.
C Math. Comput., 27,124 (Oct. 1973), 927 - 937.
C
C
C***************************************
*******************************
C .. Scalar Arguments ..
REAL av,sd
C ..
C .. External Functions ..
REAL snorm
EXTERNAL snorm
C ..
C .. Executable Statements ..
C JJV added check to ensure SD >= 0.0
IF (sd.GE.0.0) GO TO 10
WRITE (*,*) 'SD < 0.0 in GENNOR - ABORT'
WRITE (*,*) 'Value of SD: ',sd
STOP 'SD < 0.0 in GENNOR - ABORT'

10 gennor = sd*snorm() + av
RETURN

END

Richard E Maine

2005-04-22, 3:59 pm

In article <1114145232.425888.45630@o13g2000cwo.googlegroups.com>,
"student" <adarsh@stat.tamu.edu> wrote:

> Hi!
>
> I am trying to call a function inside a .f file using a subroutine
> inside a .f90 file. However, i get a symbol referencing error while
> compilation. can anyone help me sort that out?


Well, what's the error? Specifically and exactly. I'm not going to
carefully read through that much code to try to guess what an error
might be. And I can't throw it at a compiler because you didn't also
include the included "matrixoperations.f90" file. Note that there
is no essential difference between what you call a ".f file" and a
".f90" file. Many (most?) compilers default to assuming that ".f" files
are in fixed source form and ".f90" files are in free source form, but
this is not a fundamental property of those file names.

Though I didn't read through the code carefully, one thing that
immediately jumped out at me even when skimming was possibly the same
issue as you had in another post, which Giles answered. You have some
lines that are either awfully long or are incorrectly continued (it is
hard to tell because of possible line wrapping by new posting software).
I didn't count, but some of the lines sure look long.

For fixed source form, the main body of the statements needs to be
between columns 7 and 72 inclusive. For free source form it is columns 1
to 132. If you need to go to more than one line, you have to do
something to indicate the continuation (details later if needed - they
vary depending on source form); you can't just continue typing on
another line as though there were no difference.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
student

2005-04-22, 3:59 pm

Alright Richard.. thanks for your reply.. let me explain the whole
situation. the uname -X command on the system that I am working on has
the following output:

bash-2.03$ uname -X
System = SunOS
Node = hartley
Release = 5.8
KernelID = Generic_108528-27
Machine = sun4u
BusType = <unknown>
Serial = <unknown>
Users = <unknown>
OEM# = 0
Origin# = 1
NumCPU = 2

The gibbsnorm.f90 code is in a directory, and the gennor.f code is in
the directory: ./randlib.f/src/ . "randlib.f/src/" is a library of
random number generator functions.

now i get the following message when trying to compile:

--------------------------------
bash-2.03$ f90 gibbsnorm.f90 -L.randlib.f/src
Undefined first referenced
symbol in file
main /local/SUNWspro/WS6U2/lib/crt1.o
gennor_ gibbsnorm.o
ld: fatal: Symbol referencing errors. No output written to a.out
--------------------------------


the source matrixoperations.f90 which was included in the same
directory as gibbsnorm.f90 is as pasted below. Also, I realized after
my previous posting that the subroutine gibbsnorm.f90 is using assumed
shape arrays and hence needs an explicit interface. so, i put it inside
a module. I had already corrected the length of the statements as the
Giles pointed out, and I don't get the delimiter error anymore. The
file gibbsnorm.f90 compiles well when linking is suppressed; so the
error is somewhere in linking. Please let me know if you need anymore
information.


Thanks


---------------------------------------------------
MODULE matrix

CONTAINS


real function inv(A) result(In)

IMPLICIT NONE
REAL,DIMENSION(:,:) :: A
INTEGER :: m
REAL :: x,y
INTEGER::i,j,k,l
REAL,DIMENSION(size(A,1),2*size(A,2)) :: B
REAL,DIMENSION(size(A,1),size(A,2)) :: In

m=size(A,1)

IF (size(A,1)/=size(A,2)) THEN
WRITE(*,*) "Error in the inverse procedure: Matrix not square"
STOP
end IF

DO i=1,m
DO j=1,m
B(i,j)=A(i,j)
end DO
DO j=(m+1),2*m
IF((j-m)==i) then
B(i,j)=1
else
B(i,j)=0
end IF
end DO
end DO

DO i=1,m
x=B(i,i)
IF (x /= 0) THEN
DO j=i,2*m
B(i,j)=B(i,j)/x
end DO
IF (i>1) THEN
DO k=1,i-1
y=B(k,i)
DO l=i,(2*m)
B(k,l)=B(k,l)-y*B(i,l)
end DO
end DO
ENDIF

IF (i<m) THEN
DO k=i+1,m
y=B(k,i)
DO l=i,(2*m)
B(k,l)=B(k,l)-y*B(i,l)
end DO
end DO
ENDIF
ELSE
WRITE(*,*) "Error in the inverse procedure: Singular Matrix"
STOP
ENDIF
end DO

DO i=1,m
DO j=1,m
In(i,j)=B(i,j+m)
ENDDO
ENDDO

end function inv











real function trans(A) result(B)
IMPLICIT NONE
INTEGER::i,j
REAL,DIMENSION(:,:) :: A
REAL,DIMENSION(size(A,2),size(A,1)) :: B

DO i=1,size(A,1)
DO j=1,size(A,2)
B(i,j)=A(j,i)
end DO
end DO

end function trans











real function add(A,B) result(C)
IMPLICIT NONE
INTEGER::i,j
REAL,DIMENSION(:,:) :: A,B
REAL,DIMENSION(size(A,1),size(A,2)) :: C

IF ((size(A,1)/=size(B,1)).OR.((size(A,2)/=size(B,2)))) THEN
WRITE(*,*) "Error in the addition procedure: Matrix dimensions
not compatible!"
STOP

ELSE

DO i=1,size(A,1)
DO j=1,size(A,2)
C(i,j) = A(i,j) + B(i,j)
end DO
end DO
ENDIF

end function add









real function difference(A,B) result(C)
IMPLICIT NONE
INTEGER::i,j
REAL,DIMENSION(:,:) :: A,B
REAL,DIMENSION(size(A,1),size(A,2)) :: C

IF ((size(A,1)/=size(B,1)).OR.((size(A,2)/=size(B,2)))) THEN
WRITE(*,*) "Error in the addition procedure: Matrix dimensions
not compatible!"
STOP

ELSE

DO i=1,size(A,1)
DO j=1,size(A,2)
C(i,j) = A(i,j) - B(i,j)
end DO
end DO
ENDIF

end function difference






SUBROUTINE printmatrix(A)
IMPLICIT NONE
REAL,DIMENSION(:,:) :: A
INTEGER :: i,j

DO i = 1,size(A,1)
WRITE(*,*) (A(i,j),j=1,size(A,2))
end DO
WRITE(*,*) ""
end SUBROUTINE printmatrix

end MODULE matrix
----------------------------------------------------------------------

beliavsky@aol.com

2005-04-22, 3:59 pm


student wrote:
> Hi!
>
> I am trying to call a function inside a .f file using a subroutine
> inside a .f90 file. However, i get a symbol referencing error while
> compilation. can anyone help me sort that out?
>
> the subroutine source is as follows:
>
> INCLUDE 'matrixoperations.f90'


General comment: I don't think using INCLUDing a file with a lot of
source code is good practice.

If file a.90 includes b.f90, it is better to remove the INCLUDE and
just add b.f90 to the list of files to be compiled to create an
executable, unless there are unusual circumstances. If a.f90 USEs
b.f90, put b.f90 before a.f90 in the compilation list.

INCLUDE was useful in Fortran 77 for small files containing PARAMETERs
and similar uses, but from Fortran 90 onwards it is better IMO to use
MODULEs. I think it's a little amusing that committee added INCLUDE to
the language when the need for it diminished. I guess it was so common
in F77 compilers that they decided to standardize it. Maybe it's still
useful as a crude way of doing generic programming in Fortran.

If you send the code to my email beliavsky at aol dot com I can look at
it on Saturday.

Richard E Maine

2005-04-22, 3:59 pm

In article <1114183153.221452.299940@z14g2000cwz.googlegroups.com>,
"student" <adarsh@stat.tamu.edu> wrote:


> The gibbsnorm.f90 code is in a directory, and the gennor.f code is in
> the directory: ./randlib.f/src/ . "randlib.f/src/" is a library of
> random number generator functions.
>
> now i get the following message when trying to compile:


Ah. I half wondered about asking for clarification of whether it was
really a compilation error, but I see that you answered without me
having to ask. Good. This isn't actually a compilation error. This is
an error in linking (the linker is named "ld"). The compiler has
finished and has invoked the linker sort of "behind your back". I
understand how you might think of it as during compilation because you
just use the name of the compiler to do it all, but the class of errors
you see during linking is different from those you see during
compilation. Anyway...

> bash-2.03$ f90 gibbsnorm.f90 -L.randlib.f/src
> Undefined first referenced
> symbol in file
> main /local/SUNWspro/WS6U2/lib/crt1.o
> gennor_ gibbsnorm.o
> ld: fatal: Symbol referencing errors. No output written to a.out


Two errors here. The first is the undefined symbol "main". Where is your
main program? I don't see one... and neither does the linker. All you
have are subroutines and functions. Somewhere, at the top level, you
need a main program to get it all going. Did you just omit the main
program or perhaps should one of your subroutines really be the main
program?

The second is that the linker couldn't find gennor; ignore the
underscore at the end - that's an artifact of name mangling. I think
that the secret to that problem is in the command line you used rather
than in the source code (so I'm glad you showed the command line).

You mentioned that ranlib.f/src (aka ./ranlib.f/src) is a library. Well,
three things about that.

1. Look carefully at your command line; it has neither "./ranlib.f/src"
nor "ranlib.f/src". Instead it has ".ranlib.f/src". The other 2 forms
are equivalent, but that one isn't.

2. A directory isn't a library. The difference matters. There might be a
library in the directory, but the directory itself is not the library.
Hmm. I was just explaining things about this same unix command-line
library stuff to someone else here a few days ago. Anyway... the -L
switch just says to look in that directory when searching for libraries,
but you haven't told it any libraries to look for, so the -L is pretty
irrelevant (even after you fix the path name). You'll also need an
appropriate -l (lower case "ell") switch to tell it to look for a
specific library. The name after the -l will automatically get "lib"
prepended and ".a" appended, so that, for example, -lstuff will look for
a library named "libstuff.a". Alternatively, you can dispense with the
-L and -l business and just put the path to the library itself on the
command line; the -L bit is mostly useful if you have multiple libraries
in the same directory or if you want to make it handy to chang ethe
directory name independently of the library name.

3. Not your problem - just a piece of personal style preference trivial:
I find is slightly unusual to use ".f" as a directory name suffix. I
have seen it before, but I don't recommend it. You are likely, for
example, to run into problems with makefiles or scripts that assume
anything ending in ".f" is a source file (an actual source file - not a
directory containing source). Nothing actually wrong here - just a style
suggestion.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
student

2005-04-23, 3:57 am

Thanks richard, my program's working now.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com