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 ::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 # 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 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 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