Sayed M. Hussein
Sayed M. Hussein

Reputation: 33

Issue about logical output from MEX function in MATLAB

Why is the output always 1 from my MEX function although it was expected to be 0?

I wrote the following MEX source code shown below

#include "mex.h"

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
  bool *x,*y;

  /* Create matrix for the return argument. */
  plhs[0] = mxCreateLogicalMatrix(1,1);

  /* Assign pointers to each input and output. */
  x = mxGetLogicals(prhs[0]); //input
  y = mxGetLogicals(plhs[0]); //output

  /* Calculations. */
  if (*x == 0) *y = 1;
  else *y = 0;
}

and the following appears:

y = test(5)

y =

     1

Upvotes: 3

Views: 1165

Answers (1)

rayryeng
rayryeng

Reputation: 104555

I'd like to point you to the documentation of mxGetLogicals. Part of the documentation says:

Returns

Pointer to the first logical element in the mxArray. The result is unspecified if the mxArray is not a logical array.

What you are passing is a double precision number, not a logical. By doing this, you will get undefined behaviour. As such, there are three ways you can resolve this error:

  1. Pass an actual logical value to the function.
  2. Leave everything as is, but change what you are returning. Instead of *y = 1 and *y = 0, change this to true and false respectively, but the input has to be double.
  3. You basically must change any reference to logical / bool to double. Specifically, change mxGetLogicals to mxGetPr so you can get a pointer to a double precision real array. You'll also need to change mxCreateLogicalMatrix to mxCreateDoubleMatrix and you'll have to change your pointers from bool to double.

Option #1 - Passing a logical value to the function:

You simply need to do:

y = test(false);

or:

y = test(true);

Running this with these changes gives me the following:

>> y = test(false)

y =

     1

>> y = test(true)

y =

     0

Option #2 - Input type is double, output type is bool:

These changes are what you need to make:

#include "mex.h"

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
  double *x;
  bool *y; // Change

  /* Create matrix for the return argument. */
  plhs[0] = mxCreateLogicalMatrix(1,1);

  /* Assign pointers to each input and output. */
  x = mxGetPr(prhs[0]); //input - Change
  y = mxGetLogicals(plhs[0]); //output

  /* Calculations. */
  if (*x == 0) *y = true; // Change
  else *y = false;
}


Running this code with the above changes gives me:

>> y = test(0)

y =

     1

>> y = test(5)

y =

     0

Option #3 - Change bool behaviour to double:

#include "mex.h"

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
  double *x,*y; // Change

  /* Create matrix for the return argument. */
  plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); // Change

  /* Assign pointers to each input and output. */
  x = mxGetPr(prhs[0]); //input - Change
  y = mxGetPr(plhs[0]); //output - Change

  /* Calculations. */
  if (*x == 0) *y = 1;
  else *y = 0;
}

Running this code with the above changes gives me:

>> y = test(0)

y =

     1

>> y = test(5)

y =

     0

Upvotes: 3

Related Questions