-
-
Save aldente-hu/2b5a03670e5a1e33a87d668347fb7ac9 to your computer and use it in GitHub Desktop.
対数線形近似を用いて指数関数近似を行う
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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