Using ruby for scientific computing

Hi all,

For pedagogic purposes, I am trying to solve simple partial differential
equations (say a diffusion equation on a regular mesh in 2D) with Ruby.
Using the NArray gem, I have built a satisfactory tool from an interface
(and ease of use) point of view but the performance are suboptimal.

I am now wondering what is the right way to improve my code
performance-wise. I am doing a lot of matrix-vector and vector-vector
products.

From 2 2D NArrays describing two scalar fields, dot-product is
implemented as :

def dot_product(vec_a, vec_b)
dot_product=(vec_avec_b">vec_avec_b).sum
end

and as I am working with sparse matrices, (for the time being) a matrix
is an Array of Hashes. Each key of the hash contains the index of the
non-vanishing coefficients (the value of this coefficient is the value
of the Hash) of the matrix. For the identity matrix it gives

def identity(sizeX, sizeY)
mat=[]
(0…sizeXsizeY">sizeXsizeY).each { |ind|
mat << {ind=>1.0}
}
mat
end

Matrix vector product is then defined as

def matrix_vector_product(mat, vector)
ff=NArray.float(100,100)
(0…100100).each { |ind|
matrix[ind].each do |key,value|
ff[[ind]]+=value
vector[[key]][0]
end
}
ff
end

I am wondering what is the best way to tackle this performance problem :

  1. Improve the ruby code (and how? :slight_smile: Should I avoid using hashes?
  2. Write an extension to perform these operations in C. BTW is there a
    way to access directly NArray data (without copy) from a C extension?
  3. Use a wrapper like Ruby-lapack
    (
    https://rubyforge.org/projects/ruby-lapack/
    ).

What do you think?

Thanks for your help !

Hello,

On 8 Σεπ 2012, at 18:06 , Olivier S. [email protected] wrote:

Hi all,

For pedagogic purposes, I am trying to solve simple partial differential
equations (say a diffusion equation on a regular mesh in 2D) with Ruby.
Using the NArray gem, I have built a satisfactory tool from an interface
(and ease of use) point of view but the performance are suboptimal.

Is the code available on a public repo?

and as I am working with sparse matrices, (for the time being) a matrix
end
}
).

Panagiotis A.

Le 8 sept. 2012 à 19:39, Panagiotis A. [email protected] a
écrit :

Is the code available on a public repo?

Not yet, but I plan to share it as soon as I am convinced it is usable
for my students.

I am now wondering what is the right way to improve my code
performance-wise. I am doing a lot of matrix-vector and vector-vector
products.

From 2 2D NArrays describing two scalar fields, dot-product is implemented as :

def dot_product(vec_a, vec_b)
dot_product=(vec_avec_b">vec_avec_b).sum
end

The definition above is wrong, the right ones

def dot_product(vec_a, vec_b)
(vec_a*vec_b).sum
end

  }
          ff[[ind]]+=value*vector[[key]][0]

(
https://rubyforge.org/projects/ruby-lapack/
).

What do you think?

Thanks for your help !

Best regards,
- Olivier

Olivier S. wrote in post #1075138:

Hi all,

For pedagogic purposes, I am trying to solve simple partial differential
equations (say a diffusion equation on a regular mesh in 2D) with Ruby.
Using the NArray gem, I have built a satisfactory tool from an interface
(and ease of use) point of view but the performance are suboptimal.

