Hi list,
My question has to do with the Numpy/SWIG typemapping system.
I recently got the typemaps in numpy.i to work on most of my C
functions that are wrapped using SWIG, if they have arguments of the
form (int sizeArray, float *pArray).
Now I am trying to figure out how to wrap function that aren't of the
form, such as the following function:
/*! \brief compute magnitude spectrum of a DFT
*
* \param sizeMag size of output Magnitude (half of input real FFT)
* \param pFReal pointer to input FFT real array
(real/imag floats)
* \param pFMAg pointer to float array of magnitude spectrum
*/
void sms_spectrumMag( int sizeMag, float *pInRect, float *pOutMag)
{
int i, it2;
float fReal, fImag;
for (i=0; i<sizeMag; i++)
{
it2 = i << 1;
fReal = pInRect[it2];
fImag = pInRect[it2+1];
pOutMag[i] = sqrtf(fReal * fReal + fImag * fImag);
}
}
There are two arrays, one is half the size of the other. But, SWIG
doesn't know this, according to the type map it will think *pInRect is
of size sizeMag and will not know anything about *pOutMag.
Ideally in python, I would like to call the function as
sms_spectrumMag(nArray1, nArray2), where nArray1 is twice the size of
nArray2, and nArray2 is of size sizeMag.
I think in order to do this (although if someone has a better
suggestion, I am open to it), I will have to modify the typemap in
order to tell SWIG how to call the C function properly. I do not want
to have to edit the wrapped C file every time it is regenerated from
the interface file.
Here is a start I made with the existing typemap code in numpy.i (not working):
/* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
*/
%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,
fragment="NumPy_Macros")
(DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
{
$1 = is_array($input) && PyArray_EquivTypenums(array_type($input),
DATA_TYPECODE);
}
%typemap(in,
fragment="NumPy_Fragments")
(DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)
(PyArrayObject* array=NULL, int i=0)
{
array = obj_to_array_no_conversion($input, DATA_TYPECODE);
if (!array || !require_dimensions(array,1) || !require_contiguous(array)
|| !require_native(array)) SWIG_fail;
$1 = 1;
for (i=0; i < array_numdims(array); ++i) $1 *= array_size(array,i);
$2 = (DATA_TYPE*) array_data(array);
}
and try to alter it to allow for a conversion of type:
(DIM_TYPE DIM1, DATA_TYPE* ARRAY1, DATA_TYPE* ARRAY2)
where ARRAY1 is size DIM1 * 2 and ARRAY2 is size DIM1. Then I can
%apply this to my function that I mentioned in the last post.
So here are my first two questions:
1) where is DIM1 used to declare the array size? I don't see where it
is used at all, and I need to somewhere multiply it by 2 to declare
the size of ARRAY1
2) I am not understanding where $input comes from, so I do not
understand how to distinguish between ARRAY1 and ARRAY2. In the
attempt I have already tried, I think I just use the pointer to ARRAY1
twice.
If anyone has suggestions on how to solve this problem, thanks!
regards,
Rich