How to pass a Matlab function handle to C-Mex Code
15 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Friedrich
le 18 Oct 2024
Commenté : Friedrich
le 22 Oct 2024 à 12:59
Hi all,
I am new to C-Mex and maybe my task is too ambitious for now. I am trying to write some ODE-Solvers with C-Mex functions so that the solvers are callable from Matlab. To achieve this I need to pass the model equations from Matlab as function handles to the C-Code. I am struggeling here since the model equations return an array. I simply don't know how to implement such thing with C-Mex.
Could anyone provide a simple example so I could get a better understanding?
Thanks a lot.
0 commentaires
Réponse acceptée
James Tursa
le 21 Oct 2024
Modifié(e) : James Tursa
le 22 Oct 2024
To use a function handle in a mex function with C array as an input to the function handle, you can use mexCallMATLAB( ) with the function handle as an argument to the feval( ) function along with converting the C array to an mxArray inside the C code. E.g., compile this C code (CAUTION: Bare Bones for Example Only ... No Argument Checking Included):
// fnhandle.c , evaluates function handle inside mex function.
// This example assumes function handle takes one input
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *rhs[2]; // mxArrays used for input to mexCallMATLAB
double data[3] = {1.0, 2.0, -3.0}; // Some sample data in a C array
double *pr; // Pointer used for copying C array to mxArray
// Copy function handle to input array
rhs[0] = (mxArray *) prhs[0];
// Create input to the function handle
rhs[1] = mxCreateDoubleMatrix(1,3,mxREAL);
// Copy the C array data to the mxArray
pr = (double *) mxGetData(rhs[1]);
pr[0] = data[0]; pr[1] = data[1]; pr[2] = data[2];
// Call feval( ) to evaluate the function handle with one input and put the result in plhs[0]
mexCallMATLAB(1,plhs,2,rhs,"feval");
// Destroy the temporary mxArray
mxDestroyArray(rhs[1]);
}
And run it as follows:
>> mex fnhandle.c
Building with 'MinGW64 Compiler (C)'.
MEX completed successfully.
>> fh = @(x)2*x+1
fh =
function_handle with value:
@(x)2*x+1
>> fnhandle(fh)
ans =
3 5 -5
>> fh = @(x)x.^2-2
fh =
function_handle with value:
@(x)x.^2-2
>> fnhandle(fh)
ans =
-1 2 7
Note that MATLAB workspace variables used in the function handle are embedded in the function handle at the time of function handle creation, so they get automatically passed into the mex routine as part of the function handle. E.g.,
>> A = [2;-1;2];
>> fh = @(x)x*A % A is part of the function handle fh
fh =
function_handle with value:
@(x)x*A
>> fnhandle(fh) % This will do an inner product
ans =
-6
>> fh = @(x)A*x % A is part of the function handle fh
fh =
function_handle with value:
@(x)A*x
>> fnhandle(fh) % This will do an outer product
ans =
2 4 -6
-1 -2 3
2 4 -6
In these last examples, the A variable from the MATLAB workspace is embedded in the function handle fh, so it gets passed into the mex routine as part of fh.
If you need to use the results of the function handle call inside the C mex function, then instead of putting the result in plhs[0] you could put the result in a different mxArray and then use a pointer to get at the data of this mxArray. E.g., in the above code you could have done this:
pr = (double *) mxGetData(plhs[0]);
Or using a different output variable the above code could be changed to:
mxArray *lhs[1];
:
mexCallMATLAB(1,lhs,2,rhs,"feval");
pr = (double *) mxGetData(lhs[0]);
// Use pr here
mxDestroyArray(lhs[0]);
And then dereferenced pr to get at the results of the function handle call inside the C code.
Plus de réponses (1)
Bruno Luong
le 18 Oct 2024
Rather than using function handle, call MATLAB with function name using mexCallMATLAB
Voir également
Catégories
En savoir plus sur Mathematics and Optimization dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!