Использование функции Бесселка в C MexFunction

Я хотел бы реализовать корреляционную функцию Matern в C mexFunction, которая требует вычисления для модифицированной функции Бесселка второго рода.

В MATLAB можно использовать функцию besselk. Тем не менее, нет такого эквивалента в любой библиотеке C (я прав?). Я знал, что библиотека boost (библиотека C ++) предоставляет доступ к модифицированной функции Besselk второго рода, см. https://en.cppreference.com/w/cpp/experimental/special_math, но у меня проблемы с его работой в моей функции C mex с MATLAB 2018a на моем Mac, а также в системе Linux. Кстати, я не хочу вызывать функцию MATLAB besselk внутри кода C mex.

Любые предложения будут оценены. Ниже приведен минимальный пример построения материнской корреляционной функции с использованием C-мекс-кода.

#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 ++, я смогу успешно получить код C ++, скомпилированный с помощью компилятора g ++ на моем Mac.

#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

Решение

Это не совсем Mex-специфично.

Вы можете использовать специальные математические функции Boost из C-программы; они предназначены для использования в C или C ++.

Для этого нужно добавить

#include <boost/math/tr1.hpp>

В C ++ объявления в этом файле вставляются в пространство имен booth::math но очевидно, что вы не можете использовать пространства имен C ++ в C-коде. Сами функции скомпилированы с C-связью, поэтому они являются глобальными именами, и их можно просто использовать как есть.

Обратите внимание, что Boost предоставляет специальные математические функции как C99, так и TR1 (поэтому его можно использовать со стандартной библиотекой C, которая предшествует C99, если вы все еще живете в прошлом), но они находятся в разных библиотеках, как объяснено в Повысить документацию. Даже если у вас есть стандартная библиотека C99, после включения заголовка Boost вам потребуется использовать библиотеки Boost для функций C99. Поэтому вам, вероятно, потребуется добавить две опции ссылки в вашу команду сборки:

-lboost_math_c99 -lboost_math_tr1

Если тебе надо float или же long double версии, вам понадобятся другие библиотеки. См. Выше ссылку на документацию Boost для деталей.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]