Defining complex input types to make a complex mex function

6 visualizaciones (últimos 30 días)
Mohammad Shojaei Arani
Mohammad Shojaei Arani el 4 de Jul. de 2022
Respondida: Varun el 1 de Dic. de 2023
Hello friends,
Recently I became familliar with mex function. I am quite new to this and have lots of hopes to speed up my slow codes. However, I ran into a problem and really need your help (this is not easy for me to fix). I have a function
Cost_Spline3(par,J,Coeff,N,X0,X,dt,EZ,H,H_coeff,mesh,mesh_fine,dmesh_fine,M,SplineType)
but I have difficulty to 'define input types' for 4 inputs: H,EZ,Coeff,H_coeff. H is a matlab function which accepts the vector x (1*N) and as output gives a vector (actually a matrix)
H =
function_handle with value:
@(x)[-x.*(x.^2-3.0);x.^2.*(x.^2-6.0)+3.0]
but, note that depending on J the number of outputs of H are (J-2). EZ is a rather complex function handle. For instance,
EZ = @(Dm0,Dm1,Dm2,Dm3,Ds0,Ds1,Ds2,Ds3)[(Ds0.*(Ds0.*(Ds0.*(10.*5.^(1./2).*Dm2-5.*5.^(1./2).*Ds0.*Ds3)-5.^(1./2).*(4.*Ds1+20.*Dm0.*Ds2+20.*Dm1.*Ds1))+5.^(1./2).*(8.*Dm0+20.*Dm0.*Ds1.^2+20.*Dm0.*Dm1))-20.*5.^(1./2).*Dm0.^2.*Ds1)./(8.*Ds0.^2);(Ds0.*(Ds0.*(20.*Dm1+5.*Ds1.^2-10.*Ds0.*Ds2+4)-40.*Dm0.*Ds1)+20.*Dm0.^2)./(4.*Ds0.^2);(6.*5.^(1./2).*Dm0-3.*5.^(1./2).*Ds0.*Ds1)./(2.*Ds0);0.*Ds0+3]
so, the number of inputs of EZ are dynamic. Based on J and K, EZ can have up to 4K-1 inputs and exactly J outputs. Coeff is a cell array of matlab functions. For instance,
Coeff =
1×2 cell array
{@(w)[0.*w+1,-3.*w,3.*w.^2,-w.^3]} {@(w)[0.*w+1,-4.*w,6.*w.^2,-4.*w.^3,w.^4]}
where w would be column vectors later with different lengths. H_coeff is a J*1 cell array with variable array lengths.
Your help is greatly appreciated!
Babak

Respuestas (1)

Varun
Varun el 1 de Dic. de 2023
Hi Mohammad,
Looks like you are facing difficulties in defining input types for 4 inputs: “H”, “EZ”, “Coeff”, “H_coeff”.
You can pass these 4 inputs as “mxArray” types in C++, and then within your “MEX” function, call them using "mexCallMATLAB" functions. Alternatively, you could pass them as strings representing MATLAB code and then use "eval" or "feval" within your "MEX" function.
Please refer the example code snippet:
#include "mex.h"
// Function to call a MATLAB function handle with input arguments
mxArray* callFunctionHandle(const mxArray* functionHandle, const mxArray* input) {
mxArray* output;
mxArray* rhs[2]; // Two arguments: function handle and input
rhs[0] = const_cast<mxArray*>(functionHandle);
rhs[1] = const_cast<mxArray*>(input);
mexCallMATLAB(1, &output, 2, rhs, "feval");
return output;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
// Check the number of inputs and outputs
if (nrhs != 1 || nlhs != 1) {
mexErrMsgIdAndTxt("MyToolbox:invalidInputOutput", "One input and one output required.");
}
// Assume the first input is a function handle
mxArray* H_functionHandle = const_cast<mxArray*>(prhs[0]);
// Call the H function handle with a sample input (modify this based on your needs)
mxArray* input = mxCreateDoubleScalar(2.0); // Example input
mxArray* output = callFunctionHandle(H_functionHandle, input);
// Assign the output to the output argument of the MEX function
plhs[0] = output;
// Free allocated memory if needed
mxDestroyArray(input);
}
Please refer to the follwing documentations to learn more:
Hope it helps.

Categorías

Más información sobre Write C Functions Callable from MATLAB (MEX Files) en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by