lib/dydx/algebra/operator/parts/formula.rb in dydx-0.0.4 vs lib/dydx/algebra/operator/parts/formula.rb in dydx-0.0.5

- old
+ new

@@ -1,63 +1,97 @@ module Dydx module Algebra module Operator module Parts module Formula - %w(+ -).map(&:to_sym).each do |operator| + %w(+ *).map(&:to_sym).each do |operator| define_method(operator) do |x| - if multiplication? && x.multiplication? - if f == x.f - f * g.send(operator, x.g) - elsif g == x.g - f.send(operator, x.f) * g + if self.operator == operator + if f.combinable?(x, operator) + f.send(operator, x).send(operator, g) + elsif g.combinable?(x, operator) + g.send(operator, x).send(operator, f) else super(x) end - elsif ([self.operator, operator].sort == [:+, :-]) && include?(x) - if f == x - g - elsif g == x - f + elsif operator == :+ + if multiplication? && x.multiplication? + if f == x.f + f * g.send(operator, x.g) + elsif f == x.g + f * g.send(operator, x.f) + elsif g == x.f + f.send(operator, x.g) * g + elsif g == x.g + f.send(operator, x.f) * g + else + super(x) + end + # expect(((:b * :a) - (:c * :a)).to_s).to eq('( ( b - c ) * a )') + elsif multiplication? && x.subtrahend? && x.x.multiplication? + if f == x.x.f + f * g.send(operator, inverse(x.x.g, :+)) + elsif f == x.x.g + f * g.send(operator, inverse(x.x.f, :+)) + elsif g == x.x.f + f.send(operator, inverse(x.x.g, :+)) * g + elsif g == x.x.g + f.send(operator, inverse(x.x.f, :+)) * g + else + super(x) + end + else + super(x) end - elsif (self.operator == operator) && include?(x) - if f == x - f.send(operator, x).send(operator, g) - elsif g == x - f.send(operator, g.send(:+, x)) + elsif operator == :* + if exponentiation? && x.exponentiation? + if f == x.f + f ^ g.send(:+, x.g) + elsif g == x.g + f.send(operator, x.f) ^ g + else + super(x) + end + elsif exponentiation? && x.divisor? && x.x.exponentiation? + if f == x.x.f + f ^ g.send(:-, x.x.g) + elsif g == x.x.g + f.send(:/, x.x.f) ^ g + else + super(x) + end + # x * inverse(:y, :+) + elsif x.subtrahend? + inverse(self * x.x, :+) + elsif multiplication? + if f.combinable?(x, operator) + f.send(operator, x).send(operator, g) + elsif g.combinable?(x, operator) + g.send(operator, x).send(operator, f) + else + super(x) + end + else + super(x) end - else - super(x) end end end - %w(* /).map(&:to_sym).each do |operator| - define_method(operator) do |x| - if exponentiation? && x.exponentiation? - if f == x.f - f ^ g.send({'*'=>'+', '/'=>'-'}[operator.to_s], x.g) - elsif g == x.g - f.send(operator, x.f) ^ g - else - super(x) - end - elsif ([self.operator, operator].sort == [:*, :/]) && include?(x) - if f == x - g - elsif g == x - f - end - elsif (self.operator == operator) && include?(x) - if f == x - f.send(operator, x).send(operator, g) - elsif g == x - f.send(operator, g.send(:* , x)) - end - else - super(x) - end + def ^(x) + if multiplication? && openable?(x) + (f ^ x).send(self.operator, (g ^ x)) + else + super(x) end + end + + def to_str(operator) + { + addition: :+, + multiplication: :*, + exponentiation: :^ + }.key(operator) end end end end end