Ruby, C, swig and variable types

A

Axel Etzold

Dear all,

I'd like some advice about extending Ruby with C via SWIG ....

I've got

a.) a bunch of files written in C doing some form of division with
remainder on a set of algebraic objects,

b.) a bunch of code in Ruby determining which object from the
set above to divide by which other next.

Now I could use SWIG to write a C extension of Ruby to connect
the two. I've read tutorials about that and it seems to
work, tentatively.

But I've got an additional issue.
The algebraic objects are polynomials, i.e., objects
a_0 + a_i x + ... + a_n x^n, where the coefficients a_i can so far
only be integers (big numbers allowed), according to the existing C code.
But I must be able to use other coefficients as well, such as
fractions (adding them needs common denominators), floats,
and complex numbers.

What do you think is an economical way of telling C about
Ruby Rational(x,y) or Complex(x,y) or Float coefficients and
returning the results ?

Thank you very much!

Best regards,

Axel
 
M

M. Edward (Ed) Borasky

Axel said:
Dear all,

I'd like some advice about extending Ruby with C via SWIG ....

I've got

a.) a bunch of files written in C doing some form of division with
remainder on a set of algebraic objects,

b.) a bunch of code in Ruby determining which object from the
set above to divide by which other next.

Is your C code one of the "well-known" open source libraries that do
this kind of computation, or is it home-grown? The reason I ask is that
there are quite a few Python interfaces to the well-known libraries, and
it would be relatively easy to port some of them to Ruby.
Now I could use SWIG to write a C extension of Ruby to connect
the two. I've read tutorials about that and it seems to
work, tentatively.

SWIG requires detailed knowledge of the C or C++ API of your libraries
to be used effectively. However, once you get your SWIG interface
descriptions written, you can embed the library in just about all the
major scripting languages with little extra effort. If you're only
interested in a Ruby interface, SWIG might be a lot more effort than you
need.
But I've got an additional issue.
The algebraic objects are polynomials, i.e., objects
a_0 + a_i x + ... + a_n x^n, where the coefficients a_i can so far
only be integers (big numbers allowed), according to the existing C code.
But I must be able to use other coefficients as well, such as
fractions (adding them needs common denominators), floats,
and complex numbers.

What do you think is an economical way of telling C about
Ruby Rational(x,y) or Complex(x,y) or Float coefficients and
returning the results ?

Thank you very much!

Best regards,

Axel

One other note -- have you looked at RubyInline?
 
A

Axel Etzold

Dear Ed,
Is your C code one of the "well-known" open source libraries that do
this kind of computation, or is it home-grown? The reason I ask is that
there are quite a few Python interfaces to the well-known libraries, and
it would be relatively easy to port some of them to Ruby.

It is home-grown ... partly because the divisions I have to do
involve several variables (see an example here: http://www.geocities.com/famancin/buchberger.html) ... I am not aware that there are any "well-known" open-source libraries for this as it seems a more exotic part of computational algebra after all.

One problem of this type of computations is that they tend to be
a.) extremely consuming in computation (twice exponential in the number
of variables ... and any interesting applied problem now
involves around 20 variables or more),
so C seemed a good choice for doing the bulk of the work, but problems
of this size tend to be just unfeasible unless one can make good use of:
b.) the actual amount of computations depends on the ordering of the
terms (defined based on the different variables) and you can achieve dramatic differences if a good procedure is found. So I am trying out several strategies for reducing the amount of work based on the
concrete structure of the problem (graph theoretic ideas, mostly).

These things are done in Ruby, as it is so much nicer to code in :)
and as this is a part of the problem where speed of computation
is not so critical, as most of the computation is done in the division
process written in C.

Now, to connect the two, I looked at this tutorial:

http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html

I've managed to make this work without any problem.
Now, what I still do not understand is quite what SWIG does precisely
for the communication of Ruby and C.

1.) I faintly recall reading a post on this list that SWIG could be used not only to extend Ruby with C, but also the other way round ... so I was
thinking that maybe I could use the Ruby's Rational to extend
my C code .. if you have any pointers for extending C with Ruby, please
let me know.

