dydx 0.1.314 → 0.1.412

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