Module: LU

Defined in:
lib/linmeric/LU.rb

Overview

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

Author

Massimiliano Dal Mas ([email protected])

License

Distributed under MIT license

Class Method Summary collapse

Class Method Details

.factorize(mx, sol) ⇒ Object

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



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# 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

.LObject

Returns the ‘L` matrix



27
28
29
# File 'lib/linmeric/LU.rb', line 27

def self.L()
  return @L
end

.resetObject

Sets to nil @L and @U variables



37
38
39
40
# File 'lib/linmeric/LU.rb', line 37

def self.reset
  @L = nil
  @U = nil
end

.solve(sol) ⇒ Object

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



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# 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) ⇒ Object

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



19
20
21
22
23
24
# 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

.UObject

Returns the ‘U` matrix



32
33
34
# File 'lib/linmeric/LU.rb', line 32

def self.U()
  return @U
end