项目里需要求出两个表达式之间的关系,涉及到3个未知数,就用Ruby写了一个算法,利用了Ruby的BigDecimal,算法本身应该不算复杂,也可以方便的扩展到N元线性方程。之前用JS也写了一个,但JS的浮点精度不够,换成了RUBY,都放在了github上(https://github.com/caiqingfeng/formula-solver),如果有用就直接拿过去了,free to copy and commercial use:-)
formula-solver.rb代码如下:
require "bigdecimal"
#solver for a three variables linear formula (three dimensional matrix)
# matrix M=
# a11 a12 a13
# a21 a22 a23
# a31 a32 a33
# variables = (x, y, z)
# res = (A, B, C)
# res = M * variables;
class FormulaSolver
def findAnswer(matrixInput, resInput)
#combine matrix with resInput
matrix = Array.new(3) {Array.new(4) {BigDecimal.new("0.0")}}
for ii in 0..2
for jj in 0..2
matrix[ii][jj] = BigDecimal.new(matrixInput[ii][jj].to_s)/BigDecimal.new("1.0")
end
matrix[ii][3] = BigDecimal.new(resInput[ii].to_s)/BigDecimal.new("1.0")
end
#step 1: row2 or row3+row1*something to get a21 and a31 0
#matrix[0][0] should not be zero, otherwise to reset it by row+row
#reset matrix to guarantee matrix[0][0]!=0
if matrix[0][0] == 0
line = 1;
if matrix[1][0] == 0
if matrix[2][0] == 0
puts "this formula cannot be solved!"
return
end
line = 2;
end
for ii in 0..3
matrix[0][ii] = matrix[0][ii]+matrix[line][ii]
end
end
for ii in 1..2
if matrix[ii][0] != 0
factor = matrix[ii][0]/matrix[0][0]
for jj in 0..3
matrix[ii][jj] = matrix[ii][jj] - matrix[0][jj]*factor
end
end
end
#step 2: set matrix[2][1] = 0
if matrix[1][1] == 0
if matrix[2][1] == 0
puts "this formula cannot be solved!"
return
end
for ii in 1..3
matrix[1][ii] = matrix[1][ii]+matrix[2][ii]
end
end
for ii in 2..2
factor = matrix[ii][1]/matrix[1][1]
if matrix[ii][1] != 0
for jj in 1..3
matrix[ii][jj] = matrix[ii][jj] - matrix[1][jj]*factor
end
end
end
#step 3: set matrix[0][2], matrix[1][2] = 0
if matrix[2][2] == 0
puts "this formula cannot be solved!"
return
end
for ii in 0..1
factor = matrix[ii][2]/matrix[2][2]
if matrix[ii][2] != 0
for jj in 2..3
matrix[ii][jj] = matrix[ii][jj] - matrix[2][jj]*factor
end
end
end
#step 4: set matrix[0][1] = 0
for ii in 0..0
factor = matrix[ii][1]/matrix[1][1]
if matrix[ii][1] != 0
for jj in [1, 3]
matrix[ii][jj] = matrix[ii][jj] - matrix[1][jj]*factor
end
end
end
#step 5: set [0][0]=1, [1][1]=1, [2][2]=1
for ii in 0..2
matrix[ii][3] = matrix[ii][3]/matrix[ii][ii]
matrix[ii][ii] = 1.0
end
matrix
end
end
测试代码:test.rb
require_relative "formula-solver"
matrix = [[1, 113.9231311, 22.5034716], [1, 113.95313110000001, 22.5034716], [1, 113.95313110000001, 22.533471600000002]]
#res = [113.93454840179, 113.96456293154, 113.96454575759]
res = [113.93454840179, 113.96454575759, 113.96454575759]
puts FormulaSolver.new.findAnswer(matrix, res)
matrix = [[1, 113.9231311, 22.5034716], [1, 113.95313110000001, 22.5034716], [1, 113.95313110000001, 22.533471600000002]]
#res = [22.506156406299, 22.506279984718, 22.536277316988]
res = [22.506279984718, 22.506279984718, 22.536277316988]
puts FormulaSolver.new.findAnswer(matrix, res)
运行ruby test.rb得到输出:(略)