I am trying to figure out how to call a solver in Fortran to solve some n-dimensional nonlinear equation. I've come across the SLATEC library which has some nonlinear solver routines, and the one I'm trying to use is SNSQE. (aside: maybe you know of some better/easier solvers to use. please tell!)
My example code tries to solve a simple 2-dimensional problem. You could solve it by hand but the point is to figure out how the solver works. Code here:
program test
implicit none
! declarations
real :: theta0, x0, d(2), theta_ss(2)
integer, parameter :: nprint=0, n=2, iopt=2, lwa = 180
integer :: info
real :: tol, fvec(2), jac(2), wa(lwa)
! set parameters
theta_ss = 3.
tol = .0000001
! make sure my function works
d = FNC(theta_ss)
write(*,*) theta_ss
write(*,*) d
! call the solver and write output
call SNSQE( FNC, jac, iopt, n, theta_ss, fvec, tol, nprint, info, wa, lwa )
write(*,*) theta_ss, fvec, tol, info
contains
function FNC(x)
real, intent(in) :: x(2)
real :: FNC(2)
FNC(1) = x(1)**2 - 1
FNC(2) = x(2)**3 - 10
end function FNC
end program test
which I compile with the following:
ifort -fast test_solver.f90 -o test -lslatec
I run the resulting executable ./test
and get:
3.000000 3.000000
8.000000 17.00000
forrtl: severe (174): SIGSEGV, segmentation fault occurred
So my function FNC works on its own, but not within SNSQE. All my inputs are of the correct type and in the correct order. I've tried writing the FNC function in different ways. I'm not sure why it isn't working.
Running OSX - Yosemite, Intel Fortran compiler, SLATEC is compiled from source with the same compiler.
The user-supplied function is not what SNSQE
expects. From the comments in the linked file you can see that FCN
must be a subroutine of the following form:
SUBROUTINE FCN(N,X,FVEC,IFLAG)
INTEGER N,IFLAG
REAL X(N),FVEC(N)
! ----------
! Calculate the functions at X and
! return this vector in FVEC.
! ----------
END SUBROUTINE