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