Skip to content

Instantly share code, notes, and snippets.

@aldente-hu
Last active December 25, 2020 02:14
Show Gist options
  • Save aldente-hu/2b5a03670e5a1e33a87d668347fb7ac9 to your computer and use it in GitHub Desktop.
Save aldente-hu/2b5a03670e5a1e33a87d668347fb7ac9 to your computer and use it in GitHub Desktop.
対数線形近似を用いて指数関数近似を行う
# Usage: ruby y_log_linear.rb datafile
# datafileはn行100列(決め打ち)のCSVファイル。1列目がx、それ以降の列が各セットのyの値。
# 結果は100行2列のCSV形式。1セットにつき1行で、1列目がaの値、2列目がbの値。
# 標準出力に出力するので、ファイルに保存するときはシェルのリダイレクトを使って下さい。
# Example. ruby y_log_linear.rb datafile > result
# return [a, b] where y ~ a*x + b with least square method
def linear(x_array, y_array)
n = x_array.size
sum_y = y_array.sum
sum_x = x_array.sum
sum_x2 = x_array.sum(0.0) { |x| x * x}
sum_xy = 0.0
n.times do |i|
sum_xy += x_array[i] * y_array[i]
end
denominator = n * sum_x2 - sum_x * sum_x
return [(n * sum_xy - sum_x * sum_y) / denominator, (sum_y * sum_x2 - sum_xy * sum_x) / denominator]
end
# return [a, b] where y ~ b * exp(a*x)
def y_log_linear(x_array, y_array)
a, b = linear(x_array, y_array.map { |y| Math.log(y)})
[a, Math.exp(b)]
end
if (ARGV.size == 0)
puts "Usage: ruby #{$0} datafile (> result)"
else
all_data = []
File.open(ARGV.first).each_line { |line|
unless line.strip.empty?
all_data << line.split(',').map { |value| value.to_f }
end
}
x_array = all_data.map { |array| array.first }
(1..100).each do |i|
y_array = all_data.map { |array| array[i]}
a, b = y_log_linear(x_array, y_array)
puts "#{a},#{b}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment