dydx 0.1.4 → 0.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -3
  3. data/README.md +124 -61
  4. data/Rakefile +8 -5
  5. data/dydx.gemspec +13 -13
  6. data/lib/dydx.rb +25 -23
  7. data/lib/dydx/algebra.rb +76 -8
  8. data/lib/dydx/algebra/formula.rb +38 -71
  9. data/lib/dydx/algebra/inverse.rb +12 -19
  10. data/lib/dydx/algebra/operator/common_parts.rb +3 -0
  11. data/lib/dydx/algebra/operator/formula.rb +4 -0
  12. data/lib/dydx/algebra/operator/general.rb +4 -0
  13. data/lib/dydx/algebra/operator/inverse.rb +4 -0
  14. data/lib/dydx/algebra/operator/num.rb +4 -0
  15. data/lib/dydx/algebra/operator/parts/base.rb +2 -2
  16. data/lib/dydx/algebra/operator/parts/formula.rb +38 -63
  17. data/lib/dydx/algebra/operator/parts/general.rb +31 -84
  18. data/lib/dydx/algebra/operator/parts/interface.rb +22 -0
  19. data/lib/dydx/algebra/operator/parts/inverse.rb +4 -4
  20. data/lib/dydx/algebra/operator/parts/num.rb +11 -16
  21. data/lib/dydx/algebra/operator/parts/symbol.rb +2 -2
  22. data/lib/dydx/algebra/operator/symbol.rb +15 -0
  23. data/lib/dydx/algebra/set.rb +34 -271
  24. data/lib/dydx/algebra/set/base.rb +9 -0
  25. data/lib/dydx/algebra/set/cos.rb +22 -0
  26. data/lib/dydx/algebra/set/e.rb +16 -0
  27. data/lib/dydx/algebra/set/fixnum.rb +14 -0
  28. data/lib/dydx/algebra/set/float.rb +14 -0
  29. data/lib/dydx/algebra/set/log.rb +22 -0
  30. data/lib/dydx/algebra/set/num.rb +26 -0
  31. data/lib/dydx/algebra/set/pi.rb +16 -0
  32. data/lib/dydx/algebra/set/sin.rb +21 -0
  33. data/lib/dydx/algebra/set/symbol.rb +14 -0
  34. data/lib/dydx/algebra/set/tan.rb +17 -0
  35. data/lib/dydx/delta.rb +1 -1
  36. data/lib/dydx/function.rb +1 -1
  37. data/lib/dydx/helper.rb +61 -55
  38. data/lib/dydx/integrand.rb +10 -22
  39. data/lib/dydx/version.rb +1 -1
  40. data/spec/dydx_spec.rb +29 -10
  41. data/spec/lib/algebra/formula_spec.rb +38 -44
  42. data/spec/lib/algebra/operator/parts/base_spec.rb +5 -5
  43. data/spec/lib/algebra/operator/parts/formula_spec.rb +50 -57
  44. data/spec/lib/algebra/operator/parts/inverse_spec.rb +8 -8
  45. data/spec/lib/algebra/set/cos_spec.rb +18 -0
  46. data/spec/lib/algebra/set/e_spec.rb +27 -0
  47. data/spec/lib/algebra/set/fixnum_spec.rb +65 -0
  48. data/spec/lib/algebra/set/float_spec.rb +65 -0
  49. data/spec/lib/algebra/set/log_spec.rb +15 -0
  50. data/spec/lib/algebra/set/num_spec.rb +23 -0
  51. data/spec/lib/algebra/set/pi_spec.rb +25 -0
  52. data/spec/lib/algebra/set/sin_spec.rb +14 -0
  53. data/spec/lib/algebra/set/symbol_spec.rb +22 -0
  54. data/spec/lib/algebra/set/tan_spec.rb +13 -0
  55. data/spec/lib/delta_spec.rb +8 -32
  56. data/spec/lib/function_spec.rb +34 -60
  57. data/spec/lib/helper_spec.rb +49 -47
  58. data/spec/lib/integrand_spec.rb +15 -13
  59. data/spec/spec_helper.rb +1 -2
  60. metadata +39 -9
  61. data/.pryrc +0 -2
  62. data/.rubocop.yml +0 -25
  63. data/spec/lib/algebra/set_spec.rb +0 -263
