Матрица, которую я мог бы вернуть, имеет только первый элемент правильно, а все остальные - нули. Я попытался следовать, как предлагалось в этом link; но для меня это не тренировалось. Некоторая помощь будет оценена по достоинству.MEX: Как вернуть матрицу из C++/C в MATLAB
Выход:
>> Matlab_mex_Testing
B1 =
1.0000 0 0
0 1.0000 0
0 0 1.0000
0 0 0
B =
1 0 0
0 0 0
0 0 0
0 0 0
Matlab код:
Dir2 = '/home/dkumar/Mex_Codes_DKU/MexCode_Working/Mex_CPP_N_ARMADILLO_Codes_DKU_makefile_Working';
% MEX
cd(Dir2);
[y, B] = normpdfDKU(1/2,0,1);
%Matlab declared
B1 = eye(4,3)
% Identical matrix returned from MEX
B
CPP:
#include "mex.h"
#include <math.h>
#include "/home/dkumar/armadillo-4.600.3/include/armadillo"
using namespace arma;
using namespace std;
#define pi (3.141592653589793)
extern void _main();
const int numInputArgs = 3;
const int numOutputArgs = 2;
// Function declarations.
// -----------------------------------------------------------------
double getMatlabScalar (const mxArray* ptr);
double& createMatlabScalar (mxArray*& ptr);
int TestingLibraries() ; // declared and defined in In Include_4_TSNNLS.c and Include_4_TSNNLS.h
// Function definitions.
// -----------------------------------------------------------------
void mexFunction (int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
// Check to see if we have the correct number of input and output
// arguments.
if (nrhs != numInputArgs)
mexErrMsgTxt(" DKU-1: Incorrect number of input arguments");
if (nlhs != numOutputArgs)
mexErrMsgTxt("DKU-2: Incorrect number of output arguments");
// Get the inputs.
double x = getMatlabScalar(prhs[0]);
double mu = getMatlabScalar(prhs[1]);
double v = getMatlabScalar(prhs[2]);
// Create the output. It is also a double-precision scalar.
double& p = createMatlabScalar(plhs[0]);
// Compute the value of the univariate Normal at x.
p = exp(-(x-mu)*(x-mu)/(2*v))/sqrt(2*pi*v);
// CREATE ARMA::mat and print
mat B = eye<mat>(4,3);
//Print B
B.print();
// Trying to return B as second output
mwSize sz[2];
sz[0] = B.n_rows ; // Matlab is row first
sz[1] = B.n_cols ;
//mxArray* pOUT = mxCreateNumericArray(2, sz, mxDOUBLE_CLASS, mxREAL);
plhs[1] = mxCreateNumericArray(2, sz, mxDOUBLE_CLASS, mxREAL);
//Get a pointer to pOUT
double* p2 = (double*)mxGetData(plhs[1]);
*p2 = B[0];
}
double getMatlabScalar (const mxArray* ptr) {
// Make sure the input argument is a scalar in double-precision.
if (!mxIsDouble(ptr) || mxGetNumberOfElements(ptr) != 1)
mexErrMsgTxt("The input argument must be a double-precision scalar");
return *mxGetPr(ptr);
}
double& createMatlabScalar (mxArray*& ptr) {
ptr = mxCreateDoubleMatrix(1,1,mxREAL);
return *mxGetPr(ptr);
}
спасибо, это сработало. Поскольку я плохо разбираюсь в C++, и указатель всегда меня смущает, не могли бы вы ответить на еще один вопрос? In, p2 [i] = B [i]; 'LHS - ** указатель + i приращений **; а RHS - это ** массив **. Почему компилятор не жалуется на несоответствие типов? –
@ DushyantKumar 'p2 [i]' является синтаксическим сахаром для '* (p2 + i)'. Не существует рассогласования типа, поскольку выполнение 'p2 [i]' выполняет операцию разыменования. Помните, что массивы являются непрерывными фрагментами памяти, поэтому то, что вы на самом деле делаете, когда вы выполняете 'p2 [i]', - это то, что вы получаете доступ к элементу, начинающемуся с позиции, где начинается 'p2', и вы перемещаете байты с плавающей запятой i над. Доступ к массиву и арифметика указателя на самом деле одно и то же, но '* (p2 + i)' на самом деле известно немного быстрее. Тем не менее, всегда пишите для удобочитаемости перед исполнением. Напишите так, как вам удобно. – rayryeng