Skip to content

Instantly share code, notes, and snippets.

@komasaru
Last active December 22, 2017 05:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save komasaru/9202158 to your computer and use it in GitHub Desktop.
Save komasaru/9202158 to your computer and use it in GitHub Desktop.
Ruby script to solve approximate equation with least squares method.
#! /usr/local/bin/ruby
# ***************************************
# 最小二乗法
# ***************************************
#
class LeastSquaresMethod
N, M = 7, 5 # データ数, 予測曲線の次数
X = [-3, -2, -1, 0, 1, 2, 3] # 測定データ x
Y = [ 5, -2, -3, -1, 1, 4, 5] # 測定データ y
def initialize
# a, s, t データ
@a = Array.new(M + 1).map{ Array.new(M + 2, 0.0) }
@s = Array.new(2 * M + 1, 0.0)
@t = Array.new(M + 1, 0.0)
end
# 実行
def exec
# s, t 計算
calc_st
# a に s, t 代入
ins_st
# 掃き出し
sweap_out
# y 値計算&結果出力
display
end
private
# s, t 計算
def calc_st
N.times do |i|
(2 * M + 1).times { |j| @s[j] += (X[i] ** j) }
(M + 1).times { |j| @t[j] += (X[i] ** j) * Y[i] }
end
rescue => e
raise
end
# a に s, t 代入
def ins_st
(M + 1).times do |i|
(M + 1).times { |j| @a[i][j] = @s[i + j] }
@a[i][M + 1] = @t[i]
end
rescue => e
raise
end
# 掃き出し
def sweap_out
(M + 1).times do |k|
p = @a[k][k]
k.upto(M + 1) { |j| @a[k][j] /= p }
(M + 1).times do |i|
unless i == k
d = @a[i][k]
k.upto(M + 1) { |j| @a[i][j] -= d * @a[k][j] }
end
end
end
rescue => e
raise
end
# y 値計算&結果出力
def display
(M + 1).times { |k| puts "a%d = %10.6f" % [k, @a[k][M + 1]] }
puts " x y"
-3.step(3, 0.5) do |px|
p = 0
(M + 1).times { |k| p += @a[k][M + 1] * (px ** k) }
puts "%5.1f%5.1f" % [px, p]
end
rescue => e
raise
end
end
exit 0 unless __FILE__ == $0
begin
# インスタンス化&実行
LeastSquaresMethod.new.exec
rescue => e
$stderr.puts "[#{e.class}] #{e.message}"
e.backtrace.each{ |tr| $stderr.puts "\t#{tr}" }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment