Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
rand() using mexCallMATLAB

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 12 Sep, 2013 10:47:09

Message: 1 of 12

I want to use the existing Matlab rand() function in a Mex function. I have two int variables which determine the size of the array of random numbers. Since I have to use mexCallMATLAB for using the Matlab rand() function, I don't know how to pass the 2 int variables as the prhs[] input to mexCallMATLAB. Any help will be really helpful.

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 12 Sep, 2013 10:53:06

Message: 2 of 12

"Hariprasad" wrote in message <l0s63d$f2e$1@newscl01ah.mathworks.com>...
> I want to use the existing Matlab rand() function in a Mex function. I have two int variables(rows and cols) which determine the size of the array of random numbers. Since I have to use mexCallMATLAB for using the Matlab rand() function, I don't know how to pass the 2 int variables as the prhs[] input to mexCallMATLAB. Any help will be really helpful.

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 12 Sep, 2013 12:20:06

Message: 3 of 12

"Hariprasad" wrote in message <l0s6ei$krk$1@newscl01ah.mathworks.com>...
> "Hariprasad" wrote in message <l0s63d$f2e$1@newscl01ah.mathworks.com>...
> > I want to use the existing Matlab rand() function in a Mex function. I have two int variables(rows and cols) which determine the size of the array of random numbers. Since I have to use mexCallMATLAB for using the Matlab rand() function, I don't know how to pass the 2 int variables as the prhs[] input to mexCallMATLAB. Any help will be really helpful.

i have done something like this inside the mexFunction()

mxArray *lhs,*rhs[2];
int *p1,*p2;
double *randoms;

lhs = mxCreateDoubleMatrix(m,no_of_levels,mxREAL); /* m =2, no_of_levels = 4 */
randoms = mxGetPr(lhs);
rhs[0] = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
rhs[1] = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
p1 = mxGetPr(rhs[0]); *p1 = m;
p2 = mxGetPr(rhs[1]); *p2 = no_of_levels;

mxCallMATLAB(1,lhs,2,rhs,"rand");

but the data is zero in randoms. Where am I going wrong??
Thanks

Subject: rand() using mexCallMATLAB

From: James Tursa

Date: 12 Sep, 2013 14:44:06

Message: 4 of 12

"Hariprasad" wrote in message <l0sbhm$m70$1@newscl01ah.mathworks.com>...
> "Hariprasad" wrote in message <l0s6ei$krk$1@newscl01ah.mathworks.com>...
> > "Hariprasad" wrote in message <l0s63d$f2e$1@newscl01ah.mathworks.com>...
> > > I want to use the existing Matlab rand() function in a Mex function. I have two int variables(rows and cols) which determine the size of the array of random numbers. Since I have to use mexCallMATLAB for using the Matlab rand() function, I don't know how to pass the 2 int variables as the prhs[] input to mexCallMATLAB. Any help will be really helpful.
>
> i have done something like this inside the mexFunction()
>
> mxArray *lhs,*rhs[2];
> int *p1,*p2;
> double *randoms;
>
> lhs = mxCreateDoubleMatrix(m,no_of_levels,mxREAL); /* m =2, no_of_levels = 4 */
> randoms = mxGetPr(lhs);
> rhs[0] = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
> rhs[1] = mxCreateNumericMatrix(1,1,mxUINT8_CLASS,mxREAL);
> p1 = mxGetPr(rhs[0]); *p1 = m;
> p2 = mxGetPr(rhs[1]); *p2 = no_of_levels;
>
> mxCallMATLAB(1,lhs,2,rhs,"rand");
>
> but the data is zero in randoms. Where am I going wrong??
> Thanks

Your basic problem is that mxUINT8_CLASS is a 1-byte integer, but your are accessing the data area using an int *, which points to a 4-byte integer. This has the potential to bomb MATLAB btw. Try this instead:

 mxArray *lhs,*rhs[2];
 double *randoms;
 rhs[0] = mxCreateDoubleScalar(m);
 rhs[1] = mxCreateDoubleScalar(no_of_levels);
 mexCallMATLAB(1,lhs,2,rhs,"rand");
 mxDestroyArray(rhs[1]);
 mxDestroyArray(rhs[0]);
 randoms = mxGetPr(lhs[0]);
 // use randoms
 mxDestroyArray(lhs[0]);

