Matlab使用mex调用C函数

Posted

技术标签:

【中文标题】Matlab使用mex调用C函数【英文标题】:Matlab calling C function using mex 【发布时间】:2015-08-06 10:40:36 【问题描述】:

首先,我从未尝试在 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;

我现在有两个问题,第一个我已经解决了:

我收到以下警告

警告:您使用的是 gcc 版本“4.6.3-1ubuntu5)”。版本 MEX 目前支持的是“4.4.6”。 有关当前支持的编译器的列表,请参见: http://www.mathworks.com/support/compilers/current_release/

mex: durlevML.c 不是普通文件或不存在。

但是通过更改相应条目并安装 gcc-4.4 来遵循solution,警告消失了,但 第二个实际问题 仍然存在,尽管我没有不再收到任何警告我仍然收到错误

mex: durlevML.c 不是普通文件或不存在。

这可能是什么原因?

我正在使用

ubuntu 12.04 Matlab 2012b gcc-4.6 但能够让 Matlab 使用 gcc-4.4

运行调用 durlevML.c 函数的函数 arfima_test.m 时出现问题,相关(我猜)部分是

  % 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

【问题讨论】:

我的猜测是该文件只是不在您正在执行该操作的文件夹中。使用 Visual Studio 编译器在我的系统中编译运行正常。 @AnderBiguri 是的,确实! 【参考方案1】:

感谢 Ander Biguri 的评论!

解决方案确实很简单,问题是C文件durlevML.c没有正确链接,所以编译器找不到任何东西。所以我不得不通过以下方式在 arfima_test.m 中添加一些信息

mex durlevML.c <---------------- needs to be linked /home/....

C 代码本身可以解决一个较小的问题。我的编译器 - 由于 Matlab 与较新的编译器不兼容,我使用 gcc-4.4 - 无法识别 cmets // 并且总是产生错误,所以我不得不将它们更改为长注释格式 /**/ 最终工作。

据我所知,除此之外一切正常!

【讨论】:

以上是关于Matlab使用mex调用C函数的主要内容,如果未能解决你的问题,请参考以下文章

matlab怎么调用函数

Matlab 编译C/C++源文件并调用

如何在从 Matlab 调用的 mex 函数中使用 Matlab 引擎

使用带有 MEX Wrapper 的辅助 C 文件从 MATLAB 2016 调用 C++ 代码时遇到问题

使用代码包将 Matlab 代码转换为 .mex

MATLAB mex文件