lib/polynomials/analyzable.rb in polynomials-0.4.3 vs lib/polynomials/analyzable.rb in polynomials-0.4.4
- old
+ new
@@ -2,14 +2,17 @@
module Analyzable
AfterExtremaCurvatureMapping = { maximum: :right, minimum: :left }
MinimumOrMaximum = {[1.0,-1.0] => :maximum,[-1.0,1.0] => :minimum}
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 }
+ points = self.roots.map(&:x) | self.local_extrema.map(&:x)
+ return nil if points.empty?
+ points.minmax.zip([-1,1])
+ .map do |point,direction|
+ sign = self.(point + direction).sign
+ Extremum.new(Infinity * direction, sign * Infinity, sign < 0 ? :minimum : :maximum)
+ end
end
def inflection_points
self.derivative.local_extrema.map { |p| InflectionPoint.new(p.x,self.calculate(p.x)) }.to_set
end
@@ -26,30 +29,25 @@
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}
+ 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
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
+ strives_for = derivative.strives_for
+ return nil if !strives_for
- ([[-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
+ delimiter = [strives_for[0]] | derivative.local_extrema.to_a | [strives_for[1]]
+ delimiter.sort.each_cons(2).group_by do |b,_|
+ AfterExtremaCurvatureMapping[b.kind_of_extremum]
+ end.tap { |h| h.values.each { |a| a.each { |r| r.map!(&:x) }}}
end
end
end