malge 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES +12 -3
- data/Gemfile +6 -5
- data/VERSION +1 -1
- data/lib/malge.rb +3 -0
- data/lib/malge/errorfittedfunction.rb +48 -2
- data/lib/malge/errorfittedfunction/aexpbx.rb +1 -1
- data/lib/malge/errorfittedfunction/aexpbx32.rb +8 -10
- data/lib/malge/errorfittedfunction/axinv.rb +1 -2
- data/lib/malge/errorfittedfunction/axinv2.rb +2 -2
- data/lib/malge/errorfittedfunction/axinv3.rb +2 -2
- data/lib/malge/errorfittedfunction/axinv32.rb +7 -8
- data/lib/malge/errorfittedfunction/axinv4.rb +33 -0
- data/lib/malge/leastsquare.rb +15 -15
- data/lib/malge/multivariablefunction.rb +106 -0
- data/lib/malge/simultaneousequations.rb +21 -6
- data/test/analyzeerror/scatter.dat +12 -0
- data/test/helper.rb +4 -4
- data/test/test_errorfittedfunction.rb +78 -21
- data/test/test_errorfittedfunction_aexpbx.rb +4 -3
- data/test/test_errorfittedfunction_aexpbx32.rb +10 -9
- data/test/test_errorfittedfunction_axinv.rb +6 -7
- data/test/test_errorfittedfunction_axinv2.rb +6 -54
- data/test/test_errorfittedfunction_axinv3.rb +7 -53
- data/test/test_errorfittedfunction_axinv32.rb +14 -12
- data/test/test_errorfittedfunction_axinv4.rb +50 -0
- data/test/test_leastsquare.rb +36 -36
- data/test/test_multivariablefunction.rb +264 -0
- data/test/test_simultaneousequations.rb +25 -25
- metadata +74 -35
- data/malge.gemspec +0 -78
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4ee499ce2d36b0655594c91a589d22e9eb19d704
|
4
|
+
data.tar.gz: 10599d6fb90300bde348a2409ecb163edf21bb0c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5edf025d2d35ecf31d3a9254762388b650261b2f68b5a9f0f7c66f091a083eaa034db8456461b23922323af51d91605fb6672e3f52c0504c55ae58837e9fa158
|
7
|
+
data.tar.gz: bc2d58afee1de8dac341eafdf3c7459f55a74f4319f5f17922668a8ed712265f5f5130d5139b705f7bc80faee83462aa7872af6204920c921caeff949156a86e
|
data/CHANGES
CHANGED
@@ -1,8 +1,17 @@
|
|
1
|
-
=
|
1
|
+
= malge changelog
|
2
2
|
|
3
|
-
== Master (for 0.0.
|
3
|
+
== Master (for 0.0.10)
|
4
4
|
|
5
|
-
== Version 0.0.
|
5
|
+
== Version 0.0.9 [2016-03-04] released
|
6
|
+
* Modify errorfittedfunction to ignore most strict pair at fitting.
|
7
|
+
* Malge::SimultaneousEquations::NotRegularError is added
|
8
|
+
* Malge::SimultaneousEquations::SizeMismatchError is added
|
9
|
+
* Malge::SimultaneousEquations::NotSquareError is added
|
10
|
+
|
11
|
+
== Version 0.0.8 [2013-03-18] released
|
12
|
+
* Small revision.
|
13
|
+
|
14
|
+
== Version 0.0.7
|
6
15
|
* Add Malge::ErrorFittedFunction::AXInv2
|
7
16
|
* Add Malge::ErrorFittedFunction::AXInv3
|
8
17
|
* Malge::ErrorFittedFunction may raise UnableCalculationError if contain not finit value in coefficients after fitting.
|
data/Gemfile
CHANGED
@@ -6,9 +6,10 @@ source "http://rubygems.org"
|
|
6
6
|
# Add dependencies to develop your gem here.
|
7
7
|
# Include everything needed to run rake, tests, features, etc.
|
8
8
|
group :development do
|
9
|
-
gem "
|
10
|
-
gem "
|
11
|
-
gem "
|
12
|
-
gem "
|
13
|
-
|
9
|
+
gem "test-unit", "~> 3.1"
|
10
|
+
gem "rdoc", "~> 4.2"
|
11
|
+
gem "bundler", "~> 1.11"
|
12
|
+
gem "jeweler", "~> 2.0"
|
13
|
+
gem "simplecov", "~> 0.11"
|
14
|
+
gem "builtinextension", ">= 0.1.3"
|
14
15
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/lib/malge.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Malge; end
|
2
2
|
|
3
|
+
require "float/equalindelta.rb"
|
3
4
|
require "malge/errorfittedfunction.rb"
|
4
5
|
require "malge/errorfittedfunction/aexpbx.rb"
|
5
6
|
require "malge/errorfittedfunction/aexpbx32.rb"
|
@@ -7,7 +8,9 @@ require "malge/errorfittedfunction/axinv.rb"
|
|
7
8
|
require "malge/errorfittedfunction/axinv32.rb"
|
8
9
|
require "malge/errorfittedfunction/axinv2.rb"
|
9
10
|
require "malge/errorfittedfunction/axinv3.rb"
|
11
|
+
require "malge/errorfittedfunction/axinv4.rb"
|
10
12
|
require "malge/leastsquare.rb"
|
11
13
|
require "malge/matrix.rb"
|
12
14
|
require "malge/simultaneousequations.rb"
|
13
15
|
require "malge/vector.rb"
|
16
|
+
require "malge/multivariablefunction.rb"
|
@@ -24,8 +24,13 @@ class Malge::ErrorFittedFunction
|
|
24
24
|
raise SizeMismatchError unless pair.size == 2
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
@
|
27
|
+
#@raw_pairs = data_pairs
|
28
|
+
@raw_pairs = data_pairs.sort_by{|xy| xy[0]}
|
29
|
+
most_strict_x = most_strict_pair[0]
|
30
|
+
tmp_pairs = Marshal.load(Marshal.dump( @raw_pairs))
|
31
|
+
tmp_pairs.delete_if {|pair| pair[0] == most_strict_x}
|
32
|
+
|
33
|
+
@diff_abs_pairs = tmp_pairs.map { |pair| [pair[0], (pair[1] - most_strict_pair[1]).abs] }
|
29
34
|
fit
|
30
35
|
|
31
36
|
@coefficients.each do |coef|
|
@@ -52,6 +57,7 @@ class Malge::ErrorFittedFunction
|
|
52
57
|
def variance
|
53
58
|
sum = 0.0
|
54
59
|
@diff_abs_pairs.each do |pair|
|
60
|
+
#pp pair
|
55
61
|
sum += (pair[1] - expected_error(pair[0]) )**2
|
56
62
|
end
|
57
63
|
sum
|
@@ -71,6 +77,46 @@ class Malge::ErrorFittedFunction
|
|
71
77
|
@raw_pairs.mix_by{ |pair| pair[0] }
|
72
78
|
end
|
73
79
|
|
80
|
+
# Compare expected error and @raw_pairs and
|
81
|
+
# return a count of estimations of [equal, over, under].
|
82
|
+
# (order is like as result of <=>. )
|
83
|
+
# Excluding last data.
|
84
|
+
def count_equal_under_over
|
85
|
+
results = [0,0,0]
|
86
|
+
@diff_abs_pairs.each do |x,y|
|
87
|
+
results[expected_error(x) <=> y ] += 1
|
88
|
+
end
|
89
|
+
results
|
90
|
+
end
|
91
|
+
|
92
|
+
def summary(io = $stdout)
|
93
|
+
io.puts "Fitted function: #{equation}"
|
94
|
+
io.printf("%15s, %15s, %15s, %15s\n",
|
95
|
+
"x",
|
96
|
+
"raw_y",
|
97
|
+
"|diff_y_best|",
|
98
|
+
"expected_error"
|
99
|
+
)
|
100
|
+
|
101
|
+
datalist = []
|
102
|
+
@raw_pairs.size.times do |i|
|
103
|
+
if i != (@raw_pairs.size - 1)
|
104
|
+
diff = sprintf("%15.10f", @diff_abs_pairs[i][1])
|
105
|
+
else
|
106
|
+
diff = '-'*12
|
107
|
+
end
|
108
|
+
|
109
|
+
datalist << sprintf("%15.10f, %15.10f, %15s, %15.10f\n",
|
110
|
+
@raw_pairs[i][0],
|
111
|
+
@raw_pairs[i][1],
|
112
|
+
diff,
|
113
|
+
expected_error(@raw_pairs[i][0])
|
114
|
+
)
|
115
|
+
end
|
116
|
+
io.puts datalist.sort.join
|
117
|
+
end
|
118
|
+
|
119
|
+
|
74
120
|
private
|
75
121
|
|
76
122
|
#Fit the data pairs to a certain function.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
#Assumed y = a[0] * exp(a[1] * (x
|
4
|
+
#Assumed y = a[0] * exp(a[1] * (x **{3/2}))
|
5
5
|
#
|
6
6
|
#NOTE: @coefficients[0] might become negative value.
|
7
7
|
# Need discussion for dealing?
|
@@ -19,19 +19,19 @@ class Malge::ErrorFittedFunction::AExpBX32 < Malge::ErrorFittedFunction
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def equation
|
22
|
-
sprintf("
|
22
|
+
sprintf("%f \* exp(%f \* x**(3.0/2.0))", * @coefficients)
|
23
23
|
end
|
24
24
|
|
25
25
|
def expected_error(x)
|
26
26
|
@coefficients[0] * Math::exp( @coefficients[1] * x **(3.0/2.0))
|
27
27
|
end
|
28
28
|
|
29
|
-
#y = a[0] * exp(a[1] *x
|
30
|
-
#a[0] * exp(a[1] *x
|
31
|
-
#exp(a[1] *x
|
32
|
-
#a[1] *x
|
33
|
-
#x
|
34
|
-
#x = (log( y/a[0])/a[1])
|
29
|
+
#y = a[0] * exp(a[1] *x**(3/2))
|
30
|
+
#a[0] * exp(a[1] *x**(3/2)) = y
|
31
|
+
#exp(a[1] *x**(3/2)) = y/a[0]
|
32
|
+
#a[1] *x**(3/2) = log( y/a[0])
|
33
|
+
#x**(3/2) = log( y/a[0])/a[1]
|
34
|
+
#x = (log( y/a[0])/a[1])**(2/3)
|
35
35
|
def x(y)
|
36
36
|
return (Math::log( y / @coefficients[0])/@coefficients[1]) **(2.0/3.0)
|
37
37
|
end
|
@@ -40,7 +40,5 @@ class Malge::ErrorFittedFunction::AExpBX32 < Malge::ErrorFittedFunction
|
|
40
40
|
@raw_pairs.max_by{ |pair| pair[0] }
|
41
41
|
end
|
42
42
|
|
43
|
-
|
44
43
|
end
|
45
44
|
|
46
|
-
|
@@ -7,13 +7,12 @@ class Malge::ErrorFittedFunction::AXInv < Malge::ErrorFittedFunction
|
|
7
7
|
|
8
8
|
def fit
|
9
9
|
inv_pairs = Marshal.load(Marshal.dump(@diff_abs_pairs))
|
10
|
-
#inv_pairs.delete([most_strict_x, 0.0])
|
11
10
|
inv_pairs.map! {|pair| [1.0/pair[0], pair[1]]}
|
12
11
|
@coefficients = Malge::LeastSquare.least_square_proportional(inv_pairs)
|
13
12
|
end
|
14
13
|
|
15
14
|
def equation
|
16
|
-
sprintf("
|
15
|
+
sprintf("%f / x", * @coefficients)
|
17
16
|
end
|
18
17
|
|
19
18
|
def expected_error(x)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
#Assumed y = a[0] /(x
|
4
|
+
#Assumed y = a[0] /(x**2)
|
5
5
|
#
|
6
6
|
class Malge::ErrorFittedFunction::AXInv2 < Malge::ErrorFittedFunction
|
7
7
|
|
@@ -11,7 +11,7 @@ class Malge::ErrorFittedFunction::AXInv2 < Malge::ErrorFittedFunction
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def equation
|
14
|
-
sprintf("
|
14
|
+
sprintf("%f / (x**2)", * @coefficients)
|
15
15
|
end
|
16
16
|
|
17
17
|
def expected_error(x)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
#Assumed y = a[0]/(x
|
4
|
+
#Assumed y = a[0]/(x**3)
|
5
5
|
#
|
6
6
|
class Malge::ErrorFittedFunction::AXInv3 < Malge::ErrorFittedFunction
|
7
7
|
|
@@ -11,7 +11,7 @@ class Malge::ErrorFittedFunction::AXInv3 < Malge::ErrorFittedFunction
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def equation
|
14
|
-
sprintf("
|
14
|
+
sprintf("%f / (x**3)", * @coefficients)
|
15
15
|
end
|
16
16
|
|
17
17
|
def expected_error(x)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
# coding: utf-8
|
3
3
|
|
4
|
-
#Assumed y = a[0] /x
|
4
|
+
#Assumed y = a[0] /x**{3/2}
|
5
5
|
#
|
6
6
|
#NOTE: @coefficients[0] might become negative value.
|
7
7
|
# Need discussion for dealing?
|
@@ -13,18 +13,18 @@ class Malge::ErrorFittedFunction::AXInv32 < Malge::ErrorFittedFunction
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def equation
|
16
|
-
sprintf("
|
16
|
+
sprintf("%f / (x**(3.0/2.0))", * @coefficients)
|
17
17
|
end
|
18
18
|
|
19
19
|
def expected_error(x)
|
20
20
|
@coefficients[0] /(x** (3.0/2.0))
|
21
21
|
end
|
22
22
|
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#x
|
26
|
-
#
|
27
|
-
#
|
23
|
+
# y = a[0]/x**{3/2}
|
24
|
+
# y = a[0]/x**{3/2}
|
25
|
+
#x**{3/2} y = a[0]
|
26
|
+
# x**{3/2} = a[0]/y
|
27
|
+
# x = (a[0]/y)**{2/3}
|
28
28
|
def x(y)
|
29
29
|
return (@coefficients[0] / y ) ** (2.0/3.0)
|
30
30
|
end
|
@@ -33,6 +33,5 @@ class Malge::ErrorFittedFunction::AXInv32 < Malge::ErrorFittedFunction
|
|
33
33
|
@raw_pairs.max_by{ |pair| pair[0] }
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
36
|
end
|
38
37
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#Assumed y = a[0]/(x**4)
|
5
|
+
#
|
6
|
+
class Malge::ErrorFittedFunction::AXInv4 < Malge::ErrorFittedFunction
|
7
|
+
|
8
|
+
def fit
|
9
|
+
inv_pairs = @diff_abs_pairs.map {|pair| [1.0/(pair[0]**4), pair[1]]}
|
10
|
+
@coefficients = Malge::LeastSquare.least_square_proportional(inv_pairs)
|
11
|
+
end
|
12
|
+
|
13
|
+
def equation
|
14
|
+
sprintf("%f / (x**4)", * @coefficients)
|
15
|
+
end
|
16
|
+
|
17
|
+
def expected_error(x)
|
18
|
+
@coefficients[0] / (x**4)
|
19
|
+
end
|
20
|
+
|
21
|
+
#y = a/x
|
22
|
+
#x = a/y
|
23
|
+
def x(y)
|
24
|
+
return (@coefficients[0] / y) ** (1.0/4.0)
|
25
|
+
end
|
26
|
+
|
27
|
+
def most_strict_pair
|
28
|
+
@raw_pairs.max_by{ |pair| pair[0] }
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
33
|
+
|
data/lib/malge/leastsquare.rb
CHANGED
@@ -10,11 +10,11 @@ module Malge::LeastSquare
|
|
10
10
|
|
11
11
|
#Return values of [a_0, a_1] in y = a_0 x^0 + a_1 x^1.
|
12
12
|
#Argument 'data_pairs' should be Array of Array's. For example,
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
13
|
+
# [
|
14
|
+
# [ 1.0, 2.0],
|
15
|
+
# [ 2.0, 4.0],
|
16
|
+
# [ 3.0, 6.0],
|
17
|
+
# ]
|
18
18
|
#Note that not [a, b] in y = ax + b.
|
19
19
|
def self.least_square_1st_degree(data_pairs)
|
20
20
|
a = 0.0 #x^2
|
@@ -52,11 +52,11 @@ module Malge::LeastSquare
|
|
52
52
|
|
53
53
|
#Return variance when fitted to y = a_0 x^0 + a_1 x^1.
|
54
54
|
#Argument 'data_pairs' should be Array of Array's. For example,
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
55
|
+
# [
|
56
|
+
# [ 1.0, 2.0],
|
57
|
+
# [ 2.0, 4.0],
|
58
|
+
# [ 3.0, 6.0],
|
59
|
+
# ]
|
60
60
|
def self.variance_1st_degree(data_pairs)
|
61
61
|
coefficients = self.least_square_1st_degree(data_pairs)
|
62
62
|
data_pairs.inject(0.0) do |sum, pair|
|
@@ -83,11 +83,11 @@ module Malge::LeastSquare
|
|
83
83
|
|
84
84
|
#Return fitted values of [a, b] in a e^{bx} from more than two data points.
|
85
85
|
#Argument 'data_pairs' should be Array of Array's. For example,
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
86
|
+
# [
|
87
|
+
# [ 1.0, 2.0],
|
88
|
+
# [ 2.0, 4.0],
|
89
|
+
# [ 3.0, 6.0],
|
90
|
+
# ]
|
91
91
|
def self.least_square_a_exp_bx(data_pairs)
|
92
92
|
data_pairs.each do |pair|
|
93
93
|
raise UnableCalculationError if pair[1] == 0.0
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
|
4
|
+
#
|
5
|
+
#
|
6
|
+
#
|
7
|
+
class Malge::MultiVariableFunction
|
8
|
+
attr_reader :data
|
9
|
+
|
10
|
+
TOLERANCE = 1E-10
|
11
|
+
|
12
|
+
# data example:
|
13
|
+
# [
|
14
|
+
# {x => 0.0, y => 0.1, z => 0.0},
|
15
|
+
# {x => 1.0, y => 1.1, z => 1.0},
|
16
|
+
# {x => 2.0, y => 2.1, z => 3.0},
|
17
|
+
# ]
|
18
|
+
#
|
19
|
+
def initialize(data)
|
20
|
+
@data = data
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return array of data which matches the hash.
|
24
|
+
def abstract!(conditions)
|
25
|
+
results = @data.select do |coords|
|
26
|
+
match_condition?(coords, conditions)
|
27
|
+
end
|
28
|
+
@data = results
|
29
|
+
end
|
30
|
+
|
31
|
+
def abstract(conditions)
|
32
|
+
result = Marshal.load(Marshal.dump(self))
|
33
|
+
result.abstract!(conditions)
|
34
|
+
result
|
35
|
+
end
|
36
|
+
|
37
|
+
# unite axes with the same value.
|
38
|
+
# keys : [:a, :b]
|
39
|
+
# new_key : default is keys[0]
|
40
|
+
def unite_axes!(keys, new_key = nil)
|
41
|
+
new_key ||= keys[0]
|
42
|
+
results = []
|
43
|
+
@data.each do |datum|
|
44
|
+
new_datum = Marshal.load(Marshal.dump(datum))
|
45
|
+
if same?(new_datum, keys)
|
46
|
+
val = new_datum[keys[0]]
|
47
|
+
keys.each {|key| new_datum.delete(key) }
|
48
|
+
new_datum[new_key] = val
|
49
|
+
results << new_datum
|
50
|
+
end
|
51
|
+
end
|
52
|
+
@data = results
|
53
|
+
end
|
54
|
+
|
55
|
+
def unite_axes(keys, new_key = nil)
|
56
|
+
result = Marshal.load(Marshal.dump(self))
|
57
|
+
result.unite_axes!(keys, new_key)
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
def delete_axis!(axis)
|
62
|
+
@data.each do |datum|
|
63
|
+
datum.delete axis
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def delete_axis(axis)
|
68
|
+
result = Marshal.load(Marshal.dump(self))
|
69
|
+
result.delete_axis!(axis)
|
70
|
+
result
|
71
|
+
end
|
72
|
+
|
73
|
+
# return 2-dimensional array.
|
74
|
+
# [
|
75
|
+
# [x0, y0],
|
76
|
+
# [x1, y1],
|
77
|
+
# :
|
78
|
+
# ]
|
79
|
+
def data_pairs(key0, key1)
|
80
|
+
results = []
|
81
|
+
@data.each do |datum|
|
82
|
+
results << [datum[key0], datum[key1]]
|
83
|
+
end
|
84
|
+
results
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
#if when the same value among keys, return true.
|
90
|
+
#if not, return false.
|
91
|
+
def same?(datum, keys, tolerance = TOLERANCE)
|
92
|
+
ref = datum[keys[0]]
|
93
|
+
keys.each do |key|
|
94
|
+
return false unless ref.to_f.equal_in_delta?(datum[key].to_f, tolerance)
|
95
|
+
end
|
96
|
+
return true
|
97
|
+
end
|
98
|
+
|
99
|
+
def match_condition?(datum, conditions)
|
100
|
+
conditions.each do |key, val|
|
101
|
+
return false unless datum[key] == val
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|