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.
 
It also looks like you have 'x2' in the subroutine argument list and 'X2' in the declaration list.
 
So Fortran is case-sensitive now? :eek:
 
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