How to define a function with mexCallMatlab

Hi,
I have main C-code which has many functions in it. I wanted to turn it into a mex file and I wanted to take one of the functions from MATLAB. Basically one function inside my main function is:
void func_2(double f[], double x[])
{
f[1] = 3 + x[2]*x[5] + x[1]*x[4] - x[3]*x[5];
f[2] = 2 + x[2]*x[5] + x[1]*x[2] +x[3]*x[3];
f[3] = 8 + x[3]*x[5] + x[1]*x[3] + x[3]*x[4];
f[4] = x[3]*x[3] + x[1]*x[5] + x[1] - 11;
return;
}
What I want to do is to erase this function from the c code and define it inside the mexfunction as:
mexCallMATLAB(1, f, 1, &x, "func_2"); func_2 = f;
but it gives error and does not turn to mex file. How can I define a function like this?
Thank you.
Ezgi Koker

7 Commenti

Whenever you mention inthe forum, that you get an error, post a complete copy of the error message. What type has "func_2" in the C code?
James Tursa
James Tursa il 17 Apr 2017
Modificato: James Tursa il 17 Apr 2017
What is the purpose of replacing your C code with a call to mexCallMATLAB? Are you trying to make it so that the C code will call an m-file (func_2.m) instead of a hard-coded function? Also, where is the input "x" coming from? Native C/C++ memory or MATLAB allocated memory? And where is the result "f" intended to be used? Only in the C code or will it be returned back to MATLAB as part of an mxArray?
There are lots of different ways of doing things depending on the answers to these questions.
Side Comment: It looks like you are perhaps passing pointers to doubles to mexCallMATLAB, instead of pointers to mxArray's. This will crash MATLAB.
The error is " error C2106: '=' : left operand must be l-value". I think that mexCallMatlab gives a double matrix but func_2 must be a function. So I am assuming that this error occurs because these two does not match each other, is this correct?
My aim is to erase the function from c code and put an m-file call instead. Inside my c code there are many calls for this func_2 and in each call x is changing. I will give the initial values of x from Matlab. So if I manage to call m-file every time, the c-code will change x values in each call, get the renewed values of f and return to c-code with the new values. At the end of the procedure the c-code will give the final values of f to matlab.
It is not clear, why you want the function to appear in M-code instead of using the efficient implementation in C.
I ask again: What type has "func_2" in the C code?
@Jan: It appears func_2 is in fact a function. Hence this line will produce a compile error:
func_2 = f;
since the left hand side is effectively a const pointer and can't be an l-value. (i.e., you can't assign a value to something that is const)
James Tursa
James Tursa il 19 Apr 2017
Modificato: James Tursa il 19 Apr 2017
@ezgi: What are the sizes of x and f? Your current func_2 code assumes they point to arrays that are at least 6 elements in length for x and 5 elements in length for f. Also, your code ignores the first elements (x[0] and f[0]) since C arrays use 0-based indexing. Is this correct and intended? Do you want to pass a 6 element vector to MATLAB via mexCallMATLAB and get back a 5 element vector as a result? And ignore the 1st elements in both vectors?
It would not be all that hard to code up what you have as mexCallMATLAB calling an m-file, but the way things are currently coded I am not at all sure what the sizes of the inputs and outputs are supposed to be.
@Jan func_2 is one of the subroutines for my main code (void func_2(double f[], double x[])). I write this subroutine to be an example. In one of my other subroutines there is a constant that needs to be calculated with an interaction between different m-files. That is why I want to make the calculations in MATLAB and take the results back to C-code.
@James x is a 6 element vector and f is going to give a 5 element vector including that [0] element. I did it deliberately to cover the indexing differences. x is coming from previous steps of the code and will be transferred to MATLAB via mexCallMatlab. In the end I want f vector to be transferred to c-code again.

Accedi per commentare.

 Risposta accettata

I am still not entirely sure this is what you want, but here goes ...
// Takes 6-element x, passes it to MATLAB function func_2, then puts output in 5-element f
void func_2(double f[], double x[])
{
mxArray *rhs[1], *lhs[1];
double *xp, *fp;
int i;
rhs[0] = mxCreateDoubleMatrix(6,1,mxREAL);
xp = mxGetPr(rhs[0]);
for( i=0; i<6; i++ ) {
xp[i] = x[i];
}
mexCallMATLAB( 1, lhs, 1, rhs, "func_2" );
mxDestroyArray(rhs[0]);
if( lhs[0] ) {
if( mxIsDouble(lhs[0]) && mxGetNumberOfElements(lhs[0]) == 5 &&
!mxIsComplex(lhs[0]) && !mxIsSparse(lhs[0]) ) {
fp = mxGetPr(lhs[0]);
for( i=0; i<5; i++ ) {
f[i] = fp[i];
}
}
mxDestroyArray(lhs[0]);
}
}

1 Commento

Thank you so much for the answer, that solves my problem:)

Accedi per commentare.

Più risposte (0)

Categorie

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by