我没有完全看到我遇到的问题,而且我已尝试过我在其他论坛帖子中看到过的建议。我正在尝试根据我老板的要求写一个(fortran)mex文件。但是,在将矩阵传递给我的计算例程时,我收到了警告。如果我忽略了警告,我的MATLAB就会关闭。所以现在我尝试一个更简单的程序,一个内在的产品。但是,我仍然收到警告:"预计在(1)"其中(1)是在调用innerProd(x,y,c)'在x下面。我不确定这意味着什么......我已经包含了我的代码。
#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 aids。那里没有任何帮助。我无法运行该函数,因此我无法使用print语句,这是一种很好的调试方法。我认为mex有打印功能,我会尽力让它起作用。
谢谢!
答案 0 :(得分:2)
主要问题是你没有在任何地方将innerProd
的参数声明为数组。这适用于子例程x
中的实际参数y
和mexFunction
以及虚拟参数x
和{ {1}}本身{1}}。
因此,y
innerProd
表达式innerProd
并未引用x(i)
数组i
的{{1}}个元素,但{ {1}}带有参数real*8
的函数 x
的结果。由于您通过的real*8
不是函数(过程),因此这是一个错误。
有很多方法可以解决这个问题,但所有方法都涉及将伪参数声明为数组。这提出了另一点。
你有x
i
其中未定义x
。至关重要的是,从innerProd
开始,您希望编译器知道integer:: i,m
do i=1,m
temp=temp+x(i)*y(i)
end do
是数组m
和mexfunction
的大小:这不是真的。 m
是x
的本地变量。相反,您可能希望将其作为参数传递给子例程,并使用它来标注数组:
y
[当然,你可以使用假定形状的数组(以及m
内在数据),但这是一个需要更多实质性更改的额外复杂因素。]你也可以需要考虑如何在innerProd
中适当地声明数组,注意对subroutine innerProd(x,y,c,m)
implicit none
integer :: m
real*8:: x(m),y(m),temp,c
...
end subroutine
的调用也需要数组参数。
答案 1 :(得分:-1)
我无法让Fortran代码适用于innerProd,但我确实得到了C代码。如果你遇到Fortran问题,我建议使用C.看来matlab在mex文件和C语言方面更灵活。以下是代码:
#include "mex.h"
/*
* innerProd.c
*
*Computational function that takes the inner product of two vectors.
*
*Mex-file for MATLAB.
*/
void innerProd(double *x, double *y,double *c,int m){
double temp;
int i;
for(i=0; i < m; i++){
temp = temp + x[i]*y[i];
}
*c=temp;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *x, *y, *c;
size_t m;
/*check for proper number of arguments.*/
if(nrhs != 2){
mexErrMsgIdAndTxt("MATLAB:innerProd:invalidNumInputs","Two input required.");
}
/*The input must be a noncomplex double vector.*/
m = mxGetM(prhs[0]);
if(!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || m==1){
mexErrMsgIdAndTxt("MATLAB:innerProd:inputNotRealDouble","Input must be noncomplex double vector");
}
/*create return argument */
plhs[0] = mxCreateDoubleMatrix(1,1,0);
c=mxGetPr(plhs[0]);
/*Assign pointers to each input and output. */
x = mxGetPr(prhs[0]);
y=mxGetPr(prhs[1]);
/*call subroutine*/
innerProd(x,y,c,m);
}
但我仍然会对上面的Fortran代码提出建议。我想知道如何让它发挥作用。谢谢!