spliner 1.0.5 → 1.0.6

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.
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  *.gem
2
2
  Gemfile.lock
3
+ .idea
@@ -1,4 +1,5 @@
1
1
  rvm:
2
+ - 2.0.0
2
3
  - 1.9.2
3
4
  - 1.9.3
4
5
  - jruby
data/Gemfile CHANGED
File without changes
File without changes
data/Rakefile CHANGED
File without changes
@@ -1,5 +1,5 @@
1
1
  require 'spliner/spliner'
2
2
 
3
3
  module Spliner
4
- VERSION = '1.0.5'
4
+ VERSION = '1.0.6'
5
5
  end
@@ -170,10 +170,10 @@ module Spliner
170
170
  end
171
171
 
172
172
  get_func = lambda do |v|
173
- i = @sections.find_index {|section| section.range.member? v }
173
+ i = @sections.find_index {|section| section.range.cover? v }
174
174
  if i
175
175
  @sections[i].get v
176
- elsif range.member? v
176
+ elsif range.cover? v
177
177
  extrapolate(v)
178
178
  else
179
179
  nil
@@ -24,10 +24,10 @@ module Spliner
24
24
 
25
25
  def calculate_a_k
26
26
  if @x.size > 1
27
- inv_diff = @x.each_cons(2).map {|x1, x2| 1 / (x2 - x1) }
27
+ inv_diff = @x.each_cons(2).map {|x1, x2| 1.0 / (x2 - x1) }
28
28
  a_diag = 2.0 * Matrix::diagonal(*vector_helper(inv_diff))
29
29
  a_non_diag = Matrix::build(@x.size) do |row, col|
30
- if row == col+ 1
30
+ if row == col + 1
31
31
  inv_diff[col]
32
32
  elsif col == row + 1
33
33
  inv_diff[row]
@@ -41,11 +41,16 @@ module Spliner
41
41
  tmp = @x.zip(@y).each_cons(2).map do |p1, p2|
42
42
  x1, y1 = p1
43
43
  x2, y2 = p2
44
- 3.0 * (y2 - y1) / (x2 - x1) ** 2.0
44
+ delta_x = (x2 - x1)
45
+ 3.0 * (y2 - y1) / (delta_x * delta_x)
45
46
  end
46
47
  b = vector_helper(tmp)
47
48
 
48
- @k = a.inv * b
49
+ if RUBY_VERSION < "1.9.3"
50
+ @k = a.inv * b
51
+ else
52
+ @k = a.lup_decomposition.solve b
53
+ end
49
54
  else
50
55
  @k = Vector[0.0]
51
56
  end
@@ -54,14 +59,19 @@ module Spliner
54
59
 
55
60
  # returns an interpolated value
56
61
  def get(v)
57
- i = @x_pairs.find_index {|pair| pair.member? v }
62
+ i = @x_pairs.find_index {|pair| pair.cover? v }
58
63
  if i
59
- dx = @x[i + 1] - @x[i]
60
- dy = @y[i + 1] - @y[i]
61
- t = (v - @x[i]) / dx
62
- a = @k[i] * dx - dy
63
- b = -(@k[i + 1] * dx - dy)
64
- (1 - t) * @y[i] + t * @y[i + 1] + t * (1 - t) * (a * (1 - t) + b * t)
64
+ x_pair = @x_pairs[i]
65
+ x_min = x_pair.min
66
+ dx = x_pair.max - x_min
67
+ y_max = @y[i + 1]
68
+ y_min = @y[i]
69
+ dy = y_max - y_min
70
+ t = (v - x_min) / dx
71
+ a = @k[i] * dx - dy
72
+ b = -@k[i + 1] * dx + dy
73
+ one_minus_t = 1 - t
74
+ t * y_max + one_minus_t * ( y_min + t * ( a * one_minus_t + b * t ) )
65
75
  elsif @x.size == 1 && @x.first == v
66
76
  @y.first
67
77
  else
@@ -6,6 +6,17 @@ describe Spliner::Spliner do
6
6
  DATASET_Y = [0.0, 1.0, 0.5]
7
7
  KEYS_0_100 = {0.0 => 0.0, 100.0 => 100.0}
8
8
 
9
+ before(:all) do
10
+ epsilon = nil
11
+ e = 1
12
+ while e + 1 > 1
13
+ epsilon = e
14
+ e *= 0.5
15
+ end
16
+
17
+ @two_epsilon = 2 * epsilon
18
+ end
19
+
9
20
 
10
21
  it 'should not accept x values that are not increasing' do
11
22
  expect(lambda { Spliner::Spliner.new [0.0, -1.0], [0.0, 1.0] }).to raise_exception
