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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.pryrc +2 -0
  3. data/.rubocop.yml +25 -0
  4. data/Gemfile +3 -0
  5. data/README.md +29 -64
  6. data/Rakefile +5 -8
  7. data/dydx.gemspec +13 -13
  8. data/lib/dydx.rb +20 -29
  9. data/lib/dydx/algebra.rb +8 -76
  10. data/lib/dydx/algebra/formula.rb +67 -29
  11. data/lib/dydx/algebra/inverse.rb +16 -2
  12. data/lib/dydx/algebra/operator/formula.rb +0 -4
  13. data/lib/dydx/algebra/operator/general.rb +0 -4
  14. data/lib/dydx/algebra/operator/inverse.rb +0 -4
  15. data/lib/dydx/algebra/operator/num.rb +0 -4
  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 -30
  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 +271 -34
  23. data/lib/dydx/delta.rb +1 -1
  24. data/lib/dydx/function.rb +1 -1
  25. data/lib/dydx/helper.rb +53 -67
  26. data/lib/dydx/integrand.rb +22 -10
  27. data/lib/dydx/version.rb +1 -1
  28. data/spec/dydx_spec.rb +10 -29
  29. data/spec/lib/algebra/formula_spec.rb +44 -38
  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 +263 -0
  34. data/spec/lib/delta_spec.rb +32 -8
  35. data/spec/lib/function_spec.rb +60 -34
  36. data/spec/lib/helper_spec.rb +44 -51
  37. data/spec/lib/integrand_spec.rb +13 -15
  38. data/spec/spec_helper.rb +2 -1
  39. metadata +20 -64
  40. data/lib/dydx/algebra/operator/common_parts.rb +0 -3
  41. data/lib/dydx/algebra/operator/parts/interface.rb +0 -22
  42. data/lib/dydx/algebra/operator/symbol.rb +0 -15
  43. data/lib/dydx/algebra/set/base.rb +0 -9
  44. data/lib/dydx/algebra/set/cos.rb +0 -22
  45. data/lib/dydx/algebra/set/e.rb +0 -16
  46. data/lib/dydx/algebra/set/fixnum.rb +0 -14
  47. data/lib/dydx/algebra/set/float.rb +0 -14
  48. data/lib/dydx/algebra/set/log.rb +0 -22
  49. data/lib/dydx/algebra/set/num.rb +0 -22
  50. data/lib/dydx/algebra/set/pi.rb +0 -16
  51. data/lib/dydx/algebra/set/sin.rb +0 -22
  52. data/lib/dydx/algebra/set/symbol.rb +0 -14
  53. data/lib/dydx/algebra/set/tan.rb +0 -17
  54. data/spec/lib/algebra/set/cos_spec.rb +0 -18
  55. data/spec/lib/algebra/set/e_spec.rb +0 -27
  56. data/spec/lib/algebra/set/fixnum_spec.rb +0 -65
  57. data/spec/lib/algebra/set/float_spec.rb +0 -65
  58. data/spec/lib/algebra/set/log_spec.rb +0 -15
  59. data/spec/lib/algebra/set/num_spec.rb +0 -23
  60. data/spec/lib/algebra/set/pi_spec.rb +0 -25
  61. data/spec/lib/algebra/set/sin_spec.rb +0 -14
  62. data/spec/lib/algebra/set/symbol_spec.rb +0 -22
  63. data/spec/lib/algebra/set/tan_spec.rb +0 -13
@@ -1,7 +1,7 @@
1
1
  module Dydx
2
2
  class Delta
3
3
  attr_accessor :var, :function
4
- def initialize(var=nil, function=nil)
4
+ def initialize(var = nil, function = nil)
5
5
  @var = var
6
6
  @function = function
7
7
  end
@@ -10,7 +10,7 @@ module Dydx
10
10
  self
11
11
  end
12
12
 
13
- def differentiate(sym=:x)
13
+ def differentiate(sym = :x)
14
14
  @algebra.differentiate(sym)
15
15
  end
16
16
  alias_method :d, :differentiate