James Tursa

Subject: rand() using mexCallMATLAB

From: James Tursa

Date: 12 Sep, 2013 15:08:06

Message: 5 of 12

"James Tursa" wrote in message <l0sjvm$50f$1@newscl01ah.mathworks.com>...

> mxArray *lhs,*rhs[2];

Typo, make the above line:

  mxArray *lhs[1],*rhs[2];

James Tursa

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 13 Sep, 2013 05:06:09

Message: 6 of 12

"James Tursa" wrote in message <l0slcm$ki8$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <l0sjvm$50f$1@newscl01ah.mathworks.com>...
>
> > mxArray *lhs,*rhs[2];
>
> Typo, make the above line:
>
> mxArray *lhs[1],*rhs[2];
>
> James Tursa

Hello Sir, I made the changes as directed by you but still the 'randoms' is Zero. I have used the codes as follows: -

double *randoms1, *randoms2; /* need 2 diff sized arrays 2x4 and 2x1 */
mxArray *rhs1[2], *rhs2[2], *lhs1[1], *lhs2[1];

/* (m=2,no_of_levels=4) from int to double would be a problem?*/
lhs1[0] = mxCreateDoubleMatrix(m,no_of_levels,mxREAL);
lhs2[0] = mxCreateDoubleMatrix(1,m,mxREAL);

rhs1[0] = mxCreateDoubleScalar(m);
rhs1[1] = mxCreateDoubleScalar(no_of_levels);

rhs2[0] = mxCreateDoubleScalar(m);
rhs2[1] = mxCreateDoubleScalar(1);

mexCallMATLAB(1,lhs1[0],2,rhs1,"rand");
mxDestroyArray(rhs1[0]);mxDestroyArray(rhs1[1]);
randoms1 = mxGetPr(lhs1[0]);

like wise I call mexCallMATLAB(1,lhs2[0],2,rhs2,"rand");

I also use mexEvalString("rand('twister',sum(100*clock));");
to set the seed before the start of each iteration. Would this be the cause of trouble? Also the randoms1 and randoms2 will be regenerated many times in the code(at least 100 times), so I guess I should use mxDestroyArray at the end of the codes, right?

Hariprasad

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 13 Sep, 2013 05:32:06

Message: 7 of 12

"Hariprasad" wrote in message <l0u6g1$d3n$1@newscl01ah.mathworks.com>...
> "James Tursa" wrote in message <l0slcm$ki8$1@newscl01ah.mathworks.com>...
> > "James Tursa" wrote in message <l0sjvm$50f$1@newscl01ah.mathworks.com>...
> >
> > > mxArray *lhs,*rhs[2];
> >
> > Typo, make the above line:
> >
> > mxArray *lhs[1],*rhs[2];
> >
> > James Tursa
>
> Hello Sir, I made the changes as directed by you but still the 'randoms' is Zero. I have used the codes as follows: -
>
> double *randoms1, *randoms2; /* need 2 diff sized arrays 2x4 and 2x1 */
> mxArray *rhs1[2], *rhs2[2], *lhs1[1], *lhs2[1];
>
> /* (m=2,no_of_levels=4) from int to double would be a problem?*/
> lhs1[0] = mxCreateDoubleMatrix(m,no_of_levels,mxREAL);
> lhs2[0] = mxCreateDoubleMatrix(1,m,mxREAL);
>
> rhs1[0] = mxCreateDoubleScalar(m);
> rhs1[1] = mxCreateDoubleScalar(no_of_levels);
>
> rhs2[0] = mxCreateDoubleScalar(m);
> rhs2[1] = mxCreateDoubleScalar(1);
>
> mexCallMATLAB(1,lhs1[0],2,rhs1,"rand");
> mxDestroyArray(rhs1[0]);mxDestroyArray(rhs1[1]);
> randoms1 = mxGetPr(lhs1[0]);
>
> like wise I call mexCallMATLAB(1,lhs2[0],2,rhs2,"rand");
>
> I also use mexEvalString("rand('twister',sum(100*clock));");
> to set the seed before the start of each iteration. Would this be the cause of trouble? Also the randoms1 and randoms2 will be regenerated many times in the code(at least 100 times), so I guess I should use mxDestroyArray at the end of the codes, right?