@@ -2,44 +2,24 @@ module Dydx
2
2
  module Algebra
3
3
  class Formula
4
4
  include Helper
5
- attr_accessor :operator, :terms
5
+ attr_accessor :f, :operator, :g
6
6
 
7
- def initialize(operator, *terms)
8
- @operator, @terms = operator, terms
9
- commutate! if (terms[1].num? && operator.commutative?)
7
+ def initialize(f, g, operator)
8
+ @f, @g, @operator = f, g, operator
10
9
  end
11
10
 
12
- def f
13
- @terms[0]
14
- end
15
-
16
- def g
17
- @terms[1]
18
- end
19
-
20
- def f=(x)
21
- @terms[0] = x
22
- end
23
-
24
- def g=(x)
25
- @terms[1] = x
26
- end
27
-
28
- def trs
29
- terms
30
- end
31
-
32
- # TODO: Cylomatic complexity for differentiate is too high. [7/6]
33
- def differentiate(sym = :x)
11
+ def differentiate(sym=:x)
34
12
  case @operator
35
- when :+ then f.d(sym) + g.d(sym)
36
- when :* then (f.d(sym) * g) + (f * g.d(sym))
37
- when :**
13
+ when :+
14
+ f.d(sym) + g.d(sym)
15
+ when :*
16
+ (f.d(sym) * g) + (f * g.d(sym))
17
+ when :^
38
18
  # TODO:
39
- if g.num?
40
- f.d(sym) * g * (f ** (g - 1))
19
+ if g.is_num?
20
+ f.d(sym) * g * (f ^ (g - 1) )
41
21
  elsif f == sym
42
- g * (f ** (g - 1))
22
+ g * (f ^ (g - 1))
43
23
  elsif f == e
44
24
  g.d(sym) * self
45
25
  else
@@ -50,29 +30,21 @@ module Dydx
50
30
  alias_method :d, :differentiate
51
31
 
52
32
  def to_s
53
- if formula?(:*) && (f.minus1? || g.minus1?)
54
- "( - #{g} )"
55
- elsif g.inverse?(operator)
56
- "( #{f} #{operator.inv} #{g.x} )"
57
- elsif f.inverse?(operator)
58
- "( #{g} #{operator.inv} #{f.x} )"
59
- elsif formula?(:*) && !rationals.empty?
60
- terms = [f, g]
61
- terms.delete(rationals.first)
62
- "( #{(terms.first * rationals.first.n.numerator)} / #{rationals.first.n.denominator} )"
33
+ if (multiplication? && (f.is_minus1? || g.is_minus1?) )
34
+ "( - #{g.to_s} )"
35
+ elsif multiplication? && g.inverse?(:*)
36
+ "( #{f.to_s} / #{g.x.to_s} )"
37
+ elsif multiplication? && f.inverse?(:*)
38
+ "( #{g.to_s} / #{f.x.to_s} )"
39
+ elsif addition? && g.inverse?(:+)
40
+ "( #{f.to_s} - #{g.x.to_s} )"
41
+ elsif addition? && f.inverse?(:+)
42
+ "( #{g.to_s} - #{f.x.to_s} )"
63
43
  else
64
- "( #{f} #{operator} #{g} )"
44
+ "( #{f.to_s} #{@operator} #{g.to_s} )"
65
45
  end
66
46
  end
67
47
 
68
- def subst(hash = {})
69
- f.subst(hash).send(operator, g.subst(hash))
70
- end
71
-
72
- def to_f
73
- f.to_f.send(operator, g.to_f)
74
- end
75
-
76
48
  def include?(x)
