dydx 0.1.4 → 0.1.25

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 +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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 79327c9edd590f2a006eb29d8b148919d913c9a4
4
- data.tar.gz: d5b7e817ffe55271c3a473d3b1679b3abaa929ee
3
+ metadata.gz: 50e18dda6ca41f30bb45fdbc2f73c906c6e01c94
4
+ data.tar.gz: 14094dd2083a888d715e93eb0a1faa8aa6f9cf13
5
5
  SHA512:
6
- metadata.gz: 5716ffe76bc6e49af3ef2560920cebc20845b01ec1be35ca6b46a4a454530b1582a9820add4c6a2b0a29bfc84e26751133faea9c5c277c19fd1f5f9b8c8c842b
7
- data.tar.gz: f5dd91eb57c7ac6d6a3dd8a8318b98953295d4de7fb67c530fad3c040b351e225c1a79da03fe4bbb51110545a572fb8ba194de715a34f8ce96a1d6b627c7e4bd
6
+ metadata.gz: abbe8199d94ede3e5568aaf41c5d4dba0996af0b2da53e8313372d96d67c401c64e802f30777995f92fc966cb4e81740ffae5228ce352f711856793615435d3c
7
+ data.tar.gz: 12087ca360a5da0e9fa6c32ed5818d8b40c3044a1f9efa2da4bbf75772fad9794a5b7660eb6239009c051ebe30ac7f8ef293611caf16b3610c265709a6f5e7c8
data/Gemfile CHANGED
@@ -1,8 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in dydx.gemspec
4
- gem 'rubocop'
5
4
  gem 'pry'
6
- gem 'pry-coolline'
7
- # gem 'pry-debugger'
8
5
  gemspec
data/README.md CHANGED
@@ -1,94 +1,157 @@
1
- # Dydx is new MATH Language on Ruby.
1
+ # Dydx
2
+ It always happens you want to differentiate some formulas with ruby. right?.....
2
3
 
3
- ### Since you report a bug, I will fix it within 24 hours.
4
-
5
- The most important thing in this DSL is
4
+ After `inlcude Dydx` , ruby become like other language.
6
5
 
7
- we can handle math in the same sense sense of the math on paper.
6
+ ## Dydx is new math DSL in Ruby
8
7
 
9
- ex. limit, trigonometric functions and logarithmic.
8
+ I'm going to add for more explanation.
10
9
 
11
- ## We should enjoy MATH even using PC.
12
- (to say nothing of using pen.)
13
10
 
14
- After `inlcude Dydx` , ruby become like other language.
15
11
 
16
- ## Outline
17
12
  ```ruby:
18
13
  require 'dydx'
19
14
  include Dydx
20
15
 
21
- # Define the function. syntax is not good enough...
22
- f(x, y) <= x + x*y + y
16
+ f(x) <= x ^ 2
17
+
18
+ f(3)
19
+ # => 9
20
+
21
+ f(x).to_s
22
+ # => "( x ^ 2 )"
23
+
24
+ f(x) == eval('f(x).to_s')
25
+ # => true
23
26
 
24
- # simplify
25
- f(x, y) == x * (1 + y) + y
26
- => true
27
+ g(x) <= d/dx(f(x))
27
28
 
28
- #part substitution
29
- f(a, 2) == 3*a + 2
30
- => true
29
+ g(3)
30
+ # => 6
31
31
 
32
- f(1, a + b) == 1 + 2 * ( a + b )
33
- => true
32
+ # => '2 * x'
34
33
 
34
+ S(f(x), dx)[0, 1]
35
+ # => 0.3333333333333334
36
+
37
+ ( d/dx(log(x)) ).to_s
38
+ # => "( 1 / x )"
39
+
40
+ ( d/dx(cos(x)) ).to_s
41
+ # => "( - sin( x ) )"
42
+
43
+ ( d/dx(e ^ x) ).to_s
44
+ # => "( e ^ x )"
45
+
46
+ f(x) <= sin(x)
47
+ S(f(x), dx)[0, Math::PI/2]
48
+ # => 1.000000000021139
49
+
50
+ f(x) <= (1.0 / ( ( 2.0 * pi ) ^ 0.5 ) ) * ( e ^ (- (x ^ 2) / 2) )
51
+ S(f(x), dx)[-oo, oo]
52
+ # => 0.9952054164466917
35
53
 
36
- # Differentiate
37
- d/dx(f(x, y)) == 1 + y
38
- => true
54
+ f(x) <= x ^ 2
39
55
 
40
- g(x) <= sin(x)
56
+ f(a + b).to_s
57
+ # => "( ( a + b ) ^ 2 )"
41
58
 
42
- d/dx(g(x)) == cos(x)
59
+ g(a, b) <= f(a + b)
43
60
 
44
- # Integrate
45
- S(g(x), dx)[0, pi/2]
46
- => 1.0
61
+ g(a, b).to_s
62
+ # => "( ( a + b ) ^ 2 )"
63
+
64
+ g(2, 2)
65
+ # => 16
66
+
67
+ ( d/da(g(a, b)) ).to_s
68
+ => "( 2 * ( a + b ) )"
47
69
  ```