2.) If you don't have to declare variables with types in Ruby, but can
use Ruby nevertheless in connection with C via SWIG, and possibly inversely (as said in 1.), SWIG must somehow be able to determine the underlying
C structure of Ruby and associate the two.
Beyond the problem I'm having here, I would also like to know how
realistic this is - in the most perfect of all worlds, this would mean
one could re-use any code from any language having a C basis in
any other ... just a dream, but a nagging one.
One other note -- have you looked at RubyInline?

Yes, but as far as I understand it, this allows to use C as if it
were a scripting language, but it comes at a cost of speed, which I
can't afford here.

Best regards,

Axel
 
J

Jason Roelofs

[Note: parts of this message were removed to make it a legal post.]

Using SWIG is a good way to go. The most basic wrapping, if there's no out
parameters is simply this:

wrapper.i:

%{
#include "file1.h"
#include "file2.h"
...
%}

%include "file1.h"
%include "file2.h"
...

SWIG doesn't take much to learn. Look through the website at www.swig.org,
the wiki, and especially http://www.swig.org/Doc1.3/Ruby.html.

And as a clarification of RubyInline, the only speed hit is the first run
where Inline has to parse your C code, generate Ruby wrapper code (if
applicable), and compile an extension. If the extension exists and the code
hasn't changed, it just require's your extension.

Jason
 
M

M. Edward (Ed) Borasky

Axel said:
Dear Ed,


It is home-grown ... partly because the divisions I have to do
involve several variables (see an example here: http://www.geocities.com/famancin/buchberger.html) ... I am not aware that there are any "well-known" open-source libraries for this as it seems a more exotic part of computational algebra after all.

Groebner basis calculations are built in to most computer algebra
systems, and there are some highly-tuned C-language libraries available.
I don't know the field (pun unintended) well enough to know anything
more than the names, but the ones that show up in the Gentoo repository are

* sci-mathematics/Macaulay2
* sci-mathematics/axiom
* sci-mathematics/gap
* sci-mathematics/ginac
* sci-mathematics/mathomatic
* sci-mathematics/maxima
* sci-mathematics/pari
* sci-mathematics/singular
* sci-mathematics/yacas

And there are some others in the Python-based Sage project at

http://www.sagemath.org/

There is also a project called "swiginac" which is building Python
wrappers for the GiNaC library using SWIG.

[snip]
These things are done in Ruby, as it is so much nicer to code in :)
and as this is a part of the problem where speed of computation
is not so critical, as most of the computation is done in the division
process written in C.

Now, to connect the two, I looked at this tutorial:

http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html

I've managed to make this work without any problem.
Now, what I still do not understand is quite what SWIG does precisely
for the communication of Ruby and C.

SWIG is fairly automatic once you define the interface (.i) files.
Sometimes, all you need to do is feed SWIG the header files for the C
library and it can generate the wrapper code automatically. But more
often, you need to know the kinds of objects that must pass across the
scripting language-library interface.

In the case of Ruby, you can define classes, methods and objects in C or
C++ and SWIG will build wrapper code you can use to access these from
Ruby. As I said earlier, if you're only interested in Ruby as the
scripting language, you don't need SWIG.

The SWIG documentation is quite comprehensive, and there are quite a few
open source packages that make good use of SWIG and can be used for
coding examples if you want to go that way. Try

http://www.swig.org/Doc1.3/Contents.html#Contents

Read the first two chapters, and the third chapter if you're using
Windows. Then read the Ruby chapter, chapter 30, at

http://www.swig.org/Doc1.3/Ruby.html#Ruby
1.) I faintly recall reading a post on this list that SWIG could be used not only to extend Ruby with C, but also the other way round ... so I was
thinking that maybe I could use the Ruby's Rational to extend
my C code .. if you have any pointers for extending C with Ruby, please
let me know.

I'm not sure why you'd want to do Rational arithmetic in Ruby from a C
program. There are a couple of decent C libraries for
arbitrary-precision integer and rational arithmetic. Try CLN ("Common
Lisp Numbers", which is used in GiNaC) and "gmp" (Gnu Multi-Precision).
 
A

Axel Etzold

Dear Ed,
Dear Jason,

thank you for the load of information you provided.
I'll have a look at the gmp libraries specifically.

Best regards,

Axel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top