dydx 0.1.3 → 0.1.4
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.
- checksums.yaml +7 -0
- data/.pryrc +2 -0
- data/.rubocop.yml +25 -0
- data/Gemfile +3 -0
- data/README.md +29 -64
- data/Rakefile +5 -8
- data/dydx.gemspec +13 -13
- data/lib/dydx.rb +20 -29
- data/lib/dydx/algebra.rb +8 -76
- data/lib/dydx/algebra/formula.rb +67 -29
- data/lib/dydx/algebra/inverse.rb +16 -2
- data/lib/dydx/algebra/operator/formula.rb +0 -4
- data/lib/dydx/algebra/operator/general.rb +0 -4
- data/lib/dydx/algebra/operator/inverse.rb +0 -4
- data/lib/dydx/algebra/operator/num.rb +0 -4
- data/lib/dydx/algebra/operator/parts/base.rb +2 -2
- data/lib/dydx/algebra/operator/parts/formula.rb +61 -40
- data/lib/dydx/algebra/operator/parts/general.rb +83 -30
- data/lib/dydx/algebra/operator/parts/inverse.rb +4 -4
- data/lib/dydx/algebra/operator/parts/num.rb +16 -11
- data/lib/dydx/algebra/operator/parts/symbol.rb +2 -2
- data/lib/dydx/algebra/set.rb +271 -34
- data/lib/dydx/delta.rb +1 -1
- data/lib/dydx/function.rb +1 -1
- data/lib/dydx/helper.rb +53 -67
- data/lib/dydx/integrand.rb +22 -10
- data/lib/dydx/version.rb +1 -1
- data/spec/dydx_spec.rb +10 -29
- data/spec/lib/algebra/formula_spec.rb +44 -38
- data/spec/lib/algebra/operator/parts/base_spec.rb +5 -5
- data/spec/lib/algebra/operator/parts/formula_spec.rb +57 -57
- data/spec/lib/algebra/operator/parts/inverse_spec.rb +8 -8
- data/spec/lib/algebra/set_spec.rb +263 -0
- data/spec/lib/delta_spec.rb +32 -8
- data/spec/lib/function_spec.rb +60 -34
- data/spec/lib/helper_spec.rb +44 -51
- data/spec/lib/integrand_spec.rb +13 -15
- data/spec/spec_helper.rb +2 -1
- metadata +20 -64
- data/lib/dydx/algebra/operator/common_parts.rb +0 -3
- data/lib/dydx/algebra/operator/parts/interface.rb +0 -22
- data/lib/dydx/algebra/operator/symbol.rb +0 -15
- data/lib/dydx/algebra/set/base.rb +0 -9
- data/lib/dydx/algebra/set/cos.rb +0 -22
- data/lib/dydx/algebra/set/e.rb +0 -16
- data/lib/dydx/algebra/set/fixnum.rb +0 -14
- data/lib/dydx/algebra/set/float.rb +0 -14
- data/lib/dydx/algebra/set/log.rb +0 -22
- data/lib/dydx/algebra/set/num.rb +0 -22
- data/lib/dydx/algebra/set/pi.rb +0 -16
- data/lib/dydx/algebra/set/sin.rb +0 -22
- data/lib/dydx/algebra/set/symbol.rb +0 -14
- data/lib/dydx/algebra/set/tan.rb +0 -17
- data/spec/lib/algebra/set/cos_spec.rb +0 -18
- data/spec/lib/algebra/set/e_spec.rb +0 -27
- data/spec/lib/algebra/set/fixnum_spec.rb +0 -65
- data/spec/lib/algebra/set/float_spec.rb +0 -65
- data/spec/lib/algebra/set/log_spec.rb +0 -15
- data/spec/lib/algebra/set/num_spec.rb +0 -23
- data/spec/lib/algebra/set/pi_spec.rb +0 -25
- data/spec/lib/algebra/set/sin_spec.rb +0 -14
- data/spec/lib/algebra/set/symbol_spec.rb +0 -22
- data/spec/lib/algebra/set/tan_spec.rb +0 -13
data/lib/dydx/algebra/inverse.rb
CHANGED
@@ -15,12 +15,26 @@ module Dydx
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
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
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def differentiate(sym = :x)
|
19
33
|
case operator
|
20
34
|
when :+
|
21
35
|
inverse(x.differentiate(sym), :+)
|
22
36
|
when :*
|
23
|
-
inverse(x.differentiate(sym) * inverse(x
|
37
|
+
inverse(x.differentiate(sym) * inverse(x ** 2, :*), :+)
|
24
38
|
end
|
25
39
|
end
|
26
40
|
alias_method :d, :differentiate
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'dydx/algebra/operator/common_parts'
|
2
|
-
require 'dydx/algebra/operator/parts/formula'
|
3
|
-
|
4
1
|
module Dydx
|
5
2
|
module Algebra
|
6
3
|
module Operator
|
@@ -8,7 +5,6 @@ module Dydx
|
|
8
5
|
include Parts::Base
|
9
6
|
include Parts::Formula
|
10
7
|
include Parts::General
|
11
|
-
include Parts::Interface
|
12
8
|
end
|
13
9
|
end
|
14
10
|
end
|
@@ -1,13 +1,9 @@
|
|
1
|
-
require 'dydx/algebra/operator/common_parts'
|
2
|
-
require 'dydx/algebra/operator/parts/general'
|
3
|
-
|
4
1
|
module Dydx
|
5
2
|
module Algebra
|
6
3
|
module Operator
|
7
4
|
module General
|
8
5
|
include Parts::Base
|
9
6
|
include Parts::General
|
10
|
-
include Parts::Interface
|
11
7
|
end
|
12
8
|
end
|
13
9
|
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'dydx/algebra/operator/common_parts'
|
2
|
-
require 'dydx/algebra/operator/parts/inverse'
|
3
|
-
|
4
1
|
module Dydx
|
5
2
|
module Algebra
|
6
3
|
module Operator
|
@@ -8,7 +5,6 @@ module Dydx
|
|
8
5
|
include Parts::Base
|
9
6
|
include Parts::Inverse
|
10
7
|
include Parts::General
|
11
|
-
include Parts::Interface
|
12
8
|
end
|
13
9
|
end
|
14
10
|
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'dydx/algebra/operator/common_parts'
|
2
|
-
require 'dydx/algebra/operator/parts/num'
|
3
|
-
|
4
1
|
module Dydx
|
5
2
|
module Algebra
|
6
3
|
module Operator
|
@@ -8,7 +5,6 @@ module Dydx
|
|
8
5
|
include Parts::Base
|
9
6
|
include Parts::Num
|
10
7
|
include Parts::General
|
11
|
-
include Parts::Interface
|
12
8
|
end
|
13
9
|
end
|
14
10
|
end
|
@@ -3,9 +3,9 @@ module Dydx
|
|
3
3
|
module Operator
|
4
4
|
module Parts
|
5
5
|
module Base
|
6
|
-
%w(+ *
|
6
|
+
%w(+ * **).map(&:to_sym).each do |operator|
|
7
7
|
define_method(operator) do |x|
|
8
|
-
::Algebra::Formula.new(self, x
|
8
|
+
::Algebra::Formula.new(operator.to_sym, self, x)
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
@@ -3,60 +3,81 @@ module Dydx
|
|
3
3
|
module Operator
|
4
4
|
module Parts
|
5
5
|
module Formula
|
6
|
-
%w(+ *).map(&:to_sym).each do |
|
7
|
-
define_method(
|
8
|
-
if self.operator ==
|
9
|
-
if f.combinable?(
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
+
)
|
13
17
|
else
|
14
|
-
super(
|
18
|
+
super(rtr)
|
15
19
|
end
|
16
|
-
elsif formula?(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
+
)
|
31
44
|
end
|
32
45
|
end
|
33
|
-
elsif formula?(
|
34
|
-
|
35
|
-
return super(
|
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
|
36
49
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
when
|
45
|
-
|
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
|
+
)
|
46
65
|
end
|
47
66
|
end
|
48
67
|
else
|
49
|
-
super(
|
68
|
+
super(rtr)
|
50
69
|
end
|
51
70
|
end
|
52
71
|
end
|
53
72
|
|
54
|
-
%w(
|
55
|
-
define_method(
|
56
|
-
if formula?(
|
57
|
-
|
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
|
+
)
|
58
79
|
else
|
59
|
-
super(
|
80
|
+
super(rtr)
|
60
81
|
end
|
61
82
|
end
|
62
83
|
end
|
@@ -2,48 +2,94 @@ module Dydx
|
|
2
2
|
module Algebra
|
3
3
|
module Operator
|
4
4
|
module Parts
|
5
|
-
module
|
6
|
-
%w(+ *
|
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|
|
7
52
|
define_method(operator) do |x|
|
8
|
-
if x.
|
53
|
+
if x.zero?
|
9
54
|
case operator
|
10
|
-
when :+
|
11
|
-
when :*
|
12
|
-
when
|
55
|
+
when :+ then self
|
56
|
+
when :* then x
|
57
|
+
when :** then e1
|
13
58
|
end
|
14
|
-
elsif x.
|
59
|
+
elsif x.one?
|
15
60
|
case operator
|
16
|
-
when :+
|
17
|
-
when :*
|
18
|
-
when
|
61
|
+
when :+ then super(x)
|
62
|
+
when :* then self
|
63
|
+
when :** then self
|
19
64
|
end
|
20
65
|
elsif self == x
|
21
66
|
case operator
|
22
|
-
when :+
|
23
|
-
when :*
|
24
|
-
when
|
67
|
+
when :+ then _(2) * self
|
68
|
+
when :* then self ** _(2)
|
69
|
+
when :** then super(x)
|
25
70
|
end
|
26
|
-
elsif
|
27
|
-
|
28
|
-
|
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)
|
71
|
+
elsif inverse?(operator, x)
|
72
|
+
case operator
|
73
|
+
when :+ then e0
|
74
|
+
when :* then e1
|
37
75
|
end
|
38
|
-
elsif
|
39
|
-
if
|
40
|
-
send(operator
|
41
|
-
elsif combinable?(x.x.g, operator)
|
42
|
-
send(operator, inverse(x.x.g, operator)).send(operator, inverse(x.x.f, operator))
|
76
|
+
elsif [:+, :*].include?(operator)
|
77
|
+
if x.formula?(operator.super) && self == x.f
|
78
|
+
send(operator.super, (1 + x.g))
|
43
79
|
else
|
44
80
|
super(x)
|
45
81
|
end
|
46
|
-
|
82
|
+
else
|
83
|
+
super(x)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
module General2
|
90
|
+
%w(+ * **).map(&:to_sym).each do |operator|
|
91
|
+
define_method(operator) do |x|
|
92
|
+
if operator == :* && x.inverse?(:+)
|
47
93
|
-(self * x.x)
|
48
94
|
else
|
49
95
|
super(x)
|
@@ -51,6 +97,13 @@ module Dydx
|
|
51
97
|
end
|
52
98
|
end
|
53
99
|
end
|
100
|
+
|
101
|
+
module General
|
102
|
+
include General2
|
103
|
+
include General1
|
104
|
+
include Associative
|
105
|
+
include Interface
|
106
|
+
end
|
54
107
|
end
|
55
108
|
end
|
56
109
|
end
|
@@ -3,17 +3,17 @@ module Dydx
|
|
3
3
|
module Operator
|
4
4
|
module Parts
|
5
5
|
module Inverse
|
6
|
-
%w(+ *
|
6
|
+
%w(+ * **).map(&:to_sym).each do |operator|
|
7
7
|
define_method(operator) do |x|
|
8
8
|
if inverse?(operator, x)
|
9
9
|
case operator
|
10
10
|
when :+ then e0
|
11
11
|
when :* then e1
|
12
12
|
end
|
13
|
-
elsif !x.is_a?(Inverse)
|
13
|
+
elsif operator.eql?(:+) && !x.is_a?(Inverse)
|
14
14
|
x + self
|
15
|
-
elsif
|
16
|
-
inverse(self.x
|
15
|
+
elsif operator.eql?(:**) && self.operator.eql?(:*)
|
16
|
+
inverse(self.x ** x, :*)
|
17
17
|
else
|
18
18
|
super(x)
|
19
19
|
end
|
@@ -3,31 +3,36 @@ module Dydx
|
|
3
3
|
module Operator
|
4
4
|
module Parts
|
5
5
|
module Num
|
6
|
-
%w(+ *
|
6
|
+
%w(+ * **).map(&:to_sym).each do |operator|
|
7
7
|
define_method(operator) do |x|
|
8
|
-
if
|
8
|
+
if x.is_a?(Num)
|
9
|
+
_(n.send(operator, x.n))
|
10
|
+
elsif operator == :+ && x.inverse?(:+) && x.x.is_a?(Num)
|
11
|
+
_(n - x.x.n)
|
12
|
+
elsif operator == :* && x.inverse?(:*) && x.x.is_a?(Num) && n % x.x.n == 0
|
13
|
+
_(n / x.x.n)
|
14
|
+
elsif zero?
|
9
15
|
case operator
|
10
16
|
when :+ then x
|
11
17
|
when :* then e0
|
12
|
-
when
|
18
|
+
when :** then e0
|
13
19
|
end
|
14
|
-
elsif
|
20
|
+
elsif one?
|
15
21
|
case operator
|
16
22
|
when :+ then super(x)
|
17
23
|
when :* then x
|
18
|
-
when
|
24
|
+
when :** then e1
|
19
25
|
end
|
20
|
-
elsif x.is_a?(Num)
|
21
|
-
_(n.send(operator, x.n))
|
22
|
-
elsif operator == :+ && x.inverse?(:+) && x.x.is_a?(Num)
|
23
|
-
_(n - x.x.n)
|
24
|
-
elsif operator == :* && x.inverse?(:*) && x.x.is_a?(Num)
|
25
|
-
_(n / x.x.n)
|
26
26
|
else
|
27
27
|
super(x)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
def %(num)
|
33
|
+
fail ArgumentError, "#{num} should be Num class object" unless num.is_a?(Num)
|
34
|
+
_(n % num.n)
|
35
|
+
end
|
31
36
|
end
|
32
37
|
end
|
33
38
|
end
|
data/lib/dydx/algebra/set.rb
CHANGED
@@ -1,33 +1,210 @@
|
|
1
|
-
require 'dydx/algebra/
|
2
|
-
require 'dydx/algebra/
|
3
|
-
require 'dydx/algebra/
|
4
|
-
require 'dydx/algebra/
|
5
|
-
require 'dydx/algebra/
|
6
|
-
|
7
|
-
require 'dydx/algebra/
|
8
|
-
require 'dydx/algebra/
|
9
|
-
require 'dydx/algebra/
|
10
|
-
require 'dydx/algebra/
|
11
|
-
|
1
|
+
require 'dydx/algebra/operator/parts/base'
|
2
|
+
require 'dydx/algebra/operator/parts/general'
|
3
|
+
require 'dydx/algebra/operator/parts/formula'
|
4
|
+
require 'dydx/algebra/operator/parts/inverse'
|
5
|
+
require 'dydx/algebra/operator/parts/num'
|
6
|
+
|
7
|
+
require 'dydx/algebra/operator/inverse'
|
8
|
+
require 'dydx/algebra/operator/formula'
|
9
|
+
require 'dydx/algebra/operator/num'
|
10
|
+
require 'dydx/algebra/operator/general'
|
11
|
+
|
12
|
+
require 'dydx/algebra/formula'
|
13
|
+
require 'dydx/algebra/inverse'
|
12
14
|
|
13
15
|
module Dydx
|
14
16
|
module Algebra
|
15
17
|
module Set
|
16
|
-
|
17
|
-
|
18
|
+
module Base
|
19
|
+
include Helper
|
20
|
+
|
21
|
+
# TODO: Pi should not have attr_accessor
|
22
|
+
def self.included(_klass)
|
23
|
+
attr_accessor :n, :x
|
24
|
+
alias_method :d, :differentiate
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(x = nil)
|
28
|
+
case self
|
29
|
+
when Num
|
30
|
+
@n = x
|
31
|
+
when Sin, Cos, Tan, Log, Log10, Log2
|
32
|
+
@x = x
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
case self
|
38
|
+
when Num then n.to_s
|
39
|
+
when Pi then 'pi'
|
40
|
+
when E then 'e'
|
41
|
+
when Sin then "sin( #{x} )"
|
42
|
+
when Cos then "cos( #{x} )"
|
43
|
+
when Tan then "tan( #{x} )"
|
44
|
+
when Log then "log( #{x} )"
|
45
|
+
when Log10 then "log10( #{x} )"
|
46
|
+
when Log2 then "log2( #{x} )"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_f
|
51
|
+
case self
|
52
|
+
when Num then n.to_f
|
53
|
+
when Pi then Math::PI
|
54
|
+
when E then Math::E
|
55
|
+
when Symbol then fail ArgumentError
|
56
|
+
when Sin then Math.sin(x.to_f)
|
57
|
+
when Cos then Math.cos(x.to_f)
|
58
|
+
when Tan then Math.tan(x.to_f)
|
59
|
+
when Log then Math.log(x.to_f)
|
60
|
+
when Log10 then Math.log(x.to_f, 10)
|
61
|
+
when Log2 then Math.log(x.to_f, 2)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def subst(hash = {})
|
66
|
+
case self
|
67
|
+
when Num, Pi, E
|
68
|
+
self
|
69
|
+
when Symbol
|
70
|
+
hash[self] || self
|
71
|
+
when Sin then sin(x.subst(hash))
|
72
|
+
when Cos then cos(x.subst(hash))
|
73
|
+
when Tan then tan(x.subst(hash))
|
74
|
+
when Log then log(x.subst(hash))
|
75
|
+
when Log10 then log10(x.subst(hash))
|
76
|
+
when Log2 then log2(x.subst(hash))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def differentiate(sym = :x)
|
81
|
+
case self
|
82
|
+
when Num, Pi, E then e0
|
83
|
+
when Symbol then self == sym ? e1 : e0
|
84
|
+
when Sin then cos(x) * x.d(sym)
|
85
|
+
when Cos then -1 * sin(x) * x.d(sym)
|
86
|
+
when Tan then 1 / (cos(x) ** 2)
|
87
|
+
when Log then x.d(sym) / (x)
|
88
|
+
when Log10 then x.d(sym) / (x * log(10))
|
89
|
+
when Log2 then x.d(sym) / (x * log(2))
|
90
|
+
end
|
91
|
+
end
|
18
92
|
end
|
19
93
|
|
20
|
-
|
21
|
-
|
94
|
+
class Num
|
95
|
+
include Base
|
96
|
+
include Operator::Num
|
97
|
+
%w(> >= < <=).each do |operator|
|
98
|
+
define_method(operator) do |x|
|
99
|
+
x = x.n if x.is_a?(Num)
|
100
|
+
n.send(operator, x)
|
101
|
+
end
|
102
|
+
end
|
22
103
|
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
104
|
+
|
105
|
+
class Pi
|
106
|
+
include Base
|
107
|
+
include Operator::General
|
108
|
+
end
|
109
|
+
|
110
|
+
class E
|
111
|
+
include Base
|
112
|
+
include Operator::General
|
113
|
+
end
|
114
|
+
|
115
|
+
class Sin
|
116
|
+
include Base
|
117
|
+
include Operator::General
|
118
|
+
end
|
119
|
+
|
120
|
+
class Cos
|
121
|
+
include Base
|
122
|
+
include Operator::General
|
123
|
+
end
|
124
|
+
|
125
|
+
class Tan
|
126
|
+
include Base
|
127
|
+
include Operator::General
|
128
|
+
end
|
129
|
+
|
130
|
+
class Log
|
131
|
+
include Base
|
132
|
+
include Operator::General
|
133
|
+
end
|
134
|
+
|
135
|
+
class Log10
|
136
|
+
include Base
|
137
|
+
include Operator::General
|
138
|
+
end
|
139
|
+
|
140
|
+
class Log2
|
141
|
+
include Base
|
142
|
+
include Operator::General
|
143
|
+
end
|
144
|
+
|
145
|
+
Symbol.class_eval do
|
146
|
+
include Base
|
147
|
+
include Operator::General
|
148
|
+
end
|
149
|
+
|
150
|
+
numeric_proc = Proc.new do
|
151
|
+
include Helper
|
152
|
+
|
153
|
+
def subst(_hash = {})
|
154
|
+
self
|
155
|
+
end
|
156
|
+
|
157
|
+
def differentiate(_sym = :x)
|
158
|
+
e0
|
159
|
+
end
|
160
|
+
alias_method :d, :differentiate
|
161
|
+
|
162
|
+
alias_method :addition, :+
|
163
|
+
alias_method :subtraction, :-
|
164
|
+
alias_method :multiplication, :*
|
165
|
+
alias_method :division, :/
|
166
|
+
alias_method :exponentiation, :**
|
167
|
+
alias_method :modulation, :%
|
168
|
+
|
169
|
+
ope_to_str = {
|
170
|
+
addition: :+,
|
171
|
+
subtraction: :-,
|
172
|
+
multiplication: :*,
|
173
|
+
division: :/,
|
174
|
+
exponentiation: :**,
|
175
|
+
modulation: :%
|
176
|
+
}
|
177
|
+
%w(+ - * / ** %).each do |operator|
|
178
|
+
define_method(operator) do |g|
|
179
|
+
if g.is_a?(Symbol) ||
|
180
|
+
g.is_a?(Formula) ||
|
181
|
+
g.is_a?(Base)
|
182
|
+
|
183
|
+
_(self).send(operator.to_sym, g)
|
184
|
+
else
|
185
|
+
send(ope_to_str.key(operator.to_sym), g)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
if self == Rational
|
190
|
+
def to_s
|
191
|
+
"( #{numerator} / #{denominator} )"
|
192
|
+
end
|
28
193
|
end
|
29
194
|
end
|
30
195
|
|
196
|
+
Float.class_eval(&numeric_proc)
|
197
|
+
Fixnum.class_eval(&numeric_proc)
|
198
|
+
Rational.class_eval(&numeric_proc)
|
199
|
+
|
200
|
+
def e0
|
201
|
+
eval('$e0 ||= _(0)')
|
202
|
+
end
|
203
|
+
|
204
|
+
def e1
|
205
|
+
eval('$e1 ||= _(1)')
|
206
|
+
end
|
207
|
+
|
31
208
|
def pi
|
32
209
|
$pi ||= Pi.new
|
33
210
|
end
|
@@ -40,14 +217,15 @@ module Dydx
|
|
40
217
|
Float::INFINITY
|
41
218
|
end
|
42
219
|
|
220
|
+
# TODO: Method has too many lines. [13/10]
|
43
221
|
def log(formula)
|
44
|
-
if formula.
|
222
|
+
if formula.formula?(:*)
|
45
223
|
f, g = formula.f, formula.g
|
46
224
|
log(f) + log(g)
|
47
|
-
elsif formula.
|
225
|
+
elsif formula.formula?(:**)
|
48
226
|
f, g = formula.f, formula.g
|
49
227
|
g * log(f)
|
50
|
-
elsif formula.
|
228
|
+
elsif formula.one?
|
51
229
|
e0
|
52
230
|
elsif formula.is_a?(E)
|
53
231
|
e1
|
@@ -56,28 +234,87 @@ module Dydx
|
|
56
234
|
end
|
57
235
|
end
|
58
236
|
|
59
|
-
def
|
60
|
-
|
61
|
-
if
|
237
|
+
def log2(formula)
|
238
|
+
# TODO: refactor with log function.
|
239
|
+
if formula.formula?(:*)
|
240
|
+
f, g = formula.f, formula.g
|
241
|
+
log2(f) + log2(g)
|
242
|
+
elsif formula.formula?(:**)
|
243
|
+
f, g = formula.f, formula.g
|
244
|
+
g * log2(f)
|
245
|
+
elsif formula.one?
|
62
246
|
e0
|
247
|
+
elsif formula.is_a?(Num)
|
248
|
+
(formula.n == 2) ? e1 : log2(formula.n)
|
249
|
+
elsif formula == 2
|
250
|
+
e1
|
63
251
|
else
|
64
|
-
|
252
|
+
Log2.new(formula)
|
65
253
|
end
|
66
254
|
end
|
67
255
|
|
68
|
-
def
|
69
|
-
|
70
|
-
if
|
256
|
+
def log10(formula)
|
257
|
+
# TODO: refactor with log function.
|
258
|
+
if formula.formula?(:*)
|
259
|
+
f, g = formula.f, formula.g
|
260
|
+
log10(f) + log10(g)
|
261
|
+
elsif formula.formula?(:**)
|
262
|
+
f, g = formula.f, formula.g
|
263
|
+
g * log10(f)
|
264
|
+
elsif formula.one?
|
265
|
+
e0
|
266
|
+
elsif formula.is_a?(Num)
|
267
|
+
(formula.n == 10) ? e1 : log10(formula.n)
|
268
|
+
elsif formula == 10
|
71
269
|
e1
|
72
|
-
elsif multiplier.is_a?(Num) && multiplier.n % 2 == 1
|
73
|
-
_(-1)
|
74
270
|
else
|
75
|
-
|
271
|
+
Log10.new(formula)
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# TODO: We should negative num
|
276
|
+
def sin(x)
|
277
|
+
return Sin.new(x) unless x.multiple_of?(pi) && (x / pi).num?
|
278
|
+
|
279
|
+
radn = (x / pi)
|
280
|
+
loop do
|
281
|
+
break if radn < 2
|
282
|
+
radn -= 2
|
283
|
+
end
|
284
|
+
|
285
|
+
case radn
|
286
|
+
when 0 then 0
|
287
|
+
when _(1) / 2 then 1
|
288
|
+
when 1 then 0
|
289
|
+
when _(3) / 2 then -1
|
290
|
+
else Sin.new(x)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
def cos(x)
|
295
|
+
return Cos.new(x) unless x.multiple_of?(pi) && (x / pi).num?
|
296
|
+
|
297
|
+
radn = (x / pi)
|
298
|
+
loop do
|
299
|
+
break if radn < 2
|
300
|
+
radn -= 2
|
301
|
+
end
|
302
|
+
|
303
|
+
case radn
|
304
|
+
when 0 then 1
|
305
|
+
when _(1) / 2 then 0
|
306
|
+
when 1 then -1
|
307
|
+
when _(3) / 2 then 0
|
308
|
+
else Sin.new(x)
|
76
309
|
end
|
77
310
|
end
|
78
311
|
|
79
312
|
def tan(x)
|
80
|
-
|
313
|
+
if x == 0
|
314
|
+
0
|
315
|
+
else
|
316
|
+
Tan.new(x)
|
317
|
+
end
|
81
318
|
end
|
82
319
|
end
|
83
320
|
end
|