48
70
 
49
71
 
50
- #### limit, trigonometric functions and logarithmic.
51
- ```ruby:
52
72
 
53
- f(z) <= log(z)
54
- S(f(z), dz)[0,1]
55
- => -Infinity
56
73
 
57
- d/dx(log(x)) == 1 / x
58
- => true
59
74
 
60
- d/dx(cos(x)) == -cos(x)
61
- => true
75
+ ```
76
+ require 'dydx'
77
+ include Dydx
62
78
 
63
- d/dx(e ** x) == e ** x
64
- => true
79
+ # There are three types of differential interface
80
+
81
+ ( d/dx(x^2) ).to_s
82
+ => "( 2 * x )"
83
+
84
+ log(z).d(z).to_s
85
+ => "( 1 / z )"
86
+
87
+ $y = e ^ x
88
+ (dy/dx).to_s
89
+ => "( e ^ x )"
65
90
 
66
- # standard normal distribution;
67
- f(x) <= (1.0 / ( 2.0 * pi ) ** 0.5) * e ** (- x ** 2 / 2)
68
- S(f(x), dx)[-oo, oo]
69
- => 1.0
70
91
  ```
71
92
 
72
- ## Documents
73
- I'm going to write now...cominng soon....
93
+ You may wonder why undefined `x` , `e` and `z` are handleable?
94
+
95
+ `method_missing` solve this problem by converting undefine variable into internal class object.
74
96
 
75
- ### Module, class configuration
97
+ Like this.
76
98
 
77
99
  ```
78
- Dydx
79
- |- Algebra
80
- | |- Operator
81
- | | |- Interface
82
- | | |- ....
83
- | |
84
- | |- Set
85
- | |- Formula
86
- | |- inverse
87
- |
88
- |- Function
89
- |- Delta
90
- |- Integrand
100
+ x + x
101
+ => #<Dydx::Algebra::Formula:0x007fb0a4039fb0 @f=#<Dydx::Algebra::Set::Num:0x007fb0a48169e0 @n=2>, @operator=:*, @g=:x>
102
+
103
+ e
104
+ => #<Dydx::Algebra::Set::E:0x007fb0a383e9f0>
105
+
106
+ log(sin(x))
107
+ => #<Dydx::Algebra::Set::Log:0x007fe7cd971528 @f=#<Dydx::Algebra::Set::Sin:0x007fe7cd971550 @x=:x>>
108
+ ```
109
+
110
+ And this DSL has strong simplify.
111
+
112
+ ```
113
+ ((x * y) + (z * x)).to_s
114
+ => "( x * ( y + z ) )"
115
+
116
+ ((x ^ y) / (x ^ z)).to_s
117
+ => "( x ^ ( y - z ) )"
118
+
119
+ (x + x).to_s
120
+ => "( 2 * x )"
121
+ ```
122
+
123
+ I show some differential calculus.
124
+
91
125
  ```
