Как передать переменные в решатель нелинейных уравнений Fortran IMSL neqnf?

Я работал над преобразованием своих программ MATLAB в Fortran (при этом используя некоторые функции MATLAB). Я пытаюсь использовать подпрограммы, доступные в IMSL. Он предоставляет средство решения нелинейных уравнений, neqnf, но я не смог понять, как пройти через переменные, которые изменяются в зависимости от того, когда вызывается подпрограмма (например, как вы можете с fsolve в MATLAB). Например, ниже mexFunction для MATLAB, написанная на Fortran, вызывает neqnf. Подпрограмма sub содержит решаемую систему уравнений. Как передать переменные через neqnf в sub для коэффициентов и точек пересечения двух линейных уравнений?

Спасибо!

#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

person nathrock    schedule 29.05.2013    source источник


Ответы (1)


Чтобы получить переменные в подпрограмме, вы можете использовать модуль для объявления некоторых переменных, а затем «использовать» модуль в подпрограмме и основной процедуре. Таким образом, вы можете изменить переменные в основной процедуре (или получить переменные из Matlab), а затем получить к ним доступ в подпрограмме.

Почему вы конвертируете в фортран? Скорость выполнения?

Кроме того, если вы часто конвертируете файлы такого типа, подумайте о том, чтобы попробовать matlab2fmex на файловом обмене. Он может сделать за вас большую часть работы по преобразованию числового кода Matlab в fortran.

person Ben Barrowes    schedule 30.05.2013
comment
Хорошо, спасибо за предложение! Я рассмотрю использование модулей. Итак, в основном вы предлагаете, чтобы я мог установить параметры в модуле, в котором я могу обновить их значения в основной программе перед вызовом подпрограммы? Это похоже на глобальные переменные в MATLAB. Я привык не использовать глобальные переменные, а вместо этого решил явно передавать переменные в функции из основного скрипта. - person nathrock; 30.05.2013
comment
Я обнаружил места в своих скриптах MATLAB, которые работают очень медленно. Например, в какой-то момент итерации в моей программе происходит много интерполяции аппроксимирующей функции. Я обнаружил, что программирование цикла для выполнения интерполяции НАМНОГО быстрее в Fortran, чем в MATLAB. Как правило, циклы в MATLAB работают медленно. Я также обнаружил, что OpenMP является превосходной альтернативой parfor MATLAB. До сих пор основным недостатком была отладка кода Fortran; очень легко определить проблемы со сценариями в MATLAB. - person nathrock; 30.05.2013