Created
June 11, 2021 08:08
-
-
Save sudeeptarlekar/8a60f2981597d1a5fb81b34160ead019 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class GaussJordanElimination | |
attr_reader :max_elements, :matrix, :solution, :sorted_columns | |
def initialize(max_elements) | |
@max_elements = max_elements | |
@matrix = [] | |
@solution = [] | |
@sorted_columns = [] | |
end | |
def take_input | |
@matrix = [] | |
@sorted_columns = [] | |
@solution = [] | |
puts "Enter the values of equation comma separated" | |
max_elements.times do |_n| | |
temp = gets.chomp.split(',').map(&:to_i) | |
while temp.count != max_elements + 1 do | |
puts 'Not valid matrix, give input again' | |
temp = gets.chomp.split(',').map(&:to_i) | |
end | |
matrix << temp | |
end | |
end | |
def print_matrix | |
matrix.each { |row| puts row.join(' ') } | |
end | |
def forward_elimination | |
for column in 0...@max_elements do | |
for row in column...@max_elements do | |
# sort first column in the matrix | |
sort column(column) | |
# go to next row if element is 0 | |
next if matrix[row][column] == 0 | |
# if element is diagonal element | |
# then multiply same by inverse of element to get 1 | |
if column == row | |
# get inverse of current element | |
multiplier = 1.0 / matrix[row][column] | |
#multiply current row with inverse | |
matrix[row] = multiply_row(row, multiplier) | |
# if this is first row in matrix | |
# then go to next iterations | |
next if row == 0 | |
# else eliminate column elemetns in all above rows | |
(0...row).each { |i| perform_operation(i, column) } | |
else | |
# if element is not diagonal element then eliminatio other column elements | |
perform_operation(row, column) | |
end | |
end | |
end | |
solve_system | |
end | |
def print_solution | |
if solution.include? nil | |
puts "No solution possible" | |
return | |
elsif solution.include? 'arbitary' | |
puts "Infinitely many solutions possible" | |
return | |
end | |
solution.each_with_index { |sol, index| puts "x#{index + 1} = #{sol}" } | |
end | |
private | |
def solve_system | |
# Each diagonal element contains the 1 | |
(0...@max_elements).reduce(solution) do |arr, i| | |
# If diagonal element is 0 and RHS is not 0 then x/0 is infinity and hence | |
# infinitely many solutions possible for system | |
if matrix[i][i] == 0 && matrix[i][max_elements] != 0 | |
arr << nil | |
# If both LHS and RHS are 0 then variable can be arbitary | |
elsif matrix[i][i] == 0 && matrix[i][max_elements] == 0 | |
arr << 'arbitary' | |
else | |
arr << matrix[i][max_elements] / matrix[i][i] | |
end | |
arr | |
end | |
end | |
def perform_operation(row, column) | |
multiplied_row = multiply_row(column, matrix[row][column]) | |
if subtract_rows?(multiplied_row[column], matrix[row][column]) | |
matrix[row] = subtract_rows(matrix[row], multiplied_row) | |
else | |
matrix[row] = add_rows(matrix[row], multiplied_row) | |
end | |
end | |
def multiply_row(row_number, multiplier) | |
matrix[row_number].map { |element| element * multiplier } | |
end | |
def subtract_rows?(element_1, element_2) | |
(element_1.negative? && element_2.negative?) || !(element_1.negative? || element_2.negative? ) | |
end | |
def sort(column) | |
return if sorted_columns.include? column | |
sorted_columns << column | |
for row in column...@max_elements - 1 do | |
swap_rows(row + 1, row) if matrix[row + 1][column] < matrix[row][column] | |
end | |
end | |
def swap_rows(row_1, row_2) | |
return if row_2 >= @max_elements | |
temp = matrix[row_1] | |
matrix[row_1] = matrix[row_2] | |
matrix[row_2] = temp | |
end | |
def add_rows(row_1, row_2) | |
(0..max_elements).reduce([]) { |arr, column| arr << row_1[column] + row_2[column] } | |
end | |
def subtract_rows(row_1, row_2) | |
(0..max_elements).reduce([]) { |arr, column| arr << row_1[column] - row_2[column] } | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment