dydx 0.1.314 → 0.1.412

Sign up to get free protection for your applications and to get access to all the features.
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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c3575108c38dd6f4c3e191dcada2dfcc03e11b10
4
- data.tar.gz: 37dbeb379531178c52253e213f6b79b930b0d9b7
3
+ metadata.gz: 05be03d422e433fa724050ae6c77c6de2044005d
4
+ data.tar.gz: 5a8ef94f9d271d9383ac3308c0f77acec91c6864
5
5
  SHA512:
6
- metadata.gz: 047b709dd5da3ec9b0058c86ced1755fbee7928279794c1f4d366c9f3e50c27a948e6feba092425073a3a3dc6781dfdacd4d5724aa947a41393ef6ae4e511c2f
7
- data.tar.gz: 846c7e77de2aad86f4e65a8b7e6cac39f88c9427b00c39fe7297efc6aa2d34f260450233c09ecca108200e2f8eb1cec492f7d0af48815bf24d1e85c0f916b6f4
6
+ metadata.gz: 9c2d8881754f7ee43700223926c2a249d91c3431bcc49ce9886c8c2991e5c58694a83626d5d1947c97c822208159d487343d8a85e353448ad7843177446757a7
7
+ data.tar.gz: 4a89a20e3810e52c23c97d88dd915e2a54263374e3f1a9b8a52ca444f9f1e3b219e63d1367be693a3787bf4f10f6e69f86baf6e9bc97ab1d2f2c7c5b46590760
@@ -0,0 +1,25 @@
1
+ Eval:
2
+ Enabled: false
3
+
4
+ LineLength:
5
+ Enabled: false
6
+
7
+ # Configuration parameters: AllowedVariables.
8
+ GlobalVars:
9
+ Enabled: false
10
+
11
+ # Configuration parameters: EnforcedStyle, SupportedStyles.
12
+ MethodName:
13
+ Enabled: false
14
+
15
+ OpMethod:
16
+ Enabled: false
17
+
18
+ Void:
19
+ Enabled: false
20
+
21
+ SpaceInsideParens:
22
+ Enabled: false
23
+
24
+ SpaceAroundOperators:
25
+ Enabled: false
@@ -1,6 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.0.0
3
4
  - 2.1.1
5
+ - jruby-head
4
6
  script: rake spec
5
7
  notifications:
6
- email: qlli.illb@gmail.com
8
+ email: mail@tanakakazuki.com
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in dydx.gemspec
4
+ gem 'rubocop'
4
5
  gem 'pry'
5
6
  gem 'pry-coolline'
6
7
  # gem 'pry-debugger'
data/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ### Since you report a bug, I will fix it within 24 hours.
4
4
 
