# Using ruby for scientific computing

**URL:** <https://rubytalk.org/t/using-ruby-for-scientific-computing/66255>\
**Category:** ruby-talk\
**Created:** [8 September 2012 16:06 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255 "2012-09-08T16:06:58Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Olivier\_Saut1](https://avatars.discourse-cdn.com/v4/letter/o/858c86/32.png) [@Olivier\_Saut1](https://rubytalk.org/u/Olivier_Saut1)\
**Post date:** [8 September 2012 16:06 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/1 "2012-09-08T16:06:58Z")

</div>

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)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dot\_product=(vec\_a\*vec\_b"\>vec\_a\*vec\_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)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat=[]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0..sizeX\*sizeY"\>sizeX\*sizeY).each { |ind|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat \<\< {ind=\>1.0}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat  
end

Matrix vector product is then defined as

def matrix\_vector\_product(mat, vector)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff=NArray.float(100,100)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0..100\*100).each { |ind|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matrix[ind].each do |key,value|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff[[ind]]+=value\*vector[[key]][0]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff  
end

I am wondering what is the best way to tackle this performance problem :  
1. Improve the ruby code (and how? 🙂 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/](https://rubyforge.org/projects/ruby-lapack/)  
).

What do you think?

Thanks for your help !

> **···**
>
> --  
> &nbsp;&nbsp;Olivier Saut  
> &nbsp;&nbsp;  
> [osaut@airpost.net](mailto:osaut@airpost.net)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Olivier

---

<div class="post-metadata">

**Author:** ![Panagiotis\_Atmatzid1](https://avatars.discourse-cdn.com/v4/letter/p/b5ac83/32.png) [@Panagiotis\_Atmatzid1](https://rubytalk.org/u/Panagiotis_Atmatzid1)\
**Post date:** [8 September 2012 17:39 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/2 "2012-09-08T17:39:25Z")

</div>

Hello,

> 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?

> 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)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dot\_product=(vec\_a\*vec\_b"\>vec\_a\*vec\_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)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat=  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0..sizeX\*sizeY"\>sizeX\*sizeY).each { |ind|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat \<\< {ind=\>1.0}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat  
> end
> 
> Matrix vector product is then defined as
> 
> def matrix\_vector\_product(mat, vector)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff=NArray.float(100,100)  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0..100\*100).each { |ind|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matrix[ind].each do |key,value|  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff[[ind]]+=value\*vector[[key]][0]  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff  
> end
> 
> I am wondering what is the best way to tackle this performance problem :  
> 1. Improve the ruby code (and how? 🙂 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/](https://rubyforge.org/projects/ruby-lapack/)  
> ).
> 
> What do you think?
> 
> Thanks for your help !
> 
> --  
> Olivier Saut
> 
> osaut@airpost.net  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Olivier

Panagiotis Atmatzidis

> **···**
>
> On 8 Σεπ 2012, at 18:06 , Olivier Saut \<osaut@airpost.net\> wrote:  
> -----------------------------  
> Pharmacy Student at VFU
> 
> email4lists: ml@convalesco.org  
> More info: [http://about.me/atmosx](http://about.me/atmosx)
> 
> The wise man said: "Never argue with an idiot, he brings you down to his level and beat you with experience."

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [8 September 2012 18:26 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/3 "2012-09-08T18:26:23Z")

</div>

Olivier Saut 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? 🙂 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/](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

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).

---

<div class="post-metadata">

**Author:** ![Ryan\_Davis1](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/ryan_davis1/32/1848_2.png) [@Ryan\_Davis1](https://rubytalk.org/u/Ryan_Davis1)\
**Post date:** [8 September 2012 21:31 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/4 "2012-09-08T21:31:34Z")

</div>

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

= MMaattrriixx \<\< OObbjjeecctt

(from ruby core)

> **···**
>
> On Sep 8, 2012, at 09:06 , Olivier Saut \<osaut@airpost.net\> 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.
> 
> ------------------------------------------------------------------------------  
> 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.(\*rows)  
> \* 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::
> 
> &nbsp;&nbsp;I  
> &nbsp;&nbsp;  
> &nbsp;&nbsp;column\_vector  
> &nbsp;&nbsp;columns  
> &nbsp;&nbsp;diagonal  
> &nbsp;&nbsp;identity  
> &nbsp;&nbsp;new  
> &nbsp;&nbsp;row\_vector  
> &nbsp;&nbsp;rows  
> &nbsp;&nbsp;scalar  
> &nbsp;&nbsp;unit  
> &nbsp;&nbsp;zero
> 
> = IInnssttaannccee mmeetthhooddss::
> 
> &nbsp;&nbsp;\*  
> &nbsp;&nbsp;\*\*  
> &nbsp;&nbsp;+  
> &nbsp;&nbsp;-  
> &nbsp;&nbsp;/  
> &nbsp;&nbsp;==  
> &nbsp;&nbsp;  
> &nbsp;&nbsp;clone  
> &nbsp;&nbsp;coerce  
> &nbsp;&nbsp;collect  
> &nbsp;&nbsp;column  
> &nbsp;&nbsp;column\_size  
> &nbsp;&nbsp;column\_vectors  
> &nbsp;&nbsp;compare\_by\_row\_vectors  
> &nbsp;&nbsp;det  
> &nbsp;&nbsp;determinant  
> &nbsp;&nbsp;eql?  
> &nbsp;&nbsp;hash  
> &nbsp;&nbsp;init\_rows  
> &nbsp;&nbsp;inspect  
> &nbsp;&nbsp;inv  
> &nbsp;&nbsp;inverse  
> &nbsp;&nbsp;inverse\_from  
> &nbsp;&nbsp;map  
> &nbsp;&nbsp;minor  
> &nbsp;&nbsp;rank  
> &nbsp;&nbsp;regular?  
> &nbsp;&nbsp;row  
> &nbsp;&nbsp;row\_size  
> &nbsp;&nbsp;row\_vectors  
> &nbsp;&nbsp;singular?  
> &nbsp;&nbsp;square?  
> &nbsp;&nbsp;t  
> &nbsp;&nbsp;to\_a  
> &nbsp;&nbsp;to\_s  
> &nbsp;&nbsp;tr  
> &nbsp;&nbsp;trace  
> &nbsp;&nbsp;transpose

---

<div class="post-metadata">

**Author:** ![Saji\_Hameed](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/saji_hameed/32/2120_2.png) [@Saji\_Hameed](https://rubytalk.org/u/Saji_Hameed)\
**Post date:** [9 September 2012 06:06 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/5 "2012-09-09T06:06:15Z")

</div>

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

> **[第5回SCDN - Ruby Summer of Code: NArray on OpenCL](https://www.slideshare.net/scdn/5scdn-ruby-summer-of-code-narray-on-opencl)**
>
> 第5回SCDN - Ruby Summer of Code: NArray on OpenCL - Download as a PDF or view online for free

> **[GitHub - kazuyukitanimura/narray: Ruby/NArray : N-dimensional Numerical Array...](https://github.com/kazuyukitanimura/narray)**
>
> Ruby/NArray : N-dimensional Numerical Array for Ruby - GitHub - kazuyukitanimura/narray: Ruby/NArray : N-dimensional Numerical Array for Ruby

There is also this project [http://ruby-opencl.rubyforge.org/](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

> **···**
>
> On Sun, Sep 9, 2012 at 1:06 AM, Olivier Saut \<osaut@airpost.net\> 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.
> > 
> > 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.
> 
> --
> 
> 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: saji@u-aizu.ac.jp  
> url: [http://www.u-aizu.ac.jp](http://www.u-aizu.ac.jp)  
> bib: [Web of Science](http://www.researcherid.com/rid/B-9188-2009)

---

<div class="post-metadata">

**Author:** ![Olivier\_Saut1](https://avatars.discourse-cdn.com/v4/letter/o/858c86/32.png) [@Olivier\_Saut1](https://rubytalk.org/u/Olivier_Saut1)\
**Post date:** [8 September 2012 18:00 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/6 "2012-09-08T18:00:32Z")

</div>

> Hello,
> 
> > 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?

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)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dot\_product=(vec\_a\*vec\_b"\>vec\_a\*vec\_b).sum  
> > end

The definition above is wrong, the right ones

def dot\_product(vec\_a, vec\_b)  
&nbsp;&nbsp;(vec\_a\*vec\_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)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat=  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0..sizeX\*sizeY"\>sizeX\*sizeY).each { |ind|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat \<\< {ind=\>1.0}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mat  
> > end
> > 
> > Matrix vector product is then defined as
> > 
> > def matrix\_vector\_product(mat, vector)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff=NArray.float(100,100)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0..100\*100).each { |ind|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matrix[ind].each do |key,value|  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff[[ind]]+=value\*vector[[key]][0]  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ff  
> > end
> > 
> > I am wondering what is the best way to tackle this performance problem :  
> > 1. Improve the ruby code (and how? 🙂 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/](https://rubyforge.org/projects/ruby-lapack/)  
> > ).
> > 
> > What do you think?
> > 
> > Thanks for your help !

Best regards,  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Olivier

> **···**
>
> Le 8 sept. 2012 à 19:39, Panagiotis Atmatzidis \<ml@convalesco.org\> a écrit :
> 
> > On 8 Σεπ 2012, at 18:06 , Olivier Saut \<osaut@airpost.net\> wrote:

---

<div class="post-metadata">

**Author:** ![Olivier\_Saut1](https://avatars.discourse-cdn.com/v4/letter/o/858c86/32.png) [@Olivier\_Saut1](https://rubytalk.org/u/Olivier_Saut1)\
**Post date:** [9 September 2012 07:31 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/7 "2012-09-09T07:31:01Z")

</div>

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](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 Tensor \<lists@ruby-forum.com\> a écrit :
> 
> > Olivier Saut 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? 🙂 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/](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
> > 
> > --  
> > Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Olivier

---

<div class="post-metadata">

**Author:** ![Olivier\_Saut1](https://avatars.discourse-cdn.com/v4/letter/o/858c86/32.png) [@Olivier\_Saut1](https://rubytalk.org/u/Olivier_Saut1)\
**Post date:** [9 September 2012 07:33 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/8 "2012-09-09T07:33:32Z")

</div>

> > 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 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,

> = 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.(\*rows)  
> \* 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

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Olivier

> **···**
>
> Le 8 sept. 2012 à 23:31, Ryan Davis \<ryand-ruby@zenspider.com\> a écrit :
> 
> > On Sep 8, 2012, at 09:06 , Olivier Saut \<osaut@airpost.net\> wrote:

---

<div class="post-metadata">

**Author:** ![Olivier\_Saut1](https://avatars.discourse-cdn.com/v4/letter/o/858c86/32.png) [@Olivier\_Saut1](https://rubytalk.org/u/Olivier_Saut1)\
**Post date:** [9 September 2012 07:38 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/9 "2012-09-09T07:38:55Z")

</div>

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 Hameed \<saji@u-aizu.ac.jp\> a écrit :
> 
> > On Sun, Sep 9, 2012 at 1:06 AM, Olivier Saut \<osaut@airpost.net\> 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.
> > > 
> > > 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.
> > 
> > Sometime ago, there was a Google Summer of Code project to port NArray to OpenCL  
> > [第5回SCDN - Ruby Summer of Code: NArray on OpenCL | PPT](http://www.slideshare.net/scdn/5scdn-ruby-summer-of-code-narray-on-opencl)  
> > [GitHub - kazuyukitanimura/narray: Ruby/NArray : N-dimensional Numerical Array for Ruby](https://github.com/kazuyukitanimura/narray)
> > 
> > There is also this project [http://ruby-opencl.rubyforge.org/](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: saji@u-aizu.ac.jp  
> > url: [http://www.u-aizu.ac.jp](http://www.u-aizu.ac.jp)  
> > bib: [Web of Science](http://www.researcherid.com/rid/B-9188-2009)
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- Olivier

---

<div class="post-metadata">

**Author:** ![7stud2](https://avatars.discourse-cdn.com/v4/letter/7/9de053/32.png) [@7stud2](https://rubytalk.org/u/7stud2)\
**Post date:** [9 September 2012 17:46 UTC](https://rubytalk.org/t/using-ruby-for-scientific-computing/66255/10 "2012-09-09T17:46:27Z")

</div>

Olivier Saut 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](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/\](http://tensor.heliohost.org/rtensor/%5C)) 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

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/\](http://www.ruby-forum.com/%5C).
