我应该如何将数据传递给 mexFunction 的 mxArray *plhs[] 以便在 Matlab 中获得其输出?

Posted

技术标签:

【中文标题】我应该如何将数据传递给 mexFunction 的 mxArray *plhs[] 以便在 Matlab 中获得其输出?【英文标题】:How should I pass data to mxArray *plhs[] of mexFunction in order to get its outputs in Matlab? 【发布时间】:2016-08-29 16:27:13 【问题描述】:

我想要一个预编译函数,如果它有任何正根,则返回二次方程的最大正实根,如果没有,则返回 0。我正在处理一些遥感数据,我已经做了一些测试,现在在我的例子中,所有二次多项式都有实根,但不能确定它们的符号。因此,我编写了以下 C 源代码。

/*
 * mx_solve_quadratic.cpp
 *
 * Solves for real roots of the standard quadratic equation
 *
 * The calling syntax is:
 *
 *      MaxRoot = mx_solve_quadratic(coefficientMatrix)
 *
 * This is a MEX file for MATLAB.
*/


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



int gsl_poly_solve_quadratic (double , double , double , double *, double *);

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

  double a; /* coefficient for x^2 */
  double b; /* coefficient for x */
  double c; /* coefficient for 1 */
  double x0; /* the smaller root */
  double x1; /* the bigger root */
  double *inMatrix = NULL;
  inMatrix = mxGetPr(prhs[0]);
  a = inMatrix[0];
  b = inMatrix[1];
  c = inMatrix[2];
  int i = gsl_poly_solve_quadratic(a,b,c,&x0,&x1);
  double signRoot = (x1 > 0 ? x1 : 0);
  mxSetPr(plhs[0], &signRoot);



int gsl_poly_solve_quadratic (double a, double b, double c, double *x0, double *x1)

  if (a == 0) /* Handle linear case */
    
      if (b == 0)
        
          return 0;
        
      else
        
          *x0 = -c / b;
          return 1;
        ;
    

  
    double disc = b * b - 4 * a * c;

    if (disc > 0)
      
        if (b == 0)
          
            double r = sqrt (-c / a);
            *x0 = -r;
            *x1 =  r;
          
        else
          
            double sgnb = (b > 0 ? 1 : -1);
            double temp = -0.5 * (b + sgnb * sqrt (disc));
            double r1 = temp / a ;
            double r2 = c / temp ;

            if (r1 < r2) 
              
                *x0 = r1 ;
                *x1 = r2 ;
               
            else 
              
                *x0 = r2 ;
                  *x1 = r1 ;
              
          
        return 2;
      
    else if (disc == 0) 
      
        *x0 = -0.5 * b / a ;
        *x1 = -0.5 * b / a ;
        return 2 ;
      
    else
      
        return 0;
      
  

事实上,我希望signRoot 作为标量值返回给 MATLAB。我已经调试了两次代码:

a=[1 3 2];
b=mx_solve_quadratic(a)

a=[1 -3 2];
b=mx_solve_quadratic(a)  

我看到一切都很好,直到最后一行,我想通过 signRoot 作为输出。如果我按F10,我会得到错误:

或者如果我尝试在 MATLAB 中运行 mex 函数而不进行调试,我会得到:

【问题讨论】:

您在 C 中分配一个数组,然后尝试将其交给 MATLAB。相反,您想在 MATLAB 中分配内存(使用 mxCreate* 函数),然后填充此数组。 @Suever 非常感谢 【参考方案1】:

Suever 是正确的。您正在尝试传递在 C 中创建的数组并将其交给 MATLAB,这是不明智和未定义的行为。您必须做的是使用任何mxCreate* 函数并将内存位置设置为您想要的任何结果。最简单的方法是使用 mxCreateDoubleMatrix 并指定输出为 1 行 1 列(即标量)并确保输出是真实的。

因此,请执行以下操作来替换 mexFunction 中的最后一行代码:

plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
double *out = mxGetPr(plhs[0]);
*out = signRoot;

这首先在 MATLAB 端为单个标量分配内存。然后你会得到一个指向这个内存的指针,然后相应地设置它。

为了绝对确定我们在同一页面上,下面是 mexFunction 修改后的样子。请注意,更改的行以/* NEW */ 注释引用。

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

  double a; /* coefficient for x^2 */
  double b; /* coefficient for x */
  double c; /* coefficient for 1 */
  double x0; /* the smaller root */
  double x1; /* the bigger root */
  double *inMatrix = NULL;
  inMatrix = mxGetPr(prhs[0]);
  a = inMatrix[0];
  b = inMatrix[1];
  c = inMatrix[2];
  int i = gsl_poly_solve_quadratic(a,b,c,&x0,&x1);
  double signRoot = (x1 > 0 ? x1 : 0);
  plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); /* NEW */
  double *out = mxGetPr(plhs[0]); /* NEW */
  *out = signRoot; /* NEW */


现在使用您的两个示例输入运行上述代码:

>> a = [1 -3 2];
>> b = mx_solve_quadratic(a)

b =

     2

>> a = [1 3 2];
>> b = mx_solve_quadratic(a)

b =

     0

【讨论】:

以上是关于我应该如何将数据传递给 mexFunction 的 mxArray *plhs[] 以便在 Matlab 中获得其输出?的主要内容,如果未能解决你的问题,请参考以下文章

如何将数据传递给 Modal ionic 2

如何使用json将数据传递给ajax函数?

如何将数据传递给BottomSheetDialogFragment [重复]

如何通过数组将数据传递给表格视图?

从 tableviewcontroller 将数据传递给父 viewcontroller

使用 jquery ajax 将数据传递给 php 的问题