MATLAB,mex文件,Fortran,警告和错误 [英] MATLAB, mex files, Fortran, warnings and errors
问题描述
我不太清楚自己遇到的问题,并且我尝试了在其他论坛帖子中看到的建议.我正在尝试根据老板的要求编写一个(fortran)mex文件.但是,将矩阵传递给我的计算例程时,我收到警告.如果我忽略了警告,我的MATLAB将关闭.所以现在我正在尝试一个更简单的程序,一个内部产品.但是,我仍然收到警告:在(1)处出现了一个过程",其中(1)在x下方的"call innerProd(x,y,c)"处.我不确定这意味着什么...我已经包含了我的代码.
I'm not quite seeing the issue I'm having, and I've tried suggestions I've seen in other forum posts. I am trying to write a (fortran) mex file, per request of my boss. However, I was getting warnings when passing a matrix to my computational routine. If I ignored the warning, my MATLAB shut down. So now I'm trying a simpler program, an inner product. However, I am still getting the warning: "Expected a procedure at (1)" where (1) is at 'call innerProd(x,y,c)' underneath the x. I'm not sure what that means... I've included my code.
#include "fintrf.h"
C======================================================================
#if 0
C
C innerProd.F
C .F file needs to be preprocessed to generate .for equivalent
C
#endif
C
C innerProd.F
C calculates the inner product
C This is a MEX file for MATLAB.
C Copyright 1984-2011 The MathWorks, Inc.
C $Revision: 1.12.2.9 $
C======================================================================
C Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer:: plhs(*), prhs(*)
integer:: nlhs, nrhs
C Function declarations:
mwPointer:: mxCreateDoubleMatrix, mxGetPr,mxGetM, mxGetData
integer:: mxIsNumeric
C Pointers to input/output mxArrays:
mwPointer:: x_ptr, y_ptr, c_ptr
C Array information:
mwSize:: m
C Arguments for computational routine:
real*8:: x,y,c
C----------------------------------------------------------------------
C Check for proper number of arguments.
if (nrhs .ne. 2) then
call mexErrMsgTxt('Error.')
elseif (nlhs .ne. 1) then
call mexErrMsgTxt('One output required.')
endif
C Check to see if inputs are numeric.
if (mxIsNumeric(prhs(1)) .ne. 1 ) then
call mexErrMsgTxt('Input # 1 is not a numeric array.')
elseif (mxIsNumeric(prhs(2)) .ne. 1) then
call mexErrMsgTxt('Input #2 is not a numeric array.')
endif
C Find dimensions of mxArrays
m=mxGetM(prhs(1))
C create Fortran arrays from the input arguments
x_ptr=mxGetData(prhs(1))
call mxCopyPtrToReal8(x_ptr,x,m)
y_ptr= mxGetData(prhs(2))
call mxCopyPtrToReal8(y_ptr,y,m)
C create matrix for the return argument
plhs(1) =mxCreateDoubleMatrix(1,1,0)
c_ptr= mxGetPr(plhs(1))
C Call the computational subroutine.
call innerProd(x,y,c)
C Load the output into a MATLAB array.
call mxCopyReal8ToPtr(c, c_ptr, 1)
return
end subroutine mexFunction
C----------------------------------------------------------------------
C Computational routine
subroutine innerProd(x,y,c)
implicit none
real*8:: x,y,temp,c
integer:: i,m
do i=1,m
temp=temp+x(i)*y(i)
end do
c = temp
return
end subroutine innerProd
我是第一次学习此内容,我将不胜感激任何建议.即使在哪里寻找解决方案.我已经在线查看了MATLAB mex Fortran辅助工具.那里没有任何帮助.我无法运行该函数,因此无法使用print语句,这是调试的一种好方法.我认为mex具有打印功能,我将尽力使其发挥作用.
I'm just learning this for the first time, and I would appreciate any suggestions. Even if it is where to look for solutions. I've looked through MATLAB mex Fortran aids online. There isn't any help there. I can't get the function to run, so I can't use print statements which is a good way to debug. I think mex has a print function, I will try to get that to work.
谢谢!
推荐答案
主要问题是您还没有在任何地方将innerProd
的参数声明为数组.这适用于子例程mexFunction
中的 actual 自变量x
和y
以及innerProd
自身中的 dummy 自变量x
和y
.
The main problem is that you haven't anywhere declared the arguments of innerProd
as arrays. That holds for the actual arguments x
and y
in the subroutine mexFunction
and the dummy arguments x
and y
in innerProd
itself.
因此,在innerProd
中,表达式x(i)
并不引用real*8
数组x
的第i
个元素,而是函数real*8结果> x
,参数为i
.由于您传递的x
不是函数(过程),因此是错误的.
So, in innerProd
the expression x(i)
isn't referencing the i
-th element of the real*8
array x
, but the real*8
result of the function x
with argument i
. As the x
you've passed isn't a function (procedure), this is an error.
有多种方法可以解决此问题,但是所有方法都涉及将虚拟参数声明为数组.这又提出了另一点.
There are ways to solve this, but all involve declaring the dummy arguments as arrays. Which brings up another point.
您在innerProd
integer:: i,m
do i=1,m
temp=temp+x(i)*y(i)
end do
其中未定义m
.至关重要的是,您期望编译器从mexfunction
知道m
是数组x
和y
的大小:这是不正确的. m
是innerProd
本地的变量.相反,您可能希望将其作为参数传递给子例程,并使用该变量来确定数组的大小:
where m
is not defined. Crucially, from mexfunction
you're expecting the compiler to know that m
is the size of the arrays x
and y
: this isn't true. m
is a variable local to innerProd
. Instead you may want to pass it as an argument to the subroutine and use that to dimension the arrays:
subroutine innerProd(x,y,c,m)
implicit none
integer :: m
real*8:: x(m),y(m),temp,c
...
end subroutine
[您当然可以使用假定形状数组(和SIZE
内在函数,但这是一个额外的复杂性,需要进行更大的更改.)您还需要考虑如何在mexfunction
中适当地声明数组,请注意,对mxCopyPtrToReal8
的调用也需要一个数组参数.
[You could, of course, use assumed-shape arrays (and the SIZE
intrinsic), but that's an additional complication requiring more substantial changes.] You also need to think about how to declare arrays appropriately in mexfunction
, noting that the call to mxCopyPtrToReal8
also requires an array argument.
这篇关于MATLAB,mex文件,Fortran,警告和错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!