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.
- checksums.yaml +4 -4
- data/Gemfile +0 -3
- data/README.md +124 -61
- data/Rakefile +8 -5
- data/dydx.gemspec +13 -13
- data/lib/dydx.rb +25 -23
- data/lib/dydx/algebra.rb +76 -8
- data/lib/dydx/algebra/formula.rb +38 -71
- data/lib/dydx/algebra/inverse.rb +12 -19
- data/lib/dydx/algebra/operator/common_parts.rb +3 -0
- data/lib/dydx/algebra/operator/formula.rb +4 -0
- data/lib/dydx/algebra/operator/general.rb +4 -0
- data/lib/dydx/algebra/operator/inverse.rb +4 -0
- data/lib/dydx/algebra/operator/num.rb +4 -0
- data/lib/dydx/algebra/operator/parts/base.rb +2 -2
- data/lib/dydx/algebra/operator/parts/formula.rb +38 -63
- data/lib/dydx/algebra/operator/parts/general.rb +31 -84
- data/lib/dydx/algebra/operator/parts/interface.rb +22 -0
- data/lib/dydx/algebra/operator/parts/inverse.rb +4 -4
- data/lib/dydx/algebra/operator/parts/num.rb +11 -16
- data/lib/dydx/algebra/operator/parts/symbol.rb +2 -2
- data/lib/dydx/algebra/operator/symbol.rb +15 -0
- data/lib/dydx/algebra/set.rb +34 -271
- data/lib/dydx/algebra/set/base.rb +9 -0
- data/lib/dydx/algebra/set/cos.rb +22 -0
- data/lib/dydx/algebra/set/e.rb +16 -0
- data/lib/dydx/algebra/set/fixnum.rb +14 -0
- data/lib/dydx/algebra/set/float.rb +14 -0
- data/lib/dydx/algebra/set/log.rb +22 -0
- data/lib/dydx/algebra/set/num.rb +26 -0
- data/lib/dydx/algebra/set/pi.rb +16 -0
- data/lib/dydx/algebra/set/sin.rb +21 -0
- data/lib/dydx/algebra/set/symbol.rb +14 -0
- data/lib/dydx/algebra/set/tan.rb +17 -0
- data/lib/dydx/delta.rb +1 -1
- data/lib/dydx/function.rb +1 -1
- data/lib/dydx/helper.rb +61 -55
- data/lib/dydx/integrand.rb +10 -22
- data/lib/dydx/version.rb +1 -1
- data/spec/dydx_spec.rb +29 -10
- data/spec/lib/algebra/formula_spec.rb +38 -44
- data/spec/lib/algebra/operator/parts/base_spec.rb +5 -5
- data/spec/lib/algebra/operator/parts/formula_spec.rb +50 -57
- data/spec/lib/algebra/operator/parts/inverse_spec.rb +8 -8
- data/spec/lib/algebra/set/cos_spec.rb +18 -0
- data/spec/lib/algebra/set/e_spec.rb +27 -0
- data/spec/lib/algebra/set/fixnum_spec.rb +65 -0
- data/spec/lib/algebra/set/float_spec.rb +65 -0
- data/spec/lib/algebra/set/log_spec.rb +15 -0
- data/spec/lib/algebra/set/num_spec.rb +23 -0
- data/spec/lib/algebra/set/pi_spec.rb +25 -0
- data/spec/lib/algebra/set/sin_spec.rb +14 -0
- data/spec/lib/algebra/set/symbol_spec.rb +22 -0
- data/spec/lib/algebra/set/tan_spec.rb +13 -0
- data/spec/lib/delta_spec.rb +8 -32
- data/spec/lib/function_spec.rb +34 -60
- data/spec/lib/helper_spec.rb +49 -47
- data/spec/lib/integrand_spec.rb +15 -13
- data/spec/spec_helper.rb +1 -2
- metadata +39 -9
- data/.pryrc +0 -2
- data/.rubocop.yml +0 -25
- data/spec/lib/algebra/set_spec.rb +0 -263
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50e18dda6ca41f30bb45fdbc2f73c906c6e01c94
|
4
|
+
data.tar.gz: 14094dd2083a888d715e93eb0a1faa8aa6f9cf13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abbe8199d94ede3e5568aaf41c5d4dba0996af0b2da53e8313372d96d67c401c64e802f30777995f92fc966cb4e81740ffae5228ce352f711856793615435d3c
|
7
|
+
data.tar.gz: 12087ca360a5da0e9fa6c32ed5818d8b40c3044a1f9efa2da4bbf75772fad9794a5b7660eb6239009c051ebe30ac7f8ef293611caf16b3610c265709a6f5e7c8
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,94 +1,157 @@
|
|
1
|
-
# Dydx
|
1
|
+
# Dydx
|
2
|
+
It always happens you want to differentiate some formulas with ruby. right?.....
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
The most important thing in this DSL is
|
4
|
+
After `inlcude Dydx` , ruby become like other language.
|
6
5
|
|
7
|
-
|
6
|
+
## Dydx is new math DSL in Ruby
|
8
7
|
|
9
|
-
|
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
|
-
|
22
|
-
|
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
|
-
|
25
|
-
f(x, y) == x * (1 + y) + y
|
26
|
-
=> true
|
27
|
+
g(x) <= d/dx(f(x))
|
27
28
|
|
28
|
-
|
29
|
-
|
30
|
-
=> true
|
29
|
+
g(3)
|
30
|
+
# => 6
|
31
31
|
|
32
|
-
|
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
|
-
|
37
|
-
d/dx(f(x, y)) == 1 + y
|
38
|
-
=> true
|
54
|
+
f(x) <= x ^ 2
|
39
55
|
|
40
|
-
|
56
|
+
f(a + b).to_s
|
57
|
+
# => "( ( a + b ) ^ 2 )"
|
41
58
|
|
42
|
-
|
59
|
+
g(a, b) <= f(a + b)
|
43
60
|
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
61
|
-
|
75
|
+
```
|
76
|
+
require 'dydx'
|
77
|
+
include Dydx
|
62
78
|
|
63
|
-
|
64
|
-
|
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
|
-
|
73
|
-
|
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
|
-
|
97
|
+
Like this.
|
76
98
|
|
77
99
|
```
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
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.
|
125
|
-
|
187
|
+
Finished in 3.23 seconds
|
188
|
+
309 examples, 0 failures
|
126
189
|
```
|
data/Rakefile
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
3
|
require 'bundler/setup'
|
4
4
|
|
5
|
-
desc
|
5
|
+
desc "run spec"
|
6
6
|
|
7
|
-
#
|
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 =
|
7
|
+
spec.name = "dydx"
|
8
8
|
spec.version = Dydx::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.homepage =
|
12
|
-
spec.summary = %q
|
13
|
-
spec.description = %q
|
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 =
|
15
|
+
spec.license = "MIT"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0")
|
18
|
-
spec.executables = spec.files.grep(
|
19
|
-
spec.test_files = spec.files.grep(
|
20
|
-
spec.require_paths = [
|
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
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
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
|
-
|
9
|
+
# TODO: Refactor
|
10
|
+
%w(f g h).each do |functioner|
|
10
11
|
define_method(functioner) do |*vars|
|
11
|
-
function = eval("$#{functioner}")
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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.
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|