Discussion:
C99 complex datatypes?
Mark Hoemmen
2006-10-15 10:04:58 UTC
Permalink
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
Juan Jose Garcia-Ripoll
2006-10-15 12:00:25 UTC
Permalink
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_002dfuncall-Primitive

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
Luís Oliveira
2006-10-15 13:15:15 UTC
Permalink
Post by Mark Hoemmen
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.
--
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Mark Hoemmen
2006-10-15 16:19:07 UTC
Permalink
Post by Luís Oliveira
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
Luís Oliveira
2006-10-15 16:31:44 UTC
Permalink
Post by Mark Hoemmen
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 );
}
[...]
Post by Mark Hoemmen
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.
--
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Loading...