diff --git a/lib/ruby_algebra/expression.rb b/lib/ruby_algebra/expression.rb index 542ec5c..44a0258 100644 --- a/lib/ruby_algebra/expression.rb +++ b/lib/ruby_algebra/expression.rb @@ -17,6 +17,9 @@ module RubyAlgebra def op_assoc_type raise NotImplementedError end + def diff(v) + raise NotImplementedError, "#{self.class}#diff not implemented" + end end class Addition < Expression @@ -47,6 +50,9 @@ module RubyAlgebra def op_assoc_type :left end + def diff(v) + Addition.new(@lhs.diff(v), @rhs.diff(v)) + end end class Subtraction < Addition @@ -63,6 +69,9 @@ module RubyAlgebra def type :sub end + def diff(v) + Subtraction.new(@lhs.diff(v), @rhs.diff(v)) + end end class Multiplication < Expression @@ -105,6 +114,13 @@ module RubyAlgebra def op_assoc_type :left end + def diff(v) + u_prime = @lhs.diff(v) + v_prime = @rhs.diff(v) + term1 = Multiplication.new(u_prime, @rhs) + term2 = Multiplication.new(@lhs, v_prime) + Addition.new(term1, term2) + end end class Division < Multiplication @@ -119,6 +135,17 @@ module RubyAlgebra def type :div end + def diff(v) + u_prime = @lhs.diff(v) + v_prime = @rhs.diff(v) + + numerator = Subtraction.new( + Multiplication.new(u_prime, @rhs), + Multiplication.new(@lhs, v_prime) + ) + denominator = Power.new(@rhs, Constant.new(2)) + Division.new(numerator, denominator) + end end class Power < Expression @@ -149,6 +176,18 @@ module RubyAlgebra def op_assoc_type :right end + def diff(v) + unless @exponent.is_a?(Constant) + raise NotImplementedError, "Дифференцирование степени с неконстантным показателем не реализовано" + end + + n = @exponent.value + # (u^n)' = n * u^(n-1) * u' + base_diff = @base.diff(v) + new_power = Power.new(@base, Constant.new(n - 1)) + coeff = Constant.new(n) + Multiplication.new(coeff, Multiplication.new(new_power, base_diff)) + end end class Constant < Expression @@ -173,6 +212,9 @@ module RubyAlgebra def op_assoc_type nil end + def diff(v) + Constant.new(0) + end end class Variable < Expression @@ -202,5 +244,8 @@ module RubyAlgebra def single_letter? @is_single_letter end + def diff(v) + @symbol == v ? Constant.new(1) : Constant.new(0) + end end end