質問

I am new in mex and Matlab. I have just learned how to pass real variables and matrix variables from mex function to Matlab.

After installing GMP(its alternative mpir and mpfr libraries), now my questions are: when I am building mex functions via C++ and GMP, how to pass a "multiple precision" variable output argument as Matlab's native function does?

Is there any simple working example?

Below is mex function code sample, to which I added multiple precision related headers. How to set the "multiple precision" pi as a third output argument? or printf/mexPrintf it as string?

PS. in order to build it correctly, mpir, mpfr, and a C++ wrapper (mpreal.h) have to be installed.

#include <iostream>
#include <math.h>
#include "mex.h"

// The multiple precision libraries
// #include "mpir.h"
#include "mpreal.h"


using namespace mpfr;
using namespace std;

extern void _main();

/****************************/
class MyData {

public:
  void display();
  void set_data(double v1, double v2);
  MyData(double v1 = 0, double v2 = 0);
  ~MyData() { }
private:
  double val1, val2;
};

MyData::MyData(double v1, double v2)
{
  val1 = v1;
  val2 = v2;
}

void MyData::display()
{
#ifdef _WIN32
    mexPrintf("Value1 = %g\n", val1);
    mexPrintf("Value2 = %g\n\n", val2);
#else
  cout << "Value1 = " << val1 << "\n";
  cout << "Value2 = " << val2 << "\n\n";
#endif
}

void MyData::set_data(double v1, double v2) { val1 = v1; val2 = v2; }

/*********************/

static
void mexcpp(
        double num1,
        double num2
        )
{
#ifdef _WIN32
    mexPrintf("\nThe initialized data in object:\n");
#else
  cout << "\nThe initialized data in object:\n";
#endif
  MyData *d = new MyData; // Create a  MyData object
  d->display();           // It should be initialized to
                          // zeros
  d->set_data(num1,num2); // Set data members to incoming
                          // values
#ifdef _WIN32
  mexPrintf("After setting the object's data to your input:\n");
#else
  cout << "After setting the object's data to your input:\n";
#endif
  d->display();           // Make sure the set_data() worked
  delete(d);
  flush(cout);
  return;
}

void mexFunction(
         int          nlhs,
         mxArray      *[],
         int          nrhs,
         const mxArray *prhs[]
         )
{
  double      *vin1, *vin2;

  /* Check for proper number of arguments */

  if (nrhs != 2) {
    mexErrMsgIdAndTxt("MATLAB:mexcpp:nargin", 
            "MEXCPP requires two input arguments.");
  } else if (nlhs >= 1) {
    mexErrMsgIdAndTxt("MATLAB:mexcpp:nargout",
            "MEXCPP requires no output argument.");
  }

  vin1 = (double *) mxGetPr(prhs[0]);
  vin2 = (double *) mxGetPr(prhs[1]);


  ////////////// Here are the multiple precision settings
  const int digits = 64;
  mpreal::set_default_prec(mpfr::digits2bits(digits));
  const mpreal pi          =    mpfr::const_pi();
  ////////////// How can I set the multiple precision pi as a third output argument?
  ///// say vpa? or something else?
  mexPrintf(" The multiple precision pi is %g \n",pi);

  mexcpp(*vin1, *vin2);
  return;
}
役に立ちましたか?

解決

I now think the answer should be very simple. for example, if I want to pass an obtained VectorXmp to Matlab

VectorXmp x(n);

Use mxCreateCellMatrix to create a same dimensional Vector, convert all components of x into char and then put them into the output cell using codes as below:

plhs[0]=mxCreateCellMatrix(n, 1);
 for (int i = 0; i < n; i++) {
     mxSetCell(plhs[0],i,mxCreateString(_strdup(x(i).toString().c_str())));
 }

Then in Matlab environment, use

 vpa(x) 

to convert the output into symbol matrix(vector), and

 double(vpa(x))

to convert it into double matrix(vector) with precision loss.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top