lib/polynomials.rb in polynomials-0.1.7 vs lib/polynomials.rb in polynomials-0.2.0
- old
+ new
@@ -17,31 +17,36 @@
polynomial.terms[parsed.exponent].coefficient += parsed.coefficient
end
return polynomial
end
- def initialize
+ def initialize(*args)
self.terms = Hash.new { |hash, key| hash[key] = Term.new(key) }
+ unless args.empty?
+ args.reverse.each.with_index do |coefficient,exponent|
+ self.terms[exponent].coefficient += coefficient
+ end
+ end
end
def calculate(x)
self.terms.values.inject(0.0) do |acc,t|
acc + (t.coefficient.to_f * (x**t.exponent))
end
end
def derivative
- new_function = self.alter do |nf, term|
- nf.terms[term.exponent - 1].coefficient += term.exponent * term.coefficient
- end
- new_function.terms.reject! { |_,t| t.coefficient == 0 }
+ new_function = self.alter do |nf, term|
+ nf.terms[term.exponent - 1].coefficient += term.exponent * term.coefficient
+ end
+ new_function.terms.reject! { |_,t| t.coefficient == 0 }
return new_function
end
def roots
if !terms.empty? and terms.keys.none?(&:zero?)
- self.alter { |nf, term| nf.terms[term.exponent-1].coefficient = term.coefficient }.roots << 0.0
+ self.alter { |nf, term| nf.terms[term.exponent-self.lt.exponent].coefficient = term.coefficient }.roots << 0.0
else
case self.degree
when 1
Set[-self.terms[0].coefficient / self.terms[1].coefficient]
when 2
@@ -65,69 +70,76 @@
(before + after)/2
end
possible_extrema.zip(samples.each_cons(2)).each do |pe,(after,before)|
yafter = derivative.calculate(after)
- ybefore = derivative.calculate(before)
- kind_of_extremum = NegPosMinMaxExtremumMapping[[yafter/yafter.abs,ybefore/ybefore.abs]]
- max_min_extremum[kind_of_extremum] << pe if kind_of_extremum
+ ybefore = derivative.calculate(before)
+ kind_of_extremum = NegPosMinMaxExtremumMapping[[yafter/yafter.abs,ybefore/ybefore.abs]]
+ max_min_extremum[kind_of_extremum] << pe if kind_of_extremum
end
end
return max_min_extremum
end
def curvature_behaviour
hash = Hash.new {|h,k|h[k]=Set.new}
+ return hash if self.degree > 5
extrema = self.derivative.extrema
- extrema.values.inject(Set[],&:|).sort.each_cons(2).inject(hash) do |curvature_behaviour,(start_point,end_point)|
- kind_of_curvature = AfterextremaCurvatureMapping[extrema.find { |k,v| v.include?(start_point) }.first]
- curvature_behaviour[kind_of_curvature] << Range.new(start_point,end_point)
- curvature_behaviour
+ all_extremas = extrema.values.inject(Set[],&:|).sort
+ all_extremas.each_cons(2).map { |s,e| Range.new(s,e) }.group_by do |range|
+ kind_of_curvature = AfterextremaCurvatureMapping[extrema.find { |k,v| v.include?(range.begin) }.first]
end
end
def degree
self.terms.keys.max || 0
end
def to_s
- terms.delete_if { |_,t| t.coefficient.zero? }.sort_by { |_,t| -t.exponent }.inject("") do |string,(_,term)|
- string << term.to_s
- end.strip
+ terms.sort_by { |_,t| -t.exponent }.inject("") do |string,(_,term)|
+ string << term.to_s unless term.coefficient.zero? && !term.exponent.zero?
+ string
+ end.strip.sub(/\A\+\s/, '')
end
def ==(other)
delete_zeros = proc{ |_,t| t.coefficient.zero? }
self.terms.delete_if(&delete_zeros) == other.terms.delete_if(&delete_zeros)
end
def extrema
extrema = local_extrema
- a = self.terms[self.degree].coefficient
unless self.degree == 0
- max_or_min = (self.degree.even? ? [1,1] : [-1,1]).map { |n| (n * a)/a.abs }
+ a = self.gt.coefficient
+ max_or_min = (self.degree.even? ? [1.0,1.0] : [-1.0,1.0]).map { |n| (n * a)/a.abs }
extrema[MinMaxMapping[max_or_min.first]] << -1.0/0
extrema[MinMaxMapping[max_or_min.last]] << 1.0/0
end
return extrema
end
- private
+ def gt
+ self.terms[self.degree]
+ end
+ def lt
+ self.terms[self.terms.min_by{ |_,t| t.exponent}.first]
+ end
+
def coefficients_till(n)
coefficients = []
(0..n).each do |e|
coefficients << self.terms[e].coefficient
end
return coefficients.reverse
end
+ private :coefficients_till
- protected
-
def alter
new_function = self.class.new
self.terms.values.each do |term|
yield new_function, term
end
return new_function
end
+ protected :alter
end