rubynmatrix

solve function of gem NMatrix


When I tried to use the function "solve" in gem NMatrix, I find wrong result...

I am trying to solve the linear system a*x = b where

a = [[1,  0, 0], 
     [4, -5, 1],
     [0,  0, 1]]

and

b = [0, 0, 729]

Which should give the answer

x = [0, 145.8, 729]

I call the solve function doing a.solve(b) (as explained at http://www.rubydoc.info/gems/nmatrix/0.2.1/NMatrix#solve-instance_method) but it returns

x = [0, 1.013500790889141e-30, 1.013500790889141e-30]

Therefore, I have two questions:

  1. Am I doing something wrong?
  2. If not, what would be the other solution (excluding GSL) to solve matrix systems with ruby?

Thank you !


Solution

  • To answer part 2 of your question, you can use Ruby's built-in Matrix class.

    require 'matrix'
    
    m = Matrix[[1, 0, 0], [4, -5, 1], [0, 0, 1]]
      #=> Matrix[[1, 0, 0], [4, -5, 1], [0, 0, 1]]
    b = Vector[0, 0, 729]
      #=> Vector[0, 0, 729]
    
    a = m.lup.solve(b).to_a
      #=> [(0/1), (729/5), (729/1)]
    

    If one prefers floats (rather than rational numbers),

    a.map(&:to_f)
      #=> [0.0, 145.8, 729.0]
    

    See Matrix#lup and Matrix::LUPDecomposition#solve, which solve the linear system using LU decomposition.

    If the system of linear equations has no solution (e.g., [[0,0], [0,0]]*x = b) or an infinite number of solutions (that is, m is singular), Ruby will raise an exception. For example,

    Matrix[[0,0],[0,0]].lup.solve [1, 1]
      #=> ExceptionForMatrix::ErrNotRegular: Not Regular Matrix
    

    require matrix makes both the Matrix and Vector classes (and subclasses) available for use.