|
Hi there,
I'm new with mex and need your help. I want to use C
function (exactly amebsa.c routine) in MAtlab, but I don't
know how to pass a function from Matlab to mex file.
The code is quite long so i will put here only a part
concerning my mex problem.
All questions are listed from Q.1. to Q.6.
You can just answer i.e.:
Q.1. It's easier than you could imagine...
or post correct mexFunction
------------------------------------------------------
My SSA.m file is a function:
-------------------------------------------------------
function [x,fval]=SSA(catalog,name)
//within this function I declare random values of x:
x = rand(8,1);
//then i have a subfunction, which takes an x, for this x
//calculates many others parameters and returns sum of
//squares of them.
function [SumOfSquares]=sse(x)
//I want to optimize my function sse(x) and use for this C
//function 'amebsa.c'.
//I call this function with many input parameters, also
//with my function sse(x).
[pb,yb]= amebsa(p, y, n_dim, TolFun, @sse, iter, Temp_begin);
//...
end
---------------------------------------------------
My mex gateway function amebsa.c
----------------------------------------------------
#include "mex.h"
//Instead of operation on arrays I use names:
/* Input Arguments */
#define simplex_vectors prhs[0]
#define f_begin_values prhs[1]
#define n_dimensions prhs[2]
#define convergence_tolerance prhs[3]
#define function prhs[4]
#define n_iterations prhs[5]
#define temperature prhs[6]
/* Output Arguments */
#define optimized_function plhs[0]
#define optimal_vector plhs[1]
// function amebsa
void amebsa(float **p, float y[], int ndim, float pb[],
float *yb, float ftol, float (*funk)(float []), int *iter,
float temptr)
{
//... is not important for this problem what's inside
}
//Now is my mexFunction, the problem is with a pointer
//float *funk, which needs to pass a pointer to my sse(x)
//function from Matlab to amebsa function.
//Q.1. How to do it?
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray*prhs[] )
{
float *p;
float *y;
int *ndim;
float *pb;
float *yb;
float *ftol;
//Q.2.How to declare funk, so that it pass a
// float (*funk)(float [])??
float *funk;
int *iter;
float *temptr;
mwSize m,n;
/* Create a matrix for the return argument */
m = mxGetM(f_begin_values)-1;
n = mxGetN(f_begin_values);
optimal_vector = mxCreateDoubleMatrix(m, n, mxREAL);
m = mxGetM(temperature);
n = mxGetN(temperature);
optimized_function = mxCreateDoubleMatrix(m, n, mxREAL);
/* Assign pointers to the various parameters */
p = (float*)mxGetPr(simplex_vectors);
y = (float*)mxGetPr(f_begin_values);
ndim = (int*)mxGetPr(n_dimensions);
pb = (float*)mxGetPr(optimal_vector);
yb = (float*)mxGetPr(optimized_function);
ftol = (float*)mxGetPr(convergence_tolerance);
//Q.3.Should I use here mxGetPr?
//Q.4.'function' is not an array and mxGetPr returns only a
//double pointer (I can cast it to float pointer or integer
//pointer, but to pointer to float function(pointer to //float)?
//Q.5. Is there any solution how to deal with this problem?
//Q.6. How does the mex pass it right now? As what,
//structure? object?
funk = (float*)mxGetPr(function);
iter = (int*)mxGetPr(n_iterations);
temptr =(float*)mxGetPr(temperature);
/* Do the actual computations in a subroutine */
amebsa(&p,y,*ndim,pb,yb,*ftol,funk,iter,temptr);
return;
}
---------------------------------------------------------
When I try to compile a code written above:
--------------------------------------------------------
>> mex amebsa.c amotsa.c ran1.c nrutil.c
//I get:
Warning amebsa.c: 146 assignment of pointer to float
function(pointer to float) to pointer to float
//If i change declaration in mexFunction 'float *funk' to
float (*funk)(float [])
//and instead of 'funk = (float*)mxGetPr(function)'
funk = (float* (float //[]))mxGetPr(function)
//I get a message:
Error amebsa.c: 141 cast from `pointer to double' to
`pointer to float function(pointer to float)' is illegal
//(It's because mxGetPr returns only a double pointer)
!!!thanks a lot for looking at it!!!
|