Ruby, C, swig and variable types

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

···

--
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail

Axel Etzold wrote:

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?

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 :slight_smile:
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

···

--
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: http://www.gmx.net/de/go/freemail

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

···

On Jan 20, 2008 5:36 AM, Axel Etzold <AEtzold@gmx.de> wrote:

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:
Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos) ... 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 :slight_smile:
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:

How to create a Ruby extension in C in under 5 minutes

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
--
GMX FreeMail: 1 GB Postfach, 5 E-Mail-Adressen, 10 Free SMS.
Alle Infos und kostenlose Anmeldung: GMX E-Mail ✉ sichere & kostenlose E-Mail-Adresse ✉

Axel Etzold wrote:

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: Yahoo | Mail, Weather, Search, Politics, News, Finance, Sports & Videos) ... 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

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 :slight_smile:
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:

How to create a Ruby extension in C in under 5 minutes

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).

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

···

--
Psssst! Schon vom neuen GMX MultiMessenger gehört?
Der kann`s mit allen: http://www.gmx.net/de/go/multimessenger