Why is the 'aroot' Symbol Causing an IMPLICIT Type Error in Fortran?

  • Context: Fortran 
  • Thread starter Thread starter Bashkir
  • Start date Start date
  • Tags Tags
    Fortran Type
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
10 replies · 6K views
Bashkir
Messages
31
Reaction score
1
I'm writing a subroutine for solving Newton's method for the root of a function and I am coming across an interesting problem. This is the start of my code, where it is says the error is occurring

SUBROUTINE Newton(f, x1, x2, dx, aroot, error)

IMPLICIT NONE

! Declare Arguments
REAL, EXTERNAL :: f
REAL, INTENT(IN) :: x1
REAL, INTENT(IN) :: X2
REAL, INTENT(IN) :: dx
REAL, INTENT(OUT) : aroot
INTEGER, INTENT(OUT) :: error

! Declare parameter:
REAL, PARAMETER :: epsilon = 1.0E-5 ! Convergence criterion

!Declare local variables:
LOGICAL :: l_value_a ! True if f(xa) > 0
LOGICAL :: l_value_b ! True if f(xb) > 0
LOGICAL :: l_value_m ! True if f(xm) > 0
INTEGER :: i ! Index variable
INTEGER :: n ! Number of iterations
REAL :: value_a, value_b, value_m ! f(xa), f(xb), f(xm)
REAL :: xa, xb, xm ! Start, middle, end of interval


Now, when I try to compile the whole routine it gives me this error

REAL, INTENT(OUT) : aroot
1
Error: Invalid character in name at (1)
Newton.f90:1.38:

SUBROUTINE Newton(f, x1, x2, dx, aroot, error)
1
Error: Symbol 'aroot' at (1) has no IMPLICIT type

I'm really not sure where I am going wrong here. Any help would be appreciated. Thank you!
 
Physics news on Phys.org
Bashkir said:
I'm writing a subroutine for solving Newton's method for the root of a function and I am coming across an interesting problem. This is the start of my code, where it is says the error is occurring

SUBROUTINE Newton(f, x1, x2, dx, aroot, error)

IMPLICIT NONE

! Declare Arguments
REAL, EXTERNAL :: f
REAL, INTENT(IN) :: x1
REAL, INTENT(IN) :: X2
REAL, INTENT(IN) :: dx
REAL, INTENT(OUT) : aroot
INTEGER, INTENT(OUT) :: error

! Declare parameter:
REAL, PARAMETER :: epsilon = 1.0E-5 ! Convergence criterion

!Declare local variables:
LOGICAL :: l_value_a ! True if f(xa) > 0
LOGICAL :: l_value_b ! True if f(xb) > 0
LOGICAL :: l_value_m ! True if f(xm) > 0
INTEGER :: i ! Index variable
INTEGER :: n ! Number of iterations
REAL :: value_a, value_b, value_m ! f(xa), f(xb), f(xm)
REAL :: xa, xb, xm ! Start, middle, end of interval


Now, when I try to compile the whole routine it gives me this error

REAL, INTENT(OUT) : aroot
1
Error: Invalid character in name at (1)
Newton.f90:1.38:

SUBROUTINE Newton(f, x1, x2, dx, aroot, error)
1
Error: Symbol 'aroot' at (1) has no IMPLICIT type

I'm really not sure where I am going wrong here. Any help would be appreciated. Thank you!

Do you notice any difference between the line that's colored and the rest?
REAL, EXTERNAL :: f
REAL, INTENT(IN) :: x1
REAL, INTENT(IN) :: X2
REAL, INTENT(IN) :: dx
REAL, INTENT(OUT) : aroot[/color]
INTEGER, INTENT(OUT) :: error
 
Even with a double colon it still gives me the same error.
 
Bashkir said:
Even with a double colon it still gives me the same error.
The same error? The two errors in the OP specifically cited aroot.

REAL, INTENT(OUT) : aroot
1
Error: Invalid character in name at (1)
Newton.f90:1.38:

