Thread: [pure-lang-users] C macros
Status: Beta
Brought to you by:
agraef
From: Eddie R. <er...@bm...> - 2008-08-25 17:34:28
|
How do I import constants defined as macros in C? Example: GSL has M_EULER defined as #ifndef M_EULER #define M_EULER 0.57721566490153286060651209008 /* Euler constant */ #endif I want to be able to access that from gsl.pure. using "lib.libgsl"; extern ??? e.r. |
From: Eddie R. <er...@bm...> - 2008-08-25 17:39:26
|
On Mon, 2008-08-25 at 12:34 -0500, Eddie Rucker wrote: > How do I import constants defined as macros in C? > > Example: > GSL has M_EULER defined as > > #ifndef M_EULER > #define M_EULER 0.57721566490153286060651209008 /* Euler > constant */ > #endif > > I want to be able to access that from gsl.pure. > > using "lib.libgsl"; > > extern ??? and also macros like #define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params) e.r. |
From: John C. <co...@cc...> - 2008-08-25 17:53:25
|
Eddie Rucker scripsit: > > How do I import constants defined as macros in C? > and also macros like > #define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params) It's not possible, as all macros are removed in the first pass of the compiler and don't make it into the shared library at all. For something like this you need SWIG, which processes the source code. -- John Cowan co...@cc... http://ccil.org/~cowan Consider the matter of Analytic Philosophy. Dennett and Bennett are well-known. Dennett rarely or never cites Bennett, so Bennett rarely or never cites Dennett. There is also one Dummett. By their works shall ye know them. However, just as no trinities have fourth persons (Zeppo Marx notwithstanding), Bummett is hardly known by his works. Indeed, Bummett does not exist. It is part of the function of this and other e-mail messages, therefore, to do what they can to create him. |
From: Eddie R. <er...@bm...> - 2008-08-25 18:15:42
|
On Mon, 2008-08-25 at 13:53 -0400, John Cowan wrote: > Eddie Rucker scripsit: > > > > How do I import constants defined as macros in C? > > and also macros like > > #define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params) > > It's not possible, as all macros are removed in the first pass of the > compiler and don't make it into the shared library at all. For something > like this you need SWIG, which processes the source code. > Thanks. I noticed all of the math functions in math.pure are implemented in GSL. Quoted from the manual "For multiple-valued functions the branch cuts have been chosen to follow the conventions of Abramowitz and Stegun in the Handbook of Mathematical Functions. The functions return principal values which are the same as those in GNU Calc, which in turn are the same as those in Common Lisp, The Language (Second Edition)1 and the HP-28/48 series of calculators." e.r. |
From: Eddie R. <er...@bm...> - 2008-08-25 18:31:51
|
On Mon, 2008-08-25 at 13:15 -0500, Eddie Rucker wrote: > On Mon, 2008-08-25 at 13:53 -0400, John Cowan wrote: > > Eddie Rucker scripsit: > > > > > > How do I import constants defined as macros in C? > > > and also macros like > > > #define GSL_FN_FDF_EVAL_DF(FDF,x) (*((FDF)->df))(x,(FDF)->params) > > > > It's not possible, as all macros are removed in the first pass of the > > compiler and don't make it into the shared library at all. For something > > like this you need SWIG, which processes the source code. > > Since aren't too many of these macros, I might could code some of these by hand while Albert gets SWIG operational. I at least want to get the Matrix stuff and distribution stuff going right now. e.r. |
From: Eddie R. <er...@bm...> - 2008-08-25 20:28:28
|
On Mon, 2008-08-25 at 13:31 -0500, Eddie Rucker wrote: Something else that would be neat. Since matrices are created in gsl with an gsl_matrix_alloc command and freed by gsl_matrix_free command, it would be nice if we had some way to mark stuff so that the garbage collector would call gsl_matrix_free when a matrix is no longer in use. Is this possible? I noticed vectors and a bunch of other stuff allocated and deallocated this way. e.r. |
From: Albert G. <Dr....@t-...> - 2008-08-25 21:21:19
|
Eddie Rucker wrote: > Something else that would be neat. Since matrices are created in gsl > with an gsl_matrix_alloc command and freed by gsl_matrix_free command, > it would be nice if we had some way to mark stuff so that the garbage > collector would call gsl_matrix_free when a matrix is no longer in use. > Is this possible? I noticed vectors and a bunch of other stuff allocated > and deallocated this way. Yes, sentinels. They're on my TODO list for 0.6, which I started working on today (yes, you can already find some nifty new stuff in svn ;-). Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Eddie R. <er...@bm...> - 2008-08-25 22:44:36
|
On Mon, 2008-08-25 at 23:22 +0200, Albert Graef wrote: > Yes, sentinels. They're on my TODO list for 0.6, which I started working > on today (yes, you can already find some nifty new stuff in svn ;-). Great. MACROS :) GSL gives two methods of handling errors, (1) the gsl function returns success or failure (0, 1, or null for alloc) or (2) a gsl error handler that will abort the program. IMO, (2) cause too much havoc and you might like some type of a soft real time system for music. However, for (1) how about invoking a rule that can be overridden by the user like with the csv module? Two final things would be all I need to get matrices working (and I know your working on a type system): Some way to designate a matrix type. And a way to get at the fields of a struct. Then, I could write: a::Matrix + b::Matrix = m if ok when m = gsl_matrix_alloc (a->size1) (a->size2); c_ok = gsl_matrix_memcopy m a; a_ok = gsl_matrix_add m b; end; gsl_matrix returns it's value through the first parameter. So, to keep referential transparency, I need to copy a to m before adding. Somewhere in there I have to mark m for garbage collection as well. The only way to get matrices with complex entries or int entries is to go through the BLAS interface as I see it. Weird that I have to implement both the gsl_matrix_ stuff and BLAS but some of the later stuff uses the gsl_matrix_* routines. e.r. e.r. |
From: Albert G. <Dr....@t-...> - 2008-08-27 06:53:37
|
Eddie Rucker wrote: >> Better yet: HYGIENIC macros. :-P > I'm looking forward to playing with this. These thingies are really useful! I'll post something to the list as soon as I've had a chance to play with them some more. > I would probably do this to if I had a computer at home. It is probably > best that I don't because I would never get anything around the house > done ;-) I'm all thumbs, so my wife wouldn't let me near a hammer anyway, let alone more precious equipment. ;-) > In csv.c and csv.pure I just invoked an error rule with a message about > the error. Maybe I should revisit csv.c and throw a Pure exceptions in > the alloc cases? (NB: Sorry, I *still* didn't have the time to review your csv yet. I'll eventually get to it, but maybe you should just commit it to svn, so that people can start using it. There's just so many things on my TODO list. In particular, I have to get Pure working in Pd before October, because I want to use that combo in a course on algorithmic composition during the winter semester.) Getting back to your problem: In fact, with macros being available now, you can make it work either way. If you already have a foo_error function, say, you can easily make it throw an exception instead, by just adding a rule: foo_error msg = throw (foo_exception msg); Conversely, if you have a function foo which throws an exception and that's unconvenient for your application, you can simply patch it up with a macro which catches the exception and returns a foo_error value instead. This even works with builtins. (That'll slow them down, of course, but in some cases it might still be a useful trick.) Example: > 3 div 1; 3 div 0; 3 <stdin>:1.9-15: unhandled exception 'signal 8' while evaluating '3 div 0' Naughty div! Let's patch it up, baby! > div_fun = (div); > def (div) = \x y -> catch div_error (div_fun x y); > 3 div 1; 3 div 0; 3 div_error (signal 8) > map (\x->3 div x) (0..2); [div_error (signal 8),3,1] Almost like magic. :) (Note: The extra indirection through div_fun is needed, because we can't use (div) itself on the rhs of the macro definition for (div) to prevent infinite macro recursion.) > Yes, it is a GSL struct. I've been playing with the following > constructor. > > Matrix (x:xs) = (gsl_matrix_alloc rows cols, rows, cols) No, what I meant is to wrap it up in a real constructor, not a tuple, so that you can match against it. For the container data types, Jiri and I developed the convention to use xyz for the construction function, Xyz for the constructor symbol and xyzp for the type predicate, this works pretty well. So: matrix ys@(x:xs) = Matrix (gsl_matrix_alloc rows cols) when rows = #ys, cols = #x end; matrixp m = case m of Matrix _ = 1; _ = 0 end; Of course it would be more convenient to have the Pure compiler do the type checking on C pointer types. That's not possible with the current symbol tables, but when I have some spare time I'll see whether I can do something about that... > Since I can access fields, I can completely do away with the rows and cols and access the > rows and cols with getter functions. Exactly. Say that these are named gsl_matrix_rows and gsl_matrix_cols, then you could define: #(Matrix m) = gsl_matrix_rows m, gsl_matrix_cols m; > So you're suggesting to differentiate matrices and vectors. No sorry, I assumed that it would be that way in GSL, but what do I know? If vectors are just 1D "matrices" in GSL then there's no need to do that. > I hope you got a good rest. Yeah, I already completed the documentation of macros in the manual this morning, and now I'm working on private/public symbols. :) Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Eddie R. <er...@bm...> - 2008-08-27 12:25:03
|
On Wed, 2008-08-27 at 10:42 +0200, Albert Graef wrote: > Sorry for the repeated posts. Looks like this message took a long detour > to Mars or whatever. LOL LOL LOL LOL ... ;-) e.r. |
From: Albert G. <Dr....@t-...> - 2008-08-27 15:12:27
|
Eddie Rucker wrote: > On Wed, 2008-08-27 at 10:42 +0200, Albert Graef wrote: >> Sorry for the repeated posts. Looks like this message took a long detour >> to Mars or whatever. > > LOL LOL LOL LOL ... ;-) Don't laugh. I hear it that some guys must already be working on interplanetary TCP/IP. ;-) -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Albert G. <Dr....@t-...> - 2008-08-28 15:40:52
|
Albert Graef wrote: > Eddie Rucker wrote: >> Something else that would be neat. Since matrices are created in gsl >> with an gsl_matrix_alloc command and freed by gsl_matrix_free command, >> it would be nice if we had some way to mark stuff so that the garbage >> collector would call gsl_matrix_free when a matrix is no longer in use. >> Is this possible? I noticed vectors and a bunch of other stuff allocated >> and deallocated this way. > > Yes, sentinels. They're on my TODO list for 0.6, which I started working > on today (yes, you can already find some nifty new stuff in svn ;-). Ok, these are implemented now, you can find them in primitives.pure. I named them "sentries" this time around, that's shorter and can't be confused with the well-established notion of the sentinel value. Usage is easy, see the fopen function in system.pure for a real-world example. I've rewritten that so that it returns a file pointer that takes care of closing itself when it gets garbage-collected. Let's see these in action: > using system; > let x = sentry (\x->puts $ "done: "+str x) (foo 99); > clear x done: foo 99 How about doing smart pointers: mymalloc size = sentry free (malloc size); One thing worth noting here is that 'sentry' takes the sentry function as its first argument, which makes it easy to curry it. Add minimal error checking: mymalloc size = if null p then p else sentry free p when p = malloc size end; If you also want to be able to free the pointer explicitly, the sentry must of course then be released from his duty: myfree p = clear_sentry p $$ free p; Note that only a single sentry per expression is supported by 'sentry', but since you can find an existing sentry with get_sentry, it's easy to chain them if you need more than one. Also note that sentries can only be placed at applications and pointer objects, but this should cover all cases where they're really needed. Cheers, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: John C. <co...@cc...> - 2008-08-30 21:52:23
|
Albert Graef scripsit: > Is it true that complex double is just two doubles, similar for complex > float? That would make things much easier, because a complex matrix > could be represented internally as a double matrix with twice the number > of columns. I guess that ISO C99 implementations are free to choose the > internal representation, though. Probably so, but I can't imagine any C compiler choosing a representation other than two consecutive floats, because Fortran requires that a COMPLEX must take up the same space as two REALs. Nobody is going to implement complex numbers in C in a way that's incompatible with Fortran (other than C being row-major rather than column-major). -- There are three kinds of people in the world: John Cowan those who can count, co...@cc... and those who can't. |
From: Albert G. <Dr....@t-...> - 2008-08-25 21:18:25
|
Eddie Rucker wrote: > Since aren't too many of these macros, I might could code some of these > by hand while Albert gets SWIG operational. You don't need SWIG for that. Write a little wrapper module which can be loaded in Pure and which in turn links against GSL, then you can add any needed wrappers for symbolic constants and other macros to that module. You already know how to do that. Have a look at the pure_sys_vars function in runtime.cc and how it's called in system.pure, that shows how you can set up a few predefined constant and variable values from corresponding C values. If there's not too many macro definitions then this is the most straightforward way to do it, and you'd probably need that wrapper module for other stuff anyway, like marshalling functions for the datatypes. SWIG is really only needed for wrapping up C++ (or huge C) libraries, since it generates all the necessary declarations and tiny C wrapper functions for you. Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Albert G. <Dr....@t-...> - 2008-08-25 21:05:33
|
Eddie Rucker wrote: > I noticed all of the math functions in math.pure are implemented in GSL. Then you don't need these in your GSL wrapper. Of course math.pure does its own complex numbers type for convenience (those x+:y and r<:y thingies), so you will have to marshall these in your GSL interface to whatever data structure GSL uses for complex numbers. > "For multiple-valued functions the branch cuts have been chosen to > follow the conventions of Abramowitz and Stegun in the Handbook of > Mathematical Functions. The functions return principal values which are > the same as those in GNU Calc, which in turn are the same as those in > Common Lisp, The Language (Second Edition)1 and the HP-28/48 series of > calculators." Told 'ya. :) As I pointed out earlier it's no accident that these calculators are pretty much the "gold standard" when it comes to numeric algorithms on portable devices. Kahan was hired by HP to design the numeric algorithms for the HP "Voyager" calculators (HP-10C et al), which were then later ported to the Saturn-based calcs (HP 28, 48/49/50). The HP 50G, which I used to test against math.pure, still uses those algorithms (although it emulates the Saturn cpu on an ARM processor and is thus much faster than the 48 or the 49G). It's a pity that HP's calculator division (like so many things at HP) went south during Carly Fiorina's reign. But of course with a laptop not costing much more than a high-end scientific calc these days, I guess I can be happy that they still produce something like the 50G at all. Cheers, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Albert G. <Dr....@t-...> - 2008-08-30 21:58:30
|
John Cowan wrote: > Probably so, but I can't imagine any C compiler choosing a representation > other than two consecutive floats, because Fortran requires that a > COMPLEX must take up the same space as two REALs. Nobody is going to > implement complex numbers in C in a way that's incompatible with Fortran > (other than C being row-major rather than column-major). That's good to know, thanks! Yes, I agree, it would indeed be utterly insane to do it in a different way. -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: John C. <co...@cc...> - 2008-08-30 22:06:24
|
Albert Graef scripsit: > That's good to know, thanks! Yes, I agree, it would indeed be utterly > insane to do it in a different way. It's all about the weirdness of the Fortran EQUIVALENCE statement, which lets you declare the exact overlap pattern of global storage, thus: EQUIVALENCE(I(5), A(2,7)) where I is an integer vector and A is a floating-point matrix. -- Overhead, without any fuss, the stars were going out. --Arthur C. Clarke, "The Nine Billion Names of God" John Cowan <co...@cc...> |
From: Albert G. <Dr....@t-...> - 2008-08-30 21:35:41
|
Eddie Rucker wrote: > Um... Is there some way from Pure to find out the byte sizeof ints, > doubles, complex, etc? When the sizes change on different machines > and/or compilers I'd like the library to automatically handle this. FWIW, system.pure now provides the following constants. These probably aren't of much use for figuring out struct alignment, but at least they provide the necessary information to malloc pointers to these types in a portable manner. Also, you can test whether you're on a 64 bit system by inspecting SIZEOF_POINTER. (BTW, I see no point in adding the long double types right now, since these aren't supported by Pure in any way.) > using system; > list -g SIZEOF* const SIZEOF_BYTE = 1; const SIZEOF_COMPLEX_DOUBLE = 16; const SIZEOF_COMPLEX_FLOAT = 8; const SIZEOF_DOUBLE = 8; const SIZEOF_FLOAT = 4; const SIZEOF_INT = 4; const SIZEOF_LONG = 4; const SIZEOF_LONG_LONG = 8; const SIZEOF_POINTER = 4; const SIZEOF_SHORT = 2; The complex sizes are for the ISO C99 complex float and double types. I don't know how portable that is, but gcc surely has them and they're also in POSIX. Is it true that complex double is just two doubles, similar for complex float? That would make things much easier, because a complex matrix could be represented internally as a double matrix with twice the number of columns. I guess that ISO C99 implementations are free to choose the internal representation, though. Cheers, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Eddie R. <er...@bm...> - 2008-08-25 22:52:48
|
On Mon, 2008-08-25 at 17:44 -0500, Eddie Rucker wrote: > The only way to get matrices with complex entries or int entries is to > go through the BLAS interface as I see it. Weird that I have to > implement both the gsl_matrix_ stuff and BLAS but some of the later > stuff uses the gsl_matrix_* routines. Wrong! I can use gsl_matrix_complex_ routines. e.r. |
From: Albert G. <Dr....@t-...> - 2008-08-26 00:53:02
|
Eddie Rucker wrote: > Great. MACROS :) Better yet: HYGIENIC macros. :-P I'm falling asleep at the keyboard (past 2:30am over here), will reply to your questions in more detail tomorrow. Just some quick remarks: - You can make a C function fail, but only if it returns an expr* (pure_expr* on the C side), then you can just return a null pointer. So you need to provide a wrapper for the GSL function which returns a real pure_expr*, that's probably not what you want I guess. But for hard error conditions like alloc failure it would be ok to just throw a Pure exception, no? - I'd eventually like the GSL matrices to be some kind of native type in Pure if possible. For the time being, I'd suggest to wrap them up in a Pure constructor (matrix p or something like that where p is the pointer to the GSL struct or whatever it is). - Accessing the fields of a struct through pointers in Pure is possible (see the stuff at the end of primitives.pure), but probably non-portable. You'd probably need some getter/setter functions in your wrapper to do that in a safe way. G'night, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Eddie R. <er...@bm...> - 2008-08-26 13:06:06
|
On Tue, 2008-08-26 at 02:54 +0200, Albert Graef wrote: > Better yet: HYGIENIC macros. :-P I'm looking forward to playing with this. > I'm falling asleep at the keyboard (past 2:30am over here), will reply > to your questions in more detail tomorrow. Just some quick remarks: I would probably do this to if I had a computer at home. It is probably best that I don't because I would never get anything around the house done ;-) > You can make a C function fail, but only if it returns an expr* > (pure_expr* on the C side), then you can just return a null pointer. So > you need to provide a wrapper for the GSL function which returns a real > pure_expr*, that's probably not what you want I guess. But for hard > error conditions like alloc failure it would be ok to just throw a Pure > exception, no? In csv.c and csv.pure I just invoked an error rule with a message about the error. Maybe I should revisit csv.c and throw a Pure exceptions in the alloc cases? > - I'd eventually like the GSL matrices to be some kind of native type in > Pure if possible. For the time being, I'd suggest to wrap them up in a > Pure constructor (matrix p or something like that where p is the pointer > to the GSL struct or whatever it is). Yes, it is a GSL struct. I've been playing with the following constructor. Matrix (x:xs) = (gsl_matrix_alloc rows cols, rows, cols) when rows = #(x:xs); cols = #x end; To take a list of lists to convert it to the GSL struct and returns a tuple with the pointer, the number of rows and cols. Since I can access fields, I can completely do away with the rows and cols and access the rows and cols with getter functions. Now, I just need a constructor for a zero matrix and an identity matrix. So you're suggesting to differentiate matrices and vectors. I should do something like Matrix (x:xs) = matrix (gsl_matrix_alloc rows cols) when rows = #(x:xs); cols = #x end; and Vector (x:xs) = vector (gsl_vector_alloc len) when len = #(x:xs) end; ? Then the operations become: (matrix a) + (matrix b) = ... (vector a) + (vector b) = ... Am I following correctly? > - Accessing the fields of a struct through pointers in Pure is possible > (see the stuff at the end of primitives.pure), but probably > non-portable. You'd probably need some getter/setter functions in your > wrapper to do that in a safe way. Got it. I hope you got a good rest. e.r. |
From: Albert G. <Dr....@t-...> - 2008-08-27 07:30:15
|
Eddie Rucker wrote: >> Better yet: HYGIENIC macros. :-P > I'm looking forward to playing with this. These thingies are really useful! I'll post something to the list as soon as I've had a chance to play with them some more. > I would probably do this to if I had a computer at home. It is probably > best that I don't because I would never get anything around the house > done ;-) I'm all thumbs, so my wife wouldn't let me near a hammer anyway, let alone more precious equipment. ;-) > In csv.c and csv.pure I just invoked an error rule with a message about > the error. Maybe I should revisit csv.c and throw a Pure exceptions in > the alloc cases? (NB: Sorry, I *still* didn't have the time to review your csv yet. I'll eventually get to it, but maybe you should just commit it to svn, so that people can start using it. There's just so many things on my TODO list. In particular, I have to get Pure working in Pd before October, because I want to use that combo in a course on algorithmic composition during the winter semester.) Getting back to your problem: In fact, with macros being available now, you can make it work either way. If you already have a foo_error function, say, you can easily make it throw an exception instead, by just adding a rule: foo_error msg = throw (foo_exception msg); Conversely, if you have a function foo which throws an exception and that's unconvenient for your application, you can simply patch it up with a macro which catches the exception and returns a foo_error value instead. This even works with builtins. (That'll slow them down, of course, but in some cases it might still be a useful trick.) Example: > 3 div 1; 3 div 0; 3 <stdin>:1.9-15: unhandled exception 'signal 8' while evaluating '3 div 0' Naughty div! Let's patch it up, baby! > div_fun = (div); > def (div) = \x y -> catch div_error (div_fun x y); > 3 div 1; 3 div 0; 3 div_error (signal 8) > map (\x->3 div x) (0..2); [div_error (signal 8),3,1] Almost like magic. :) (Note: The extra indirection through div_fun is needed, because we can't use (div) itself on the rhs of the macro definition for (div) to prevent infinite macro recursion.) > Yes, it is a GSL struct. I've been playing with the following > constructor. > > Matrix (x:xs) = (gsl_matrix_alloc rows cols, rows, cols) No, what I meant is to wrap it up in a real constructor, not a tuple, so that you can match against it. For the container data types, Jiri and I developed the convention to use xyz for the construction function, Xyz for the constructor symbol and xyzp for the type predicate, this works pretty well. So: matrix ys@(x:xs) = Matrix (gsl_matrix_alloc rows cols) when rows = #ys, cols = #x end; matrixp m = case m of Matrix _ = 1; _ = 0 end; Of course it would be more convenient to have the Pure compiler do the type checking on C pointer types. That's not possible with the current symbol tables, but when I have some spare time I'll see whether I can do something about that... > Since I can access fields, I can completely do away with the rows and cols and access the > rows and cols with getter functions. Exactly. Say that these are named gsl_matrix_rows and gsl_matrix_cols, then you could define: #(Matrix m) = gsl_matrix_rows m, gsl_matrix_cols m; > So you're suggesting to differentiate matrices and vectors. No sorry, I assumed that it would be that way in GSL, but what do I know? If vectors are just 1D "matrices" in GSL then there's no need to do that. > I hope you got a good rest. Yeah, I already completed the documentation of macros in the manual this morning, and now I'm working on private/public symbols. :) Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Albert G. <Dr....@t-...> - 2008-08-27 07:36:19
|
Eddie Rucker wrote: >> Better yet: HYGIENIC macros. :-P > I'm looking forward to playing with this. These thingies are really useful! I'll post something to the list as soon as I've had a chance to play with them some more. > I would probably do this to if I had a computer at home. It is probably > best that I don't because I would never get anything around the house > done ;-) I'm all thumbs, so my wife wouldn't let me near a hammer anyway, let alone more precious equipment. ;-) > In csv.c and csv.pure I just invoked an error rule with a message about > the error. Maybe I should revisit csv.c and throw a Pure exceptions in > the alloc cases? (NB: Sorry, I *still* didn't have the time to review your csv yet. I'll eventually get to it, but maybe you should just commit it to svn, so that people can start using it. There's just so many things on my TODO list. In particular, I have to get Pure working in Pd before October, because I want to use that combo in a course on algorithmic composition during the winter semester.) Getting back to your problem: In fact, with macros being available now, you can make it work either way. If you already have a foo_error function, say, you can easily make it throw an exception instead, by just adding a rule: foo_error msg = throw (foo_exception msg); Conversely, if you have a function foo which throws an exception and that's unconvenient for your application, you can simply patch it up with a macro which catches the exception and returns a foo_error value instead. This even works with builtins. (That'll slow them down, of course, but in some cases it might still be a useful trick.) Example: > 3 div 1; 3 div 0; 3 <stdin>:1.9-15: unhandled exception 'signal 8' while evaluating '3 div 0' Naughty div! Let's patch it up, baby! > div_fun = (div); > def (div) = \x y -> catch div_error (div_fun x y); > 3 div 1; 3 div 0; 3 div_error (signal 8) > map (\x->3 div x) (0..2); [div_error (signal 8),3,1] Almost like magic. :) (Note: The extra indirection through div_fun is needed, because we can't use (div) itself on the rhs of the macro definition for (div) to prevent infinite macro recursion.) > Yes, it is a GSL struct. I've been playing with the following > constructor. > > Matrix (x:xs) = (gsl_matrix_alloc rows cols, rows, cols) No, what I meant is to wrap it up in a real constructor, not a tuple, so that you can match against it. For the container data types, Jiri and I developed the convention to use xyz for the construction function, Xyz for the constructor symbol and xyzp for the type predicate, this works pretty well. So: matrix ys@(x:xs) = Matrix (gsl_matrix_alloc rows cols) when rows = #ys, cols = #x end; matrixp m = case m of Matrix _ = 1; _ = 0 end; Of course it would be more convenient to have the Pure compiler do the type checking on C pointer types. That's not possible with the current symbol tables, but when I have some spare time I'll see whether I can do something about that... > Since I can access fields, I can completely do away with the rows and cols and access the > rows and cols with getter functions. Exactly. Say that these are named gsl_matrix_rows and gsl_matrix_cols, then you could define: #(Matrix m) = gsl_matrix_rows m, gsl_matrix_cols m; > So you're suggesting to differentiate matrices and vectors. No sorry, I assumed that it would be that way in GSL, but what do I know? If vectors are just 1D "matrices" in GSL then there's no need to do that. > I hope you got a good rest. Yeah, I already completed the documentation of macros in the manual this morning, and now I'm working on private/public symbols. :) Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Albert G. <Dr....@t-...> - 2008-08-26 14:10:56
|
Eddie Rucker wrote: > On Mon, 2008-08-25 at 17:44 -0500, Eddie Rucker wrote: > >> The only way to get matrices with complex entries or int entries is to >> go through the BLAS interface as I see it. Weird that I have to >> implement both the gsl_matrix_ stuff and BLAS but some of the later >> stuff uses the gsl_matrix_* routines. > > Wrong! I can use gsl_matrix_complex_ routines. Does GSL have integer matrices, too? -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |
From: Eddie R. <er...@bm...> - 2008-08-26 14:19:57
|
On Tue, 2008-08-26 at 16:12 +0200, Albert Graef wrote: > Eddie Rucker wrote: > > On Mon, 2008-08-25 at 17:44 -0500, Eddie Rucker wrote: > > > >> The only way to get matrices with complex entries or int entries is to > >> go through the BLAS interface as I see it. Weird that I have to > >> implement both the gsl_matrix_ stuff and BLAS but some of the later > >> stuff uses the gsl_matrix_* routines. > > > > Wrong! I can use gsl_matrix_complex_ routines. > > Does GSL have integer matrices, too? > Ja, all the types we can have are double, float, long double, int, unsigned int, long, unsigned long, short, unsigned short, char, unsigned char, complex double, complex float, complex long double. The only thing missing from Pure types is rationals. e.r. |