@@ -13,33 +24,33 @@ describe Spliner::Spliner do
13
24
 
14
25
  it 'should support key points with a single value' do
15
26
  s1 = Spliner::Spliner.new Hash[0.0, 0.0]
16
- expect(s1.get 0.0).to be_within(0.0001).of(0.0)
27
+ expect(s1.get 0.0).to be_within(@two_epsilon).of(0.0)
17
28
  expect(s1.get 1.5).to be_nil
18
29
 
19
30
  s2 = Spliner::Spliner.new Hash[0.0, 0.0], :extrapolate => -1..1
20
- expect(s2.get 0.0).to be_within(0.0001).of(0.0)
21
- expect(s2.get 0.5).to be_within(0.0001).of(0.0)
31
+ expect(s2.get 0.0).to be_within(@two_epsilon).of(0.0)
32
+ expect(s2.get 0.5).to be_within(@two_epsilon).of(0.0)
22
33
  end
23
34
 
24
35
  it 'supports the Hash initializer' do
25
36
  s1 = Spliner::Spliner.new Hash[0.0, 0.0, 1.0, 1.0]
26
- expect(s1[0.5]).to be_within(0.0001).of(0.5)
37
+ expect(s1[0.5]).to be_within(@two_epsilon).of(0.5)
27
38
 
28
39
  s2 = Spliner::Spliner.new Hash[0.0, 0.0, 1.0, 1.0], :extrapolate => '100%'
29
- expect(s2[0.5]).to be_within(0.0001).of(0.5)
30
- expect(s2.range.first).to be_within(0.0001).of(-1.0)
40
+ expect(s2[0.5]).to be_within(@two_epsilon).of(0.5)
41
+ expect(s2.range.first).to be_within(@two_epsilon).of(-1.0)
31
42
  end
32
43
 
33
44
  it 'supports the x-y array/vector initializer' do
34
45
  s1 = Spliner::Spliner.new [0.0, 1.0], [0.0, 1.0]
35
- expect(s1[0.5]).to be_within(0.0001).of(0.5)
46
+ expect(s1[0.5]).to be_within(@two_epsilon).of(0.5)
36
47
 
37
48
  s2= Spliner::Spliner.new [0.0, 1.0], [0.0, 1.0], :extrapolate => '100%'
38
- expect(s2[0.5]).to be_within(0.0001).of(0.5)
39
- expect(s2.range.first).to be_within(0.0001).of(-1.0)
49
+ expect(s2[0.5]).to be_within(@two_epsilon).of(0.5)
50
+ expect(s2.range.first).to be_within(@two_epsilon).of(-1.0)
40
51
 
41
52
  s3 = Spliner::Spliner.new Vector[0.0, 1.0], Vector[0.0, 1.0]
42
- expect(s3[0.5]).to be_within(0.0001).of(0.5)
53
+ expect(s3[0.5]).to be_within(@two_epsilon).of(0.5)
43
54
  end
44
55
 
45
56
  it 'should return the data points themselves' do
@@ -57,62 +68,62 @@ describe Spliner::Spliner do
57
68
 
58
69
  it 'should generate a smooth curve (predefined points)' do
59
70
  s = Spliner::Spliner.new DATASET
60
- expect(s.get(0.4)).to be_within(0.0001).of(0.5260)
61
- expect(s.get(0.8)).to be_within(0.0001).of(0.9080)
62
- expect(s.get(1.2)).to be_within(0.0001).of(1.0080)
63
- expect(s.get(1.6)).to be_within(0.0001).of(0.8260)
71
+ expect(s.get(0.4)).to be_within(@two_epsilon).of(0.5260)
72
+ expect(s.get(0.8)).to be_within(@two_epsilon).of(0.9080)
73
+ expect(s.get(1.2)).to be_within(@two_epsilon).of(1.0080)
74
+ expect(s.get(1.6)).to be_within(@two_epsilon).of(0.8260)
64
75
  end
65
76
 
66
77
  it 'should perform linear interpolation in the case of two data points' do
67
78
  s = Spliner::Spliner.new({0 => 0, 10.0 => 100.0})
68
- expect(s.get(3.0)).to be_within(0.0001).of(30.0)
79
+ expect(s.get(3.0)).to be_within(@two_epsilon).of(30.0)
69
80
  end
70
81
 
71
82
  it 'supports the [] operator (indexing like)' do
72
83
  s = Spliner::Spliner.new DATASET
73
84
  expect(s[-1]).to be_nil
74
- expect(s[0]).to be_within(0.0001).of(0.0)
85
+ expect(s[0]).to be_within(@two_epsilon).of(0.0)
75
86
  end