126
+ # pretermit '#to_s'
127
+
128
+ d/dz(log(z))
129
+ => "( 1 / z )"
130
+
131
+ d/dx(x^n)
132
+ => "( n * ( x ^ ( n - 1 ) ) )"
133
+
134
+ $y = cos(x)
135
+ dy/dx
136
+ => "( - sin( x ) )"
137
+
138
+ $x = a * ( (t ^ 2) / 2 )
139
+ dx/dt
140
+ => "( a * t )"
141
+
142
+ d/dt(dx/dt)
143
+ =>"a"
144
+
145
+ ((x ^ 2) * y).d(x)
146
+ => "( ( 2 * x ) * y )"
147
+
148
+ ((x ^ 2) * y).d(x).d(y)
149
+ => "( 2 * x )"
150
+
151
+ ```
152
+
153
+
154
+ (That's wonderful!!!!! ..............)
92
155
 
93
156
  ## Installation
94
157
 
@@ -121,6 +184,6 @@ Or install it yourself as:
121
184
  run `bundle exec rake spec`
122
185
 
123
186
  ```
124
- Finished in 3.76 seconds
125
- 325 examples, 0 failures
187
+ Finished in 3.23 seconds
188
+ 309 examples, 0 failures
126
189
  ```
data/Rakefile CHANGED
@@ -1,10 +1,13 @@
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)
7
+ #do `rake spec`
8
+ RSpec::Core::RakeTask.new(:spec) do |t|
9
+ t.rspec_opts = ["-c", "-fs"]
10
+ end
9
11
 
10
12
  task default: :spec
13
+
data/dydx.gemspec CHANGED
@@ -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 = ["qlli.illb@gmail.com"]
11
+ spec.homepage = "https://github.com/gogotanaka"
12
+ spec.summary = %q{We can enjoy the derivative.}
13
+ spec.description = %q{It is possible to use the differential using the Symbol and Fixnum by including the Dydx. And, we can use the natural logarithm and log.}
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(/^bin\//) { |f| File.basename(f) }
19
- spec.test_files = spec.files.grep(/^(test|spec|features)\//)
20
- spec.require_paths = ['lib']
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"]
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
data/lib/dydx.rb CHANGED
@@ -6,19 +6,32 @@ require 'dydx/integrand'
6
6
 
7
7
  module Dydx
8
8
  include Algebra
9
- %w(f g h temp_cal_f).each do |functioner|
9
+ # TODO: Refactor
10
+ %w(f g h).each do |functioner|
10
11
  define_method(functioner) do |*vars|
11
- function = eval("$#{functioner}")
12
- return eval("$#{functioner} = Function.new(*vars)") unless function
13
-
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
16
-
17
- subst_hash = Hash[*[function.vars, vars].transpose.flatten]
18
- begin
19
- function.algebra.subst(subst_hash).to_f
20
- rescue ArgumentError
21
- eval(function.algebra.subst(subst_hash).to_s)
12
+ if function = eval("$#{functioner}")
13
+ raise ArgumentError, "invalid number of values (#{vars.count} for #{function.vars.count})" unless function.vars.count == vars.count
14
+ return function if function.vars == vars
15
+ if function.algebra
16
+ if vars.all?{|v| v.is_a?(Numeric)}
17
+ string = function.algebra.to_s
18
+ .gsub('cos', 'Math.cos')
19
+ .gsub('sin', 'Math.sin')
20
+ .gsub('log', 'Math.log')
21
+ .gsub('e', 'Math::E')
22
+ .gsub('pi', 'Math::PI')
23
+ else
24
+ string = function.algebra.to_s
25
+ end
26
+ function.vars.each_with_index do |var, i|
27
+ string.gsub!(var.to_s, vars[i].to_s)
28
+ end
29
+ eval(string)
30
+ else
31
+ function
32
+ end
33
+ else
34
+ eval("$#{functioner} = Function.new(*vars)")
22
35
  end
23
36
  end
24
37
  end
@@ -35,17 +48,6 @@ module Dydx
35
48
  $f, $g, $h = nil, nil, nil
36
49
  end
37
50
 
38
- def _(*args)
39
- case args.count
40
- when 1
41
- num = args.first
42
- Num.new(num)
43
- when 3
44
- ltr, op, rtr = args
45
- ltr.send(op, rtr)
46
- end
47
- end
48
-
49
51
  def method_missing(method, *args, &block)
50
52
  method_name = method.to_s
51
53
  if method_name =~ /^d.$/
data/lib/dydx/algebra.rb CHANGED
@@ -1,21 +1,89 @@
1
+ require 'dydx/algebra/formula'
2
+ require 'dydx/algebra/inverse'
3
+
1
4
  require 'dydx/algebra/set'
2
5
 
6
+ require 'dydx/algebra/operator/inverse'
7
+ require 'dydx/algebra/operator/formula'
8
+ require 'dydx/algebra/operator/symbol'
9
+ require 'dydx/algebra/operator/num'
10
+ require 'dydx/algebra/operator/general'
11
+
3
12
  module Dydx
4
13
  module Algebra
5
14
  include Set
15
+ module Set
16
+ # TODO: Refactor
17
+ Symbol.class_eval{ include Operator::Symbol }
18
+ Fixnum.class_eval do
19
+ alias_method :addition, :+
20
+ alias_method :subtraction, :-
21
+ alias_method :multiplication, :*
22
+ alias_method :division, :/
23
+ alias_method :exponentiation, :**
24
+ ope_to_str = {
25
+ addition: :+,
26
+ subtraction: :-,
27
+ multiplication: :*,
28
+ division: :/,
29
+ exponentiation: :^
30
+ }
31
+ %w(+ - * / ^).each do |operator|
32
+ define_method(operator) do |g|
33
+ if g.is_a?(Symbol) ||
34
+ g.is_a?(Formula) ||
35
+ g.is_a?(Base)
36
+
37
+ Num.new(self).send(operator.to_sym, g)
38
+ else
39
+ send(ope_to_str.key(operator.to_sym), g)
40
+ end
41
+ end
42
+ end
43
+ end
6
44
 
45
+ Float.class_eval do
46
+ alias_method :addition, :+
47
+ alias_method :subtraction, :-
48
+ alias_method :multiplication, :*
49
+ alias_method :division, :/
50
+ alias_method :exponentiation, :**
51
+ ope_to_str = {
52
+ addition: :+,
53
+ subtraction: :-,
54
+ multiplication: :*,
55
+ division: :/,
56
+ exponentiation: :^
57
+ }
58
+ %w(+ - * / ^).each do |operator|
59
+ define_method(operator) do |g|
60
+ if g.is_a?(Symbol) ||
61
+ g.is_a?(Formula) ||
62
+ g.is_a?(Base)
63
+
64
+ Num.new(self).send(operator.to_sym, g)
65
+ else
66
+ send(ope_to_str.key(operator.to_sym), g)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ class Num; include Operator::Num; end
72
+ class E; include Operator::General; end
73
+ class Pi; include Operator::General; end
74
+ class Log; include Operator::General; end
75
+ class Sin; include Operator::General; end
76
+ class Cos; include Operator::General; end
77
+ class Tan; include Operator::General; end
78
+ end
7
79
  class Formula; include Operator::Formula; end
8
80
  class Inverse; include Operator::Inverse; end
9
81
 
10
- # TODO: Cyclomatic complexity for inverse is too high. [7/6]
11
82
  def inverse(x, operator)
12
- if x.num?
13
- x = x.to_numeric
14
- if operator == :+
15
- _(- x)
16
- else
17
- _(Rational(1, x))
18
- end
83
+ if operator == :+ && x.is_0?
84
+ e0
85
+ elsif operator == :* && x.is_1?
86
+ e1
19
87
  elsif x.is_a?(Inverse) && x.operator == operator
20
88
  x.x
21
89
  else