Mercurial > forge
view extra/mex/TODO @ 0:6b33357c7561 octave-forge
Initial revision
author | pkienzle |
---|---|
date | Wed, 10 Oct 2001 19:54:49 +0000 |
parents | |
children |
line wrap: on
line source
* mex.oct is a shared library. We should rename it libmex.so and link to it instead of including a separate copy of mex.o in each oct file. Only thing is, how do we install it beside version of liboctave we are using, and how do we make the loader find the correct version if we have multiple versions of octave installed. * More complete testing * Better error handling in mex * Use tempory files for Octave glue? * mex should translate -V4 to -DV4 * mex should remove mex_*.cc when done * clean up warnings in myset.c * If you want to support Octave and Matlab with the same code base without penalizing either, you will need to write a high level layer which supports both. Particularly, you must prohibit direct modification of the fields of the mxArray type, which means eliminating mxSet{Pi,Pr,N,M} from your matlab code. You can get the same functionality by adding the routines: mxResize (to add/remove rows and columns), mxReshape (to change the shape without changing the data), mxMakeComplex (to change a double matrix into a complex matrix), mxMakeReal (to change a complex matrix into a double matrix), mxAssign (to replace an array with a new one) These are all easy enough to define in Matlab. The octave routines will represent the data using either ComplexMatrix or Matrix so that an octave value can easily be constructed when it is needed. The matlab side can continue to use mxArray. The function mxGetPr is problematic for values passed from octave. Because you cannot get a reference to the Matrix in the ocave_value, you must assign it. Since mxGetPr returns a pointer to the contents of the array, you must use tmp.fortran_vec(). Since tmp is assigned, and arrays are copy-on-modify, the simple act of mxGetPr will trigger a copy. A solution is to trick the compiler: return the const pointer given by tmp.data(), but declare the function header included in the mex files as returning a nonconst pointer. You will need to hide the difference in storage between complex arrays, which matlab defines as two matrices (one for real and one for imaginary), and Octave defines as one matrix (with real and imaginary values alternating). This is easy to handle by returning Pi as Pr+1, and multiplying the current matlab index by 2. In octave this would be: #define mxStride 2 double *mxGetPr(mxArray *m) { return m->data(); } double *mxGetPzr(mxArray *m) { return (double *)(cm->data()); } double *mxGetPzi(mxArray *m) { return (double *)(cm->data()) + 1; } and for matlab #define mxStride 1 #define mxGetPzr mxGetPr #define mxGetPzi mxGetPi Then you could implement abs(z) as something like: int M, N; double *pr, *pi, *pd; M = mxGetM(prhs[0]); N = mxGetN(prhs[0]); pr = mxGetPzr(prhs[0]); pi = mxGetPzi(prhs[0]); plhs[0] = mxCreateDoubleMatrix(M,N); pd = mxGetPr(plhs[0]); for (j=0; j < M*N; j++) pd[j] = sqrt(pr[j*mxStride]*pr[j*mxStride]+pi[j*mxStride]*pi[j*mxStrde]); If you have any functions which take real and imaginary parts as separate arrays, these should be rewritten to accept an mxArray applying the solution above, otherwise you will have to do something ugly like: #ifdef HAVE_OCTAVE double *pr, *pi, *newr, *newi; pr = mxGetPzr(m); pi = mxGetPzi(m); newr = mxMalloc(M*N*sizeof(double)); newi = mxMalloc(M*N*sizeof(double)); for (j=0; j < M*N*mxStride; j+=mxStride) newr[j]=pr[j], newi[j]=pi[j]; complex_fun(newr,newi); for (j=0; j < M*N*mxStride; j+=mxStride) pr[j]=newr[j], pi[j]=newi[j]; mxFree(newr); mxFree(newi); #else complex_fun(mxGetPr(m),mxGetPi(m)); #endif