How do I passthrough variables into Fortran IMSL neqnf nonlinear equation solver?

638 views Asked by At

I have been working on converting my MATLAB programs to Fortran (while still taking advantage of some of MATLAB's features). I am trying to utilize routines available in IMSL. It provides a nonlinear equation solver, neqnf, but I haven't been able to figure out how to pass through variables that are changing depending on when the subroutine is called (e.g., as you can with fsolve in MATLAB). For example, below is a mexFunction for MATLAB written in Fortran that calls neqnf. The subroutine, sub, contains the system of equations to be solved. How do I pass variables through neqnf into sub for the coefficients and intercepts of the two linear equations?

Thanks!

#include "fintrf.h"
#include "link_fnl_shared.h"
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
    ! Declarations
    use NEQNF_INT
    implicit none
    external sub

    ! mexFunction arguments
    mwPointer plhs(*), prhs(*)
    integer*4 nlhs, nrhs

    ! mex declarations
    mwpointer mxGetPr,mxCreateNumericArray
    integer*4 mxClassIDFromClassName 

    ! Internal variables
    integer*4 myclassid

    ! Output variables
    mwpointer :: f_pr,x_pr
    double precision :: f(2),x(2)

    ! Create return arguments and assign pointers
    myclassid = mxClassIDFromClassName('double')
    plhs(1) = mxCreateNumericArray(1,2,myclassid,0)
    plhs(2) = mxCreateNumericArray(1,2,myclassid,0)
    f_pr = mxGetPr(plhs(1))
    x_pr = mxGetPr(plhs(2))

    ! Test nonlinear solver (Math.pdf, pg. 1238)
    call d_neqnf(sub,x)

    ! Assign output
    call mxCopyReal8toPtr(f,f_pr,2)
    call mxCopyReal8toPtr(x,x_pr,2)

end subroutine mexFunction

! Subroutine
subroutine sub(x,f,n)
    mwSize n
    double precision :: x(n) ! input
    double precision :: f(n) ! output
    f(1) = 2.d0*x(1) + 1
    f(2) = -1.d0*x(2) + 4
end subroutine sub
1

There are 1 answers

2
Ben Barrowes On

To get variables into sub, you could use a module to declare some variables, then "use" the module in sub and the main routine. That way, you can modify the variables in the main routine (or get the variables from matlab), then have access to them in sub.

Why are you converting to fortran? Execution speed?

Also, if you are doing a lot of this type of converting, consider trying out matlab2fmex at the file exchange. It can do a lot of the busy work of converting numerical matlab code into fortran for you.