SUBROUTINE Newton(f, x1, x2, dx, aroot, error)
1
Error: Symbol 'aroot' at (1) has no IMPLICIT type

If the new errors are actually different, please show them.
 
Okay, haha. Adding the double colon did change things.


/usr/lib/gcc/x86_64-redhat-linux/4.4.7/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status

Is what I am getting with a double colon.
 
Bashkir said:
Okay, haha. Adding the double colon did change things./usr/lib/gcc/x86_64-redhat-linux/4.4.7/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status

Is what I am getting with a double colon.

Do you have a function named main? Please post all of your code.

This doesn't seem to be a syntax error that the compiler catches. I think that it might be a linker error. Have you been able to run any of your Fortran code? If not, you might not have things set up correctly.
 
Last edited:
it looks like an attempt to produce a final executable out of a file that only contains a subroutine...you need a main program where to call the sub from.
Code:
program mymain
.
.
.
contains
    subroutine Newton

    end subroutine Newton
end program mymain

Or, if you already have a main somewhere else, then, you are NOT suppose to compile this given file into an executable, just into *.o file, first and then you link all your *.o into an *.exe or no extension whatsoever a-la-linux
 
Last edited by a moderator:
Gsal -- I am trying to compile it into a -o.

The Full code, is this.

SUBROUTINE Newton ( f, x1, x2, dx, aroot, error )

IMPLICIT NONE

! Declare Arguments
REAL, EXTERNAL :: f
REAL, INTENT(IN) :: x1
REAL, INTENT(IN) :: x2
REAL, INTENT(IN) :: dx
REAL, INTENT(OUT) :: aroot
INTEGER, INTENT(OUT) :: error

! Declare parameter:
REAL, PARAMETER :: epsilon = 1.0E-5 ! Convergence criterion

! Declare local variables:
LOGICAL :: l_value_a
LOGICAL :: l_value_b
LOGICAL :: l_value_m
INTEGER :: i
INTEGER :: n
REAL :: value_a, value_b, value_m
REAL :: xa, xb, xm

! First check to make sure that the interval to search is valid.
error_chk: IF ( x1 > x2 ) THEN
error = 1
aroot = 0

ELSE

! Initializing error flag to 2, since no root found yet
error = 2
aroot = 0

! Get number of steps to search over for sign change
n = NINT( (x2-x1) / dx + 1. )

! Now search for a zero crossing. Get starting value
! at first step.
xa = x1
value_a = f(xa)
l_value_a = value_a > 0

! Search for a sign change between x1 and x2
outer: DO i = 1, n

! Get value at end of interval
xb = MIN( x1 + REAL(i-1) * dx, x2 )
value_b = f(xb)
l_value_b = value_b > 0.

! Is there a sign change in this interval?
sign_change: IF ( l_value_a .NEQV. l_value_b ) THEN

! There was a sign change in the interval. The
! root is somewhere between xa and xb. Process
! it in a WHILE loop.
inner: DO

! Get value at midpoint,
xm = (xa + xb) / 2.
value_m = f(xm)
l_value_m = value_m > 0.

! Test for convergence
IF (ABS((xb-xa) / xm) <= epsilon) THEN
aroot = xm
error = 0
EXIT outer

ELSE IF (l_value_a .EQV. l_value_m) THEN
! The sign change was in the second half.
xa = xm
value_a = value_m
l_value_a = l_value_m

ELSE
! The sign change was in the first half.
xb = xm
value_b = value_m
l_value_b = l_value_m
END IF
END DO inner
END IF sign_change

! We are still searching for a sign change here
! Set new starting point for interval.
xa = xb
value_a = value_b
l_value_a = l_value_b
END DO outer
END IF error_chk

END SUBROUTINE Newton
 
If you're trying to compile this directly into an executable program, you need a "main program" in this file, as gsal said.

If you want to compile it to a .o file that will be linked later to a separately-compiled main program, then (since you're apparently using Linux or something Unix-like), you need to use the -c compilation flag, something like

gfortran Newton.f -o Newton.o -c

or maybe simply

gfortran Newton.f -c