Sorry Sir, I'm getting the results now. A couple of times I tried after compiling my code, it returned Zeros. Then I compiled a couple of times and it gave non-zeros.
Now I just want to make sure I can re-use randoms1 and randoms2 in iterations and destroy arrays at the end of the code OR should I re-allocate memory every time I use them and destroy arrays every time as well?
Thanks You
> Hariprasad

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 13 Sep, 2013 06:04:06

Message: 8 of 12

"Hariprasad" wrote in message <l0u80m$8qo$1@newscl01ah.mathworks.com>...
> "Hariprasad" wrote in message <l0u6g1$d3n$1@newscl01ah.mathworks.com>...
> > "James Tursa" wrote in message <l0slcm$ki8$1@newscl01ah.mathworks.com>...
> > > "James Tursa" wrote in message <l0sjvm$50f$1@newscl01ah.mathworks.com>...
> > >
> > > > mxArray *lhs,*rhs[2];
> > >
> > > Typo, make the above line:
> > >
> > > mxArray *lhs[1],*rhs[2];
> > >
> > > James Tursa
> >
> > Hello Sir, I made the changes as directed by you but still the 'randoms' is Zero. I have used the codes as follows: -
> >
> > double *randoms1, *randoms2; /* need 2 diff sized arrays 2x4 and 2x1 */
> > mxArray *rhs1[2], *rhs2[2], *lhs1[1], *lhs2[1];
> >
> > /* (m=2,no_of_levels=4) from int to double would be a problem?*/
> > lhs1[0] = mxCreateDoubleMatrix(m,no_of_levels,mxREAL);
> > lhs2[0] = mxCreateDoubleMatrix(1,m,mxREAL);
> >
> > rhs1[0] = mxCreateDoubleScalar(m);
> > rhs1[1] = mxCreateDoubleScalar(no_of_levels);
> >
> > rhs2[0] = mxCreateDoubleScalar(m);
> > rhs2[1] = mxCreateDoubleScalar(1);
> >
> > mexCallMATLAB(1,lhs1[0],2,rhs1,"rand");
> > mxDestroyArray(rhs1[0]);mxDestroyArray(rhs1[1]);
> > randoms1 = mxGetPr(lhs1[0]);
> >
> > like wise I call mexCallMATLAB(1,lhs2[0],2,rhs2,"rand");
> >
> > I also use mexEvalString("rand('twister',sum(100*clock));");
> > to set the seed before the start of each iteration. Would this be the cause of trouble? Also the randoms1 and randoms2 will be regenerated many times in the code(at least 100 times), so I guess I should use mxDestroyArray at the end of the codes, right?
>
> Sorry Sir, I'm getting the results now. A couple of times I tried after compiling my code, it returned Zeros. Then I compiled a couple of times and it gave non-zeros.
> Now I just want to make sure I can re-use randoms1 and randoms2 in iterations and destroy arrays at the end of the code OR should I re-allocate memory every time I use them and destroy arrays every time as well?
> Thank You
> > Hariprasad

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 13 Sep, 2013 06:30:07

Message: 9 of 12


> > > mexCallMATLAB(1,lhs[0],2,rhs,"rand");

Could this have been the point of error.. "lhs[0]" ?
Because in my other loop for randoms2 I had put mexCallMATLAB(1,lhs2[0],2,rhs2,"rand");
I got randoms2 as Zero. Then I changed it to
mexCallMATLAB(1,lhs2,2,rhs2,"rand"); and compiled again, got it fine!!!
I'm not sure but that's how it worked for me.

Thank You
Hariprasad

Subject: rand() using mexCallMATLAB

From: James Tursa

