lib/dydx/algebra/set.rb in dydx-0.1.314 vs lib/dydx/algebra/set.rb in dydx-0.1.412

- old
+ new

@@ -1,24 +1,32 @@ -require 'dydx/algebra/operator/parts' +require 'dydx/algebra/operator/parts/base' +require 'dydx/algebra/operator/parts/general' +require 'dydx/algebra/operator/parts/formula' +require 'dydx/algebra/operator/parts/inverse' +require 'dydx/algebra/operator/parts/num' + require 'dydx/algebra/operator/inverse' require 'dydx/algebra/operator/formula' require 'dydx/algebra/operator/num' require 'dydx/algebra/operator/general' +require 'dydx/algebra/formula' +require 'dydx/algebra/inverse' + module Dydx module Algebra module Set module Base include Helper # TODO: Pi should not have attr_accessor - def self.included(klass) + def self.included(_klass) attr_accessor :n, :x alias_method :d, :differentiate end - def initialize(x=nil) + def initialize(x = nil) case self when Num @n = x when Sin, Cos, Tan, Log, Log10, Log2 @x = x @@ -28,25 +36,25 @@ def to_s case self when Num then n.to_s when Pi then 'pi' when E then 'e' - when Sin then "sin( #{x.to_s} )" - when Cos then "cos( #{x.to_s} )" - when Tan then "tan( #{x.to_s} )" - when Log then "log( #{x.to_s} )" - when Log10 then "log10( #{x.to_s} )" - when Log2 then "log2( #{x.to_s} )" + when Sin then "sin( #{x} )" + when Cos then "cos( #{x} )" + when Tan then "tan( #{x} )" + when Log then "log( #{x} )" + when Log10 then "log10( #{x} )" + when Log2 then "log2( #{x} )" end end def to_f case self when Num then n.to_f when Pi then Math::PI when E then Math::E - when Symbol then raise ArgumentError + when Symbol then fail ArgumentError when Sin then Math.sin(x.to_f) when Cos then Math.cos(x.to_f) when Tan then Math.tan(x.to_f) when Log then Math.log(x.to_f) when Log10 then Math.log(x.to_f, 10) @@ -84,10 +92,16 @@ end class Num include Base include Operator::Num + %w(> >= < <=).each do |operator| + define_method(operator) do |x| + x = x.n if x.is_a?(Num) + n.send(operator, x) + end + end end class Pi include Base include Operator::General @@ -131,137 +145,65 @@ Symbol.class_eval do include Base include Operator::General end - # FIX: Numeric - Fixnum.class_eval do + numeric_proc = Proc.new do include Helper - def subst(hash = {}) + def subst(_hash = {}) self end - def differentiate(sym=:x) + def differentiate(_sym = :x) e0 end alias_method :d, :differentiate alias_method :addition, :+ alias_method :subtraction, :- alias_method :multiplication, :* alias_method :division, :/ alias_method :exponentiation, :** - ope_to_str = { - addition: :+, - subtraction: :-, - multiplication: :*, - division: :/, - exponentiation: :^ - } - %w(+ - * / ^).each do |operator| - define_method(operator) do |g| - if g.is_a?(Symbol) || - g.is_a?(Formula) || - g.is_a?(Base) + alias_method :modulation, :% - Num.new(self).send(operator.to_sym, g) - else - send(ope_to_str.key(operator.to_sym), g) - end - end - end - end - - Float.class_eval do - include Helper - - def subst(hash = {}) - self - end - - def differentiate(sym=:x) - e0 - end - alias_method :d, :differentiate - - alias_method :addition, :+ - alias_method :subtraction, :- - alias_method :multiplication, :* - alias_method :division, :/ - alias_method :exponentiation, :** ope_to_str = { addition: :+, subtraction: :-, multiplication: :*, division: :/, - exponentiation: :^ + exponentiation: :**, + modulation: :% } - %w(+ - * / ^).each do |operator| + %w(+ - * / ** %).each do |operator| define_method(operator) do |g| - if g.is_a?(Symbol) || - g.is_a?(Formula) || - g.is_a?(Base) - - Num.new(self).send(operator.to_sym, g) - else + if g.is_a?(Numeric) send(ope_to_str.key(operator.to_sym), g) + else + _(self).send(operator, g) end end end - end - - Rational.class_eval do - include Helper - - def subst(hash = {}) - self - end - - def differentiate(sym=:x) - e0 - end - alias_method :d, :differentiate - - alias_method :addition, :+ - alias_method :subtraction, :- - alias_method :multiplication, :* - alias_method :division, :/ - alias_method :exponentiation, :** - ope_to_str = { - addition: :+, - subtraction: :-, - multiplication: :*, - division: :/, - exponentiation: :^ - } - %w(+ - * / ^).each do |operator| - define_method(operator) do |g| - if g.is_a?(Symbol) || - g.is_a?(Formula) || - g.is_a?(Base) - - Num.new(self).send(operator.to_sym, g) - else - send(ope_to_str.key(operator.to_sym), g) - end + if self == Rational + def to_s + "( #{numerator} / #{denominator} )" end end end + Float.class_eval(&numeric_proc) + Fixnum.class_eval(&numeric_proc) + Rational.class_eval(&numeric_proc) + def e0 - eval("$e0 ||= Num.new(0)") + eval('$e0 ||= _(0)') end def e1 - eval("$e1 ||= Num.new(1)") + eval('$e1 ||= _(1)') end - def _(num) - Num.new(num) - end - def pi $pi ||= Pi.new end def e @@ -270,35 +212,36 @@ def oo Float::INFINITY end + # TODO: Method has too many lines. [13/10] def log(formula) - if formula.multiplication? + if formula.formula?(:*) f, g = formula.f, formula.g log(f) + log(g) - elsif formula.exponentiation? + elsif formula.formula?(:**) f, g = formula.f, formula.g g * log(f) - elsif formula.is_1? + elsif formula.one? e0 elsif formula.is_a?(E) e1 else Log.new(formula) end end def log2(formula) # TODO: refactor with log function. - if formula.multiplication? + if formula.formula?(:*) f, g = formula.f, formula.g log2(f) + log2(g) - elsif formula.exponentiation? + elsif formula.formula?(:**) f, g = formula.f, formula.g g * log2(f) - elsif formula.is_1? + elsif formula.one? e0 elsif formula.is_a?(Num) (formula.n == 2) ? e1 : log2(formula.n) elsif formula == 2 e1 @@ -307,43 +250,60 @@ end end def log10(formula) # TODO: refactor with log function. - if formula.multiplication? + if formula.formula?(:*) f, g = formula.f, formula.g log10(f) + log10(g) - elsif formula.exponentiation? + elsif formula.formula?(:**) f, g = formula.f, formula.g g * log10(f) - elsif formula.is_1? + elsif formula.one? e0 elsif formula.is_a?(Num) (formula.n == 10) ? e1 : log10(formula.n) elsif formula == 10 e1 else Log10.new(formula) end end + # TODO: We should negative num def sin(x) - multiplier = x.is_multiple_of(pi) - if multiplier.is_a?(Num) - e0 - else - Sin.new(x) + return Sin.new(x) unless x.multiple_of?(pi) && (x / pi).num? + + radn = (x / pi) + loop do + break if radn < 2 + radn -= 2 end + + case radn + when 0 then 0 + when _(1) / 2 then 1 + when 1 then 0 + when _(3) / 2 then -1 + else Sin.new(x) + end end def cos(x) - multiplier = x.is_multiple_of(pi) - if multiplier.is_a?(Num) && multiplier.n % 2 == 0 - e1 - elsif multiplier.is_a?(Num) && multiplier.n % 2 == 1 - _(-1) - else - Cos.new(x) + return Cos.new(x) unless x.multiple_of?(pi) && (x / pi).num? + + radn = (x / pi) + loop do + break if radn < 2 + radn -= 2 + end + + case radn + when 0 then 1 + when _(1) / 2 then 0 + when 1 then -1 + when _(3) / 2 then 0 + else Cos.new(x) end end def tan(x) if x == 0