Non-negative Matrix Factorization for Ruby

Filed in: Ruby Add comments

Several months back I needed to compute NMF of some relatively larges matrices.
Since the native Ruby code was painfully slow, and for some reason even failed to work for some matrices, I decided to write a C implementation which will leverage the GNU Scientific Library (GSL) and then wrap it for using in Ruby application.
It was a neat add-on to the rb-gsl ruby library. What it does is adding NMF module under the GSL::Matrix, and there you have a method nmf which receives a GSL::Matrix and number of columns as a parameter and then returns two matrices.
Since this is an iterative algorithm, the number of runs is limited to 1000, and the desired difference cost metric is set to 10-6.
I tried to contact the author and even posted my code in the issue tracker, but haven’t received any response at the time of writing.
So I decided to create a git-svn mirror on Github and add my changes there.

You can install the gem using this command:

  $ gem sources -a # (you only have to do this once)
  $ gem install romanbsd-gsl

9 Responses to “Non-negative Matrix Factorization for Ruby”

  1. v01d Says:

    I was looking for some other work on wrapping GSL with Ruby on GitHub and I found yours.
    I just wanted to let you know that I’m trying to create a good wrapper for GSL using RubyFFI, in case you’re interested in it.
    I’m currently wrapping Matrix so maybe you should wait a little, but you could eventually submit your work on NMF (which I know nothing about =b) as an extension to my wrapper (it should be really easy using FFI, specially if you already have the C code).



    Roman Reply:

    What is motivation behind this effort? Is it that you’d like to use GSL with JRuby?
    Because with MRI the performance of C version is better than of FFI…


  2. v01d Says:

    Since GSL is really big and creating a wrapper gets quite complex (eventually, you have a ton of C code and it is impossible to maintain/extend), I thought that FFI could help in this aspect.
    Regarding the performance, I’m not really sure if there’s really an important difference, although I’ll create some benchmarks when I have more code wrapped.
    There are some other objectives I pursue with this wrapper, you can read them here:



  3. charles Says:


    Do you have some examples of the ruby interface to the NMF code?

    How to do you choose the seed values?
    Which algorithm did you implement?
    How large of a system can you solve?




    Roman Reply:


    The seed values are picked randomly in the min..max interval.
    The algorithm is the one that circulated in some pdf, I don’t remember the name of the authors. You can see the implementation here:

    I know that it solves a system of thousands of rows.


  4. charles Says:

    Just curious as to the status of this (and the FFI wrapper)
    I am trying to get this to install on Mac OS X using ruby 1.9.2
    I find the following error (which I assume is because I am in ruby 1.9.2 and not 1.8.6/7):

    It would be great to get this working under ruby 1.9.2
    Any idea how hard that would be?

    [I can’t get the FFi wrapper version of ruby gsl to install either]

    gcc -I. -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/x86_64-darwin10.4.0 -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/ruby/backward -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1 -I. -DHAVE_NARRAY_H -I/Users/charlesmartin/.rvm/gems/ruby-1.9.2-p0/gems/narray- -I/Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/lib/ruby/site_ruby/1.9.1/x86_64-darwin10.4.0 -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -fno-common -Wall -I../include -I/usr/local/include -o array.o -c array.c
    In file included from ../include/rb_gsl_array.h:16,
    from array.c:15:
    /Users/charlesmartin/.rvm/rubies/ruby-1.9.2-p0/include/ruby-1.9.1/ruby/backward/rubyio.h:2:2: warning: #warning use “ruby/io.h” instead of “rubyio.h”
    array.c: In function ‘carray_set_from_rarray’:
    array.c:214: error: ‘struct RArray’ has no member named ‘len’
    array.c: In function ‘Init_gsl_array’:
    array.c:656: warning: implicit declaration of function ‘Init_gsl_matrix_nmf’
    make: *** [array.o] Error 1


  5. Just how would you utilize $76195 to make even more money: Says:

    Paid Surveys: Make $5363 Or Even more Per Week:


  6. READY EARNINGS ON THE INTERNET from $6214 per day: Says:

    Fast and Big money on the Internet from $7522 per week:


  7. Snapback Cap Says:

    Thanks , I have just been looking for info about this topic for a while and yours is
    the best I’ve discovered so far. But, what about the bottom line?
    Are you positive about the source?


Leave a Reply