dydx 0.1.4 → 0.1.25

Sign up to get free protection for your applications and to get access to all the features.
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