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