Hello again,<br><br>I really don&#39;t know what came over me when I changed your function prototype, that wasn&#39;t a very thoughtful thing to do!<br><div class="Ih2E3d"><br><blockquote style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote">

Maybe I should look into using an &#39;insertion block&#39; of code in the<br>
interface file, instead of trying to typemap the array?<br></blockquote><br></div>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.<br>
<br>Basically, you can inline a new function with an easier prototype
to wrap. The function allocates memory and calls your sms_spectrumMag()
function.<br><br>my inline function: void my_spectrumMag( int sizeInMag, float *pInRect, int *sizeOutMag, float **pOutMag)<br>
<br>there&#39;s also a %rename directive: %rename (spectrumMag) my_spectrumMag;<br><br>I
had a go at defining some exceptions too (no memory and odd number of
indexes), but I&#39;m not sure errno is the easiest way to go about it...<br>
<br>Hope this helps!<br><br>... and the python test output:<br><br>~&gt;python test_dftmagnitude.py<br>array: [1, 1, 2, 2]<br>result: [ 1.41421354&nbsp; 2.82842708]<br><br>array: [1, 1, 2, 2, 3, 3, 4, 4]<br>result: [ 1.41421354&nbsp; 2.82842708&nbsp; 4.2426405&nbsp;&nbsp; 5.65685415]<br>
<br>array: [1, 1, 2]<br>result:<br>Traceback (most recent call last):<br>&nbsp; File &quot;test_dftmagnitude.py&quot;, line 15, in &lt;module&gt;<br>&nbsp;&nbsp;&nbsp; print &quot;result:&quot;,dftmagnitude.spectrumMag(a)<br>IndexError: Odd number of elements in input array: 3<br>
<br>~&gt;<br><br>Regards,<br><font color="#888888">Egor<br><br></font><br><div class="gmail_quote">On Tue, Jan 6, 2009 at 1:06 AM, Rich E <span dir="ltr">&lt;<a href="mailto:reakinator@gmail.com">reakinator@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">Egor,<br>
<br>
Thanks for the help. &nbsp;I think I want to leave the C code as-is<br>
however, as it is perfectly fine there no knowing &#39;sizeOutMag&#39; because<br>
it can deduce both array sizes from one variable. &nbsp;There are many<br>
other similar cases in my code (many where the size of the array is<br>
known by a member of a structure passed to the function).<br>
<br>
Maybe I should look into using an &#39;insertion block&#39; of code in the<br>
interface file, instead of trying to typemap the array? &nbsp;I am thinking<br>
I may just be able to copy the generated code (from SWIG) into my<br>
interface file to do this, but I have not tried it yet.<br>
<br>
I will experiment a little and post again. &nbsp;Thanks and happy holidays!<br>
<br>
regards,<br>
<font color="#888888">Rich<br>
</font><div><div></div><div class="Wj3C7c"><br>
On Mon, Jan 5, 2009 at 10:42 AM, Egor Zindy &lt;<a href="mailto:ezindy@gmail.com">ezindy@gmail.com</a>&gt; wrote:<br>
&gt; Hello Rich,<br>
&gt;<br>
&gt; sorry it took so long to answer back, holidays and all :-)<br>
&gt;<br>
&gt; That&#39;s exactly the kind of SWIG / numpy.i problems I&#39;ve been working on over<br>
&gt; the past few months: How to generate an array you don&#39;t know the size of<br>
&gt; a-priori, and then handle the memory deallocation seamlessly. In your case,<br>
&gt; you know that the output array will be half the size of the input array, but<br>
&gt; this falls under the more general case of &quot;not knowing the output size<br>
&gt; a-priori&quot;.<br>
&gt;<br>
&gt; Have a look at the files attached. I&#39;ve rewritten your function header as:<br>
&gt; void sms_spectrumMag( int sizeInMag, float *pInRect, int *sizeOutMag, float<br>
&gt; **pOutMag);<br>
&gt;<br>
&gt; Easy to see what the input and output arrays are now. Then my numpy.i<br>
&gt; handles the memory deallocation of the **pOutMag array.<br>
&gt;<br>
&gt; I&#39;ve actually moved my numpy.i explanations to the scipy/numpy cookbook last<br>
&gt; week :-)<br>
&gt; <a href="http://www.scipy.org/Cookbook/SWIG_Memory_Deallocation" target="_blank">http://www.scipy.org/Cookbook/SWIG_Memory_Deallocation</a><br>
&gt;<br>
&gt; Hope it all makes sense. If you have any questions, don&#39;t hesitate!<br>
&gt;<br>
&gt;&gt;python test_dftmagnitude.py<br>
&gt; [1, 1, 2, 2]<br>
&gt; [ 1.41421354 &nbsp;2.82842708]<br>
&gt; [1, 1, 2, 2, 3, 3, 4, 4]<br>
&gt; [ 1.41421354 &nbsp;2.82842708 &nbsp;4.2426405 &nbsp; 5.65685415]<br>
&gt; [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]<br>
&gt; [ 1.41421354 &nbsp;2.82842708 &nbsp;4.2426405 &nbsp; 5.65685415 &nbsp;7.07106781]<br>
&gt;<br>
&gt; Regards,<br>
&gt; Egor<br>
&gt;<br>
&gt; On Wed, Dec 24, 2008 at 1:52 AM, Rich E &lt;<a href="mailto:reakinator@gmail.com">reakinator@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Hi list,<br>
&gt;&gt;<br>
&gt;&gt; My question has to do with the Numpy/SWIG typemapping system.<br>
&gt;&gt;<br>
&gt;&gt; I recently got the typemaps in numpy.i to work on most of my C<br>
&gt;&gt; functions that are wrapped using SWIG, if they have arguments of the<br>
&gt;&gt; form (int sizeArray, float *pArray).<br>
&gt;&gt;<br>
&gt;&gt; Now I am trying to figure out how to wrap function that aren&#39;t of the<br>
&gt;&gt; form, such as the following function:<br>
&gt;&gt;<br>
&gt;&gt; /*! \brief compute magnitude spectrum of a DFT<br>
&gt;&gt; &nbsp;*<br>
&gt;&gt; &nbsp;* \param sizeMag &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;size of output Magnitude (half of input<br>
&gt;&gt; real FFT)<br>
&gt;&gt; &nbsp;* \param pFReal &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pointer to input FFT real array<br>
&gt;&gt; (real/imag floats)<br>
&gt;&gt; &nbsp;* \param pFMAg &nbsp; &nbsp; &nbsp; &nbsp;pointer to float array of magnitude spectrum<br>
&gt;&gt; &nbsp;*/<br>
&gt;&gt; void sms_spectrumMag( int sizeMag, float *pInRect, float *pOutMag)<br>
&gt;&gt; {<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; int i, it2;<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; float fReal, fImag;<br>
&gt;&gt;<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; for (i=0; i&lt;sizeMag; i++)<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; {<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; it2 = i &lt;&lt; 1;<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fReal = pInRect[it2];<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fImag = pInRect[it2+1];<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pOutMag[i] = sqrtf(fReal * fReal + fImag * fImag);<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; }<br>
&gt;&gt; }<br>
&gt;&gt;<br>
&gt;&gt; There are two arrays, one is half the size of the other. &nbsp;But, SWIG<br>
&gt;&gt; doesn&#39;t know this, according to the type map it will think *pInRect is<br>
&gt;&gt; of size sizeMag and will not know anything about *pOutMag.<br>
&gt;&gt;<br>
&gt;&gt; Ideally in python, I would like to call the function as<br>
&gt;&gt; sms_spectrumMag(nArray1, nArray2), where nArray1 is twice the size of<br>
&gt;&gt; nArray2, and nArray2 is of size sizeMag.<br>
&gt;&gt;<br>
&gt;&gt; I think in order to do this (although if someone has a better<br>
&gt;&gt; suggestion, I am open to it), I will have to modify the typemap in<br>
&gt;&gt; order to tell SWIG how to call the C function properly. &nbsp;I do not want<br>
&gt;&gt; to have to edit the wrapped C file every time it is regenerated from<br>
&gt;&gt; the interface file.<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; Here is a start I made with the existing typemap code in numpy.i (not<br>
&gt;&gt; working):<br>
&gt;&gt;<br>
&gt;&gt; /* Typemap suite for (DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)<br>
&gt;&gt; &nbsp;*/<br>
&gt;&gt; %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY,<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fragment=&quot;NumPy_Macros&quot;)<br>
&gt;&gt; &nbsp;(DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)<br>
&gt;&gt; {<br>
&gt;&gt; &nbsp;$1 = is_array($input) &amp;&amp; PyArray_EquivTypenums(array_type($input),<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DATA_TYPECODE);<br>
&gt;&gt; }<br>
&gt;&gt; %typemap(in,<br>
&gt;&gt; &nbsp; &nbsp; &nbsp; &nbsp;fragment=&quot;NumPy_Fragments&quot;)<br>
&gt;&gt; &nbsp;(DIM_TYPE DIM1, DATA_TYPE* INPLACE_ARRAY1)<br>
&gt;&gt; &nbsp;(PyArrayObject* array=NULL, int i=0)<br>
&gt;&gt; {<br>
&gt;&gt; &nbsp;array = obj_to_array_no_conversion($input, DATA_TYPECODE);<br>
&gt;&gt; &nbsp;if (!array || !require_dimensions(array,1) || !require_contiguous(array)<br>
&gt;&gt; &nbsp; &nbsp; || !require_native(array)) SWIG_fail;<br>
&gt;&gt; &nbsp;$1 = 1;<br>
&gt;&gt; &nbsp;for (i=0; i &lt; array_numdims(array); ++i) $1 *= array_size(array,i);<br>
&gt;&gt; &nbsp;$2 = (DATA_TYPE*) array_data(array);<br>
&gt;&gt; }<br>
&gt;&gt;<br>
&gt;&gt; and try to alter it to allow for a conversion of type:<br>
&gt;&gt; (DIM_TYPE DIM1, DATA_TYPE* ARRAY1, DATA_TYPE* ARRAY2)<br>
&gt;&gt; where ARRAY1 is size DIM1 * 2 and &nbsp;ARRAY2 is size DIM1. &nbsp;Then I can<br>
&gt;&gt; %apply this to my function that I mentioned in the last post.<br>
&gt;&gt;<br>
&gt;&gt; So here are my first two questions:<br>
&gt;&gt;<br>
&gt;&gt; 1) where is DIM1 used to declare the array size? &nbsp;I don&#39;t see where it<br>
&gt;&gt; is used at all, and I need to somewhere multiply it by 2 to declare<br>
&gt;&gt; the size of ARRAY1<br>
&gt;&gt;<br>
&gt;&gt; 2) I am not understanding where $input comes from, so I do not<br>
&gt;&gt; understand how to distinguish between ARRAY1 and ARRAY2. &nbsp;In the<br>
&gt;&gt; attempt I have already tried, I think I just use the pointer to ARRAY1<br>
&gt;&gt; twice.<br>
&gt;&gt;<br>
&gt;&gt; If anyone has suggestions on how to solve this problem, thanks!<br>
&gt;&gt;<br>
&gt;&gt; regards,<br>
&gt;&gt; Rich<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; Numpy-discussion mailing list<br>
&gt;&gt; <a href="mailto:Numpy-discussion@scipy.org">Numpy-discussion@scipy.org</a><br>
&gt;&gt; <a href="http://projects.scipy.org/mailman/listinfo/numpy-discussion" target="_blank">http://projects.scipy.org/mailman/listinfo/numpy-discussion</a><br>
&gt;<br>
&gt;<br>
</div></div></blockquote></div><br>