Method: Spliner::Spliner#initialize

Defined in:
lib/spliner/spliner.rb

#initialize(key_points, options) ⇒ Spliner #initialize(x, y, options) ⇒ Spliner

Creates a new Spliner::Spliner object to interpolate between the supplied key points.

The key points shoul be in increaing X order. When duplicate X values are encountered, the spline is split into two or more discontinuous sections.

The extrapolation method may be :linear by default, using a linear extrapolation at the curve ends using the curve derivative at the end points. The :hold method will use the Y value at the nearest end point of the curve.

Overloads:

  • #initialize(key_points, options) ⇒ Spliner

    Parameters:

    • key_points (Hash{Float => Float})

      keys are X values in increasing order, values Y

    • options (Hash)

    Options Hash (options):

    • :extrapolate (Range, String) — default: '0%'

      either a range or percentage, eg ‘10.0%’, or float 0.1

    • :emethod (Symbol) — default: :linear

      extrapolation method

    • :fix_invalid_x (Symbol) — default: false

      delete data points not in increasing order

  • #initialize(x, y, options) ⇒ Spliner

    Parameters:

    • x (Array(Float), Vector)

      the X values of the key points

    • y (Array(Float), Vector)

      the Y values of the key points

    • options (Hash)

    Options Hash (options):

    • :extrapolate (Range, String) — default: '0%'

      either a range or percentage, eg ‘10.0%’, or float 0.1

    • :emethod (Symbol) — default: :linear

      extrapolation method

    • :fix_invalid_x (Symbol) — default: false

      delete data points not in increasing order



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
102
103
104
105
106
# File 'lib/spliner/spliner.rb', line 57

def initialize(*param)
  # sort parameters from two alternative initializer signatures
  x, y = nil
  case param.first
  when Array, Vector
    xx,yy, options = param
    x = xx.to_a
    y = yy.to_a
  else
    points, options = param
    x = points.keys
    y = points.values
  end
  options ||= {}

  if options[:fix_invalid_x]
    begin
      size_at_start = x.size
      pp = Hash[x.zip y]
      to_delete = pp.keys.each_cons(2).select {|a,b| b < a}.map(&:last)
      to_delete.each {|k| pp.delete k }
      x = pp.keys
      y = pp.values
    end while x.size < size_at_start
  end

  @sections = split_at_duplicates(x).map {|slice| SplinerSection.new x[slice], y[slice] }

  # Handle extrapolation option parameter
  options[:extrapolate].tap do |ex|
    case ex
    when /^\d+(\.\d+)?\s?%$/
      percentage = ex[/\d+(\.\d+)?/].to_f
      span = x.last - x.first
      extra = span * percentage * 0.01
      @range = (x.first - extra)..(x.last + extra)
    when Range
      @range = ex
    when Float
      span = x.last - x.first
      extra = span * ex
      @range = (x.first - extra)..(x.last + extra)
    when nil
      @range = x.first..x.last
    else
      raise 'Unable to use extrapolation parameter'
    end
  end
  @extrapolation_method = options[:emethod] || :linear
end