@@ -1,15 +1,9 @@
1
1
  module Dydx
2
2
  module Helper
3
- OP_SYM_STR = {
4
- addition: :+,
5
- multiplication: :*,
6
- exponentiation: :^
7
- }
8
-
9
3
  SUPER_OPE_RELATION = {
10
4
  :+ => :*,
11
5
  :- => :/,
12
- :* => :^,
6
+ :* => :**,
13
7
  :/ => :|
14
8
  }
15
9
 
@@ -18,103 +12,75 @@ module Dydx
18
12
  :- => :+,
19
13
  :* => :/,
20
14
  :/ => :*,
21
- :^ => :|,
22
- :| => :^
15
+ :** => :|,
16
+ :| => :**
23
17
  }
24
18
 
25
- def super_ope(operator)
26
- SUPER_OPE_RELATION[operator]
27
- end
28
-
29
- def sub_ope(operator)
30
- SUPER_OPE_RELATION.invert[operator]
31
- end
32
-
33
- def inverse_ope(operator)
34
- INVERSE_OPE_RELATION[operator]
35
- end
36
-
37
- def inverse_super_ope(operator)
38
- inverse_ope(super_ope(operator))
19
+ def num?
20
+ is_a?(Num) || is_a?(Numeric)
39
21
  end
40
22
 
41
- def is_num?
42
- (is_a?(Num) || is_a?(Fixnum) || is_a?(Float)) || (is_a?(Inverse) && x.is_num?)
23
+ def to_numeric
24
+ is_a?(Num) ? n : self
43
25
  end
44
26
 
45
- def is_0?
46
- [0, 0.0].include?(self) || (is_a?(Num) && n.is_0?)
27
+ def zero?
28
+ [0, 0.0].include?(self) || (is_a?(Num) && n.zero?)
47
29
  end
48
30
 
49
- def is_1?
50
- [1, 1.0].include?(self) || (is_a?(Num) && n.is_1?)
31
+ def one?
32
+ [1, 1.0].include?(self) || (is_a?(Num) && n.one?)
51
33
  end
52
34
 
53
- def is_minus1?
54
- [1, -1.0].include?(self)|| (is_a?(Num) && n.is_minus1?)
35
+ def minus1?
36
+ [-1, -1.0].include?(self) || (is_a?(Num) && n.minus1?)
55
37
  end
56
38
 
57
39
  def distributive?(ope1, ope2)
58
- [super_ope(ope1), inverse_super_ope(ope1)].include?(ope2)
40
+ [ope1.super, ope1.inv_super].include?(ope2)
59
41
  end
60
42
 
43
+ # TODO: Cyclomatic complexity for combinable? is too high. [17/6]
61
44
  def combinable?(x, operator)
62
45
  case operator
63
46
  when :+
64
- (is_num? && x.is_num?) ||
65
- (formula?(:*) && (f.is_num? || g.is_num?)) && x.is_num? ||
47
+ (num? && x.num?) ||
48
+ (formula?(:*) && (f.num? || g.num?)) && x.num? ||
66
49
  like_term?(x) ||
67
50
  inverse?(:+, x)
68
51
  when :*
69
52
  self == x ||
70
- (is_num? && x.is_num?) ||
53
+ (num? && x.num?) ||
71
54
  inverse?(:*, x)
72
- when :^
73
- (is_num? && x.is_num?) || is_0? || is_1?
55
+ when :**
56
+ (num? && x.num?) || zero? || one?
74
57
  end
75
58
  end
76
59
 
60
+ # TODO: Cyclomatic complexity for combinable? is too high. [9/6]
77
61
  def like_term?(x)
