Matlab 使用 mex 调用 C 函数
Matlab calling C function using mex
首先,我从未尝试在 Matlab 程序中调用 C 代码 - 所以这可能只是一个我无法理解的愚蠢错误。
C 函数是以下函数,可以在 here 上找到,它称为 durlevML.c 并且是 ARFIMA(p, d,q) 估算器套件:
#include "mex.h"
#include "matrix.h"
#define square(p) ((p)*(p))
#define inv(q) (1/(q))
/* Durbin-Levinson algorithm for linear stationary AR(FI)MA(p,d,q) processes
Slightly altered for the maximum likelihood estimation
(C) György Inzelt 2011 */
void levinson_recur1(double* v,double* L, int N, double* gammas,int step)
{
int i,k;
if(step==0)
{
*(v + step) = *(gammas + step);
*(L + step) = 1;
for(k = step+1;k < N;++k)
{
*(L + k) = 0;
}
}
else if(step > 0 && step < N)
{
//phi_tt
*(L + step*N ) = (-1.00)* *(gammas + step);
if(step > 1)
{
for(i = 1;i < step ;++i)
{
*(L + step*N) -= *(L + (step-1)*N + (step -1) - i ) * *(gammas + step - i) ;
}
}
*(L +step*N) *= inv( *(v + step-1) );
//v_t
*(v + step) = *(v + step-1)*(1- square( *(L + step*N) ));
//phi_tj
for(i =1; i < step; ++i)
{
*(L + step*N + step - i) = *(L + (step-1)*N + (step -1) - i) + *(L + step*N ) * *(L + (step-1)*N + i -1 ) ;
}
//filling L with zeros and ones
*(L + step*N + step ) = 1;
if(step != N-1)
{
for(k = step*N +step+1 ;k < step*N + N ;++k)
{
*(L + k) =0;
}
}
}
if(step < N-1)
levinson_recur1(v,L,N,gammas,++step);
}
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int step=0;
int N;
double *gammas,*v,*L;
// getting the autocovariances
gammas = mxGetPr(prhs[0]);
N = mxGetM(prhs[0]);
// v
plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
mxSetM(plhs[0],N);
mxSetN(plhs[0],1);
mxSetData(plhs[0], mxMalloc(sizeof(double)*N*1));
// L
plhs[1] = mxCreateDoubleMatrix(0,0,mxREAL);
mxSetM(plhs[1],square(N));
mxSetN(plhs[1],1);
mxSetData(plhs[1], mxMalloc(sizeof(double)*square(N)*1));
//
v = mxGetPr(plhs[0]);
L = mxGetPr(plhs[1]);
//
levinson_recur1(v, L, N,gammas,step);
//
return;
}
我现在有两个问题,第一个我已经解决了:
我收到以下警告
Warning: You are using gcc version "4.6.3-1ubuntu5)". The version
currently supported with MEX is "4.4.6".
For a list of currently supported compilers see:
http://www.mathworks.com/support/compilers/current_release/
mex: durlevML.c not a normal file or does not exist.
但是在 solution 之后通过更改相应的条目并安装 gcc-4.4 警告消失了,但是 第二个实际问题 仍然存在,虽然我不再收到任何警告我仍然收到错误
mex: durlevML.c not a normal file or does not exist.
这可能是什么原因?
我正在使用
- ubuntu 12.04
- Matlab 2012b
- gcc-4.6 但能够让 Matlab 使用 gcc-4.4
问题发生在 运行 函数 arfima_test.m 调用 durlevML.c 函数时,相关的(我猜)部分是
% compiling the C/MEX file
c = input('Would you like to compile the MEX source? (1/0)');
switch c
case(1)
mex durlevML.c
case(0)
end
非常感谢 Ander Biguri 的评论!
解决方法确实很简单,问题是C文件durlevML.c没有正确链接,所以编译器找不到任何东西。所以我不得不通过以下方式在 arfima_test.m 中添加一些信息
mex durlevML.c <---------------- needs to be linked /home/....
C 代码本身没有问题,但有一个小问题。我的编译器——由于 Matlab 与较新版本的不兼容,我使用了 gcc-4.4——无法识别注释 // 并且总是产生错误,所以我不得不将它们更改为长注释格式 /**/ 最终起作用了。
除此之外一切正常,据我所知!
首先,我从未尝试在 Matlab 程序中调用 C 代码 - 所以这可能只是一个我无法理解的愚蠢错误。
C 函数是以下函数,可以在 here 上找到,它称为 durlevML.c 并且是 ARFIMA(p, d,q) 估算器套件:
#include "mex.h"
#include "matrix.h"
#define square(p) ((p)*(p))
#define inv(q) (1/(q))
/* Durbin-Levinson algorithm for linear stationary AR(FI)MA(p,d,q) processes
Slightly altered for the maximum likelihood estimation
(C) György Inzelt 2011 */
void levinson_recur1(double* v,double* L, int N, double* gammas,int step)
{
int i,k;
if(step==0)
{
*(v + step) = *(gammas + step);
*(L + step) = 1;
for(k = step+1;k < N;++k)
{
*(L + k) = 0;
}
}
else if(step > 0 && step < N)
{
//phi_tt
*(L + step*N ) = (-1.00)* *(gammas + step);
if(step > 1)
{
for(i = 1;i < step ;++i)
{
*(L + step*N) -= *(L + (step-1)*N + (step -1) - i ) * *(gammas + step - i) ;
}
}
*(L +step*N) *= inv( *(v + step-1) );
//v_t
*(v + step) = *(v + step-1)*(1- square( *(L + step*N) ));
//phi_tj
for(i =1; i < step; ++i)
{
*(L + step*N + step - i) = *(L + (step-1)*N + (step -1) - i) + *(L + step*N ) * *(L + (step-1)*N + i -1 ) ;
}
//filling L with zeros and ones
*(L + step*N + step ) = 1;
if(step != N-1)
{
for(k = step*N +step+1 ;k < step*N + N ;++k)
{
*(L + k) =0;
}
}
}
if(step < N-1)
levinson_recur1(v,L,N,gammas,++step);
}
/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int step=0;
int N;
double *gammas,*v,*L;
// getting the autocovariances
gammas = mxGetPr(prhs[0]);
N = mxGetM(prhs[0]);
// v
plhs[0] = mxCreateDoubleMatrix(0,0,mxREAL);
mxSetM(plhs[0],N);
mxSetN(plhs[0],1);
mxSetData(plhs[0], mxMalloc(sizeof(double)*N*1));
// L
plhs[1] = mxCreateDoubleMatrix(0,0,mxREAL);
mxSetM(plhs[1],square(N));
mxSetN(plhs[1],1);
mxSetData(plhs[1], mxMalloc(sizeof(double)*square(N)*1));
//
v = mxGetPr(plhs[0]);
L = mxGetPr(plhs[1]);
//
levinson_recur1(v, L, N,gammas,step);
//
return;
}
我现在有两个问题,第一个我已经解决了:
我收到以下警告
Warning: You are using gcc version "4.6.3-1ubuntu5)". The version currently supported with MEX is "4.4.6". For a list of currently supported compilers see: http://www.mathworks.com/support/compilers/current_release/
mex: durlevML.c not a normal file or does not exist.
但是在 solution 之后通过更改相应的条目并安装 gcc-4.4 警告消失了,但是 第二个实际问题 仍然存在,虽然我不再收到任何警告我仍然收到错误
mex: durlevML.c not a normal file or does not exist.
这可能是什么原因?
我正在使用
- ubuntu 12.04
- Matlab 2012b
- gcc-4.6 但能够让 Matlab 使用 gcc-4.4
问题发生在 运行 函数 arfima_test.m 调用 durlevML.c 函数时,相关的(我猜)部分是
% compiling the C/MEX file
c = input('Would you like to compile the MEX source? (1/0)');
switch c
case(1)
mex durlevML.c
case(0)
end
非常感谢 Ander Biguri 的评论!
解决方法确实很简单,问题是C文件durlevML.c没有正确链接,所以编译器找不到任何东西。所以我不得不通过以下方式在 arfima_test.m 中添加一些信息
mex durlevML.c <---------------- needs to be linked /home/....
C 代码本身没有问题,但有一个小问题。我的编译器——由于 Matlab 与较新版本的不兼容,我使用了 gcc-4.4——无法识别注释 // 并且总是产生错误,所以我不得不将它们更改为长注释格式 /**/ 最终起作用了。
除此之外一切正常,据我所知!