77
49
  f == x || g == x
78
50
  end
@@ -82,33 +54,28 @@ module Dydx
82
54
  (f.combinable?(x, operator) || g.combinable?(x, operator))
83
55
  end
84
56
 
85
- def rationals
86
- [f, g].select{ |term| term.num? && term.n.is_a?(Rational) }
87
- end
88
-
57
+ # TODO: interchangeable
89
58
  def ==(x)
90
- if to_s == x.to_s
91
- true
92
- else
93
- result = commutate!.to_s == x.to_s
94
- commutate!
95
- result
59
+ to_s == x.to_s
60
+ end
61
+
62
+ def common_factors(formula)
63
+ nil unless formula.is_a?(Formula)
64
+ if f == formula.f
65
+ [:f, :f]
66
+ elsif g == formula.g
67
+ [:g, :g]
68
+ elsif f == formula.g
69
+ [:f, :g]
70
+ elsif g == formula.f
71
+ [:g, :f]
96
72
  end
97
73
  end
98
74
 
99
75
  def commutate!
100
- @terms.reverse!
76
+ @f, @g = @g, @f
101
77
  self
102
78
  end
103
-
104
- def index(tr)
105
- trs.index(tr)
106
- end
107
-
108
- def delete(tr)
109
- trs.delete(tr)
110
- trs.count.one? ? trs.first : self
111
- end
112
79
  end
113
80
  end
114
81
  end
@@ -9,35 +9,28 @@ module Dydx
9
9
  end
10
10
 
11
11
  def to_s
12
+ # sym = {'*'=>'/', '+'=>'-'}[operator.to_s]
12
13
  case operator
13
- when :+ then "( - #{x} )"
14
- when :* then "( 1 / #{x} )"
15
- end
16
- end
17
-
18
- def subst(hash = {})
19
- case operator
20
- when :+ then x.subst(hash) * -1
21
- when :* then x.subst(hash) ** -1
22
- end
23
- end
24
-
25
- def to_f
26
- case operator
27
- when :+ then x.to_f * -1
28
- when :* then x.to_f ** -1
14
+ when :+
15
+ "( - #{x} )"
16
+ when :*
17
+ "( 1 / #{x} )"
29
18
  end
30
19
  end
31
20
 
32
- def differentiate(sym = :x)
21
+ def differentiate(sym=:x)
33
22
  case operator
34
23
  when :+
35
24
  inverse(x.differentiate(sym), :+)
36
25
  when :*
37
- inverse(x.differentiate(sym) * inverse(x ** 2, :*), :+)
26
+ inverse(x.differentiate(sym) * inverse(x ^ 2, :*), :+)
38
27
  end
39
28
  end
40
29
  alias_method :d, :differentiate
30
+
31
+ def ==(x)
32
+ to_s == x.to_s
33
+ end
41
34
  end
42
35
  end
43
- end
36
+ end
@@ -0,0 +1,3 @@
1
+ require 'dydx/algebra/operator/parts/base'
2
+ require 'dydx/algebra/operator/parts/general'
3
+ require 'dydx/algebra/operator/parts/interface'
@@ -1,3 +1,6 @@
1
+ require 'dydx/algebra/operator/common_parts'
2
+ require 'dydx/algebra/operator/parts/formula'
3
+
1
4
  module Dydx
2
5
  module Algebra
3
6
  module Operator
@@ -5,6 +8,7 @@ module Dydx
5
8
  include Parts::Base
6
9
  include Parts::Formula
7
10
  include Parts::General
11
+ include Parts::Interface
8
12
  end
9
13
  end
10
14
  end
@@ -1,9 +1,13 @@
1
+ require 'dydx/algebra/operator/common_parts'
2
+ require 'dydx/algebra/operator/parts/general'
3
+
1
4
  module Dydx
