在C MexFunction中使用Besselk函数

时间:2018-06-25 14:41:14

标签: c++ c matlab mex bessel-functions

我想在C mexFunction中实现Matern相关函数,这需要对第二种修改后的Besselk函数进行计算。

在MATLAB中,可以使用besselk函数。但是,在任何C库中都没有这样的等效项(对吗?)。我知道boost库(一个C ++库)提供了对第二种修改后的Besselk函数的访问,请参见https://en.cppreference.com/w/cpp/experimental/special_math,但是我也无法使其在Mac上的MATLAB 2018a的C mexFunction中工作作为linux系统。顺便说一句,我不想​​在C mex代码中调用MATLAB函数besselk。

任何建议将不胜感激。以下是使用C mex代码构造矩阵相关函数的最小示例。

#include "mex.h"
#include "matrix.h"
#include <math.h>
//#include <boost/math/special_functions.hpp>
double matern(double h, double nu)
{
    double tau = sqrt(2.0*nu) * h;
    double c = 0.0;
    if(h>0.0){
      c = (pow(tau, nu) * pow(2.0, 1.0-nu) / tgamma(nu)) * boost::math::cyl_bessel_k(nu, tau);
    }else{
      c = 1.0;
    }
    return c;
  }
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if(nrhs!=2){
        mexErrMsgTxt("Two Inputs are required.");
    }
    double h = mxGetScalar(prhs[0]);
    double nu = mxGetScalar(prhs[1]);
    double corr = matern(h, nu);
    mexPrint("matern(h=%g, nu=%g) = %g", h, nu, corr);
    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    mxSetPr(plhs[0], &corr);
         return;
}

如果将上面的C mex代码转换为C ++代码文件,则可以在Mac上成功获取使用g ++编译器编译的C ++代码。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#include <boost/math/special_functions.hpp>

double matern(const double h, const double nu)
{

  double tau = sqrt(2.0*nu) * h;

  double c = 0.0;
  if(h>0.0){
    c = (pow(tau, nu) * pow(2.0, 1.0-nu) / tgamma(nu)) * boost::math::cyl_bessel_k(nu, tau);
  }else{
    c = 1.0;
  }


  return c;
}

int main(){
    double nu=0.5, h=1.0;
    double corr = matern(h, nu);
    printf("corr=%lf\n", corr);

    return 0;
}

为再次强调我的问题,我不需要C ++代码,而是希望使我的C mex代码成功运行。

1 个答案:

答案 0 :(得分:0)

这不是真正针对Mex的。

您可以通过C程序使用Boost的特殊数学函数;它们旨在用于C或C ++。

为此,您需要添加

#include <boost/math/tr1.hpp>

在C ++中,此文件中的声明被插入到命名空间booth::math中,但是显然您不能在C代码中使用C ++命名空间。这些函数本身使用C链接进行编译,因此它们是全局名称,可以按原样使用。

请注意,Boost提供了C99和TR1特殊的数学函数(因此,如果您仍然生活在过去,它可以与C99之前的标准C库一起使用),但是它们位于不同的库中,如Boost documentation。即使您具有C99标准库,在包含Boost标头后,您仍需要将Boost库用于C99函数。因此,您可能需要在构建命令中添加两个链接选项:

-lboost_math_c99 -lboost_math_tr1

如果您需要floatlong double版本,则将需要其他库。有关详细信息,请参见上面的Boost文档链接。