Module: Polynomials::Analyzable

Included in:
Polynomial
Defined in:
lib/polynomials/analyzable.rb

Constant Summary collapse

AfterExtremaCurvatureMapping =
{ maximum: :right, minimum: :left }
MinimumOrMaximum =
{[1.0,-1.0] => :maximum,[-1.0,1.0] => :minimum}

Instance Method Summary collapse

Instance Method Details

#curvature_behaviourObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/polynomials/analyzable.rb', line 38

def curvature_behaviour
  hash = Hash.new {|h,k|h[k]=[]}

  dd = self.derivative.derivative
  return nil if !(strives_for = derivative.strives_for) || dd.(dd.roots.sort.last.to_f + 1) == 0

  ([[-Infinity,strives_for[0]]] + derivative.local_extrema.sort + [[Infinity,strives_for[-1]]]).each_cons(2).chunk do |b,_|
    if b.is_a? Point
      AfterExtremaCurvatureMapping[b.kind_of_extremum]
    else
      b.last < 0 ? :left : :right
    end
  end.with_index.inject(hash) do |hash,((curvature,values),i)|
    hash.tap { |h| h[curvature].concat values.each {|a| a.map! { |p| (p.is_a? Point) ? p.x : p.first }}}
  end
end

#inflection_pointsObject



13
14
15
# File 'lib/polynomials/analyzable.rb', line 13

def inflection_points
  self.derivative.local_extrema.map { |p| InflectionPoint.new(p.x,self.calculate(p.x)) }.to_set
end

#local_extremaObject



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/polynomials/analyzable.rb', line 17

def local_extrema
  derivative = self.derivative
  possible_extrema = derivative.roots.sort.map(&:x)

  return Set[] if possible_extrema.empty?

  samples = possible_extrema.sort.each_cons(2).map do |before,after|
    (before + after)/2
  end

  samples.unshift possible_extrema.first - 1
  samples.push possible_extrema.last + 1

  possible_extrema.zip(samples.each_cons(2)).inject(Set[]) do |set,(pe,sample)|
    directions = sample.map { |x| derivative.(x).sign}
    kind_of_extremum = MinimumOrMaximum[directions]
    next set unless kind_of_extremum
    set <<  Extremum.new(pe,self.calculate(pe), kind_of_extremum)
  end
end

#strives_forObject



6
7
8
9
10
11
# File 'lib/polynomials/analyzable.rb', line 6

def strives_for
  roots = self.roots.map(&:x)
  local_extrema = self.local_extrema.map(&:x)
  return nil if roots.empty? && local_extrema.empty?
  [self.((roots.min || local_extrema.min) - 1).sign, self.((roots.max || local_extrema.max) + 1).sign].map { |d| d * Infinity }
end