This helped immensely. I feel like I am getting close to being able to accomplish what I would like with SWIG: producing a python module that can be very 'python-like', while co-existing with the c library that is very 'c-like'.
There is one question still remaining though, is it possible to make the wrapped function have the same name still? Using either my_spectrumMag or spectrumMag means I have to create a number of inconsistencies between the python module and the c library. It is ideal to ignore (%ignore?) the c sms_spectrumMag and instead use the wrapped one, with the same name. But my attempts at doing this so far have not compiled because of name conflictions. Thanks for the help, I think you are doing great things with this numpy interface/typemaps system. regards, Rich On Tue, Jan 6, 2009 at 3:47 PM, Egor Zindy <[email protected]> wrote: > Hello again, > > I really don't know what came over me when I changed your function > prototype, that wasn't a very thoughtful thing to do! > >> Maybe I should look into using an 'insertion block' of code in the >> interface file, instead of trying to typemap the array? > > Insertion blocks... is that %inline code? In which case, yes! Have a look, I > attached a new version that uses some %inline directives in the > dftmagnitude.i file. > > Basically, you can inline a new function with an easier prototype to wrap. > The function allocates memory and calls your sms_spectrumMag() function. > > my inline function: void my_spectrumMag( int sizeInMag, float *pInRect, int > *sizeOutMag, float **pOutMag) > > there's also a %rename directive: %rename (spectrumMag) my_spectrumMag; > > I had a go at defining some exceptions too (no memory and odd number of > indexes), but I'm not sure errno is the easiest way to go about it... > > Hope this helps! > > ... and the python test output: > > ~>python test_dftmagnitude.py > array: [1, 1, 2, 2] > result: [ 1.41421354 2.82842708] > > array: [1, 1, 2, 2, 3, 3, 4, 4] > result: [ 1.41421354 2.82842708 4.2426405 5.65685415] > > array: [1, 1, 2] > result: > Traceback (most recent call last): > File "test_dftmagnitude.py", line 15, in <module> > print "result:",dftmagnitude.spectrumMag(a) > IndexError: Odd number of elements in input array: 3 > > ~> > > Regards, > Egor > > > On Tue, Jan 6, 2009 at 1:06 AM, Rich E <[email protected]> wrote: >> >> Egor, >> >> Thanks for the help. I think I want to leave the C code as-is >> however, as it is perfectly fine there no knowing 'sizeOutMag' because >> it can deduce both array sizes from one variable. There are many >> other similar cases in my code (many where the size of the array is >> known by a member of a structure passed to the function). >> >> Maybe I should look into using an 'insertion block' of code in the >> interface file, instead of trying to typemap the array? I am thinking >> I may just be able to copy the generated code (from SWIG) into my >> interface file to do this, but I have not tried it yet. >> >> I will experiment a little and post again. Thanks and happy holidays! >> >> regards, >> Rich >> >> On Mon, Jan 5, 2009 at 10:42 AM, Egor Zindy <[email protected]> wrote: >> > Hello Rich, >> > >> > sorry it took so long to answer back, holidays and all :-) >> > >> > That's exactly the kind of SWIG / numpy.i problems I've been working on >> > over >> > the past few months: How to generate an array you don't know the size of >> > a-priori, and then handle the memory deallocation seamlessly. In your >> > case, >> > you know that the output array will be half the size of the input array, >> > but >> > this falls under the more general case of "not knowing the output size >> > a-priori". >> > >> > Have a look at the files attached. I've rewritten your function header >> > as: >> > void sms_spectrumMag( int sizeInMag, float *pInRect, int *sizeOutMag, >> > float >> > **pOutMag); >> > >> > Easy to see what the input and output arrays are now. Then my numpy.i >> > handles the memory deallocation of the **pOutMag array. >> > >> > I've actually moved my numpy.i explanations to the scipy/numpy cookbook >> > last >> > week :-) >> > http://www.scipy.org/Cookbook/SWIG_Memory_Deallocation >> > >> > Hope it all makes sense. If you have any questions, don't hesitate! >> > >> >>python test_dftmagnitude.py >> > [1, 1, 2, 2] >> > [ 1.41421354 2.82842708] >> > [1, 1, 2, 2, 3, 3, 4, 4] >> > [ 1.41421354 2.82842708 4.2426405 5.65685415] >> > [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] >> > [ 1.41421354 2.82842708 4.2426405 5.65685415 7.07106781] >> > >> > Regards, >> > Egor >> > >> > On Wed, Dec 24, 2008 at 1:52 AM, Rich E <[email protected]> wrote: >> >> >> >> 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 >> >> _______________________________________________ >> >> Numpy-discussion mailing list >> >> [email protected] >> >> http://projects.scipy.org/mailman/listinfo/numpy-discussion >> > >> > > > > _______________________________________________ > Numpy-discussion mailing list > [email protected] > http://projects.scipy.org/mailman/listinfo/numpy-discussion > > _______________________________________________ Numpy-discussion mailing list [email protected] http://projects.scipy.org/mailman/listinfo/numpy-discussion
