diff options
author | wfspotz@sandia.gov <wfspotz@sandia.gov@localhost> | 2007-11-30 03:58:34 +0000 |
---|---|---|
committer | wfspotz@sandia.gov <wfspotz@sandia.gov@localhost> | 2007-11-30 03:58:34 +0000 |
commit | b0e8c7866f241033177e03856318b1f2d11646bb (patch) | |
tree | a59f1a13a606fba25f9e532361dcae229599eb73 /numpy/doc/swig | |
parent | 49a0503e47c9bb06d0bf7430b2958f7c23976234 (diff) | |
download | numpy-b0e8c7866f241033177e03856318b1f2d11646bb.tar.gz |
* Added support for FORTRAN-ordered arrays to numpy.i.
* Added new tests that test some of the FORTRAN-ordered typemaps.
* Updated the documentation to include the new FORTRAN-ordering
support.
Diffstat (limited to 'numpy/doc/swig')
-rw-r--r-- | numpy/doc/swig/doc/numpy_swig.html | 148 | ||||
-rw-r--r-- | numpy/doc/swig/doc/numpy_swig.pdf | bin | 166822 -> 169329 bytes | |||
-rw-r--r-- | numpy/doc/swig/doc/numpy_swig.txt | 139 | ||||
-rw-r--r-- | numpy/doc/swig/numpy.i | 374 | ||||
-rw-r--r-- | numpy/doc/swig/pyfragments.swg | 3 | ||||
-rw-r--r-- | numpy/doc/swig/test/Farray.cxx | 122 | ||||
-rw-r--r-- | numpy/doc/swig/test/Farray.h | 56 | ||||
-rw-r--r-- | numpy/doc/swig/test/Farray.i | 73 | ||||
-rw-r--r-- | numpy/doc/swig/test/Makefile | 7 | ||||
-rwxr-xr-x | numpy/doc/swig/test/setup.py | 11 | ||||
-rwxr-xr-x | numpy/doc/swig/test/testFarray.py | 158 |
11 files changed, 996 insertions, 95 deletions
diff --git a/numpy/doc/swig/doc/numpy_swig.html b/numpy/doc/swig/doc/numpy_swig.html index 93a576001..514debe94 100644 --- a/numpy/doc/swig/doc/numpy_swig.html +++ b/numpy/doc/swig/doc/numpy_swig.html @@ -353,18 +353,18 @@ double rms(double* seq, int n); Is it an array, and if so what is its length? Is it input-only? Output-only? Input-output? <a class="reference" href="http://www.swig.org">SWIG</a> cannot determine these details, and does not attempt to do so.</p> -<p>Making an educated guess, humans can conclude that this is probably a -routine that takes an input-only array of length <tt class="docutils literal"><span class="pre">n</span></tt> of <tt class="docutils literal"><span class="pre">double</span></tt> -values called <tt class="docutils literal"><span class="pre">seq</span></tt> and returns the root mean square. The default -behavior of <a class="reference" href="http://www.swig.org">SWIG</a>, however, will be to create a wrapper function -that compiles, but is nearly impossible to use from the scripting -language in the way the C routine was intended.</p> +<p>If we designed <tt class="docutils literal"><span class="pre">rms</span></tt>, we probably made it a routine that takes an +input-only array of length <tt class="docutils literal"><span class="pre">n</span></tt> of <tt class="docutils literal"><span class="pre">double</span></tt> values called <tt class="docutils literal"><span class="pre">seq</span></tt> +and returns the root mean square. The default behavior of <a class="reference" href="http://www.swig.org">SWIG</a>, +however, will be to create a wrapper function that compiles, but is +nearly impossible to use from the scripting language in the way the C +routine was intended.</p> <p>For <a class="reference" href="http://www.python.org">python</a>, the preferred way of handling contiguous (or technically, <em>strided</em>) blocks of homogeneous data is with the module <a class="reference" href="http://numpy.scipy.org">NumPy</a>, which provides full -object-oriented access to arrays of data. Therefore, the most logical -<a class="reference" href="http://www.python.org">python</a> interface for the <tt class="docutils literal"><span class="pre">rms</span></tt> function would be (including doc -string):</p> +object-oriented access to multidimensial arrays of data. Therefore, +the most logical <a class="reference" href="http://www.python.org">python</a> interface for the <tt class="docutils literal"><span class="pre">rms</span></tt> function would be +(including doc string):</p> <pre class="literal-block"> def rms(seq): """ @@ -557,7 +557,11 @@ dimension types:</p> </ul> </blockquote> <p>In the following descriptions, we reference a generic <tt class="docutils literal"><span class="pre">DATA_TYPE</span></tt>, which -could be any of the C data types listed above.</p> +could be any of the C data types listed above, and <tt class="docutils literal"><span class="pre">DIM_TYPE</span></tt> which +should be one of the many types of integers.</p> +<p>The typemap signatures are largely differentiated on the name given to +the buffer pointer. Names with <tt class="docutils literal"><span class="pre">FARRAY</span></tt> are for FORTRAN-ordered +arrays, and names with <tt class="docutils literal"><span class="pre">ARRAY</span></tt> are for C-ordered (or 1D arrays).</p> <div class="section"> <h2><a class="toc-backref" href="#id4" id="input-arrays" name="input-arrays">Input Arrays</a></h2> <p>Input arrays are defined as arrays of data that are passed into a @@ -565,17 +569,32 @@ routine but are not altered in-place or returned to the user. The <a class="reference" href="http://www.python.org">python</a> input array is therefore allowed to be almost any <a class="reference" href="http://www.python.org">python</a> sequence (such as a list) that can be converted to the requested type of array. The input array signatures are</p> +<p>1D:</p> <blockquote> <ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">IN_ARRAY1[ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY1,</span> <span class="pre">int</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY1,</span> <span class="pre">int</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY1</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>2D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">IN_ARRAY2[ANY][ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY2,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY2,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_FARRAY2,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_FARRAY2</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>3D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">IN_ARRAY3[ANY][ANY][ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY3,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY3,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_ARRAY3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_FARRAY3,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">IN_FARRAY3</span> <span class="pre">)</span></tt></li> </ul> </blockquote> <p>The first signature listed, <tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">IN_ARRAY[ANY]</span> <span class="pre">)</span></tt> is for @@ -590,17 +609,32 @@ input values may or may not be used, but the values at the time the function returns are significant. The provided <a class="reference" href="http://www.python.org">python</a> argument must therefore be a <a class="reference" href="http://numpy.scipy.org">NumPy</a> array of the required type. The in-place signatures are</p> +<p>1D:</p> <blockquote> <ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">INPLACE_ARRAY1[ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY1,</span> <span class="pre">int</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY1,</span> <span class="pre">int</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY1</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>2D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">INPLACE_ARRAY2[ANY][ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY2,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY2,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_FARRAY2,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_FARRAY2</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>3D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">INPLACE_ARRAY3[ANY][ANY][ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY3,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY3,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_ARRAY3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_FARRAY3,</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">int</span> <span class="pre">DIM2,</span> <span class="pre">int</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">INPLACE_FARRAY3</span> <span class="pre">)</span></tt></li> </ul> </blockquote> <p>These typemaps now check to make sure that the <tt class="docutils literal"><span class="pre">INPLACE_ARRAY</span></tt> @@ -618,12 +652,23 @@ wrapped function that uses these argout typemaps has more than one return argument, they are packed into a tuple or list, depending on the version of <a class="reference" href="http://www.python.org">python</a>. The <a class="reference" href="http://www.python.org">python</a> user does not pass these arrays in, they simply get returned. The argout signatures are</p> +<p>1D:</p> <blockquote> <ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">ARGOUT_ARRAY1[ANY]</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">ARGOUT_ARRAY1,</span> <span class="pre">int</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> -<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">ARGOUT_ARRAY1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE*</span> <span class="pre">ARGOUT_ARRAY1,</span> <span class="pre">int</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">int</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE*</span> <span class="pre">ARGOUT_ARRAY1</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>2D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">ARGOUT_ARRAY2[ANY][ANY]</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>3D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE</span> <span class="pre">ARGOUT_ARRAY3[ANY][ANY][ANY]</span> <span class="pre">)</span></tt></li> </ul> </blockquote> @@ -652,19 +697,35 @@ other choice.</p> pointers: pointers to the dimensions and double pointers to the data, so that these values can be passed back to the user. The argoutview typemap signatures are therefore</p> +<p>1D:</p> <blockquote> <ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_ARRAY1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_ARRAY1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_FARRAY1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_FARRAY1</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>2D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_ARRAY2,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_ARRAY2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_FARRAY2,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2</span> <span class="pre">)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2,</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_FARRAY2</span> <span class="pre">)</span></tt></li> +</ul> +</blockquote> +<p>3D:</p> +<blockquote> +<ul class="simple"> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_ARRAY3,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM3)</span></tt></li> <li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_ARRAY3)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_FARRAY3,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM3)</span></tt></li> +<li><tt class="docutils literal"><span class="pre">(</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM1,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM2,</span> <span class="pre">DIM_TYPE*</span> <span class="pre">DIM3,</span> <span class="pre">DATA_TYPE**</span> <span class="pre">ARGOUTVIEW_FARRAY3)</span></tt></li> </ul> </blockquote> -<p>Note that arrays with hard-coded dimensions are not supported. Thes -have to be allocated ahead of time, which defeats the purpose of the -typemap.</p> +<p>Note that arrays with hard-coded dimensions are not supported. These +cannot follow the double pointer signatures of these typemaps.</p> </div> <div class="section"> <h2><a class="toc-backref" href="#id8" id="output-arrays" name="output-arrays">Output Arrays</a></h2> @@ -795,11 +856,11 @@ in <tt class="docutils literal"><span class="pre">numpy.i</span></tt>, they woul <p>The <tt class="docutils literal"><span class="pre">numpy.i</span></tt> file containes several macros and routines that it uses internally to build its typemaps. However, these functions may be useful elsewhere in your interface file. These macros and routines -are implemented as fragments, as described briefly in the previous -section. If you try to use one or more of the following macros or -functions, but your compiler complains that it does not recognize the -symbol, then you need to force these fragments to appear in your code -using:</p> +are implemented as fragments, which are described briefly in the +previous section. If you try to use one or more of the following +macros or functions, but your compiler complains that it does not +recognize the symbol, then you need to force these fragments to appear +in your code using:</p> <pre class="literal-block"> %fragment("NumPy_Fragments"); </pre> @@ -833,6 +894,8 @@ buffer of <tt class="docutils literal"><span class="pre">a</span></tt>, assuming <dt><strong>array_is_native(a)</strong></dt> <dd>Evaluates as true if the data buffer of <tt class="docutils literal"><span class="pre">a</span></tt> uses native byte order. Equivalent to <tt class="docutils literal"><span class="pre">(PyArray_ISNOTSWAPPED(a))</span></tt>.</dd> +<dt><strong>array_is_fortran(a)</strong></dt> +<dd>Evaluates as true if <tt class="docutils literal"><span class="pre">a</span></tt> is FORTRAN ordered.</dd> </dl> </blockquote> </div> @@ -993,6 +1056,17 @@ each dimension.</li> specified shape, return 1. Otherwise, set the <a class="reference" href="http://www.python.org">python</a> error string and return 0.</p> </blockquote> +<p><strong>require_fortran()</strong></p> +<blockquote> +<p>Return type: <tt class="docutils literal"><span class="pre">int</span></tt></p> +<p>Arguments:</p> +<ul class="simple"> +<li><tt class="docutils literal"><span class="pre">PyArrayObject*</span> <span class="pre">ary</span></tt>, a <a class="reference" href="http://numpy.scipy.org">NumPy</a> array.</li> +</ul> +<p>Require the given <tt class="docutils literal"><span class="pre">PyArrayObject</span></tt> to to be FORTRAN ordered. If +the the <tt class="docutils literal"><span class="pre">PyArrayObject</span></tt> is already FORTRAN ordered, do nothing. +Else, set the FORTRAN ordering flag and recompute the strides.</p> +</blockquote> </blockquote> </div> </div> @@ -1121,12 +1195,14 @@ between <a class="reference" href="http://numpy.scipy.org">NumPy</a> arrays and <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">char</span></tt>, <tt class="docutils literal"><span class="pre">short</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">short</span></tt>, <tt class="docutils literal"><span class="pre">int</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">int</span></tt>, <tt class="docutils literal"><span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">long</span> <span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">long</span></tt>, <tt class="docutils literal"><span class="pre">float</span></tt> and <tt class="docutils literal"><span class="pre">double</span></tt>.</li> -<li>That support 29 different argument signatures for each data type, +<li>That support 41 different argument signatures for each data type, including:<ul> <li>One-dimensional, two-dimensional and three-dimensional arrays.</li> <li>Input-only, in-place, argout and argoutview behavior.</li> <li>Hard-coded dimensions, data-buffer-then-dimensions specification, and dimensions-then-data-buffer specification.</li> +<li>Both C-ordering ("last dimension fastest") or FORTRAN-ordering +("first dimension fastest") support for 2D and 3D arrays.</li> </ul> </li> </ul> @@ -1136,10 +1212,10 @@ wrapper developers, including:</p> <blockquote> <ul class="simple"> <li>A <a class="reference" href="http://www.swig.org">SWIG</a> macro (<tt class="docutils literal"><span class="pre">%numpy_typemaps</span></tt>) with three arguments for -implementing the 29 argument signatures for the user's choice of +implementing the 41 argument signatures for the user's choice of (1) C data type, (2) <a class="reference" href="http://numpy.scipy.org">NumPy</a> data type (assuming they match), and (3) dimension type.</li> -<li>Eight C macros and twelve C functions that can be used to write +<li>Nine C macros and 13 C functions that can be used to write specialized typemaps, extensions, or inlined functions that handle cases not covered by the provided typemaps.</li> </ul> @@ -1160,7 +1236,7 @@ contributors has made this end result possible.</p> </div> <div class="footer"> <hr class="footer" /> -Generated on: 2007-11-29 19:48 UTC. +Generated on: 2007-11-30 03:56 UTC. Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source. </div> diff --git a/numpy/doc/swig/doc/numpy_swig.pdf b/numpy/doc/swig/doc/numpy_swig.pdf Binary files differindex 7797c00b3..b952628ae 100644 --- a/numpy/doc/swig/doc/numpy_swig.pdf +++ b/numpy/doc/swig/doc/numpy_swig.pdf diff --git a/numpy/doc/swig/doc/numpy_swig.txt b/numpy/doc/swig/doc/numpy_swig.txt index fd140ead3..603bbb46f 100644 --- a/numpy/doc/swig/doc/numpy_swig.txt +++ b/numpy/doc/swig/doc/numpy_swig.txt @@ -25,19 +25,19 @@ Is it an array, and if so what is its length? Is it input-only? Output-only? Input-output? `SWIG`_ cannot determine these details, and does not attempt to do so. -Making an educated guess, humans can conclude that this is probably a -routine that takes an input-only array of length ``n`` of ``double`` -values called ``seq`` and returns the root mean square. The default -behavior of `SWIG`_, however, will be to create a wrapper function -that compiles, but is nearly impossible to use from the scripting -language in the way the C routine was intended. +If we designed ``rms``, we probably made it a routine that takes an +input-only array of length ``n`` of ``double`` values called ``seq`` +and returns the root mean square. The default behavior of `SWIG`_, +however, will be to create a wrapper function that compiles, but is +nearly impossible to use from the scripting language in the way the C +routine was intended. For `python <http://www.python.org>`_, the preferred way of handling contiguous (or technically, *strided*) blocks of homogeneous data is with the module `NumPy <http://numpy.scipy.org>`_, which provides full -object-oriented access to arrays of data. Therefore, the most logical -`python`_ interface for the ``rms`` function would be (including doc -string):: +object-oriented access to multidimensial arrays of data. Therefore, +the most logical `python`_ interface for the ``rms`` function would be +(including doc string):: def rms(seq): """ @@ -236,7 +236,12 @@ dimension types: * ``double`` In the following descriptions, we reference a generic ``DATA_TYPE``, which -could be any of the C data types listed above. +could be any of the C data types listed above, and ``DIM_TYPE`` which +should be one of the many types of integers. + +The typemap signatures are largely differentiated on the name given to +the buffer pointer. Names with ``FARRAY`` are for FORTRAN-ordered +arrays, and names with ``ARRAY`` are for C-ordered (or 1D arrays). Input Arrays ------------ @@ -247,15 +252,27 @@ routine but are not altered in-place or returned to the user. The sequence (such as a list) that can be converted to the requested type of array. The input array signatures are +1D: + * ``( DATA_TYPE IN_ARRAY1[ANY] )`` - * ``( DATA_TYPE* IN_ARRAY1, int DIM1 )`` - * ``( int DIM1, DATA_TYPE* IN_ARRAY1 )`` + * ``( DATA_TYPE* IN_ARRAY1, int DIM1 )`` + * ``( int DIM1, DATA_TYPE* IN_ARRAY1 )`` + +2D: + * ``( DATA_TYPE IN_ARRAY2[ANY][ANY] )`` - * ``( DATA_TYPE* IN_ARRAY2, int DIM1, int DIM2 )`` - * ``( int DIM1, int DIM2, DATA_TYPE* IN_ARRAY2 )`` + * ``( DATA_TYPE* IN_ARRAY2, int DIM1, int DIM2 )`` + * ``( int DIM1, int DIM2, DATA_TYPE* IN_ARRAY2 )`` + * ``( DATA_TYPE* IN_FARRAY2, int DIM1, int DIM2 )`` + * ``( int DIM1, int DIM2, DATA_TYPE* IN_FARRAY2 )`` + +3D: + * ``( DATA_TYPE IN_ARRAY3[ANY][ANY][ANY] )`` - * ``( DATA_TYPE* IN_ARRAY3, int DIM1, int DIM2, int DIM3 )`` - * ``( int DIM1, int DIM2, int DIM3, DATA_TYPE* IN_ARRAY3 )`` + * ``( DATA_TYPE* IN_ARRAY3, int DIM1, int DIM2, int DIM3 )`` + * ``( int DIM1, int DIM2, int DIM3, DATA_TYPE* IN_ARRAY3 )`` + * ``( DATA_TYPE* IN_FARRAY3, int DIM1, int DIM2, int DIM3 )`` + * ``( int DIM1, int DIM2, int DIM3, DATA_TYPE* IN_FARRAY3 )`` The first signature listed, ``( DATA_TYPE IN_ARRAY[ANY] )`` is for one-dimensional arrays with hard-coded dimensions. Likewise, @@ -271,15 +288,27 @@ function returns are significant. The provided `python`_ argument must therefore be a `NumPy`_ array of the required type. The in-place signatures are +1D: + * ``( DATA_TYPE INPLACE_ARRAY1[ANY] )`` - * ``( DATA_TYPE* INPLACE_ARRAY1, int DIM1 )`` - * ``( int DIM1, DATA_TYPE* INPLACE_ARRAY1 )`` + * ``( DATA_TYPE* INPLACE_ARRAY1, int DIM1 )`` + * ``( int DIM1, DATA_TYPE* INPLACE_ARRAY1 )`` + +2D: + * ``( DATA_TYPE INPLACE_ARRAY2[ANY][ANY] )`` - * ``( DATA_TYPE* INPLACE_ARRAY2, int DIM1, int DIM2 )`` - * ``( int DIM1, int DIM2, DATA_TYPE* INPLACE_ARRAY2 )`` + * ``( DATA_TYPE* INPLACE_ARRAY2, int DIM1, int DIM2 )`` + * ``( int DIM1, int DIM2, DATA_TYPE* INPLACE_ARRAY2 )`` + * ``( DATA_TYPE* INPLACE_FARRAY2, int DIM1, int DIM2 )`` + * ``( int DIM1, int DIM2, DATA_TYPE* INPLACE_FARRAY2 )`` + +3D: + * ``( DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY] )`` - * ``( DATA_TYPE* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3 )`` - * ``( int DIM1, int DIM2, int DIM3, DATA_TYPE* INPLACE_ARRAY3 )`` + * ``( DATA_TYPE* INPLACE_ARRAY3, int DIM1, int DIM2, int DIM3 )`` + * ``( int DIM1, int DIM2, int DIM3, DATA_TYPE* INPLACE_ARRAY3 )`` + * ``( DATA_TYPE* INPLACE_FARRAY3, int DIM1, int DIM2, int DIM3 )`` + * ``( int DIM1, int DIM2, int DIM3, DATA_TYPE* INPLACE_FARRAY3 )`` These typemaps now check to make sure that the ``INPLACE_ARRAY`` arguments use native byte ordering. If not, an exception is raised. @@ -298,10 +327,18 @@ return argument, they are packed into a tuple or list, depending on the version of `python`_. The `python`_ user does not pass these arrays in, they simply get returned. The argout signatures are +1D: + * ``( DATA_TYPE ARGOUT_ARRAY1[ANY] )`` - * ``( DATA_TYPE* ARGOUT_ARRAY1, int DIM1 )`` - * ``( int DIM1, DATA_TYPE* ARGOUT_ARRAY1 )`` + * ``( DATA_TYPE* ARGOUT_ARRAY1, int DIM1 )`` + * ``( int DIM1, DATA_TYPE* ARGOUT_ARRAY1 )`` + +2D: + * ``( DATA_TYPE ARGOUT_ARRAY2[ANY][ANY] )`` + +3D: + * ``( DATA_TYPE ARGOUT_ARRAY3[ANY][ANY][ANY] )`` These are typically used in situations where in C/C++, you would @@ -333,16 +370,29 @@ pointers: pointers to the dimensions and double pointers to the data, so that these values can be passed back to the user. The argoutview typemap signatures are therefore +1D: + * ``( DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1 )`` * ``( DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1 )`` + * ``( DATA_TYPE** ARGOUTVIEW_FARRAY1, DIM_TYPE* DIM1 )`` + * ``( DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_FARRAY1 )`` + +2D: + * ``( DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2 )`` * ``( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2 )`` + * ``( DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2 )`` + * ``( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2 )`` + +3D: + * ``( DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)`` * ``( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3)`` + * ``( DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)`` + * ``( DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3)`` -Note that arrays with hard-coded dimensions are not supported. Thes -have to be allocated ahead of time, which defeats the purpose of the -typemap. +Note that arrays with hard-coded dimensions are not supported. These +cannot follow the double pointer signatures of these typemaps. Output Arrays ------------- @@ -480,11 +530,11 @@ Helper Functions The ``numpy.i`` file containes several macros and routines that it uses internally to build its typemaps. However, these functions may be useful elsewhere in your interface file. These macros and routines -are implemented as fragments, as described briefly in the previous -section. If you try to use one or more of the following macros or -functions, but your compiler complains that it does not recognize the -symbol, then you need to force these fragments to appear in your code -using:: +are implemented as fragments, which are described briefly in the +previous section. If you try to use one or more of the following +macros or functions, but your compiler complains that it does not +recognize the symbol, then you need to force these fragments to appear +in your code using:: %fragment("NumPy_Fragments"); @@ -526,6 +576,9 @@ Macros Evaluates as true if the data buffer of ``a`` uses native byte order. Equivalent to ``(PyArray_ISNOTSWAPPED(a))``. + **array_is_fortran(a)** + Evaluates as true if ``a`` is FORTRAN ordered. + Routines -------- @@ -719,6 +772,19 @@ Routines string and return 0. + **require_fortran()** + + Return type: ``int`` + + Arguments: + + * ``PyArrayObject* ary``, a `NumPy`_ array. + + Require the given ``PyArrayObject`` to to be FORTRAN ordered. If + the the ``PyArrayObject`` is already FORTRAN ordered, do nothing. + Else, set the FORTRAN ordering flag and recompute the strides. + + Beyond the Provided Typemaps ============================ @@ -845,7 +911,7 @@ between `NumPy`_ arrays and C arrays: ``unsigned int``, ``long``, ``unsigned long``, ``long long``, ``unsigned long long``, ``float`` and ``double``. - * That support 29 different argument signatures for each data type, + * That support 41 different argument signatures for each data type, including: + One-dimensional, two-dimensional and three-dimensional arrays. @@ -855,15 +921,18 @@ between `NumPy`_ arrays and C arrays: + Hard-coded dimensions, data-buffer-then-dimensions specification, and dimensions-then-data-buffer specification. + + Both C-ordering ("last dimension fastest") or FORTRAN-ordering + ("first dimension fastest") support for 2D and 3D arrays. + The ``numpy.i`` interface file also provides additional tools for wrapper developers, including: * A `SWIG`_ macro (``%numpy_typemaps``) with three arguments for - implementing the 29 argument signatures for the user's choice of + implementing the 41 argument signatures for the user's choice of (1) C data type, (2) `NumPy`_ data type (assuming they match), and (3) dimension type. - * Eight C macros and twelve C functions that can be used to write + * Nine C macros and 13 C functions that can be used to write specialized typemaps, extensions, or inlined functions that handle cases not covered by the provided typemaps. diff --git a/numpy/doc/swig/numpy.i b/numpy/doc/swig/numpy.i index fc918f1ed..981d9d3c3 100644 --- a/numpy/doc/swig/numpy.i +++ b/numpy/doc/swig/numpy.i @@ -60,6 +60,8 @@ %#define NPY_MAX_ULONGLONG MAX_ULONGLONG %#define NPY_MAX_INTP MAX_INTP %#define NPY_MIN_INTP MIN_INTP + +%#define NPY_F_CONTIGUOUS F_CONTIGUOUS %#endif } @@ -85,6 +87,7 @@ %#define array_data(a) (((PyArrayObject *)a)->data) %#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a)) %#define array_is_native(a) (PyArray_ISNOTSWAPPED(a)) +%#define array_is_fortran(a) (PyArray_ISFORTRAN(a)) } /**********************************************************************/ @@ -391,6 +394,25 @@ } return success; } + + /* Require the given PyArrayObject to to be FORTRAN ordered. If the + * the PyArrayObject is already FORTRAN ordered, do nothing. Else, + * set the FORTRAN ordering flag and recompute the strides. + */ + int require_fortran(PyArrayObject* ary) + { + int success = 1; + int nd = array_numdims(ary); + int i; + if (array_is_fortran(ary)) return success; + /* Set the FORTRAN ordered flag */ + ary->flags = ary->flags | NPY_F_CONTIGUOUS; + /* Recompute the strides */ + ary->strides[0] = ary->strides[nd-1]; + for (i=1; i < nd; ++i) + ary->strides[i] = ary->strides[i-1] * array_size(ary,i-1); + return success; + } } /* Combine all NumPy fragments into one for convenience */ @@ -406,7 +428,7 @@ /* %numpy_typemaps() macro * - * This macro defines a family of 29 typemaps that allow C arguments + * This macro defines a family of 41 typemaps that allow C arguments * of the form * * (DATA_TYPE IN_ARRAY1[ANY]) @@ -416,10 +438,14 @@ * (DATA_TYPE IN_ARRAY2[ANY][ANY]) * (DATA_TYPE* IN_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_ARRAY2) + * (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) * * (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) * (DATA_TYPE* IN_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_ARRAY3) + * (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) * * (DATA_TYPE INPLACE_ARRAY1[ANY]) * (DATA_TYPE* INPLACE_ARRAY1, DIM_TYPE DIM1) @@ -428,10 +454,14 @@ * (DATA_TYPE INPLACE_ARRAY2[ANY][ANY]) * (DATA_TYPE* INPLACE_ARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_ARRAY2) + * (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + * (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) * * (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) * (DATA_TYPE* INPLACE_ARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_ARRAY3) + * (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + * (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) * * (DATA_TYPE ARGOUT_ARRAY1[ANY]) * (DATA_TYPE* ARGOUT_ARRAY1, DIM_TYPE DIM1) @@ -446,18 +476,25 @@ * * (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) + * (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) * * (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) + * (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) + * (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) * * where "DATA_TYPE" is any type supported by the NumPy module, and * "DIM_TYPE" is any int-like type suitable for specifying dimensions. - * In python, the dimensions will not need to be specified (except for - * the "DATA_TYPE* ARGOUT_ARRAY1" typemaps). The IN_ARRAYs can be a - * numpy array or any sequence that can be converted to a numpy array - * of the specified type. The INPLACE_ARRAYs must be numpy arrays of - * the appropriate type. The ARGOUT_ARRAYs will be returned as new - * numpy arrays of the appropriate type. + * The difference between "ARRAY" typemaps and "FARRAY" typemaps is + * that the "FARRAY" typemaps expect FORTRAN ordering of + * multidimensional arrays. In python, the dimensions will not need + * to be specified (except for the "DATA_TYPE* ARGOUT_ARRAY1" + * typemaps). The IN_ARRAYs can be a numpy array or any sequence that + * can be converted to a numpy array of the specified type. The + * INPLACE_ARRAYs must be numpy arrays of the appropriate type. The + * ARGOUT_ARRAYs will be returned as new numpy arrays of the + * appropriate type. * * These typemaps can be applied to existing functions using the * %apply directive. For example: @@ -664,6 +701,64 @@ { Py_DECREF(array$argnum); } } +/* Typemap suite for (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); +} +%typemap(freearg) + (DATA_TYPE* IN_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[2] = { -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 2) || + !require_size(array, size, 2) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* IN_FARRAY2) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + /* Typemap suite for (DATA_TYPE IN_ARRAY3[ANY][ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, @@ -753,6 +848,68 @@ { Py_DECREF(array$argnum); } } +/* Typemap suite for (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { -1, -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3) | !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); +} +%typemap(freearg) + (DATA_TYPE* IN_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* IN_FARRAY3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) +{ + $1 = is_array($input) || PySequence_Check($input); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) + (PyArrayObject* array=NULL, int is_new_object=0) +{ + npy_intp size[3] = { -1, -1, -1 }; + array = obj_to_array_contiguous_allow_conversion($input, DATA_TYPECODE, + &is_new_object); + if (!array || !require_dimensions(array, 3) || + !require_size(array, size, 3) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DATA_TYPE*) array_data(array); +} +%typemap(freearg) + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* IN_FARRAY3) +{ + if (is_new_object$argnum && array$argnum) + { Py_DECREF(array$argnum); } +} + /***************************/ /* In-Place Array Typemaps */ /***************************/ @@ -887,6 +1044,50 @@ $3 = (DATA_TYPE*) array_data(array); } +/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_FARRAY2, DIM_TYPE DIM1, DIM_TYPE DIM2) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_contiguous(array) + || !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DATA_TYPE* INPLACE_FARRAY2) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,2) || !require_contiguous(array) || + !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DATA_TYPE*) array_data(array); +} + /* Typemap suite for (DATA_TYPE INPLACE_ARRAY3[ANY][ANY][ANY]) */ %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, @@ -956,6 +1157,54 @@ $4 = (DATA_TYPE*) array_data(array); } +/* Typemap suite for (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, + * DIM_TYPE DIM3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DATA_TYPE* INPLACE_FARRAY3, DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_contiguous(array) || + !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DATA_TYPE*) array_data(array); + $2 = (DIM_TYPE) array_size(array,0); + $3 = (DIM_TYPE) array_size(array,1); + $4 = (DIM_TYPE) array_size(array,2); +} + +/* Typemap suite for (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, + * DATA_TYPE* INPLACE_FARRAY3) + */ +%typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY, + fragment="NumPy_Macros") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) +{ + $1 = is_array($input) && PyArray_EquivTypenums(array_type($input), + DATA_TYPECODE); +} +%typemap(in, + fragment="NumPy_Fragments") + (DIM_TYPE DIM1, DIM_TYPE DIM2, DIM_TYPE DIM3, DATA_TYPE* INPLACE_FARRAY3) + (PyArrayObject* array=NULL) +{ + array = obj_to_array_no_conversion($input, DATA_TYPECODE); + if (!array || !require_dimensions(array,3) || !require_contiguous(array) + || !require_native(array) || !require_fortran(array)) SWIG_fail; + $1 = (DIM_TYPE) array_size(array,0); + $2 = (DIM_TYPE) array_size(array,1); + $3 = (DIM_TYPE) array_size(array,2); + $4 = (DATA_TYPE*) array_data(array); +} + /*************************/ /* Argout Array Typemaps */ /*************************/ @@ -969,6 +1218,7 @@ { npy_intp dims[1] = { $1_dim0 }; array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); + if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) @@ -996,6 +1246,7 @@ $2 = (DIM_TYPE) PyInt_AsLong($input); dims[0] = (npy_intp) $2; array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); + if (!array) SWIG_fail; $1 = (DATA_TYPE*) array_data(array); } %typemap(argout) @@ -1023,6 +1274,7 @@ $1 = (DIM_TYPE) PyInt_AsLong($input); dims[0] = (npy_intp) $1; array = PyArray_SimpleNew(1, dims, DATA_TYPECODE); + if (!array) SWIG_fail; $2 = (DATA_TYPE*) array_data(array); } %typemap(argout) @@ -1040,6 +1292,7 @@ { npy_intp dims[2] = { $1_dim0, $1_dim1 }; array = PyArray_SimpleNew(2, dims, DATA_TYPECODE); + if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) @@ -1057,6 +1310,7 @@ { npy_intp dims[3] = { $1_dim0, $1_dim1, $1_dim2 }; array = PyArray_SimpleNew(3, dims, DATA_TYPECODE); + if (!array) SWIG_fail; $1 = ($1_ltype) array_data(array); } %typemap(argout) @@ -1081,10 +1335,9 @@ %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY1, DIM_TYPE* DIM1) - (PyObject* array = NULL) { npy_intp dims[1] = { *$2 }; - array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); + PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$1)); if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result,array); } @@ -1101,10 +1354,9 @@ %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DATA_TYPE** ARGOUTVIEW_ARRAY1) - (PyObject* array = NULL) { npy_intp dims[1] = { *$1 }; - array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); + PyObject * array = PyArray_SimpleNewFromData(1, dims, DATA_TYPECODE, (void*)(*$2)); if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result,array); } @@ -1122,10 +1374,9 @@ %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) - (PyObject* array = NULL) { npy_intp dims[2] = { *$2, *$3 }; - array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); + PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result,array); } @@ -1143,14 +1394,55 @@ %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_ARRAY2) - (PyObject* array = NULL) { npy_intp dims[2] = { *$1, *$2 }; - array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); + PyObject * array = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result,array); } +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 ) + (DATA_TYPE* data_temp , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DATA_TYPE** ARGOUTVIEW_FARRAY2, DIM_TYPE* DIM1, DIM_TYPE* DIM2) +{ + npy_intp dims[2] = { *$2, *$3 }; + PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject * array = (PyArrayObject*) obj; + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DATA_TYPE** ARGOUTVIEW_FARRAY2) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DATA_TYPE* data_temp ) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DATA_TYPE** ARGOUTVIEW_FARRAY2) +{ + npy_intp dims[2] = { *$1, *$2 }; + PyObject * obj = PyArray_SimpleNewFromData(2, dims, DATA_TYPECODE, (void*)(*$3)); + PyArrayObject * array = (PyArrayObject*) obj; + if (!array || !require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + /* Typemap suite for (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) */ @@ -1166,10 +1458,9 @@ %typemap(argout, fragment="NumPy_Backward_Compatibility") (DATA_TYPE** ARGOUTVIEW_ARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) - (PyObject* array = NULL) { npy_intp dims[3] = { *$2, *$3, *$4 }; - array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); + PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result,array); } @@ -1189,14 +1480,59 @@ %typemap(argout, fragment="NumPy_Backward_Compatibility") (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_ARRAY3) - (PyObject* array = NULL) { npy_intp dims[3] = { *$1, *$2, *$3 }; - array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3)); + PyObject * array = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3)); if (!array) SWIG_fail; $result = SWIG_Python_AppendOutput($result,array); } +/* Typemap suite for (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, + DIM_TYPE* DIM3) + */ +%typemap(in,numinputs=0) + (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) + (DATA_TYPE* data_temp, DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp) +{ + $1 = &data_temp; + $2 = &dim1_temp; + $3 = &dim2_temp; + $4 = &dim3_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DATA_TYPE** ARGOUTVIEW_FARRAY3, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3) +{ + npy_intp dims[3] = { *$2, *$3, *$4 }; + PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$1)); + PyArrayObject * array = (PyArrayObject*) obj; + if (!array || require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + +/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, + DATA_TYPE** ARGOUTVIEW_FARRAY3) + */ +%typemap(in,numinputs=0) + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) + (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DATA_TYPE* data_temp) +{ + $1 = &dim1_temp; + $2 = &dim2_temp; + $3 = &dim3_temp; + $4 = &data_temp; +} +%typemap(argout, + fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements") + (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DATA_TYPE** ARGOUTVIEW_FARRAY3) +{ + npy_intp dims[3] = { *$1, *$2, *$3 }; + PyObject * obj = PyArray_SimpleNewFromData(3, dims, DATA_TYPECODE, (void*)(*$3)); + PyArrayObject * array = (PyArrayObject*) obj; + if (!array || require_fortran(array)) SWIG_fail; + $result = SWIG_Python_AppendOutput($result,obj); +} + %enddef /* %numpy_typemaps() macro */ /* *************************************************************** */ diff --git a/numpy/doc/swig/pyfragments.swg b/numpy/doc/swig/pyfragments.swg index 479e86dc2..00c68579a 100644 --- a/numpy/doc/swig/pyfragments.swg +++ b/numpy/doc/swig/pyfragments.swg @@ -1,3 +1,4 @@ +/*-*- C -*-*/ /**********************************************************************/ /* For numpy versions prior to 1.0, the names of certain data types @@ -55,6 +56,8 @@ %#define NPY_MAX_ULONGLONG MAX_ULONGLONG %#define NPY_MAX_INTP MAX_INTP %#define NPY_MIN_INTP MIN_INTP + +%#define NPY_F_CONTIGUOUS F_CONTIGUOUS %#endif } diff --git a/numpy/doc/swig/test/Farray.cxx b/numpy/doc/swig/test/Farray.cxx new file mode 100644 index 000000000..3983c333b --- /dev/null +++ b/numpy/doc/swig/test/Farray.cxx @@ -0,0 +1,122 @@ +#include "Farray.h" +#include <sstream> + +// Size constructor +Farray::Farray(int nrows, int ncols) : + _nrows(nrows), _ncols(ncols), _buffer(0) +{ + allocateMemory(); +} + +// Copy constructor +Farray::Farray(const Farray & source) : + _nrows(source._nrows), _ncols(source._ncols) +{ + allocateMemory(); + *this = source; +} + +// Destructor +Farray::~Farray() +{ + delete [] _buffer; +} + +// Assignment operator +Farray & Farray::operator=(const Farray & source) +{ + int nrows = _nrows < source._nrows ? _nrows : source._nrows; + int ncols = _ncols < source._ncols ? _ncols : source._ncols; + for (int i=0; i < nrows; ++i) + { + for (int j=0; j < ncols; ++j) + { + (*this)(i,j) = source(i,j); + } + } + return *this; +} + +// Equals operator +bool Farray::operator==(const Farray & other) const +{ + if (_nrows != other._nrows) return false; + if (_ncols != other._ncols) return false; + for (int i=0; i < _nrows; ++i) + { + for (int j=0; j < _ncols; ++j) + { + if ((*this)(i,j) != other(i,j)) return false; + } + } + return true; +} + +// Length accessors +int Farray::nrows() const +{ + return _nrows; +} + +int Farray::ncols() const +{ + return _ncols; +} + +// Set item accessor +long & Farray::operator()(int i, int j) +{ + if (i < 0 || i > _nrows) throw std::out_of_range("Farray row index out of range"); + if (j < 0 || j > _ncols) throw std::out_of_range("Farray col index out of range"); + return _buffer[offset(i,j)]; +} + +// Get item accessor +const long & Farray::operator()(int i, int j) const +{ + if (i < 0 || i > _nrows) throw std::out_of_range("Farray row index out of range"); + if (j < 0 || j > _ncols) throw std::out_of_range("Farray col index out of range"); + return _buffer[offset(i,j)]; +} + +// String output +std::string Farray::asString() const +{ + std::stringstream result; + result << "[ "; + for (int i=0; i < _nrows; ++i) + { + if (i > 0) result << " "; + result << "["; + for (int j=0; j < _ncols; ++j) + { + result << " " << (*this)(i,j); + if (j < _ncols-1) result << ","; + } + result << " ]"; + if (i < _nrows-1) result << "," << std::endl; + } + result << " ]" << std::endl; + return result.str(); +} + +// Get view +void Farray::view(int* nrows, int* ncols, long** data) const +{ + *nrows = _nrows; + *ncols = _ncols; + *data = _buffer; +} + +// Private methods +void Farray::allocateMemory() +{ + if (_nrows <= 0) throw std::invalid_argument("Farray nrows <= 0"); + if (_ncols <= 0) throw std::invalid_argument("Farray ncols <= 0"); + _buffer = new long[_nrows*_ncols]; +} + +inline int Farray::offset(int i, int j) const +{ + return i + j * _nrows; +} diff --git a/numpy/doc/swig/test/Farray.h b/numpy/doc/swig/test/Farray.h new file mode 100644 index 000000000..4199a287c --- /dev/null +++ b/numpy/doc/swig/test/Farray.h @@ -0,0 +1,56 @@ +#ifndef FARRAY_H +#define FARRAY_H + +#include <stdexcept> +#include <string> + +class Farray +{ +public: + + // Size constructor + Farray(int nrows, int ncols); + + // Copy constructor + Farray(const Farray & source); + + // Destructor + ~Farray(); + + // Assignment operator + Farray & operator=(const Farray & source); + + // Equals operator + bool operator==(const Farray & other) const; + + // Length accessors + int nrows() const; + int ncols() const; + + // Set item accessor + long & operator()(int i, int j); + + // Get item accessor + const long & operator()(int i, int j) const; + + // String output + std::string asString() const; + + // Get view + void view(int* nrows, int* ncols, long** data) const; + +private: + // Members + int _nrows; + int _ncols; + long * _buffer; + + // Default constructor: not implemented + Farray(); + + // Methods + void allocateMemory(); + int offset(int i, int j) const; +}; + +#endif diff --git a/numpy/doc/swig/test/Farray.i b/numpy/doc/swig/test/Farray.i new file mode 100644 index 000000000..25f6cd025 --- /dev/null +++ b/numpy/doc/swig/test/Farray.i @@ -0,0 +1,73 @@ +// -*- c++ -*- + +%module Farray + +%{ +#define SWIG_FILE_WITH_INIT +#include "Farray.h" +%} + +// Get the NumPy typemaps +%include "../numpy.i" + + // Get the STL typemaps +%include "stl.i" + +// Handle standard exceptions +%include "exception.i" +%exception +{ + try + { + $action + } + catch (const std::invalid_argument& e) + { + SWIG_exception(SWIG_ValueError, e.what()); + } + catch (const std::out_of_range& e) + { + SWIG_exception(SWIG_IndexError, e.what()); + } +} +%init %{ + import_array(); +%} + +// Global ignores +%ignore *::operator=; +%ignore *::operator(); + +// Apply the 2D NumPy typemaps +%apply (int* DIM1 , int* DIM2 , long** ARGOUTVIEW_FARRAY2) + {(int* nrows, int* ncols, long** data )}; + +// Farray support +%include "Farray.h" +%extend Farray +{ + PyObject * __setitem__(PyObject* index, long v) + { + int i, j; + if (!PyArg_ParseTuple(index, "ii:Farray___setitem__",&i,&j)) return NULL; + self->operator()(i,j) = v; + return Py_BuildValue(""); + } + + PyObject * __getitem__(PyObject * index) + { + int i, j; + if (!PyArg_ParseTuple(index, "ii:Farray___getitem__",&i,&j)) return NULL; + return SWIG_From_long(self->operator()(i,j)); + } + + int __len__() + { + return self->nrows() * self->ncols(); + } + + std::string __str__() + { + return self->asString(); + } +} diff --git a/numpy/doc/swig/test/Makefile b/numpy/doc/swig/test/Makefile index b980cce78..86ba5e310 100644 --- a/numpy/doc/swig/test/Makefile +++ b/numpy/doc/swig/test/Makefile @@ -1,12 +1,12 @@ # SWIG -INTERFACES = Array.i Vector.i Matrix.i Tensor.i +INTERFACES = Array.i Farray.i Vector.i Matrix.i Tensor.i WRAPPERS = $(INTERFACES:.i=_wrap.cxx) PROXIES = $(INTERFACES:.i=.py ) # Default target: build the tests .PHONY : all -all: $(WRAPPERS) Array1.cxx Array1.h Vector.cxx Vector.h Matrix.cxx Matrix.h \ - Tensor.cxx Tensor.h +all: $(WRAPPERS) Array1.cxx Array1.h Farray.cxx Farray.h Vector.cxx Vector.h \ + Matrix.cxx Matrix.h Tensor.cxx Tensor.h ./setup.py build # Test target: run the tests @@ -16,6 +16,7 @@ test: all python testMatrix.py python testTensor.py python testArray.py + python testFarray.py # Rule: %.i -> %_wrap.cxx %_wrap.cxx: %.i %.h ../numpy.i diff --git a/numpy/doc/swig/test/setup.py b/numpy/doc/swig/test/setup.py index 948b8ec7e..68ae43283 100755 --- a/numpy/doc/swig/test/setup.py +++ b/numpy/doc/swig/test/setup.py @@ -21,6 +21,13 @@ _Array = Extension("_Array", include_dirs = [numpy_include], ) +# Farray extension module +_Farray = Extension("_Farray", + ["Farray_wrap.cxx", + "Farray.cxx"], + include_dirs = [numpy_include], + ) + # _Vector extension module _Vector = Extension("_Vector", ["Vector_wrap.cxx", @@ -46,6 +53,6 @@ _Tensor = Extension("_Tensor", setup(name = "NumpyTypemapTests", description = "Functions that work on arrays", author = "Bill Spotz", - py_modules = ["Array", "Vector", "Matrix", "Tensor"], - ext_modules = [_Array , _Vector , _Matrix , _Tensor ] + py_modules = ["Array", "Farray", "Vector", "Matrix", "Tensor"], + ext_modules = [_Array , _Farray , _Vector , _Matrix , _Tensor ] ) diff --git a/numpy/doc/swig/test/testFarray.py b/numpy/doc/swig/test/testFarray.py new file mode 100755 index 000000000..47c39136a --- /dev/null +++ b/numpy/doc/swig/test/testFarray.py @@ -0,0 +1,158 @@ +#! /usr/bin/env python + +# System imports +from distutils.util import get_platform +import os +import sys +import unittest + +# Import NumPy +import numpy as N +major, minor = [ int(d) for d in N.__version__.split(".")[:2] ] +if major == 0: BadListError = TypeError +else: BadListError = ValueError + +# Add the distutils-generated build directory to the python search path and then +# import the extension module +libDir = "lib.%s-%s" % (get_platform(), sys.version[:3]) +sys.path.insert(0,os.path.join("build", libDir)) +import Farray + +###################################################################### + +class FarrayTestCase(unittest.TestCase): + + def setUp(self): + self.nrows = 5 + self.ncols = 4 + self.array = Farray.Farray(self.nrows, self.ncols) + + def testConstructor1(self): + "Test Farray size constructor" + self.failUnless(isinstance(self.array, Farray.Farray)) + + def testConstructor2(self): + "Test Farray copy constructor" + for i in range(self.nrows): + for j in range(self.ncols): + self.array[i,j] = i + j + arrayCopy = Farray.Farray(self.array) + self.failUnless(arrayCopy == self.array) + + def testConstructorBad1(self): + "Test Farray size constructor, negative nrows" + self.assertRaises(ValueError, Farray.Farray, -4, 4) + + def testConstructorBad2(self): + "Test Farray size constructor, negative ncols" + self.assertRaises(ValueError, Farray.Farray, 4, -4) + + def testNrows(self): + "Test Farray nrows method" + self.failUnless(self.array.nrows() == self.nrows) + + def testNcols(self): + "Test Farray ncols method" + self.failUnless(self.array.ncols() == self.ncols) + + def testLen(self): + "Test Farray __len__ method" + self.failUnless(len(self.array) == self.nrows*self.ncols) + + def testSetGet(self): + "Test Farray __setitem__, __getitem__ methods" + m = self.nrows + n = self.ncols + for i in range(m): + for j in range(n): + self.array[i,j] = i*j + for i in range(m): + for j in range(n): + self.failUnless(self.array[i,j] == i*j) + + def testSetBad1(self): + "Test Farray __setitem__ method, negative row" + self.assertRaises(IndexError, self.array.__setitem__, (-1, 3), 0) + + def testSetBad2(self): + "Test Farray __setitem__ method, negative col" + self.assertRaises(IndexError, self.array.__setitem__, (1, -3), 0) + + def testSetBad3(self): + "Test Farray __setitem__ method, out-of-range row" + self.assertRaises(IndexError, self.array.__setitem__, (self.nrows+1, 0), 0) + + def testSetBad4(self): + "Test Farray __setitem__ method, out-of-range col" + self.assertRaises(IndexError, self.array.__setitem__, (0, self.ncols+1), 0) + + def testGetBad1(self): + "Test Farray __getitem__ method, negative row" + self.assertRaises(IndexError, self.array.__getitem__, (-1, 3)) + + def testGetBad2(self): + "Test Farray __getitem__ method, negative col" + self.assertRaises(IndexError, self.array.__getitem__, (1, -3)) + + def testGetBad3(self): + "Test Farray __getitem__ method, out-of-range row" + self.assertRaises(IndexError, self.array.__getitem__, (self.nrows+1, 0)) + + def testGetBad4(self): + "Test Farray __getitem__ method, out-of-range col" + self.assertRaises(IndexError, self.array.__getitem__, (0, self.ncols+1)) + + def testAsString(self): + "Test Farray asString method" + result = """\ +[ [ 0, 1, 2, 3 ], + [ 1, 2, 3, 4 ], + [ 2, 3, 4, 5 ], + [ 3, 4, 5, 6 ], + [ 4, 5, 6, 7 ] ] +""" + for i in range(self.nrows): + for j in range(self.ncols): + self.array[i,j] = i+j + self.failUnless(self.array.asString() == result) + + def testStr(self): + "Test Farray __str__ method" + result = """\ +[ [ 0, -1, -2, -3 ], + [ 1, 0, -1, -2 ], + [ 2, 1, 0, -1 ], + [ 3, 2, 1, 0 ], + [ 4, 3, 2, 1 ] ] +""" + for i in range(self.nrows): + for j in range(self.ncols): + self.array[i,j] = i-j + self.failUnless(str(self.array) == result) + + def testView(self): + "Test Farray view method" + for i in range(self.nrows): + for j in range(self.ncols): + self.array[i,j] = i+j + a = self.array.view() + self.failUnless(isinstance(a, N.ndarray)) + self.failUnless(a.flags.f_contiguous) + for i in range(self.nrows): + for j in range(self.ncols): + self.failUnless(a[i,j] == i+j) + +###################################################################### + +if __name__ == "__main__": + + # Build the test suite + suite = unittest.TestSuite() + suite.addTest(unittest.makeSuite(FarrayTestCase)) + + # Execute the test suite + print "Testing Classes of Module Farray" + print "NumPy version", N.__version__ + print + result = unittest.TextTestRunner(verbosity=2).run(suite) + sys.exit(len(result.errors) + len(result.failures)) |