Class: Music::Performance::PiecewiseFunction
- Inherits:
-
Object
- Object
- Music::Performance::PiecewiseFunction
- Defined in:
- lib/music-performance/util/piecewise_function.rb
Overview
Combine functions that are each applicable for a non-overlapping domain.
Instance Attribute Summary collapse
-
#pieces ⇒ Object
readonly
Returns the value of attribute pieces.
Instance Method Summary collapse
-
#add_piece(domain, func) ⇒ Object
Add a function piece, which covers the given domain (includes domain start but not the end).
- #add_points(prev_point, point) ⇒ Object
-
#eval(x) ⇒ Object
Evaluate the piecewise function by finding a function piece whose domain includes the given independent value.
-
#initialize(points = []) ⇒ PiecewiseFunction
constructor
Take an array of points (each point is a two-element array pair) and create a piecewise function to calculate values in-between.
Constructor Details
#initialize(points = []) ⇒ PiecewiseFunction
Take an array of points (each point is a two-element array pair) and create a piecewise function to calculate values in-between.
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
# File 'lib/music-performance/util/piecewise_function.rb', line 12 def initialize points = [] @pieces = { } points = points.sort_by {|p| p[0]} if points.count > 1 if points.is_a?(Hash) points = points.to_a end for i in 1...points.count add_points points[i-1], points[i] end end end |
Instance Attribute Details
#pieces ⇒ Object (readonly)
Returns the value of attribute pieces.
8 9 10 |
# File 'lib/music-performance/util/piecewise_function.rb', line 8 def pieces @pieces end |
Instance Method Details
#add_piece(domain, func) ⇒ Object
Add a function piece, which covers the given domain (includes domain start but not the end).
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/music-performance/util/piecewise_function.rb', line 44 def add_piece domain, func raise ArgumentError, "domain is not a Range" if !domain.is_a? Range raise ArgumentError, "func is not a Proc" if !func.is_a? Proc contains_domain_completely = @pieces.select { |d,f| d.include?(domain.begin) && d.include?(domain.end) } if contains_domain_completely.any? contains_domain_completely.each do |d,f| l = d.begin...domain.begin if d.exclude_end? r = domain.end...d.end else r = domain.end..d.end end @pieces.delete d if domain.begin != d.begin @pieces[l] = f end if domain.end == d.end @pieces[domain.begin..domain.end] = func else @pieces[domain.begin...domain.end] = func @pieces[r] = f end end else delete_completely = @pieces.select { |d,f| domain.include?(d.begin) && domain.include?(d.end) } delete_completely.each do |d,f| @pieces.delete d end # should only be one move_end = @pieces.select { |d,f| domain.include?(d.end) } move_end.each do |d,f| @pieces.delete d @pieces[d.begin...domain.begin] = f end # should only be one move_begin = @pieces.select { |d,f| domain.include?(d.begin) } move_begin.each do |d,f| @pieces.delete d if d.exclude_end? @pieces[domain.end...d.end] = f else @pieces[domain.end..d.end] = f end end if move_begin.any? @pieces[domain.begin...domain.end] = func else @pieces[domain] = func end end end |
#add_points(prev_point, point) ⇒ Object
28 29 30 31 32 33 34 35 36 |
# File 'lib/music-performance/util/piecewise_function.rb', line 28 def add_points prev_point, point domain = prev_point[0]..point[0] func = lambda do |x| perc = (x - domain.min).to_f / (domain.max - domain.min) y = Interpolation.linear prev_point[1], point[1], perc return y end add_piece(domain, func) end |
#eval(x) ⇒ Object
Evaluate the piecewise function by finding a function piece whose domain includes the given independent value.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/music-performance/util/piecewise_function.rb', line 105 def eval x y = nil @pieces.each do |domain, func| if domain.include? x y = func.call x break end end if y.nil? raise ArgumentError, "The input #{x} is not in the domain." end return y end |