tags:

views:

36

answers:

1

I'm trying to write a program with a function which returns a matrix with a random number on the diagonal, 1s on the sub-diagonals and 0s everywhere else. So, I wrote this function:

    real function am1d
    do i=1,L
        do j=1,L
            if (i.eq.j) then
                am1d(i,j)=rand()*w-w/2.
            elseif ((i-j.eq.1) .or. (j-i.eq.1)) then
                am1d(i,j)=1
            else am1d(i,j)=0
        enddo
    enddo
end function am1d

And tried to call it from here (in the same source file, just above the function)

    program make3d
    integer, parameter :: L = 20
    real, parameter    :: w = 0.5
    real :: x


    !x=rand(1234)   ! seed random manually
    x=rand(itime)   ! seed random from current local time
    print *,am1d()(:)


end program make3d

But trying to compile this throws the error:

   $ f95 make3d.f
make3d.f:18.21:

       print *,am1d()(:)                                                
                     1
Error: Syntax error in PRINT statement at (1)
make3d.f:7.72:

      program make3d                                                    
                                                                        1
make3d.f:24.72:

      real function am1d                                                
                                                                        2
Error: Two main PROGRAMs at (1) and (2)

What does that mean? I didn't think a function could ever be a program? I've had small logical functions underneath the endprogram statement before, without any trouble.

+2  A: 

If you want function am1d to return an array, you need to declare it as such. There were several other syntax errors. The compiler got confused .... Did you forget the "contains" statement ... without that or a module, the compiler wouldn't "know" what to do with another procedure and might try to interpret it as second main program.

Try:

program make3d
    integer, parameter :: L = 20
    real, parameter    :: w = 0.5
    real :: x

    x=rand(1234)   ! seed random manually
    !x=rand(itime)   ! seed random from current local time
    write (*, *) am1d()

stop

contains

function am1d ()
real, dimension (L,L) :: am1d
    integer i, j
    do i=1,L
        do j=1,L
            if (i.eq.j) then
                am1d(i,j)=rand()*w-w/2.
            elseif ((i-j.eq.1) .or. (j-i.eq.1)) then
                am1d(i,j)=1
            else 
               am1d(i,j)=0
            end if
        enddo
    enddo
end function am1d

end program make3d

or place the routine in a module, which I think provides a clearer and cleaner interface (makes variable communication explicit) -- then you will need to "use" the module in the main program and to pass w and L as arguments:

module a_mod

contains

function am1d (w,L)
real, intent (in) :: w
integer, intent (in) :: L
real, dimension (L,L) :: am1d

.....
end function am1d


end module a_mod
M. S. B.
Thank you, that's sorted it. I knew there was more wrong with it, didn't realise that could confuse the compiler into a strange error message.Incidentally, I then came up against this: https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/577881as I'm compiling code over sftp. Compiling locally avoids that.
Gyppo