I am wondering what is the best way to tackle this performance problem :

  1. Improve the ruby code (and how? :slight_smile: Should I avoid using hashes?
  2. Write an extension to perform these operations in C. BTW is there a
    way to access directly NArray data (without copy) from a C extension?
  3. Use a wrapper like Ruby-lapack
    (
    https://rubyforge.org/projects/ruby-lapack/
    ).

What do you think?

Thanks for your help !

Hi,

Because it seems that you emphasize on performance, I think the best way
is to use GNU Octave for dealing with the sparse matrices. There is a
Ruby gem (octave-ruby) to bridge between Ruby and Octave objects.

I really like Ruby, but for scientific computing I think for now Python
has better libraries.

Regards,

Bill

On Sep 8, 2012, at 09:06 , Olivier S. [email protected] wrote:

Hi all,

For pedagogic purposes, I am trying to solve simple partial differential
equations (say a diffusion equation on a regular mesh in 2D) with Ruby.
Using the NArray gem, I have built a satisfactory tool from an interface
(and ease of use) point of view but the performance are suboptimal.

Have you taken a look at stdlib’s matrix.rb?

= MMaattrriixx << OObbjjeecctt

(from ruby core)

The Matrix class represents a mathematical matrix, and provides methods
for
creating special-case matrices (zero, identity, diagonal, singular,
vector),
operating on them arithmetically and algebraically, and determining
their
mathematical properties (trace, rank, inverse, determinant).

Note that although matrices should theoretically be rectangular, this is
not
enforced by the class.

Also note that the determinant of integer matrices may be incorrectly
calculated unless you also require ‘mathn’. This may be fixed in the
future.

== MMeetthhoodd CCaattaalloogguuee

To create a matrix:

  • Matrix[*rows]
  • Matrix.
  • Matrix.rows(rows, copy = true)
  • Matrix.columns(columns)
  • Matrix.diagonal(*values)
  • Matrix.scalar(n, value)
  • Matrix.scalar(n, value)
  • Matrix.identity(n)
  • Matrix.unit(n)
  • Matrix.I(n)
  • Matrix.zero(n)
  • Matrix.row_vector(row)
  • Matrix.column_vector(column)

To access Matrix elements/columns/rows/submatrices/properties:

  • [](i, j)
  • #row_size
  • #column_size
  • #row(i)
  • #column(j)
  • #collect
  • #map
  • #minor(*param)

Properties of a matrix:

  • #regular?
  • #singular?
  • #square?

Matrix arithmetic:

  • *(m)
  • +(m)
  • -(m)
  • #/(m)
  • #inverse
  • #inv

Matrix functions:

  • #determinant
  • #det
  • #rank
  • #trace
  • #tr
  • #transpose
  • #t

Conversion to other data types:

  • #coerce(other)
  • #row_vectors
  • #column_vectors
  • #to_a

String representations:

  • #to_s
  • #inspect

= CCllaassss mmeetthhooddss::

I
[]
column_vector
columns
diagonal
identity
new
row_vector
rows
scalar
unit
zero

= IInnssttaannccee mmeetthhooddss::

**
+

/

[]
clone
coerce
collect
column
column_size
column_vectors
compare_by_row_vectors
det
determinant
eql?
hash
init_rows
inspect
inv
inverse
inverse_from
map
minor
rank
regular?
row
row_size
row_vectors
singular?
square?
t
to_a
to_s
tr
trace
transpose

Thanks for your answer !
I also really like Ruby and would prefer to avoid switching to Python.

I’ll have a look at octave-ruby. I have also found a project
http://sciruby.com that seems to be interesting. I am not sure how far
it has improved the situation for ruby in scientific computing though.

Best regards,
Le 8 sept. 2012 20:26, Admin T. [email protected] a crit :

  1. Write an extension to perform these operations in C. BTW is there a
    Hi,
    Bill


Posted via http://www.ruby-forum.com/.

                                   - Olivier

Le 8 sept. 2012 23:31, Ryan D. [email protected] a crit :

Have you taken a look at std lib’s matrix.rb?
No, I’ll check it. In particular there is a LU decomposition method
implemented which could help me a lot.

Thanks,

Note that although matrices should theoretically be rectangular, this is not

  • Matrix.rows(rows, copy = true)

Properties of a matrix:

  • #inv

= CCllaassss mmeetthhooddss::
scalar

eql?
row

  • Olivier

On Sun, Sep 9, 2012 at 1:06 AM, Olivier S. [email protected] wrote:

Sometime ago, there was a Google Summer of Code project to port NArray
to OpenCL

There is also this project http://ruby-opencl.rubyforge.org/, if you
want to try multicore acceleration
(as a means to speed up your code) with OpenCL. It should work with
multicore cpus as well as GPUs

saji

Saji N Hameed,
ARC-ENV, Center for Advanced Information Science and Technology,
University of Aizu, Tsuruga, Ikki-machi,
Aizuwakamatsu-shi, Fukushima 965-8580,
Japan

Tel: +81242 37-2736
Fax:+81242 37-2760
email: [email protected]
url: http://www.u-aizu.ac.jp
bib: Web of Science

Hi,

I had not thought of using Open CL. I’ll check it. The last commits to
the project dates back to two years ago.

Thanks !

Le 9 sept. 2012 08:06, Saji H. [email protected] a crit :

products.

Tel: +81242 37-2736
Fax:+81242 37-2760
email: [email protected]
url: http://www.u-aizu.ac.jp
bib: Web of Science

                                   - Olivier

Olivier S. wrote in post #1075180:

Thanks for your answer !
I also really like Ruby and would prefer to avoid switching to Python.

I’ll have a look at octave-ruby. I have also found a project
http://sciruby.com that seems to be interesting. I am not sure how far
it has improved the situation for ruby in scientific computing though.

Hi,

Thanks for your pointer to sciruby. I think it will take them some time
to make it usable for serious scientific computation (especially sparse
matrices) and even longer to make it comparable to Python’s NumPy.

I also tried it once by writing RTensor on Windows
(http://tensor.heliohost.org/rtensor/) but it takes too much work and
time. I think using Octave is the current practical solution, and I
think if we want to contribute to Ruby community, it is by finding a way
to easily integrate Octave and Ruby (beyond octave-ruby).

Regards,

Bill