在 Fortran 中调用 Matlab 函数
Calling a Matlab function in Fortran
使用 MATLAB Engine API for Fortran,我试图从 Fortran 代码调用一个简单的 MATLAB 函数。
我按照找到的 fengdemo 示例进行了操作 here。
它有效,所以我想调整我的 Fortran 代码以调用我编写的特定 Matlab 脚本。
我的 MATLAB 脚本 call_fortran.m
非常简单:它将 x
作为一个条目并将其乘以 2
:
function multiply = call_fortran(x)
multiply = 2*x;
end
我希望我的 FORTRAN 代码生成变量 my_x
,打开 MATLAB 会话,将变量发送到工作区,应用函数 call_fortran
并显示结果。使用 fengdemo.f 代码,我写道:
program main
C Declarations
implicit none
mwPointer engOpen, engGetVariable, mxCreateDoubleMatrix
mwPointer mxGetPr
mwPointer ep, my_x ! ep: variable linked to engOpen, starting a Matlab session, my_x: variable que je veux donner a Matlab
double precision my_x
integer engPutVariable, engEvalString, engClose
integer temp, status
mwSize i
my_x = 6
ep = engOpen('matlab ')
if (ep .eq. 0) then
write(6,*) 'Can''t start MATLAB engine'
stop
endif
C Place the variable my_x into the MATLAB workspace
status = engPutVariable(ep, 'my_x', my_x)
C
if (status .ne. 0) then
write(6,*) 'engPutVariable failed'
stop
endif
! My issue now is to call the correct Matlab script
! nlhs = 1
! plhs = 1
! nrhs = 1
! prhs = 1
! integer*4 mexCallMATLAB(nlhs, plhs, nrhs, prhs, functionName)
所以我有 my_x
,我将它发送到 MATLAB,但是如何应用 call_fortran.m
函数并获得 my_x
的新值?
这段代码有两个基本错误。您没有为 my_x 使用正确的变量类型,并且您不能从引擎应用程序(只能在 mex 例程中使用)调用 mexCallMATLAB( )。让我们解决这些问题。
首先,my_x 变量需要是一个 mxArray,而不是双精度变量。有多种方法可以做到这一点,但对于标量,创建此数组的最简单方法如下:
mwPointer, external :: mxCreateDoubleScalar
mwPointer my_x
my_x = mxCreateDoubleScalar(6.d0)
然后您可以根据您当前的代码将其传递给 MATLAB 引擎。要在 MATLAB 引擎工作区中调用您的函数,您需要在那里计算一个字符串:
integer*4, external :: engEvalString
integer*4 status
status = engEvalString( ep, 'result = call_fortran(my_x)' )
结果应该显示在引擎工作区中,因为我们没有以 semi-colon 终止字符串。如果您想将结果返回到您的 Fortran 代码中,您需要执行如下操作:
mwPointer, external :: engGetVariable
mwPointer result
result = engGetVariable( ep, 'result' )
您的 Fortran 代码中的结果将是一个 mxArray。要提取数字,有多种方法,但对于标量,最简单的方法如下(使用 real*8 而不是双精度来精确匹配文档中的 MATLAB API 签名):
real*8, external :: mxGetScalar
real*8 myresult
myresult = mxGetScalar(result)
为避免内存泄漏,一旦您使用完 mxArray 变量,您应该销毁它们。例如,
call mxDestroyArray(my_x)
call mxDestroyArray(result)
写完所有这些,您确定要创建 MATLAB 引擎应用程序,而不是 mex 例程吗? Mex 例程通常更易于使用,并且不涉及额外的数据副本来来回传递变量。
使用 MATLAB Engine API for Fortran,我试图从 Fortran 代码调用一个简单的 MATLAB 函数。
我按照找到的 fengdemo 示例进行了操作 here。 它有效,所以我想调整我的 Fortran 代码以调用我编写的特定 Matlab 脚本。
我的 MATLAB 脚本 call_fortran.m
非常简单:它将 x
作为一个条目并将其乘以 2
:
function multiply = call_fortran(x)
multiply = 2*x;
end
我希望我的 FORTRAN 代码生成变量 my_x
,打开 MATLAB 会话,将变量发送到工作区,应用函数 call_fortran
并显示结果。使用 fengdemo.f 代码,我写道:
program main
C Declarations
implicit none
mwPointer engOpen, engGetVariable, mxCreateDoubleMatrix
mwPointer mxGetPr
mwPointer ep, my_x ! ep: variable linked to engOpen, starting a Matlab session, my_x: variable que je veux donner a Matlab
double precision my_x
integer engPutVariable, engEvalString, engClose
integer temp, status
mwSize i
my_x = 6
ep = engOpen('matlab ')
if (ep .eq. 0) then
write(6,*) 'Can''t start MATLAB engine'
stop
endif
C Place the variable my_x into the MATLAB workspace
status = engPutVariable(ep, 'my_x', my_x)
C
if (status .ne. 0) then
write(6,*) 'engPutVariable failed'
stop
endif
! My issue now is to call the correct Matlab script
! nlhs = 1
! plhs = 1
! nrhs = 1
! prhs = 1
! integer*4 mexCallMATLAB(nlhs, plhs, nrhs, prhs, functionName)
所以我有 my_x
,我将它发送到 MATLAB,但是如何应用 call_fortran.m
函数并获得 my_x
的新值?
这段代码有两个基本错误。您没有为 my_x 使用正确的变量类型,并且您不能从引擎应用程序(只能在 mex 例程中使用)调用 mexCallMATLAB( )。让我们解决这些问题。 首先,my_x 变量需要是一个 mxArray,而不是双精度变量。有多种方法可以做到这一点,但对于标量,创建此数组的最简单方法如下:
mwPointer, external :: mxCreateDoubleScalar
mwPointer my_x
my_x = mxCreateDoubleScalar(6.d0)
然后您可以根据您当前的代码将其传递给 MATLAB 引擎。要在 MATLAB 引擎工作区中调用您的函数,您需要在那里计算一个字符串:
integer*4, external :: engEvalString
integer*4 status
status = engEvalString( ep, 'result = call_fortran(my_x)' )
结果应该显示在引擎工作区中,因为我们没有以 semi-colon 终止字符串。如果您想将结果返回到您的 Fortran 代码中,您需要执行如下操作:
mwPointer, external :: engGetVariable
mwPointer result
result = engGetVariable( ep, 'result' )
您的 Fortran 代码中的结果将是一个 mxArray。要提取数字,有多种方法,但对于标量,最简单的方法如下(使用 real*8 而不是双精度来精确匹配文档中的 MATLAB API 签名):
real*8, external :: mxGetScalar
real*8 myresult
myresult = mxGetScalar(result)
为避免内存泄漏,一旦您使用完 mxArray 变量,您应该销毁它们。例如,
call mxDestroyArray(my_x)
call mxDestroyArray(result)
写完所有这些,您确定要创建 MATLAB 引擎应用程序,而不是 mex 例程吗? Mex 例程通常更易于使用,并且不涉及额外的数据副本来来回传递变量。