I want to call c written functions with complex numbered inputs and in python. I’ve tried using SWIG to generate a wrapper – but it seems to fall down. I think i need to work out the proper ‘macro’ for use in numpy.i – but not sure what it is – anyone have any experience in this – or other ways I can work around this?
The numpy.i shows this at the bottom – although it has been commented out. I tried using these macros – but they fail, SWIG complains about a syntax error for the following macro expansions I tried:
%numpy_typemaps(complex float, NPY_CFLOAT , int)
%numpy_typemaps(complex double, NPY_CDOUBLE, int)
%numpy_typemaps(complex long double, NPY_CLONGDOUBLE, int)
These are my files:
ComplexNumbers.c
# include <math.h>
# include <complex.h>
double complex returnX(double complex X)
/*
fresnel reflection coefficient rs
*/
{
return X;
}
ComplexNumbers.i:
%{
#define SWIG_FILE_WITH_INIT
%}
%include "numpy.i"
%init %{
import_array();
%}
%module ComplexNumbers
%inline %{
extern double complex returnX(double complex X);
%}
Python:
#!/usr/bin/env python
"""
setup.py file for ComplexNumbers
"""
from distutils.core import setup
from distutils.extension import Extension
import numpy
ComplexNumbers_module = Extension('_ComplexNumbers',
sources=['ComplexNumbers_wrap.c',
'ComplexNumbers.c'],
include_dirs=[numpy.get_include()]
)
setup (name = 'ComplexNumbers',
version = '1.0',
author = "JP Hadden jp.hadden@bristol.ac.uk",
description = """Spectral Interfereometry functions""",
ext_modules = [ComplexNumbers_module],
py_modules = ["ComplexNumbers"],
)
Error output from compiler
C:\MinGW32-xy\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python27\lib\site-pack
ages\numpy\core\include -IC:\Python27\include -IC:\Python27\PC -c ComplexNumbers
_wrap.c -o build\temp.win32-2.7\Release\complexnumbers_wrap.o
ComplexNumbers_wrap.c:2975:23: error: expected '=', ',', ';', 'asm' or '__attrib
ute__' before 'returnX'
ComplexNumbers_wrap.c: In function '_wrap_returnX':
ComplexNumbers_wrap.c:2982:18: error: expected '=', ',', ';', 'asm' or '__attrib
ute__' before 'arg1'
ComplexNumbers_wrap.c:2982:18: error: 'arg1' undeclared (first use in this funct
ion)
ComplexNumbers_wrap.c:2982:18: note: each undeclared identifier is reported only
once for each function it appears in
ComplexNumbers_wrap.c:2986:18: error: expected '=', ',', ';', 'asm' or '__attrib
ute__' before 'result'
ComplexNumbers_wrap.c:2986:18: error: 'result' undeclared (first use in this fun
ction)
ComplexNumbers_wrap.c:2997:24: error: expected ')' before 'complex'
ComplexNumbers_wrap.c:2997:24: error: pointer value used where a floating point
value was expected
ComplexNumbers_wrap.c:2997:14: error: invalid type argument of unary '*' (have '
double')
ComplexNumbers_wrap.c:3000:20: error: expected ')' before 'complex'
ComplexNumbers_wrap.c:3000:20: warning: implicit declaration of function 'return
X'
ComplexNumbers_wrap.c:3001:15: error: expected ')' before 'complex'
ComplexNumbers_wrap.c:3001:15: error: expected ')' before 'complex'
ComplexNumbers_wrap.c:3001:15: error: expected ')' before 'complex'
ComplexNumbers_wrap.c:3001:15: error: pointer value used where a floating point
value was expected
ComplexNumbers_wrap.c:3001:15: error: expected ')' before 'complex'
ComplexNumbers_wrap.c:3001:15: error: incompatible type for argument 1 of 'memcp
y'
c:\mingw32-xy\bin\../lib/gcc/mingw32/4.5.2/../../../../include/string.h:38:40: n
ote: expected 'void *' but argument is of type 'double'
error: command 'gcc' failed with exit status 1
I’m not sure how this interacts with Numpy, but SWIG certainly includes support for C99’s complex types. I was able to verify this with the following example:
This uses the SWIG complex.i interface.
(Note that here
%inlineis used to declare, define and wrap all in one place – handy for testing, but for ‘real’ code I tend to use%include).I compiled this (on Linux) with:
Which built fine with only one warning. Once that was done I could then do:
Which seems to be accepting and returning native Python complex types.
I was also able to make the following interface compile:
With the addition of
%include <complex.i>and-std=c99to the compiler flags. I think you can make distutils set that for you using something like these options.