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

  • Thread starter Thread starter Bashkir
  • Start date Start date
  • Tags Tags
    Fortran Type
AI Thread Summary
The discussion revolves around a Fortran subroutine implementation of Newton's method for finding the root of a function. The user encounters compilation errors related to the declaration of the output variable `aroot`, specifically an invalid character error and issues with implicit typing. The problem is traced to a syntax error in the declaration of `aroot`, where a colon is incorrectly used instead of a double colon. Additionally, the user is advised that Fortran is case-sensitive, which could lead to confusion between `x2` and `X2`. The conversation also highlights a linker error indicating that there is no main program defined, which is necessary for creating an executable. To resolve this, the user is instructed to either include a main program in the same file or compile the subroutine into an object file using the `-c` flag before linking it with a main program. This guidance emphasizes the importance of proper structure in Fortran programs and the need to ensure that all components are correctly defined and compiled.
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!
 
Technology 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:
  • #10
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
 
  • #11
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
 

Similar threads

Replies
8
Views
4K
Replies
9
Views
5K
Replies
21
Views
2K
Replies
5
Views
15K
Replies
2
Views
3K
Replies
11
Views
2K
Back
Top