78
- boolean = if self == x
79
- elsif formula?(:*) && include?(x)
80
- elsif x.formula?(:*) && x.include?(self)
81
- elsif ((formula?(:*) && formula?(:*)) && (([f, g] & [x.f, x.g]).any?{|x| x.is_a?(Symbol)}))
82
- else
83
- true
84
- end
85
-
86
- !boolean
87
- end
88
-
89
- def is_multiple_of(x)
90
- if is_0?
91
- e0
92
- elsif self == x
93
- e1
94
- # elsif is_num? && x.is_num? && (self % x == 0)
95
- # _(n / x.n)
96
- elsif multiplication? && (f == x || g == x)
97
- f == x ? g : f
98
- else
99
- false
100
- end
62
+ self == x ||
63
+ formula?(:*) && include?(x) ||
64
+ x.formula?(:*) && x.include?(self)||
65
+ (formula?(:*) && formula?(:*) && !([f, g] & [x.f, x.g]).empty?)
101
66
  end
102
67
 
103
- OP_SYM_STR.each do |operator_name, operator|
104
- define_method("#{operator_name}?") do
105
- is_a?(Formula) && (@operator == operator)
106
- # is_a?(Inverse) && self.operator == operator
107
- end
68
+ # TODO: Cyclomatic complexity for combinable? is too high. [7/6]
69
+ def multiple_of?(x)
70
+ zero? ||
71
+ self == x ||
72
+ (num? && x.num? && self % x == 0) ||
73
+ (formula?(:*) && (f == x || g == x))
108
74
  end
109
75
 
110
76
  def rest(f_or_g)
111
77
  ([:f, :g] - [f_or_g]).first
112
78
  end
113
79
 
114
- def distributable?(operator)
80
+ def distributable?(_operator)
115
81
  end
116
82
 
117
- def inverse?(operator, x=nil)
83
+ def inverse?(operator, x = nil)
118
84
  if is_a?(Algebra::Inverse)
119
85
  self.operator == operator && (self.x == x || x.nil?)
120
86
  elsif x.is_a?(Algebra::Inverse)
@@ -132,6 +98,26 @@ module Dydx
132
98
  def commutative?
133
99
  [:+, :*].include?(self)
134
100
  end
101
+
102
+ def associative?
103
+ [:+, :*].include?(self)
104
+ end
105
+
106
+ def super
107
+ SUPER_OPE_RELATION[self] || self
108
+ end
109
+
110
+ def sub
111
+ SUPER_OPE_RELATION.invert[self] || self
112
+ end
113
+
114
+ def inv
115
+ INVERSE_OPE_RELATION[self] || self
116
+ end
117
+
118
+ def inv_super
119
+ self.super.inv
120
+ end
135
121
  end
136
122
 
137
123
  def ==(x)
@@ -1,26 +1,38 @@
1
1
  module Dydx
2
2
  class Integrand
3
3
  attr_accessor :function, :var
4
+
4
5
  def initialize(function, var)
5
6
  @function = function
6
7
  @var = var
7
8
  end
8
9
 
9
- def [](a, b, n = 100)
10
- f = function
11
- a, b = [a, b].map(&:to_f)
12
- raise ArgumentError, 'b should be greater than a' if a > b
10
+ def [](a, b, n = 1000)
13
11
  # HOT FIX: should implement Infinity class
14
12
  a = - 1000 if a == - Float::INFINITY
15
13
  b = 1000 if b == Float::INFINITY
16
14
 
15
+ a, b = [a, b].map(&:to_f)
16
+ fail ArgumentError, 'b should be greater than a' if a > b
17
+ $temp_cal_f = function
18
+
19
+ n = [n, (b - a) * 2].max
20
+ n += 1 if n.to_i.odd?
17
21
  h = (b - a) / n
18
- sum = 0.0
19
- xi = ->(i){ a + h * i }
20
- n.to_i.times do |i|
21
- sum += ( f(xi.(i)) + 4.0 * f(xi.(i) + h / 2.0 ) + f(xi.(i) + h) )
22
- end
23
- ( h * sum ) / 6.0
22
+ x = ->(i) { a + h * i }
23
+
24
+ odd_sum = (1..n - 1).to_a.select(&:odd?).inject(0) { |sum, i| sum += f(x.(i)) }
25
+ even_sum = (1..n - 1).to_a.select(&:even?).inject(0) { |sum, i| sum += f(x.(i)) }
26
+ round_8( (h / 3) * (f(a) + f(b) + 2 * even_sum + 4 * odd_sum) )
27
+ end
28
+
29
+ def f(vars)
30
+ temp_cal_f(vars)
31
+ end
32
+
33
+ def round_8(num)
34
+ return num if num.abs == Float::INFINITY
35
+ (num * 10 ** 8).round * 10.0 ** (-8)
24
36
  end