2
5
  module Algebra
3
6
  module Operator
4
7
  module General
5
8
  include Parts::Base
6
9
  include Parts::General
10
+ include Parts::Interface
7
11
  end
8
12
  end
9
13
  end
@@ -1,3 +1,6 @@
1
+ require 'dydx/algebra/operator/common_parts'
2
+ require 'dydx/algebra/operator/parts/inverse'
3
+
1
4
  module Dydx
2
5
  module Algebra
3
6
  module Operator
@@ -5,6 +8,7 @@ module Dydx
5
8
  include Parts::Base
6
9
  include Parts::Inverse
7
10
  include Parts::General
11
+ include Parts::Interface
8
12
  end
9
13
  end
10
14
  end
@@ -1,3 +1,6 @@
1
+ require 'dydx/algebra/operator/common_parts'
2
+ require 'dydx/algebra/operator/parts/num'
3
+
1
4
  module Dydx
2
5
  module Algebra
3
6
  module Operator
@@ -5,6 +8,7 @@ module Dydx
5
8
  include Parts::Base
6
9
  include Parts::Num
7
10
  include Parts::General
11
+ include Parts::Interface
8
12
  end
9
13
  end
10
14
  end
@@ -3,9 +3,9 @@ module Dydx
3
3
  module Operator
4
4
  module Parts
5
5
  module Base
6
- %w(+ * **).map(&:to_sym).each do |operator|
6
+ %w(+ * ^).map(&:to_sym).each do |operator|
7
7
  define_method(operator) do |x|
8
- ::Algebra::Formula.new(operator.to_sym, self, x)
8
+ ::Algebra::Formula.new(self, x, operator.to_sym)
9
9
  end
10
10
  end
11
11
  end
@@ -3,82 +3,57 @@ module Dydx
3
3
  module Operator
4
4
  module Parts
5
5
  module Formula
6
- %w(+ *).map(&:to_sym).each do |op|
7
- define_method(op) do |rtr|
8
- if self.operator == op
9
- if f.combinable?(rtr, op)
10
- _(
11
- _(trs[0], op, rtr), op, trs[1]
12
- )
13
- elsif g.combinable?(rtr, op)
14
- _(
15
- _(trs[1], op, rtr), op, trs[0]
16
- )
6
+ %w(+ *).map(&:to_sym).each do |operator|
7
+ define_method(operator) do |x|
8
+ if self.operator == operator
9
+ if f.combinable?(x, operator)
10
+ f.send(operator, x).send(operator, g)
11
+ elsif g.combinable?(x, operator)
12
+ g.send(operator, x).send(operator, f)
17
13
  else
18
- super(rtr)
14
+ super(x)
19
15
  end
20
- elsif formula?(op.sub) && openable?(op, rtr)
21
- _(
22
- _(trs[0], op, rtr), op.sub, _(trs[1], op, rtr)
23
- )
24
- elsif formula?(op.super) && rtr.formula?(op.super)
25
- cmn_fct = (trs & rtr.trs).first
26
- return super(rtr) unless cmn_fct
16
+ elsif formula?(super_ope(operator)) && x.formula?(super_ope(operator))
17
+ w1, w2 = common_factors(x)
18
+ return super(x) unless (w1 && w2) && (super_ope(operator).commutative? || w1 == w2)
27
19
 
