spliner 1.0.2 → 1.0.3
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/.travis.yml +4 -0
- data/README.markdown +12 -8
- data/lib/spliner.rb +1 -1
- data/lib/spliner/spliner.rb +83 -11
- data/spec/spliner_spec.rb +21 -0
- metadata +63 -67
data/.travis.yml
CHANGED
data/README.markdown
CHANGED
@@ -22,23 +22,27 @@ Quick Start
|
|
22
22
|
require 'spliner'
|
23
23
|
|
24
24
|
# Initialize a spline interpolation with x range 0.0..2.0
|
25
|
-
my_spline = Spliner::Spliner.new
|
25
|
+
my_spline = Spliner::Spliner.new [0.0, 1.0, 2.0], [0.0, 1.0, 2.0]
|
26
26
|
|
27
|
-
#
|
28
|
-
|
29
|
-
y_values = x_values.map {|x| my_spline[x] }
|
27
|
+
# Interpolate for a single value
|
28
|
+
y1 = my_spline[0.5]
|
30
29
|
|
30
|
+
# Perform interpolation on 11 values ranging from 0..2.0
|
31
|
+
y_values = my_spline[(0.0..2.0).step(0.1)]
|
32
|
+
|
33
|
+
# You may prefer to use the shortcut class method
|
34
|
+
y2 = Spliner::Spliner[[0.0, 1.0, 2.0], [0.0, 1.0, 0.5], 0.5]
|
31
35
|
|
32
36
|
# perform extrapolation outside key points using linear Y = aX + b
|
33
|
-
ex_spline = Spliner::Spliner.new
|
37
|
+
ex_spline = Spliner::Spliner.new [0.0, 1.0, 2.0], [0.0, 1.0, 2.0], :extrapolate => '10%'
|
34
38
|
xx = ex_spline[2.1] # returns 0.4124999999999999
|
35
39
|
|
36
40
|
# perform extrapolation outside key points using linear Y = aX + b
|
37
|
-
ex_spline = Spliner::Spliner.new
|
41
|
+
ex_spline = Spliner::Spliner.new [0.0, 1.0, 2.0], [0.0, 1.0, 2.0], :extrapolate => '10%', :emethod => :hold)
|
38
42
|
xx = ex_spline[2.1] # returns 0.5
|
39
43
|
|
40
|
-
# Alternative intialization using
|
41
|
-
ar_spline = Spliner::Spliner.new
|
44
|
+
# Alternative intialization using Hash
|
45
|
+
ar_spline = Spliner::Spliner.new({1.0 => 0.0, 2.0 => 3.0, 3.0 => 1.0})
|
42
46
|
|
43
47
|
# When duplicate X values are encountered, two or more discontinuous curves are used
|
44
48
|
two_spline = Spliner::Spliner.new [1.0, 2.0, 2.0, 3.0], [0.0, 3.0, 0.0, 1.0]
|
data/lib/spliner.rb
CHANGED
data/lib/spliner/spliner.rb
CHANGED
@@ -8,11 +8,19 @@ module Spliner
|
|
8
8
|
# == Example
|
9
9
|
#
|
10
10
|
# require 'spliner'
|
11
|
+
#
|
11
12
|
# # Initialize a spline interpolation with x range 0.0..2.0
|
12
13
|
# my_spline = Spliner::Spliner.new [0.0, 1.0, 2.0], [0.0, 1.0, 0.5]
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
14
|
+
#
|
15
|
+
# # Interpolate for a single value
|
16
|
+
# y1 = my_spline[0.5]
|
17
|
+
#
|
18
|
+
# # Perform interpolation on 11 values ranging from 0..2.0
|
19
|
+
# y_values = my_spline[(0.0..2.0).step(0.1)]
|
20
|
+
#
|
21
|
+
# # You may prefer to use the shortcut class method
|
22
|
+
# y2 = Spliner::Spliner[[0.0, 1.0, 2.0], [0.0, 1.0, 0.5], 0.5]
|
23
|
+
#
|
16
24
|
#
|
17
25
|
# Algorithm based on http://en.wikipedia.org/wiki/Spline_interpolation
|
18
26
|
#
|
@@ -80,6 +88,37 @@ module Spliner
|
|
80
88
|
@extrapolation_method = options[:emethod] || :linear
|
81
89
|
end
|
82
90
|
|
91
|
+
# shortcut method to instanciate a Spliner::Spliner object and
|
92
|
+
# return a series of interpolated values. Options are like
|
93
|
+
# Spliner::Spliner#initialize
|
94
|
+
#
|
95
|
+
# @overload interpolate(points, x, options)
|
96
|
+
# @param points [Hash{Float => Float}] keys are X values in increasing order, values Y
|
97
|
+
# @param x [Float,Vector,Enumerable(Float)] X value(s) to interpolate on
|
98
|
+
# @param options [Hash]
|
99
|
+
#
|
100
|
+
# @overload interpolate(key_x, key_y, x, options)
|
101
|
+
# @param key_x [Array(Float),Vector] the X values of the key points
|
102
|
+
# @param_key_y [Array(Float),Vector] the Y values of the key points
|
103
|
+
# @param x [Float,Vector,Enumerable(Float)] X value(s) to interpolate on
|
104
|
+
# @param options [Hash]
|
105
|
+
#
|
106
|
+
def self.interpolate(*args)
|
107
|
+
if (args.first.class == Hash)
|
108
|
+
key_points, x, options = args
|
109
|
+
s = Spliner.new key_points, (options || {})
|
110
|
+
s[x]
|
111
|
+
else
|
112
|
+
key_x, key_y, x, options = args
|
113
|
+
s = Spliner.new key_x, key_y, (options || {})
|
114
|
+
s[x]
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
class << self
|
119
|
+
alias :'[]' :interpolate
|
120
|
+
end
|
121
|
+
|
83
122
|
# returns the ranges at each slice between duplicate X values
|
84
123
|
def split_at_duplicates(x)
|
85
124
|
# find all indices with duplicate x values
|
@@ -89,15 +128,48 @@ module Spliner
|
|
89
128
|
private :split_at_duplicates
|
90
129
|
|
91
130
|
|
92
|
-
# returns
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
131
|
+
# returns the interpolated Y value(s) at the specified X
|
132
|
+
#
|
133
|
+
# @param x [Float,Vector,Enumerable(Float)] x
|
134
|
+
#
|
135
|
+
# == Example
|
136
|
+
#
|
137
|
+
# my_spline = Spliner::Spliner.new [0.0, 1.0, 2.0], [0.0, 1.0, 0.5]
|
138
|
+
# # get one value
|
139
|
+
# y1 = my_spline.get 0.5
|
140
|
+
# # get many values
|
141
|
+
# y2 = my_spline.get [0.5, 1.5, 2.5]
|
142
|
+
# y3 = my_spline.get 0.5, 1.5, 2.5
|
143
|
+
# # get a range of values
|
144
|
+
# y4 = my_spline.get 1..3
|
145
|
+
# # generate an enumeration of x values
|
146
|
+
# y5 = my_spline.get (1.5..2.5).step(0.5)
|
147
|
+
#
|
148
|
+
def get(*x)
|
149
|
+
xx = if x.size == 1
|
150
|
+
x.first
|
151
|
+
else
|
152
|
+
x
|
153
|
+
end
|
154
|
+
|
155
|
+
get_func = lambda do |v|
|
156
|
+
i = @sections.find_index {|section| section.range.member? v }
|
157
|
+
if i
|
158
|
+
@sections[i].get v
|
159
|
+
elsif range.member? v
|
160
|
+
extrapolate(v)
|
161
|
+
else
|
162
|
+
nil
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
case xx
|
167
|
+
when Vector
|
168
|
+
xx.collect {|x| get_func.call(x) }
|
169
|
+
when Enumerable
|
170
|
+
xx.map {|x| get_func.call(x) }
|
99
171
|
else
|
100
|
-
|
172
|
+
get_func.call(xx)
|
101
173
|
end
|
102
174
|
end
|
103
175
|
|
data/spec/spliner_spec.rb
CHANGED
@@ -2,6 +2,8 @@ require 'spliner'
|
|
2
2
|
|
3
3
|
describe Spliner::Spliner do
|
4
4
|
DATASET = {0.0 => 0.0, 1.0 => 1.0, 2.0 => 0.5}
|
5
|
+
DATASET_X = [0.0, 1.0, 2.0]
|
6
|
+
DATASET_Y = [0.0, 1.0, 0.5]
|
5
7
|
KEYS_0_100 = {0.0 => 0.0, 100.0 => 100.0}
|
6
8
|
|
7
9
|
|
@@ -109,4 +111,23 @@ describe Spliner::Spliner do
|
|
109
111
|
expect(s[3.5]).to be_within(0.0001).of(2.0)
|
110
112
|
expect(s[5.0]).to be_nil
|
111
113
|
end
|
114
|
+
|
115
|
+
it 'should accept an array or vector as index' do
|
116
|
+
s = Spliner::Spliner.new DATASET
|
117
|
+
expect(s[*DATASET.keys]).to eq(DATASET.values)
|
118
|
+
expect(s[DATASET.keys]).to eq(DATASET.values)
|
119
|
+
expect(s[Vector[*DATASET.keys]]).to eq(Vector[*DATASET.values])
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should accept an range/enumerator as index' do
|
123
|
+
s = Spliner::Spliner.new DATASET
|
124
|
+
expect(s[0..2]).to eq(DATASET.values)
|
125
|
+
expect(s[(0.0..2.0).step(1.0)]).to eq(DATASET.values)
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'supports the class shortcut method' do
|
129
|
+
expect(Spliner::Spliner[DATASET_X, DATASET_Y, 0..2]).to eq(DATASET.values)
|
130
|
+
expect(Spliner::Spliner::interpolate(DATASET, 0..2, :extrapolate => '5%')).to eq(DATASET.values)
|
131
|
+
end
|
132
|
+
|
112
133
|
end
|
metadata
CHANGED
@@ -1,89 +1,85 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: spliner
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.2
|
3
|
+
version: !ruby/object:Gem::Version
|
5
4
|
prerelease:
|
5
|
+
version: 1.0.3
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
8
|
-
- Tallak Tveide
|
7
|
+
authors:
|
8
|
+
- Tallak Tveide
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
|
-
requirements:
|
43
|
-
- - ~>
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: '0.9'
|
46
|
-
description: Simple library to perform cubic spline interpolation based on key X,Y
|
47
|
-
values
|
48
|
-
email:
|
49
|
-
- tallak@tveide.net
|
12
|
+
|
13
|
+
date: 2012-08-24 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rspec
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "2.11"
|
24
|
+
type: :development
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rake
|
28
|
+
prerelease: false
|
29
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
30
|
+
none: false
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: "0.9"
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id002
|
37
|
+
description: Simple library to perform cubic spline interpolation based on key X,Y values
|
38
|
+
email:
|
39
|
+
- tallak@tveide.net
|
50
40
|
executables: []
|
41
|
+
|
51
42
|
extensions: []
|
43
|
+
|
52
44
|
extra_rdoc_files: []
|
53
|
-
|
54
|
-
|
55
|
-
- .
|
56
|
-
-
|
57
|
-
-
|
58
|
-
-
|
59
|
-
-
|
60
|
-
- lib/spliner
|
61
|
-
- lib/spliner/
|
62
|
-
-
|
63
|
-
-
|
45
|
+
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- .travis.yml
|
49
|
+
- Gemfile
|
50
|
+
- README.markdown
|
51
|
+
- Rakefile
|
52
|
+
- lib/spliner.rb
|
53
|
+
- lib/spliner/spliner.rb
|
54
|
+
- lib/spliner/spliner_section.rb
|
55
|
+
- spec/spliner_spec.rb
|
56
|
+
- spliner.gemspec
|
64
57
|
homepage: http://www.github.com/tallakt/spliner
|
65
58
|
licenses: []
|
59
|
+
|
66
60
|
post_install_message:
|
67
61
|
rdoc_options: []
|
68
|
-
|
69
|
-
|
70
|
-
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
71
66
|
none: false
|
72
|
-
requirements:
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.9.1
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
72
|
none: false
|
78
|
-
requirements:
|
79
|
-
|
80
|
-
|
81
|
-
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: "0"
|
82
77
|
requirements: []
|
78
|
+
|
83
79
|
rubyforge_project: spliner
|
84
80
|
rubygems_version: 1.8.24
|
85
81
|
signing_key:
|
86
82
|
specification_version: 3
|
87
83
|
summary: Cubic spline interpolation library
|
88
84
|
test_files: []
|
89
|
-
|
85
|
+
|