mirror of https://github.com/docusealco/docuseal
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
2.3 KiB
111 lines
2.3 KiB
#
|
|
# linear.rb
|
|
#
|
|
# Solves linear equation system(A*x = b) by LU decomposition method.
|
|
# where A is a coefficient matrix,x is an answer vector,b is a constant vector.
|
|
#
|
|
# USAGE:
|
|
# ruby linear.rb [input file solved]
|
|
#
|
|
|
|
# :stopdoc:
|
|
require "bigdecimal"
|
|
|
|
# Requires gem matrix
|
|
require "matrix"
|
|
|
|
class PrecisionSpecifiedValue
|
|
# NOTE:
|
|
# Change following PREC if needed.
|
|
|
|
attr_reader :value
|
|
def initialize(value, prec)
|
|
@value = BigDecimal(value)
|
|
@prec = prec
|
|
end
|
|
|
|
def unwrap(value)
|
|
PrecisionSpecifiedValue === value ? value.value : value
|
|
end
|
|
|
|
def coerce(other)
|
|
[self.class.new(unwrap(other), @prec), self]
|
|
end
|
|
|
|
def abs
|
|
self.class.new(@value.abs, @prec)
|
|
end
|
|
|
|
def >(other)
|
|
@value > unwrap(other)
|
|
end
|
|
|
|
def <(other)
|
|
@value < unwrap(other)
|
|
end
|
|
|
|
def -(other)
|
|
self.class.new(@value.sub(unwrap(other), @prec), @prec)
|
|
end
|
|
|
|
def +(other)
|
|
self.class.new(@value.add(unwrap(other), @prec), @prec)
|
|
end
|
|
|
|
def *(other)
|
|
self.class.new(@value.mult(unwrap(other), @prec), @prec)
|
|
end
|
|
|
|
def quo(other)
|
|
self.class.new(@value.div(unwrap(other), @prec), @prec)
|
|
end
|
|
end
|
|
|
|
return if __FILE__ != $0
|
|
|
|
def rd_order(na)
|
|
printf("Number of equations ?") if(na <= 0)
|
|
ARGF.gets().to_i
|
|
end
|
|
|
|
na = ARGV.size
|
|
|
|
while (n=rd_order(na))>0
|
|
a = []
|
|
b = []
|
|
if na <= 0
|
|
# Read data from console.
|
|
printf("\nEnter coefficient matrix element A[i,j]\n")
|
|
for i in 0...n do
|
|
a << n.times.map do |j|
|
|
printf("A[%d,%d]? ",i,j); s = ARGF.gets
|
|
BigDecimal(s)
|
|
end
|
|
printf("Contatant vector element b[%d] ? ",i)
|
|
b << BigDecimal(ARGF.gets)
|
|
end
|
|
else
|
|
# Read data from specified file.
|
|
printf("Coefficient matrix and constant vector.\n")
|
|
for i in 0...n do
|
|
s = ARGF.gets
|
|
printf("%d) %s",i,s)
|
|
s = s.split
|
|
a << n.times.map {|j| BigDecimal(s[j]) }
|
|
b << BigDecimal(s[n])
|
|
end
|
|
end
|
|
|
|
prec = 100
|
|
matrix = Matrix[*a.map {|row| row.map {|v| PrecisionSpecifiedValue.new(v, prec) } }]
|
|
vector = b.map {|v| PrecisionSpecifiedValue.new(v, prec) }
|
|
x = matrix.lup.solve(vector).map(&:value)
|
|
|
|
printf("Answer(x[i] & (A*x-b)[i]) follows\n")
|
|
for i in 0...n do
|
|
printf("x[%d]=%s ",i,x[i].to_s)
|
|
diff = a[i].zip(x).sum {|aij, xj| aij*xj }.sub(b[i], 10)
|
|
printf(" & %s\n", diff.to_s)
|
|
end
|
|
end
|