Class: Dydx::Algebra::Formula

Inherits:
Object
  • Object
show all
Includes:
Operator::Formula, Helper
Defined in:
lib/dydx/algebra.rb,
lib/dydx/algebra/formula.rb

Constant Summary

Constants included from Helper

Helper::INVERSE_OPE_RELATION, Helper::SUPER_OPE_RELATION

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Helper

#combinable?, #distributable?, #distributive?, #formula?, #inverse?, #like_term?, #minus1?, #multiple_of?, #negative?, #num?, #one?, #rest, #to_numeric, #zero?

Constructor Details

#initialize(operator, *terms) ⇒ Formula

Returns a new instance of Formula.



7
8
9
10
# File 'lib/dydx/algebra/formula.rb', line 7

def initialize(operator, *terms)
  @operator, @terms = operator, terms
  commutate! if (terms[1].num? && operator.commutative?)
end

Instance Attribute Details

#operatorObject

Returns the value of attribute operator.



5
6
7
# File 'lib/dydx/algebra/formula.rb', line 5

def operator
  @operator
end

#termsObject

Returns the value of attribute terms.



5
6
7
# File 'lib/dydx/algebra/formula.rb', line 5

def terms
  @terms
end

Instance Method Details

#==(x) ⇒ Object



96
97
98
99
100
101
102
103
104
# File 'lib/dydx/algebra/formula.rb', line 96

def ==(x)
  if to_s == x.to_s
    true
  else
    result = commutate!.to_s == x.to_s
    commutate!
    result
  end
end

#commutate!Object



106
107
108
109
# File 'lib/dydx/algebra/formula.rb', line 106

def commutate!
  @terms.reverse!
  self
end

#delete(tm) ⇒ Object



115
116
117
118
# File 'lib/dydx/algebra/formula.rb', line 115

def delete(tm)
  tms.delete(tm)
  tms.count.one? ? tms.first : self
end

#differentiate(sym = :x) ⇒ Object Also known as: d

TODO: Cylomatic complexity for differentiate is too high. [7/6]



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/dydx/algebra/formula.rb', line 33

def differentiate(sym = :x)

  case @operator
  when :+ then f.d(sym) + g.d(sym)
  when :* then (f.d(sym) * g) + (f * g.d(sym))
  when :**
    # TODO:
    if g.num?
      f.d(sym) * g * (f ** (g - 1))
    elsif (f == sym) && (
        g.num? || (
          g.is_a?(Symbol) && g != sym
        )
      )
      g * f ** (g - 1)
    elsif f == e
      g.d(sym) * self
    else
      self * (g * log(f)).d(sym)
    end
  end
end

#fObject



12
13
14
# File 'lib/dydx/algebra/formula.rb', line 12

def f
  @terms[0]
end

#f=(x) ⇒ Object



20
21
22
# File 'lib/dydx/algebra/formula.rb', line 20

def f=(x)
  @terms[0] = x
end

#gObject



16
17
18
# File 'lib/dydx/algebra/formula.rb', line 16

def g
  @terms[1]
end

#g=(x) ⇒ Object



24
25
26
# File 'lib/dydx/algebra/formula.rb', line 24

def g=(x)
  @terms[1] = x
end

#include?(x) ⇒ Boolean

Returns:

  • (Boolean)


83
84
85
# File 'lib/dydx/algebra/formula.rb', line 83

def include?(x)
  f == x || g == x
end

#index(tm) ⇒ Object



111
112
113
# File 'lib/dydx/algebra/formula.rb', line 111

def index(tm)
  tms.index(tm)
end

#openable?(operator, x) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
90
# File 'lib/dydx/algebra/formula.rb', line 87

def openable?(operator, x)
  distributive?(self.operator, operator) &&
  (f.combinable?(x, operator) || g.combinable?(x, operator))
end

#rationalsObject



92
93
94
# File 'lib/dydx/algebra/formula.rb', line 92

def rationals
  [f, g].select{ |term| term.num? && term.n.is_a?(Rational) }
end

#subst(hash = {}) ⇒ Object



75
76
77
# File 'lib/dydx/algebra/formula.rb', line 75

def subst(hash = {})
  f.subst(hash).send(operator, g.subst(hash))
end

#tmsObject



28
29
30
# File 'lib/dydx/algebra/formula.rb', line 28

def tms
  terms
end

#to_fObject



79
80
81
# File 'lib/dydx/algebra/formula.rb', line 79

def to_f
  f.to_f.send(operator, g.to_f)
end

#to_sObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/dydx/algebra/formula.rb', line 57

def to_s
  str = if formula?(:*) && (f.minus1? || g.minus1?)
    "( - #{g} )"
  elsif g.inverse?(operator)
    "( #{f} #{operator.inv} #{g.x} )"
  elsif f.inverse?(operator)
    "( #{g} #{operator.inv} #{f.x} )"
  elsif f.negative?
    "( #{g} - #{f.n.abs} )"
  elsif formula?(:*) && !rationals.empty?
    terms = [f, g]
    terms.delete(rationals.first)
    "( #{(terms.first * rationals.first.n.numerator)} / #{rationals.first.n.denominator} )"
  else
    "( #{f} #{operator} #{g} )"
  end
end