5
+ [![Build Status](https://travis-ci.org/gogotanaka/dydx.svg?branch=master)](https://travis-ci.org/gogotanaka/dydx)
6
+
5
7
  The most important thing in this DSL is
6
8
 
7
9
  we can handle math in the same sense sense of the math on paper.
@@ -60,11 +62,11 @@ d/dx(log(x)) == 1 / x
60
62
  d/dx(cos(x)) == -cos(x)
61
63
  => true
62
64
 
63
- d/dx(e ^ x) == e ^ x
65
+ d/dx(e ** x) == e ** x
64
66
  => true
65
67
 
66
68
  # standard normal distribution;
67
- f(x) <= (1.0 / ( ( 2.0 * pi ) ^ 0.5 ) ) * ( e ^ (- (x ^ 2) / 2) )
69
+ f(x) <= (1.0 / ( 2.0 * pi ) ** 0.5) * e ** (- x ** 2 / 2)
68
70
  S(f(x), dx)[-oo, oo]
69
71
  => 1.0
70
72
  ```
data/Rakefile CHANGED
@@ -1,13 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
  require 'bundler/setup'
4
4
 
5
- desc "run spec"
5
+ desc 'run spec'
6
6
 
7
- #do `rake spec`
8
- RSpec::Core::RakeTask.new(:spec) do |t|
9
- t.rspec_opts = ["-c", "-fs"]
10
- end
7
+ # do `rake spec`
8
+ RSpec::Core::RakeTask.new(:spec)
11
9
 
12
10
  task default: :spec
13
-
@@ -4,22 +4,22 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'dydx/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "dydx"
7
+ spec.name = 'dydx'
8
8
  spec.version = Dydx::VERSION
9
- spec.authors = ["gogotanaka"]
10
- spec.email = ["qlli.illb@gmail.com"]
11
- spec.homepage = "https://github.com/gogotanaka"
12
- spec.summary = %q{We can enjoy the math.}
13
- spec.description = %q{Dydx is new math DSL in Ruby. The most important thing in this DSL is we can handle math in the same sense sense of the math on paper.}
9
+ spec.authors = ['gogotanaka']
10
+ spec.email = ['mail@tanakakazuki.com']
11
+ spec.homepage = 'http://gogotanaka.me/'
12
+ spec.summary = %q(We can enjoy the math.)
13
+ spec.description = %q(Dydx is new math DSL in Ruby. The most important thing in this DSL is we can handle math in the same sense sense of the math on paper.)
14
14
 
15
- spec.license = "MIT"
15
+ spec.license = 'MIT'
16
16
 
17
17
  spec.files = `git ls-files -z`.split("\x0")
18
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
- spec.require_paths = ["lib"]
18
+ spec.executables = spec.files.grep(/^bin\//) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(/^(test|spec|features)\//)
20
+ spec.require_paths = ['lib']
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.6"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "rspec"
22
+ spec.add_development_dependency 'bundler', '~> 1.6'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rspec'
25
25
  end
@@ -6,14 +6,13 @@ require 'dydx/integrand'
6
6
 
7
7
  module Dydx
8
8
  include Algebra
9
- %w(f g h int_f).each do |functioner|
9
+ %w(f g h temp_cal_f).each do |functioner|
10
10
  define_method(functioner) do |*vars|
11
11
  function = eval("$#{functioner}")
12
12
  return eval("$#{functioner} = Function.new(*vars)") unless function
13
13
 
14
- raise ArgumentError, "invalid number of values (#{vars.count} for #{function.vars.count})" unless function.vars.count == vars.count
15
- return function if function.vars == vars
16
- return function unless function.algebra
14
+ fail ArgumentError, "invalid number of values (#{vars.count} for #{function.vars.count})" unless function.vars.count == vars.count
15
+ return function if function.vars == vars || !function.algebra
17
16
 
18
17
  subst_hash = Hash[*[function.vars, vars].transpose.flatten]
19
18
  begin
@@ -25,7 +24,12 @@ module Dydx
25
24
  end
26
25
 
27
26
  def S(function, delta)
28
- Integrand.new(function, delta.var)
27
+ itgrl_var = delta.var
28
+ unless function.is_a?(Function)
29
+ eval "g(#{itgrl_var}) <= #{function}"
30
+ function = g(x)
31
+ end
32
+ Integrand.new(function, itgrl_var)
29
33
  end
30
34
 
31
35
  def d
@@ -36,6 +40,17 @@ module Dydx
36
40
  $f, $g, $h = nil, nil, nil
37
41
  end
38
42
 
43
+ def _(*args)
44
+ case args.count
45
+ when 1
46
+ num = args.first
47
+ Num.new(num)
48
+ when 3
49
+ ltr, op, rtr = args
50
+ ltr.send(op, rtr)
51
+ end
52
+ end
53
+
39
54
  def method_missing(method, *args, &block)
40
55
  method_name = method.to_s
41
56
  if method_name =~ /^d.$/
@@ -46,26 +61,4 @@ module Dydx
46
61
  super
47
62
  end
48
63
  end
49
-
50
- private
51
-
52
- def substitute(vars, function)
53
- string = function.algebra.to_s
54
- function.vars.each_with_index { |var, i| string.gsub!(var.to_s, vars[i].to_s) }
55
- string
56
- end
57
-
58
- def all_vars_num?(vars)
59
- vars.all? { |v| v.is_a?(Numeric) }
60
- end
61
-
62
- def rename_for_calc(string)
63
- # TODO: need more refactoring...
64
- string.gsub!('cos', 'Math.cos')
65
- string.gsub!('sin', 'Math.sin')
66
- string.gsub!('log', 'Math.log')
67
- string.gsub!(' e ', ' Math::E ')
68
- string.gsub!('pi', 'Math::PI')
69
- string
70
- end
71
64
  end
@@ -1,6 +1,4 @@
1
1
  require 'dydx/algebra/set'
2
- require 'dydx/algebra/formula'
3
- require 'dydx/algebra/inverse'
4
2
 
5
3
  module Dydx
6
4
  module Algebra
@@ -9,11 +7,15 @@ module Dydx
9
7
  class Formula; include Operator::Formula; end
10
8
  class Inverse; include Operator::Inverse; end
11
9
 
10
+ # TODO: Cyclomatic complexity for inverse is too high. [7/6]
12
11
  def inverse(x, operator)
13
- if operator == :+ && x.is_0?
14
- e0
15
- elsif operator == :* && x.is_1?
16
- e1
12
+ if x.num?
13
+ x = x.to_numeric
14
+ if operator == :+
15
+ _(- x)
16
+ else
17
+ _(Rational(1, x))
18
+ end
17
19
  elsif x.is_a?(Inverse) && x.operator == operator
18
20
  x.x
19
21
  else
@@ -2,23 +2,44 @@ module Dydx
2
2
  module Algebra
3
3
  class Formula
4
4
  include Helper
5
- attr_accessor :f, :operator, :g
5
+ attr_accessor :operator, :terms
6
6
 
7
- def initialize(f, g, operator)
8
- g, f = f, g if g.is_num? && operator.commutative?
9
- @f, @g, @operator = f, g, operator
7
+ def initialize(operator, *terms)
8
+ @operator, @terms = operator, terms
9
+ commutate! if (terms[1].num? && operator.commutative?)
10
10
  end
11
11
 
12
- def differentiate(sym=:x)
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 tms
29
+ terms
30
+ end
31
+
32
+ # TODO: Cylomatic complexity for differentiate is too high. [7/6]
33
+ def differentiate(sym = :x)
13
34
  case @operator
14
35
  when :+ then f.d(sym) + g.d(sym)
15
36
  when :* then (f.d(sym) * g) + (f * g.d(sym))
16
- when :^
37
+ when :**
17
38
  # TODO:
18
- if g.is_num?
19
- f.d(sym) * g * (f ^ (g - 1) )
39
+ if g.num?
40
+ f.d(sym) * g * (f ** (g - 1))
20
41
  elsif f == sym
21
- g * (f ^ (g - 1))
42
+ g * (f ** (g - 1))
22
43
  elsif f == e
23
44
  g.d(sym) * self
24
45
  else
@@ -29,14 +50,18 @@ module Dydx
29
50
  alias_method :d, :differentiate
30
51
 
31
52
  def to_s
32
- if (formula?(:*) && (f.is_minus1? || g.is_minus1?) )
33
- "( - #{g.to_s} )"
53
+ if formula?(:*) && (f.minus1? || g.minus1?)
54
+ "( - #{g} )"
34
55
  elsif g.inverse?(operator)
35
- "( #{f.to_s} #{inverse_ope(operator)} #{g.x.to_s} )"
56
+ "( #{f} #{operator.inv} #{g.x} )"
36
57
  elsif f.inverse?(operator)
37
- "( #{g.to_s} #{inverse_ope(operator)} #{f.x.to_s} )"
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} )"
38
63
  else
39
- "( #{f.to_s} #{operator} #{g.to_s} )"
64
+ "( #{f} #{operator} #{g} )"
40
65
  end
41
66
  end
42
67
 
@@ -57,6 +82,10 @@ module Dydx
57
82
  (f.combinable?(x, operator) || g.combinable?(x, operator))
58
83
  end
59
84
 
85
+ def rationals
86
+ [f, g].select{ |term| term.num? && term.n.is_a?(Rational) }
87
+ end
88
+
60
89
  def ==(x)
61
90
  if to_s == x.to_s
62
91
  true
@@ -67,23 +96,19 @@ module Dydx
67
96
  end
68
97
  end
69
98
 
70
- def common_factors(formula)
71
- nil unless formula.is_a?(Formula)
72
- if f == formula.f
73
- [:f, :f]
74
- elsif g == formula.g
75
- [:g, :g]
76
- elsif f == formula.g
77
- [:f, :g]
78
- elsif g == formula.f
79
- [:g, :f]
80
- end
81
- end
82
-
83
99
  def commutate!
84
- @f, @g = @g, @f
100
+ @terms.reverse!
85
101
  self
86
102
  end
103
+
104
+ def index(tm)
105
+ tms.index(tm)
106
+ end
107
+
108
+ def delete(tm)
109
+ tms.delete(tm)
110
+ tms.count.one? ? tms.first : self
111
+ end
87
112
  end
88
113
  end
89
114
  end
@@ -29,12 +29,12 @@ module Dydx
29
29
  end
30
30
  end
31
31
 
32
- def differentiate(sym=:x)
32
+ def differentiate(sym = :x)
33
33
  case operator
34
34
  when :+
35
35
  inverse(x.differentiate(sym), :+)
36
36
  when :*
37
- inverse(x.differentiate(sym) * inverse(x ^ 2, :*), :+)
37
+ inverse(x.differentiate(sym) * inverse(x ** 2, :*), :+)
38
38
  end
39
39
  end
40
40
  alias_method :d, :differentiate
@@ -5,7 +5,6 @@ module Dydx
5
5
  include Parts::Base
6
6
  include Parts::Formula
7
7
  include Parts::General
8
- include Parts::Interface
9
8
  end
10
9
  end
11
10
  end
@@ -4,7 +4,6 @@ module Dydx
4
4
  module General
5
5
  include Parts::Base
6
6
  include Parts::General
7
- include Parts::Interface
8
7
  end
9
8
  end
10
9
  end
@@ -5,7 +5,6 @@ module Dydx
5
5
  include Parts::Base
6
6
  include Parts::Inverse
7
7
  include Parts::General
8
- include Parts::Interface
9
8
  end
10
9
  end
11
10
  end
@@ -5,7 +5,6 @@ module Dydx
5
5
  include Parts::Base
6
6
  include Parts::Num
7
7
  include Parts::General
8
- include Parts::Interface
9
8
  end
10
9
  end
11
10
  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(self, x, operator.to_sym)
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 |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)
6
+ %w(+ *).map(&:to_sym).each do |op|
7
+ define_method(op) do |rtm|
8
+ if operator == op
9
+ if tms[0].combinable?(rtm, op)
10
+ _(
11
+ _(tms[0], op, rtm), op, tms[1]
12
+ )
13
+ elsif tms[1].combinable?(rtm, op)
14
+ _(
15
+ _(tms[1], op, rtm), op, tms[0]
16
+ )
13
17
  else
14
- super(x)
18
+ super(rtm)
15
19
  end
16
- elsif formula?(operator.sub) && openable?(operator, x)
17
- f.send(operator, x).send(operator.sub, g.send(operator, x))
18
- elsif formula?(operator.super) && x.formula?(operator.super)
19
- w1, w2 = common_factors(x)
20
- return super(x) unless (w1 && w2) && (operator.super.commutative? || w1 == w2)
20
+ elsif formula?(op.sub) && openable?(op, rtm)
21
+ _(
22
+ _(tms[0], op, rtm), op.sub, _(tms[1], op, rtm)
23
+ )
24
+ elsif formula?(op.super) && rtm.formula?(op.super)
25
+ cmn_fct = (tms & rtm.tms).first
26
+ return super(rtm) unless cmn_fct
21
27
 
22
- case operator
23
- when :+
24
- send(w1).send(operator.super, send(rest(w1)).send(operator, x.send(rest(w2))))
25
- when :*
26
- case w1
27
- when :f
28
- send(w1).send(operator.super, send(rest(w1)).send(operator.sub, x.send(rest(w2))))
29
- when :g
30
- send(w1).send(operator.super, send(rest(w1)).send(operator, x.send(rest(w2)))).commutate!
28
+ if op.super.commutative?
29
+ _(
30
+ cmn_fct, op.super, _(delete(cmn_fct), op, rtm.delete(cmn_fct))
31
+ )
32
+ else
33
+ return super(rtm) if index(cmn_fct) != rtm.index(cmn_fct)
34
+
35
+ case index(cmn_fct)
36
+ when 0
37
+ _(
38
+ cmn_fct, op.super, _(delete(cmn_fct), op.sub, rtm.delete(cmn_fct))
39
+ )
40
+ when 1
41
+ _(
42
+ _(delete(cmn_fct), op, rtm.delete(cmn_fct)), op.super, cmn_fct
43
+ )
31
44
  end
32
45
  end
33
- elsif formula?(operator.super) && x.inverse?(operator) && x.x.formula?(operator.super)
34
- w1, w2 = common_factors(x.x)
35
- return super(x) unless (w1 && w2) && (operator.super.commutative? || w1 == w2)
46
+ elsif formula?(op.super) && rtm.inverse?(op) && rtm.x.formula?(op.super)
47
+ cmn_fct = (tms & rtm.x.tms).first
48
+ return super(rtm) unless cmn_fct
36
49
 
37
- case operator
38
- when :+
39
- send(w1).send(operator.super, send(rest(w1)).send(inverse_ope(operator), x.x.send(rest(w2))))
40
- when :*
41
- case w1
42
- when :f
43
- send(w1).send(operator.super, send(rest(w1)).send(inverse_ope(operator.sub), x.x.send(rest(w2))))
44
- when :g
45
- send(w1).send(operator.super, send(rest(w1)).send(inverse_ope(operator), x.x.send(rest(w2)))).commutate!
50
+ if op.super.commutative?
51
+ _(
52
+ cmn_fct, op.super, _(delete(cmn_fct), op.inv, rtm.x.delete(cmn_fct))
53
+ )
54
+ else
55
+ return super(rtm) if index(cmn_fct) != rtm.x.index(cmn_fct)
56
+ case index(cmn_fct)
57
+ when 0
58
+ _(
59
+ cmn_fct, op.super, _(delete(cmn_fct), op.sub.inv, rtm.x.delete(cmn_fct))
60
+ )
61
+ when 1
62
+ _(
63
+ _(delete(cmn_fct), op.inv, rtm.x.delete(cmn_fct)), op.super, cmn_fct
64
+ )
46
65
  end
47
66
  end
48
67
  else
49
- super(x)
68
+ super(rtm)
50
69
  end
51
70
  end
52
71
  end
53
72
 
54
- %w(^).map(&:to_sym).each do |operator|
55
- define_method(operator) do |x|
56
- if formula?(operator.sub) && openable?(operator, x)
57
- f.send(operator, x).send(operator.sub, g.send(operator, x))
73
+ %w(**).map(&:to_sym).each do |op|
74
+ define_method(op) do |rtm|
75
+ if formula?(op.sub) && openable?(op, rtm)
76
+ _(
77
+ _(tms[0], op, rtm), op.sub, _(tms[1], op, rtm)
78
+ )
58
79
  else
59
- super(x)
80
+ super(rtm)
60
81
  end
61
82
  end
62
83
  end