25
37
  end
26
38
  end
@@ -1,3 +1,3 @@
1
1
  module Dydx
2
- VERSION = "0.1.3"
2
+ VERSION = '0.1.4'
3
3
  end
@@ -5,35 +5,16 @@ describe Dydx do
5
5
  expect(Dydx::VERSION).not_to be nil
6
6
  end
7
7
 
8
- context 'ex1' do
9
- $a = (:x ^ :n)
10
- let(:d1){ da/dx }
11
- let(:d2){ d/dx($a) }
12
- it{ expect(d1.to_s).to eq('( n * ( x ^ ( n - 1 ) ) )') }
13
- it{ expect(d2.to_s).to eq('( n * ( x ^ ( n - 1 ) ) )') }
14
- end
15
-
16
- context 'ex2' do
17
- $b = (:x ^ (:x * 2))
18
- let(:d1){ db/dx }
19
- let(:d2){ d/dx($b) }
20
- it{ expect(d1.to_s).to eq('( ( 2 * x ) * ( x ^ ( ( 2 * x ) - 1 ) ) )') }
21
- it{ expect(d2.to_s).to eq('( ( 2 * x ) * ( x ^ ( ( 2 * x ) - 1 ) ) )') }
22
- end
23
-
24
- context 'ex3' do
25
- $c = (:t ^ 2) / 2
26
- let(:d1){ dc/dt }
27
- let(:d2){ d/dt($c) }
28
- it{ expect(d1.to_s).to eq('t') }
29
- it{ expect(d2.to_s).to eq('t') }
30
- end
8
+ it 'demo' do
9
+ f(x, y) <= x + x * y + y
10
+ expect(f(x, y)).to eq(x * (1 + y) + y)
11
+ expect(f(a, 2)).to eq(3 * a + 2)
12
+ expect(f(1, a + b)).to eq(1 + 2 * ( a + b ))
13
+ expect(f(1, 2)).to eq(5)
14
+ expect(d/dx(f(x, y))).to eq(1 + y)
31
15
 
32
- context 'ex4' do
33
- $i = 2 * (e ^ (2 * :z))
34
- let(:d1){ di/dz }
35
- let(:d2){ d/dz($i) }
36
- it{ expect(d1.to_s).to eq('( 4 * ( e ^ ( 2 * z ) ) )') }
37
- it{ expect(d2.to_s).to eq('( 4 * ( e ^ ( 2 * z ) ) )') }
16
+ g(x) <= sin(x)
17
+ expect(d/dx(g(x))).to eq(cos(x))
18
+ expect(S(g(x), dx)[0, pi / 2]).to eq(1.0)
38
19
  end
39
20
  end
@@ -1,63 +1,69 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dydx::Algebra::Formula do
4
- let(:addition) { (:x + :y) }
5
- let(:subtraction) { (:x - :y) }
6
- let(:multiplication){ (:x * :y) }
7
- let(:division) { (:x / :y) }
8
- let(:exponentiation){ (:x ^ :y) }
4
+ let(:addition) { (x + y) }
5
+ let(:subtraction) { (x - y) }
6
+ let(:multiplication) { (x * y) }
7
+ let(:division) { (x / y) }
8
+ let(:exponentiation) { (x ** y) }
9
9
  describe 'Calculate' do
10
10
  context 'With Fixnum' do
11
11
  let(:formula) { (:x + :y) }