28
- if op.super.commutative?
29
- _(
30
- cmn_fct, op.super, _(delete(cmn_fct), op, rtr.delete(cmn_fct))
31
- )
32
- else
33
- return super(rtr) if index(cmn_fct) != rtr.index(cmn_fct)
34
-
35
- case index(cmn_fct)
36
- when 0
37
- _(
38
- cmn_fct, op.super, _(delete(cmn_fct), op.sub, rtr.delete(cmn_fct))
39
- )
40
- when 1
41
- _(
42
- _(delete(cmn_fct), op, rtr.delete(cmn_fct)), op.super, cmn_fct
43
- )
20
+ case operator
21
+ when :+
22
+ send(w1).send(super_ope(operator), send(rest(w1)).send(operator, x.send(rest(w2))))
23
+ when :*
24
+ case w1
25
+ when :f
26
+ send(w1).send(super_ope(operator), send(rest(w1)).send(sub_ope(operator), x.send(rest(w2))))
27
+ when :g
28
+ send(w1).send(super_ope(operator), send(rest(w1)).send(operator, x.send(rest(w2)))).commutate!
44
29
  end
45
30
  end
46
- elsif formula?(op.super) && rtr.inverse?(op) && rtr.x.formula?(op.super)
47
- cmn_fct = (trs & rtr.x.trs).first
48
- return super(rtr) unless cmn_fct
31
+ elsif formula?(super_ope(operator)) && x.inverse?(operator) && x.x.formula?(super_ope(operator))
32
+ w1, w2 = common_factors(x.x)
33
+ return super(x) unless (w1 && w2) && (super_ope(operator).commutative? || w1 == w2)
49
34
 
50
- if op.super.commutative?
51
- _(
52
- cmn_fct, op.super, _(delete(cmn_fct), op.inv, rtr.x.delete(cmn_fct))
53
- )
54
- else
55
- return super(rtr) if index(cmn_fct) != rtr.x.index(cmn_fct)
56
- case index(cmn_fct)
57
- when 0
58
- _(
59
- cmn_fct, op.super, _(delete(cmn_fct), op.sub.inv, rtr.x.delete(cmn_fct))
60
- )
61
- when 1
62
- _(
63
- _(delete(cmn_fct), op.inv, rtr.x.delete(cmn_fct)), op.super, cmn_fct
64
- )
35
+ case operator
36
+ when :+
37
+ send(w1).send(super_ope(operator), send(rest(w1)).send(inverse_ope(operator), x.x.send(rest(w2))))
38
+ when :*
39
+ case w1
40
+ when :f
41
+ send(w1).send(super_ope(operator), send(rest(w1)).send(inverse_ope(sub_ope(operator)), x.x.send(rest(w2))))
42
+ when :g
43
+ send(w1).send(super_ope(operator), send(rest(w1)).send(inverse_ope(operator), x.x.send(rest(w2)))).commutate!
65
44
  end
66
45
  end
67
46
  else
68
- super(rtr)
47
+ super(x)
69
48
  end
70
49
  end
71
50
  end
72
51
 
73
- %w(**).map(&:to_sym).each do |op|
74
- define_method(op) do |rtr|
75
- if formula?(op.sub) && openable?(op, rtr)
76
- _(
77
- _(trs[0], op, rtr), op.sub, _(trs[1], op, rtr)
78
- )
79
- else
80
- super(rtr)
81
- end
52
+ def ^(x)
53
+ if multiplication? && openable?(:^, x)
54
+ (f ^ x).send(self.operator, (g ^ x))
55
+ else
56
+ super(x)
82
57
  end
83
58
  end
84
59
  end
@@ -2,108 +2,55 @@ module Dydx
2
2
  module Algebra
3
3
  module Operator
4
4
  module Parts
