1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#
# 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
|