Greetings!
We're working on a linear algebra package (called lisp-matrix for lack of a more marketable name ;) ) in CL. We plan to call the BLAS and LAPACK for matrix-matrix multiplications and factorizations, and we want to use CFFI for maximum portability (the older package Matlisp has only been ported to SBCL and Allegro CL).
The BLAS and LAPACK fully support complex numbers (single-float and couple-float), and they are stored with the same layout in memory as a C struct would use. C99 supports complex floating-point types. As such, we would like to include complex number support in lisp-matrix. However, CFFI doesn't support passing C structs by value, so we can't implement a complex number interface in CFFI using DEFCSTRUCT.
We would be glad to help implement complex number support in CFFI, but would like some advice on the difficulty of such a project, and how we might proceed.
We've written up some plans for the lisp-matrix project -- you can see them here:
http://www.cs.berkeley.edu/~mhoemmen/lisp-matrix/
Best, mfh
2006/10/15, Mark Hoemmen mark.hoemmen@gmail.com:
As such, we would like to include complex number support in lisp-matrix. However, CFFI doesn't support passing C structs by value, so we can't implement a complex number interface in CFFI using DEFCSTRUCT.
A number of lisps, including ECL and SBCL, do not support passing structures by value. See for instance the SBCL manual page: http://www.sbcl.org/manual/The-alien_002dfuncall-Primitive.html#The-alien_00...
The reason, I believe, is that structure arguments complicate a lot the calling of a function, in terms of registers used for in and out values, and even the conventions differ between compilers on the same platform.
Juanjo
On 10/15/06, Mark Hoemmen mark.hoemmen@gmail.com wrote:
C99 supports complex floating-point types. As such, we would like to include complex number support in lisp-matrix. However, CFFI doesn't support passing C structs by value, so we can't implement a complex number interface in CFFI using DEFCSTRUCT.
I don't know anything about how C99 compilers implement the complex number types, but if passing structs by value is required, you'll need to add some C glue.
On 10/15/06, Luís Oliveira luismbo@gmail.com wrote:
I don't know anything about how C99 compilers implement the complex number types, but if passing structs by value is required, you'll need to add some C glue.
It's stored just like two floating-point numbers mashed together. It's bit-compatible with
struct z { double re; double im; };
but you can treat it as a single value.
I was thinking of dealing with the C complex array as, say, an array of (unsigned 128), and then including some C glue that casts it appropriately, like this:
typedef struct { double re; double im; } z_t; void zconverter (double* re, double* im, z_t thing) { double _Complex* thingptr = (double _Complex*) &thing; *re = creal ( *thingptr ); *im = cimag ( *thingptr ); }
(defcfun "zconverter" :void (re :pointer) (im :pointer) (thing ???))
(defun zconvert (thing) (with-foreign-objects ((re :double) (im :double)) (zconverter re im thing) (the '(complex double-float) (complex (mem-ref re :double) (mem-ref im :double)))))
Would this be a start?
Best, mfh
On 10/15/06, Mark Hoemmen mark.hoemmen@gmail.com wrote:
typedef struct { double re; double im; } z_t; void zconverter (double* re, double* im, z_t thing) { double _Complex* thingptr = (double _Complex*) &thing; *re = creal ( *thingptr ); *im = cimag ( *thingptr ); }
[...]
Would this be a start?
IIUC, you return to the same problem. You can't pass that z_t thing to zconverter() through CFFI. What you have to do is, for each foreign function that wants a complex number as parameter, write a C wrapper that will take two doubles (in addition to whatever other arguments the functions wants) and call the appropriate function with a newly created complex number. Similar wrapping would be necessary for functions that return complex numbers.
HTH.