5
- module Interface
6
- %w(+ - * / ** %).map(&:to_sym).each do |operator|
7
- define_method(operator) do |x|
8
- x = _(x) if x.is_a?(Numeric)
9
- if operator == :/ && x.zero?
10
- fail ZeroDivisionError
11
- elsif [:-, :/].include?(operator)
12
- send(operator.inv, inverse(x, operator.inv))
13
- else
14
- super(x)
15
- end
16
- end
17
- end
18
- end
19
-
20
- module Associative
21
- %w(+ * **).map(&:to_sym).each do |operator|
22
- define_method(operator) do |x|
23
- if operator.associative?
24
- if x.formula?(operator)
25
- if combinable?(x.f, operator)
26
- send(operator, x.f).send(operator, x.g)
27
- elsif combinable?(x.g, operator)
28
- send(operator, x.g).send(operator, x.f)
29
- else
30
- super(x)
31
- end
32
- elsif x.is_a?(Inverse) && x.operator == operator && x.x.formula?(operator)
33
- if combinable?(x.x.f, operator)
34
- send(operator, inverse(x.x.f, operator)).send(operator, inverse(x.x.g, operator))
35
- elsif combinable?(x.x.g, operator)
36
- send(operator, inverse(x.x.g, operator)).send(operator, inverse(x.x.f, operator))
37
- else
38
- super(x)
39
- end
40
- else
41
- super(x)
42
- end
43
- else
44
- super(x)
45
- end
46
- end
47
- end
48
- end
49
-
50
- module General1
51
- %w(+ * **).map(&:to_sym).each do |operator|
5
+ module General
6
+ %w(+ * ^).map(&:to_sym).each do |operator|
52
7
  define_method(operator) do |x|
53
- if x.zero?
8
+ if x.is_0?
54
9
  case operator
55
- when :+ then self
56
- when :* then x
57
- when :** then e1
10
+ when :+ then self
11
+ when :* then x
12
+ when :^ then e1
58
13
  end
59
- elsif x.one?
14
+ elsif x.is_1?
60
15
  case operator
61
- when :+ then super(x)
62
- when :* then self
63
- when :** then self
16
+ when :+ then super(x)
17
+ when :* then self
18
+ when :^ then self
64
19
  end
65
20
  elsif self == x
66
21
  case operator
67
- when :+ then _(2) * self
68
- when :* then self ** _(2)
69
- when :** then super(x)
22
+ when :+ then _(2) * self
23
+ when :* then self ^ _(2)
24
+ when :^ then super(x)
70
25
  end
71
- elsif inverse?(operator, x)
72
- case operator
73
- when :+ then e0
74
- when :* then e1
26
+ elsif operator == :+ && inverse?(:+, x)
27
+ e0
28
+ elsif operator == :* && inverse?(:*, x)
29
+ e1
30
+ elsif [:+, :*].include?(operator) && x.formula?(operator)
31
+ if combinable?(x.f, operator)
32
+ send(operator, x.f).send(operator, x.g)
33
+ elsif combinable?(x.g, operator)
34
+ send(operator, x.g).send(operator, x.f)
35
+ else
36
+ super(x)
75
37
  end
76
- elsif [:+, :*].include?(operator)
77
- if x.formula?(operator.super) && self == x.f
78
- send(operator.super, (1 + x.g))
38
+ elsif x.is_a?(Inverse) && x.operator == operator && x.x.formula?(operator)
39
+ if combinable?(x.x.f, operator)
40
+ send(operator, inverse(x.x.f, operator)).send(operator, inverse(x.x.g, operator))
41
+ elsif combinable?(x.x.g, operator)
42
+ send(operator, inverse(x.x.g, operator)).send(operator, inverse(x.x.f, operator))
79
43
  else
80
44
  super(x)
81
45
  end
46
+ elsif [:*].include?(operator) && x.inverse?(:+)
47
+ inverse(::Algebra::Formula.new(self, x.x, operator.to_sym), :+)
82
48
  else
83
49
  super(x)
84
50
  end
85
51
  end
86
52
  end
87
53
  end
88
-
89
- module General2
90
- %w(+ * **).map(&:to_sym).each do |operator|
91
- define_method(operator) do |x|
92
- if operator == :* && x.inverse?(:+)
93
- -(self * x.x)
94
- else
95
- super(x)
96
- end
97
- end
98
- end
99
- end
100
-
101
- module General
102
- include General2
103
- include General1
104
- include Associative
105
- include Interface
106
- end
107
54
  end
108
55
  end
109
56
  end