0

I'm trying to solve nonlinear equations by using newton method Here is the main program

 program  main  
    use nrtype; use nr ! The type and module is copyed by the numeric recipes
    implicit none
    integer(i4b) :: ntrial =20
    real(sp) :: x(2)= [0.9,0.8]
    real(sp) :: tolx = 1.0e-4_sp
    real(sp) :: tolf = 1.0e-6_sp
    call mnewt(ntrial,x,tolx,tolf,usrfun)
    write (*,*) x
contains
    SUBROUTINE usrfun(x,fvec,fjac)
        USE nrtype
        IMPLICIT NONE
        REAL(SP),intent(in) :: x(2)
        REAL(SP),intent(out) :: fvec(2)
        REAL(SP),intent(out) :: fjac(2,2)
        fvec(1) = x(1)**2 + 2*x(2)
        fvec(2) = x(2)**2 - 3*x(1)
        fjac(1,1) = 2*x(1)
        fjac(1,2) = 2
        fjac(2,1) = 2*x(2)
        fjac(2,2) = 3
    END SUBROUTINE usrfun
end program  main

And here is the subroutine called by the main program

SUBROUTINE mnewt(ntrial,x,tolx,tolf,usrfun)
  USE nrtype
  USE nr, ONLY : lubksb,ludcmp
  IMPLICIT NONE
  INTEGER(I4B), INTENT(IN) :: ntrial
  REAL(SP), INTENT(IN) :: tolx,tolf
  REAL(SP), DIMENSION(:), INTENT(INOUT) :: x
  INTERFACE
    SUBROUTINE usrfun(x,fvec,fjac)
      USE nrtype
      IMPLICIT NONE
      REAL(SP), DIMENSION(:), INTENT(IN) :: x
      REAL(SP), DIMENSION(:), INTENT(OUT) :: fvec
      REAL(SP), DIMENSION(:,:), INTENT(OUT) :: fjac
  END SUBROUTINE usrfun
END INTERFACE
....  ! the detail to solve the nolinear equations

END SUBROUTINE mnewt

Then compile the fortran file, it runs

gfortran  -c nrtype.f90
gfortran  -c nrutil.f90
gfortran  -c nr.f90
gfortran  -c ludcmp.f90
gfortran  -c lubksb.f90
gfortran  -c mnewt.f90
gfortran  -c main.f90
main.f90:9.31:
call mnewt(ntrial,x,tolx,tolf,usrfun)
                               1
Interface mismatch in dummy procedure 'usrfun' at (1): Shape mismatch in argument 'x'

it's similar to the link. why it happens? Interface mismatch - higher order functions

Community
  • 1
  • 1
fuping peng
  • 3
  • 1
  • 3

1 Answers1

0

You are using explicit size arrays in usrfun (i.e. dimension(2)) in the main program, but assumed shape arrays (i.e. dimension(:)) in the interface. You must choose one.

In this case the simplest would be probably to change the subroutine in the main program to

    REAL(SP),intent(in) :: x(:)
    REAL(SP),intent(out) :: fvec(:)
    REAL(SP),intent(out) :: fjac(:,:)

.

Note that passing of internal procedures as actual arguments is only allowed in Fortran 2008 and is supported only by some compilers.