12
- it{ expect(formula + 0).to eq(formula) }
13
- it{ expect(formula - 0).to eq(formula) }
14
- it{ expect(formula * 0).to eq(0) }
15
- it{ expect(formula * 1).to eq(formula) }
16
- it{ expect{(formula / 0).to_s}.to raise_error(ZeroDivisionError) }
17
- it{ expect(formula / 1).to eq(formula) }
18
- it{ expect(formula ^ 0).to eq(1) }
12
+ it { expect(formula + 0).to eq(formula) }
13
+ it { expect(formula - 0).to eq(formula) }
14
+ it { expect(formula * 0).to eq(0) }
15
+ it { expect(formula * 1).to eq(formula) }
16
+ it { expect { (formula / 0).to_s }.to raise_error(ZeroDivisionError) }
17
+ it { expect(formula / 1).to eq(formula) }
18
+ it { expect(formula ** 0).to eq(1) }
19
19
  end
20
20
  end
21
21
 
22
22
  describe '#to_s' do
23
- it{ expect(addition.to_s).to eq('( x + y )') }
24
- it{ expect(subtraction.to_s).to eq('( x - y )') }
25
- it{ expect(multiplication.to_s).to eq('( x * y )') }
26
- it{ expect(division.to_s).to eq('( x / y )') }
27
- it{ expect(exponentiation.to_s).to eq('( x ^ y )') }
28
- it{ expect( (addition * multiplication).to_s ).to eq('( ( x + y ) * ( x * y ) )') }
23
+ it { expect(addition.to_s).to eq('( x + y )') }
24
+ it { expect(subtraction.to_s).to eq('( x - y )') }
25
+ it { expect(multiplication.to_s).to eq('( x * y )') }
26
+ it { expect(division.to_s).to eq('( x / y )') }
27
+ it { expect(exponentiation.to_s).to eq('( x ** y )') }
28
+ it { expect((addition * multiplication).to_s).to eq('( ( x + y ) * ( x * y ) )') }
29
+ end
30
+
31
+ describe '#subst' do
32
+ it { expect((x + y).subst(x: 3, y: 3)).to eq(6) }
33
+ it { expect((x + y).subst(x: 3)).to eq(3 + y) }
34
+ it { expect((x + y + pi).subst(x: 3, y: 3).to_f).to eq(Math::PI + 6) }
29
35
  end
30
36
 
31
37
  describe '#differentiate' do
32
- it{ expect(addition.d(:x)).to eq(1) }
33
- it{ expect(addition.d(:y)).to eq(1) }
34
- it{ expect(addition.d(:z)).to eq(0) }
38
+ it { expect(addition.d(x)).to eq(1) }
39
+ it { expect(addition.d(y)).to eq(1) }
40
+ it { expect(addition.d(z)).to eq(0) }
35
41
 
36
- it{ expect(subtraction.d(:x)).to eq(1) }
37
- it{ expect(subtraction.d(:y)).to eq('( - 1 )') }
38
- it{ expect(subtraction.d(:z)).to eq(0) }
42
+ it { expect(subtraction.d(x)).to eq(1) }
43
+ it { expect(subtraction.d(y)).to eq(-1) }
44
+ it { expect(subtraction.d(z)).to eq(0) }
39
45
 
40
- it{ expect(multiplication.d(:x)).to eq(:y) }
41
- it{ expect(multiplication.d(:y)).to eq(:x) }
42
- it{ expect(multiplication.d(:z)).to eq(0) }
46
+ it { expect(multiplication.d(x)).to eq(y) }
47
+ it { expect(multiplication.d(y)).to eq(x) }
48
+ it { expect(multiplication.d(z)).to eq(0) }
43
49
 
44
- it{ expect(division.d(:x)).to eq(1/:y) }
45
- it{ expect(division.d(:y)).to eq('( - ( x / ( y ^ 2 ) ) )') }
46
- it{ expect(division.d(:z)).to eq(0) }
50
+ it { expect(division.d(x)).to eq(1 / y) }
51
+ it { expect(division.d(y)).to eq(- ( x / y ** 2 ) ) }
52
+ it { expect(division.d(z)).to eq(0) }
47
53
 
48
- it{ expect(exponentiation.d(:x).to_s).to eq('( y * ( x ^ ( y - 1 ) ) )') }
49
- it{ expect(exponentiation.d(:y)).to eq((:x ^ :y) * log(:x)) }
50
- it{ expect(exponentiation.d(:z)).to eq(0) }
54
+ it { expect(exponentiation.d(x)).to eq(y * x ** ( y - 1 )) }
55
+ it { expect(exponentiation.d(y)).to eq(x ** y * log(x)) }
56
+ it { expect(exponentiation.d(z)).to eq(0) }
51
57
  end