Date: 13 Sep, 2013 18:50:07

Message: 10 of 12

"Hariprasad" wrote in message <l0ubdf$6o4$1@newscl01ah.mathworks.com>...
>
> > > > mexCallMATLAB(1,lhs[0],2,rhs,"rand");
>
> Could this have been the point of error.. "lhs[0]" ?
> Because in my other loop for randoms2 I had put mexCallMATLAB(1,lhs2[0],2,rhs2,"rand");
> I got randoms2 as Zero. Then I changed it to
> mexCallMATLAB(1,lhs2,2,rhs2,"rand"); and compiled again, got it fine!!!
> I'm not sure but that's how it worked for me.

The signature for mexCallMATLAB listed in the documentation is as follows:

int mexCallMATLAB(int nlhs, mxArray *plhs[], int nrhs,
  mxArray *prhs[], const char *functionName);

The expected type for the 2nd argument is thus mxArray **. But the type of lhs[0] is just mxArray *. That difference, in and of itself, should tell you that the use of lhs[0] for this argument is wrong. That is why you needed to drop the [0] for this argument to work properly.

James Tursa

Subject: rand() using mexCallMATLAB

From: James Tursa

Date: 13 Sep, 2013 18:55:06

Message: 11 of 12

"Hariprasad" wrote in message <l0u80m$8qo$1@newscl01ah.mathworks.com>...
>
> Sorry Sir, I'm getting the results now. A couple of times I tried after compiling my code, it returned Zeros. Then I compiled a couple of times and it gave non-zeros.
> Now I just want to make sure I can re-use randoms1 and randoms2 in iterations and destroy arrays at the end of the code OR should I re-allocate memory every time I use them and destroy arrays every time as well?
> Thanks You
> > Hariprasad

If you are repeatedly generating new random number arrays within a C loop, then yes you should use mxDestroyArray on the results each time at the end of each iteration in order to avoid running out of memory since mexCallMATLAB will allocate new memory for the lhs return each time it is called. I'm not sure you got this point earlier so I will state it explicitly now ... you do NOT pre-allocate the lhs arrays prior to calling mexCallMATLAB. The mexCallMATLAB call itself will allocate whatever it needs for the return value(s) automatically.

James Tursa

Subject: rand() using mexCallMATLAB

From: Hariprasad

Date: 19 Sep, 2013 06:54:07

Message: 12 of 12

"James Tursa" wrote in message <l0vn2a$4ob$1@newscl01ah.mathworks.com>...
> "Hariprasad" wrote in message <l0u80m$8qo$1@newscl01ah.mathworks.com>...
> >
> > Sorry Sir, I'm getting the results now. A couple of times I tried after compiling my code, it returned Zeros. Then I compiled a couple of times and it gave non-zeros.
> > Now I just want to make sure I can re-use randoms1 and randoms2 in iterations and destroy arrays at the end of the code OR should I re-allocate memory every time I use them and destroy arrays every time as well?
> > Thanks You
> > > Hariprasad
>
> If you are repeatedly generating new random number arrays within a C loop, then yes you should use mxDestroyArray on the results each time at the end of each iteration in order to avoid running out of memory since mexCallMATLAB will allocate new memory for the lhs return each time it is called. I'm not sure you got this point earlier so I will state it explicitly now ... you do NOT pre-allocate the lhs arrays prior to calling mexCallMATLAB. The mexCallMATLAB call itself will allocate whatever it needs for the return value(s) automatically.
>
> James Tursa

Thank You Sir. Really helpful insights and solutions. I was able to solve this issue with rand(). This is what I have done: -

mxArray *lhs[1], *rhs[2];
double *randoms;

rhs[0] = mxCreateDoubleScalar(m); /* m = 2 */
rhs[1] = mxCreateDoubleScalar(no_of_levels); /* no_of_levels = 4 */

and in the code
mxCallMATLAB(1,lhs,2,rhs,"rand");
randoms = mxGetPr(lhs[0]);
and used randoms for further processing.

Just need to check when I need to clear and when I should not clear the arrays.
Hariprasad

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us