1

I want to use the Newton solver to solve some equations. Some parameters of these equation are changing during the process. I want to pass the equation as a function to the Newton function like this one: http://faculty.washington.edu/rjl/classes/am583s2013/notes/fortran_newton.html

But I am getting warnings which I do not understand.

I have listed a simplified example:

    module a
      use b
      ! module parameters:
      implicit none
    contains
      subroutine newton_method(f, fp, x0, x, iters, debug)
        implicit none
        real(kind=8), intent(in) :: x0
        real(kind=8), external :: f, fp
        logical, intent(in) :: debug
        real(kind=8), intent(out) :: x
        integer, intent(out) :: iters
        ! Declare any local variables:
        real(kind=8) :: deltax, fx, fxprime
        integer :: k
        fx = f(x)
        fxprime = fp(x)
        deltax = fx/fxprime
        return
      end subroutine newton_method
    end module a

   module b
     type, public::b_argument
        real(kind = 8)::d
        real(kind = 8)::e
        real(kind = 8)::f
     end type b_argument
     type(b_argument):: b_argu
   contains
     function gx( x )    result(gx_out)
       implicit none
       real(kind = 8)::x
       real(kind = 8)::gx_out
       real(kind = 8)::d, e, f
       d= b_argu%d
       e= b_argu%e
       f= b_argu%f
       gx_out = d * x * x + e * x + f
       return
     end function gx
     function gx_prime( x )  result(gx_prime_out)
       implicit none
       real(kind = 8)::x
       real(kind = 8)::gx_prime_out
       real(kind = 8)::d, e
       d= b_argu%d
       e= b_argu%e
       gx_prime_out = 2 * d * x + e
       return
     end function gx_prime
   end module b

   program c
     use a
     use b
     implicit none
     real(kind = 8):: x, x0
     integer :: iters
     logical :: debug ! set to .true. or .false.
     x0 = 1.0 !guess
     !change argument every time
     b_argu%d = 3
     b_argu%e = 4
     b_argu%f = 5
     call newton_method(gx, gx_prime, x0, x, iters, debug)
   end program c

makefile:

    f90comp = gfortran
    FFLAGS_DEBUG = -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace
    FFLAGS_OPT = -ggdb -O3 -fdefault-real-8 -fdefault-double-8 -ffree-line-length-none -Wuninitialized
    exe_file = c
    objects = a.o \
        b.o \
        c.o 
    mods = a.mod \
        b.mod \
        c.mod
    .PHONY: clean
    $(exe_file): $(objects) 
        @$(f90comp) $(FFLAGS_DEBUG) $(objects) -o $(exe_file)
        @echo "Code is now linking..."
    %.o: %.f90
        $(f90comp) $(FFLAGS_DEBUG) -c $<
    clean:
        @rm -rf $(objects) $(exe_file)
        @rm -rf $(mods)
    debug: FFLAGS_OPT = $(FFLAGS_DEBUG)
    debug: $(exe_file)
    a.o: b.o
    c.o: a.o b.o     

And the warning I have received is:

   make
   gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace -c b.f90
   gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace -c a.f90
   a.f90:16:17:

                fx = f(x)
                    1
   Warning: Procedure 'f' called with an implicit interface at (1) [-Wimplicit-interface]
   a.f90:17:22:

                fxprime = fp(x)
                         1
   Warning: Procedure 'fp' called with an implicit interface at (1) [-Wimplicit-interface]
   a.f90:6:61:

              subroutine newton_method(f, fp, x0, x, iters, debug)
                                                                1
   Warning: Unused dummy argument 'debug' at (1) [-Wunused-dummy-argument]
   a.f90:6:54:

              subroutine newton_method(f, fp, x0, x, iters, debug)
                                                         1
   Warning: Dummy argument 'iters' at (1) was declared INTENT(OUT) but was not set [-Wunused-dummy-argument]
   a.f90:15:24:

                integer :: k
                           1
   Warning: Unused variable 'k' declared at (1) [-Wunused-variable]
   a.f90:6:44:

              subroutine newton_method(f, fp, x0, x, iters, debug)
                                               1
   Warning: Unused dummy argument 'x0' at (1) [-Wunused-dummy-argument]
   gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -ggdb -fcheck=all -fbacktrace -c c.f90
   Code is now linking...

So why is the f and fp call is implicit? They are passed in as arguments? They are both defined in module and so I could not use interface any more.

Chang
  • 396
  • 4
  • 17
  • It turns out that whenever a procedure (defined in another module) is passed as an argument, it will trigger this warning. – Chang Nov 02 '17 at 20:18
  • 1
    Note that `real(kind=8)` is ugly, not portable and also unnecesarilly verbose. It does not mean 8-bytes, there is no kind 8 in several compilers, although they do have 8 byte reals. Use named constant for Fortran kinds, not magic constants, they are not portable. And also can be confusing for complex variables. We had two users confused by this for complex numbers very recently and thei code returned wrong answers. – Vladimir F Героям слава Nov 02 '17 at 23:21

1 Answers1

3

In newton_method, the interface for dummy arguments f and fp are implicit. Rather than declaring them with an INTERFACE block, you said EXTERNAL. The compiler you're using has an optional diagnostic feature to warn you when you make ANY call to a procedure with an implicit interface, a good thing. You enabled this warning and the compiler did its job.

The fix for this is to use INTERFACE or PROCEDURE(abstract_interface) for the declaration of f and fp rather than EXTERNAL.

Steve Lionel
  • 6,972
  • 18
  • 31