52
58
 
53
59
  describe '#include?' do
54
- it{ expect(addition.include?(:x)).to be_true }
55
- it{ expect(addition.include?(:z)).to be_false }
60
+ it { expect(addition.include?(x)).to be true }
61
+ it { expect(addition.include?(z)).to be false }
56
62
  end
57
63
 
58
64
  describe '#openable?' do
59
- it{ expect((:x + :y).openable?(:*, :x)).to be_true }
60
- it{ expect((:x + :y).openable?(:*, :y)).to be_true }
61
- it{ expect((:x + :y).openable?(:*, :z)).to be_false }
65
+ it { expect((x + y).openable?(:*, x)).to be true }
66
+ it { expect((x + y).openable?(:*, y)).to be true }
67
+ it { expect((x + y).openable?(:*, z)).to be false }
62
68
  end
63
69
  end
@@ -1,8 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dydx::Algebra::Operator::Parts::Base do
4
- it{ expect((:x + :x).to_s).to eq('( 2 * x )') }
5
- it{ expect((:x - :x).to_s).to eq('0') }
6
- it{ expect((:x * :x).to_s).to eq('( x ^ 2 )') }
7
- it{ expect((:x / :x).to_s).to eq('1') }
8
- end
4
+ it { expect((:x + :x).to_s).to eq('( 2 * x )') }
5
+ it { expect((:x - :x).to_s).to eq('0') }
6
+ it { expect((:x * :x).to_s).to eq('( x ** 2 )') }
7
+ it { expect((:x / :x).to_s).to eq('1') }
8
+ end
@@ -1,63 +1,63 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Dydx::Algebra::Operator::Parts::Formula do
4
- it{ expect(((:a * :b) + (:a * :c)).to_s).to eq('( a * ( b + c ) )') }
5
- it{ expect(((:a * :b) + (:c * :a)).to_s).to eq('( a * ( b + c ) )') }
6
- it{ expect(((:b * :a) + (:c * :a)).to_s).to eq('( a * ( b + c ) )') }
7
- it{ expect(((:b * :a) + (:a * :c)).to_s).to eq('( a * ( b + c ) )') }
8
- it{ expect(((:a * :b) - (:a * :c)).to_s).to eq('( a * ( b - c ) )') }
9
- it{ expect(((:a * :b) - (:c * :a)).to_s).to eq('( a * ( b - c ) )') }
10
- it{ expect(((:b * :a) - (:c * :a)).to_s).to eq('( a * ( b - c ) )') }
11
- it{ expect(((:b * :a) - (:a * :c)).to_s).to eq('( a * ( b - c ) )') }
12
-
13
- it{ expect(((:a ^ :b) * (:a ^ :c)).to_s).to eq('( a ^ ( b + c ) )') }
14
- it{ expect(((:a ^ :b) * (:c ^ :a)).to_s).to eq('( ( a ^ b ) * ( c ^ a ) )') }
15
- it{ expect(((:b ^ :a) * (:c ^ :a)).to_s).to eq('( ( b * c ) ^ a )') }
16
- it{ expect(((:b ^ :a) * (:a ^ :c)).to_s).to eq('( ( b ^ a ) * ( a ^ c ) )') }
17
- it{ expect(((:a ^ :b) / (:a ^ :c)).to_s).to eq('( a ^ ( b - c ) )') }
18
- it{ expect(((:a ^ :b) / (:c ^ :a)).to_s).to eq('( ( a ^ b ) / ( c ^ a ) )') }
19
- it{ expect(((:b ^ :a) / (:c ^ :a)).to_s).to eq('( ( b / c ) ^ a )') }
20
- it{ expect(((:b ^ :a) / (:a ^ :c)).to_s).to eq('( ( b ^ a ) / ( a ^ c ) )') }
21
-
22
- it{ expect(((:x - 2) + 2).to_s).to eq('x') }
23
- it{ expect(((:x + 2) - 2).to_s).to eq('x') }
24
- it{ expect(((:x * 2) / 2).to_s).to eq('x') }
25
- it{ expect(((:x / 2) * 2).to_s).to eq('x') }
26
-
27
- it{ expect((2 + (:x - 2)).to_s).to eq('x') }
28
- it{ expect((2 - (:x + 2)).to_s).to eq('( - x )') }
29
- it{ expect((2 * (:x / 2)).to_s).to eq('x') }
30
- it{ expect((2 / (:x * 2)).to_s).to eq('( 1 / x )') }
31
-
32
- it{ expect(((:x + :y) + :y).to_s).to eq('( ( 2 * y ) + x )') }
33
- it{ expect(((:y + :x) + :y).to_s).to eq('( ( 2 * y ) + x )') }
34
- it{ expect(((:x - :y) - :y).to_s).to eq('( x - ( 2 * y ) )') }
35
- it{ expect(((:y - :x) - :y).to_s).to eq('( - x )') }
36
- it{ expect(((:y * :x) * :y).to_s).to eq('( ( y ^ 2 ) * x )') }
37
- it{ expect(((:x * :y) * :y).to_s).to eq('( ( y ^ 2 ) * x )') }
38
- it{ expect(((:x / :y) / :y).to_s).to eq('( x / ( y ^ 2 ) )') }
39
- it{ expect(((:y / :x) / :y).to_s).to eq('( 1 / x )') }
40
-
41
- it{ expect((:y + (:x + :y)).to_s).to eq('( ( 2 * y ) + x )') }
42
- it{ expect((:y + (:y + :x)).to_s).to eq('( ( 2 * y ) + x )') }
43
- it{ expect((:y - (:x - :y)).to_s).to eq('( ( 2 * y ) - x )') }
44
- it{ expect((:y - (:y - :x)).to_s).to eq('x') }
45
- it{ expect((:y * (:y * :x)).to_s).to eq('( ( y ^ 2 ) * x )') }
46
- it{ expect((:y * (:x * :y)).to_s).to eq('( ( y ^ 2 ) * x )') }
47
- it{ expect((:y - (:x - :y)).to_s).to eq('( ( 2 * y ) - x )') }
48
- it{ expect((:y - (:y - :x)).to_s).to eq('x') }
49
-
50
- it{ expect((x + 3) * 2).to eq(x * 2 + 6) }
51
- # it{ expect((x - 3) * 2).to eq(x * 2 - 6) }
52
- it{ expect((x + 3) * 2).to eq(x * 2 + 6) }
53
- it{ expect((x + 3) * 2).to eq(x * 2 + 6) }
54
-
55
- it{ expect(((:x * 2) ^ 2).to_s).to eq('( 4 * ( x ^ 2 ) )') }
56
- it{ expect(((:x / 2) ^ 2).to_s).to eq('( ( x ^ 2 ) / 4 )') }
57
-
58
- it{ expect((3*x + 4*(x^2)+ 4*x).to_s).to eq('( ( 7 * x ) + ( 4 * ( x ^ 2 ) ) )') }
4
+ it { expect(a * b + a * c).to eq('( a * ( b + c ) )') }
5
+ it { expect(a * b + c * a).to eq('( a * ( b + c ) )') }
6
+ it { expect(b * a + c * a).to eq('( a * ( b + c ) )') }
7
+ it { expect(b * a + a * c).to eq('( a * ( b + c ) )') }
8
+ it { expect(a * b - a * c).to eq('( a * ( b - c ) )') }
9
+ it { expect(a * b - c * a).to eq('( a * ( b - c ) )') }
10
+ it { expect(b * a - c * a).to eq('( a * ( b - c ) )') }
11
+ it { expect(b * a - a * c).to eq('( a * ( b - c ) )') }
12
+
13
+ it { expect(a ** b * a ** c).to eq('( a ** ( b + c ) )') }
14
+ it { expect(a ** b * c ** a).to eq('( ( a ** b ) * ( c ** a ) )') }
15
+ it { expect(b ** a * c ** a).to eq('( ( b * c ) ** a )') }
16
+ it { expect(b ** a * a ** c).to eq('( ( b ** a ) * ( a ** c ) )') }
17
+ it { expect(a ** b / a ** c).to eq('( a ** ( b - c ) )') }
18
+ it { expect(a ** b / c ** a).to eq('( ( a ** b ) / ( c ** a ) )') }
19
+ it { expect(b ** a / c ** a).to eq('( ( b / c ) ** a )') }
20
+ it { expect(b ** a / a ** c).to eq('( ( b ** a ) / ( a ** c ) )') }
21
+
22
+ it { expect(((:x - 2) + 2).to_s).to eq('x') }
23
+ it { expect(((:x + 2) - 2).to_s).to eq('x') }
24
+ it { expect(((:x * 2) / 2).to_s).to eq('x') }
25
+ it { expect(((:x / 2) * 2).to_s).to eq('x') }
26
+
27
+ it { expect((2 + (:x - 2)).to_s).to eq('x') }
28
+ it { expect((2 - (:x + 2)).to_s).to eq('( - x )') }
29
+ it { expect((2 * (:x / 2)).to_s).to eq('x') }
30
+ it { expect((2 / (:x * 2)).to_s).to eq('( 1 / x )') }
31
+
32
+ it { expect((x + y) + y).to eq('( ( 2 * y ) + x )') }
33
+ it { expect((y + x) + y).to eq('( ( 2 * y ) + x )') }
34
+ it { expect((x - y) - y).to eq('( x - ( 2 * y ) )') }
35
+ it { expect((y - x) - y).to eq('( - x )') }
36
+ it { expect((y * x) * y).to eq('( ( y ** 2 ) * x )') }
37
+ it { expect((x * y) * y).to eq('( ( y ** 2 ) * x )') }
38
+ it { expect((x / y) / y).to eq('( x / ( y ** 2 ) )') }
39
+ it { expect((y / x) / y).to eq('( 1 / x )') }
40
+
41
+ it { expect(y + (x + y)).to eq('( ( 2 * y ) + x )') }
42
+ it { expect(y + (y + x)).to eq('( ( 2 * y ) + x )') }
43
+ it { expect(y - (x - y)).to eq('( ( 2 * y ) - x )') }
44
+ it { expect(y - (y - x)).to eq(x) }
45
+ it { expect(y * (y * x)).to eq('( ( y ** 2 ) * x )') }
46
+ it { expect(y * (x * y)).to eq('( ( y ** 2 ) * x )') }
47
+ it { expect(y - (x - y)).to eq('( ( 2 * y ) - x )') }
48
+ it { expect(y - (y - x)).to eq(x) }
49
+
50
+ it { expect((x + 3) * 2).to eq(x * 2 + 6) }
51
+ # it { expect((x - 3) * 2).to eq(x * 2 - 6) }
52
+ it { expect((x + 3) * 2).to eq(x * 2 + 6) }
53
+ it { expect((x + 3) * 2).to eq(x * 2 + 6) }
54
+
55
+ it { expect((x * 2) ** 2).to eq( 4 * x ** 2 ) }
56
+ it { expect((x / 2) ** 2).to eq( x ** 2 / 4 ) }
57
+
58
+ it { expect((3 * x + 4 * (x ** 2) + 4 * x).to_s).to eq('( ( 7 * x ) + ( 4 * ( x ** 2 ) ) )') }
59
59
 
60
60
  # TODO:
61
- it{ expect((2 ^ (:x * 2)).to_s).to eq('( 2 ^ ( 2 * x ) )') }
62
- it{ expect((2 ^ (:x / 2)).to_s).to eq('( 2 ^ ( x / 2 ) )') }
61
+ it { expect((2 ** (:x * 2)).to_s).to eq('( 2 ** ( 2 * x ) )') }
62
+ it { expect((2 ** (:x / 2)).to_s).to eq('( 2 ** ( x / 2 ) )') }
63
63
  end