76
87
 
77
88
  it 'performs :linear extrapolation outside the data range when such is given' do
78
89
  s = Spliner::Spliner.new KEYS_0_100, :extrapolate => -200..200
79
90
  expect(s.get -110).not_to be_nil
80
- expect(s.get -150).to be_within(0.0001).of(-150)
81
- expect(s.get 150).to be_within(0.0001).of(150)
91
+ expect(s.get -150).to be_within(1e-13).of(-150)
92
+ expect(s.get 150).to be_within(1e-13).of(150)
82
93
  end
83
94
 
84
95
  it 'performs :hold extrapolation' do
85
96
  s = Spliner::Spliner.new KEYS_0_100, :extrapolate => -200..200, :emethod => :hold
86
- expect(s.get -150).to be_within(0.0001).of(0)
87
- expect(s.get 150).to be_within(0.0001).of(100)
97
+ expect(s.get -150).to be_within(@two_epsilon).of(0)
98
+ expect(s.get 150).to be_within(@two_epsilon).of(100)
88
99
  end
89
100
 
90
101
  it 'supports data ranges given as a string like "10%"' do
91
102
  s1 = Spliner::Spliner.new KEYS_0_100, :extrapolate => '10%'
92
- expect(s1.range.first).to be_within(0.0001).of(-10.0)
93
- expect(s1.range.last).to be_within(0.0001).of(110.0)
103
+ expect(s1.range.first).to be_within(@two_epsilon).of(-10.0)
104
+ expect(s1.range.last).to be_within(@two_epsilon).of(110.0)
94
105
 
95
106
  s2 = Spliner::Spliner.new KEYS_0_100, :extrapolate => '10.0%'
96
- expect(s2.range.first).to be_within(0.0001).of(-10.0)
97
- expect(s2.range.last).to be_within(0.0001).of(110.0)
107
+ expect(s2.range.first).to be_within(@two_epsilon).of(-10.0)
108
+ expect(s2.range.last).to be_within(@two_epsilon).of(110.0)
98
109
 
99
110
  s3 = Spliner::Spliner.new KEYS_0_100, :extrapolate => '10 %'
100
- expect(s3.range.first).to be_within(0.0001).of(-10.0)
101
- expect(s3.range.last).to be_within(0.0001).of(110.0)
111
+ expect(s3.range.first).to be_within(@two_epsilon).of(-10.0)
112
+ expect(s3.range.last).to be_within(@two_epsilon).of(110.0)
102
113
 
103
114
  s4 = Spliner::Spliner.new KEYS_0_100, :extrapolate => 0.1
104
- expect(s3.range.first).to be_within(0.0001).of(-10.0)
105
- expect(s3.range.last).to be_within(0.0001).of(110.0)
115
+ expect(s3.range.first).to be_within(@two_epsilon).of(-10.0)
116
+ expect(s3.range.last).to be_within(@two_epsilon).of(110.0)
106
117
  end
107
118
 
108
119
  it 'splits data points with duplicate X values into separate sections' do
109
120
  s = Spliner::Spliner.new [0.0, 1.0, 1.0, 2.0, 2.0, 3.0], [0.0, 0.0, 1.0, 1.0, 2.0, 2.0], :extrapolate => 3.0..4.0
110
121
  expect(s.sections).to eq(3)
111
122
  expect(s[-1.0]).to be_nil
112
- expect(s[0.5]).to be_within(0.0001).of(0.0)
113
- expect(s[1.5]).to be_within(0.0001).of(1.0)
114
- expect(s[2.5]).to be_within(0.0001).of(2.0)
115
- expect(s[3.5]).to be_within(0.0001).of(2.0)
123
+ expect(s[0.5]).to be_within(@two_epsilon).of(0.0)
124
+ expect(s[1.5]).to be_within(@two_epsilon).of(1.0)
125
+ expect(s[2.5]).to be_within(@two_epsilon).of(2.0)
126
+ expect(s[3.5]).to be_within(@two_epsilon).of(2.0)
116
127
  expect(s[5.0]).to be_nil
117
128
  end
118
129
 
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spliner
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-12 00:00:00.000000000 Z
12
+ date: 2013-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -81,9 +81,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  version: '0'
82
82
  requirements: []
83
83
  rubyforge_project: spliner
84
- rubygems_version: 1.8.24
84
+ rubygems_version: 1.8.23
85
85
  signing_key:
86
86
  specification_version: 3
87
87
  summary: Cubic spline interpolation library
88
- test_files: []
89
- has_rdoc:
88
+ test_files:
89
+ - spec/spliner_spec.rb