module LU

This module provides some method to perform LU factorization on squared matrices.

Author

Massimiliano Dal Mas (max.codeware@gmail.com)

License

Distributed under MIT license

Public Class Methods

L() click to toggle source

Returns the `L` matrix

# File lib/linmeric/LU.rb, line 27
def self.L()
  return @L
end
U() click to toggle source

Returns the `U` matrix

# File lib/linmeric/LU.rb, line 32
def self.U()
  return @U
end
factorize(mx,sol) click to toggle source

Performs LU factorization calculating L and U matrices

  • argument: squared matrix to factorize

  • argument: n x 1 matrix of known values of the linear system

  • returns: same as LU.solve

# File lib/linmeric/LU.rb, line 47
def self.factorize(mx,sol)
  [mx,sol].each do |vec|
    return nil unless vec.is_a? Matrix
  end
  sol = sol.tr if sol.getCls > 1
  return nil unless sol.getCls == 1
  return nil unless mx.is_squared?
  return nil unless mx.getRws == sol.getRws
  rows = mx.getRws
  for k in 0...rows do
    column = mx[k...mx.getRws,k].export.map! { |val| val.abs}
    max_index = column.index(column.max)
    mx = self.swap(mx,k,k + max_index) unless k == max_index + k
    sol = self.swap(sol,0,k + max_index) unless k == max_index + k
    for i in (k+1)...mx.getRws do
      alpha = (mx[k,k] != 0) ? (mx[i,k] / mx[k,k].to_f) : 0
      mx[i,k] = alpha
      for j in (k+1)...mx.getCls do
        mx[i,j] -= alpha * mx[k,j] 
      end
    end
  end
  @L = Matrix.identity(mx.getRws) + Matrix.new(mx.getRws,mx.getCls){ |i,j| (i > j) ? mx[i,j] : 0}
  @U = Matrix.new(mx.getRws,mx.getCls){ |i,j| (i <= j) ? mx[i,j] : 0}
  return solve(sol)
end
reset() click to toggle source

Sets to nil @L and @U variables

# File lib/linmeric/LU.rb, line 37
def self.reset
  @L = nil
  @U = nil
end
solve(sol) click to toggle source

Finds the solutions of the linear system

  • argument: n x 1 matrix of known values of the linear system

  • returns: n x 1 matrix with the solutions of the system

# File lib/linmeric/LU.rb, line 78
def self.solve(sol)
  z = Matrix.new(sol.getRws,1) {0}
  x = Matrix.new(sol.getRws,1) {0}
  for i in 0...sol.getRws do
    z[i,0] = sol[i,0]
    for j in 0...i do       
      z[i,0] -= @L[i,j] * (z[j,0] || 1)
    end
  end

  (sol.getRws - 1).downto(0) do |i|
    x[i,0] = z[i,0]     
    for j in i...sol.getRws
      x[i,0] -= (@U[i,j+1] || 0) * (x[j+1,0] || 0)       
    end
    x[i,0] = x[i,0] / @U[i,i].to_f
  end
  return x
end
swap(mx,r1,r2) click to toggle source

Swaps two rows of a matrix (pivoting)

  • argument: matrix the rows must be swapped on

  • argument: first row

  • argument: second row

  • returns: new matrix with swapped rows

# File lib/linmeric/LU.rb, line 19
def self.swap(mx,r1,r2)
  for i in 0...mx.getCls do
    mx[r1,i],mx[r2,i] = mx[r2,i],mx[r1,i] 
  end
  return mx
end