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.
- checksums.yaml +4 -4
- data/.rubocop.yml +25 -0
- data/.travis.yml +3 -1
- data/Gemfile +1 -0
- data/README.md +4 -2
- data/Rakefile +5 -8
- data/dydx.gemspec +13 -13
- data/lib/dydx.rb +20 -27
- data/lib/dydx/algebra.rb +8 -6
- data/lib/dydx/algebra/formula.rb +53 -28
- data/lib/dydx/algebra/inverse.rb +2 -2
- data/lib/dydx/algebra/operator/formula.rb +0 -1
- data/lib/dydx/algebra/operator/general.rb +0 -1
- data/lib/dydx/algebra/operator/inverse.rb +0 -1
- data/lib/dydx/algebra/operator/num.rb +0 -1
- data/lib/dydx/algebra/operator/parts/base.rb +2 -2
- data/lib/dydx/algebra/operator/parts/formula.rb +61 -40
- data/lib/dydx/algebra/operator/parts/general.rb +83 -32
- data/lib/dydx/algebra/operator/parts/inverse.rb +4 -4
- data/lib/dydx/algebra/operator/parts/num.rb +16 -11
- data/lib/dydx/algebra/operator/parts/symbol.rb +2 -2
- data/lib/dydx/algebra/set.rb +82 -122
- data/lib/dydx/delta.rb +1 -1
- data/lib/dydx/function.rb +1 -1
- data/lib/dydx/helper.rb +43 -66
- data/lib/dydx/integrand.rb +7 -6
- data/lib/dydx/version.rb +1 -1
- data/spec/dydx_spec.rb +3 -3
- data/spec/lib/algebra/formula_spec.rb +41 -41
- data/spec/lib/algebra/operator/parts/base_spec.rb +5 -5
- data/spec/lib/algebra/operator/parts/formula_spec.rb +57 -57
- data/spec/lib/algebra/operator/parts/inverse_spec.rb +8 -8
- data/spec/lib/algebra/set_spec.rb +193 -150
- data/spec/lib/delta_spec.rb +23 -25
- data/spec/lib/function_spec.rb +4 -6
- data/spec/lib/helper_spec.rb +44 -51
- data/spec/lib/integrand_spec.rb +12 -10
- data/spec/spec_helper.rb +2 -1
- metadata +6 -7
- data/lib/dydx/algebra/operator/parts.rb +0 -6
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 05be03d422e433fa724050ae6c77c6de2044005d
|
4
|
+
data.tar.gz: 5a8ef94f9d271d9383ac3308c0f77acec91c6864
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c2d8881754f7ee43700223926c2a249d91c3431bcc49ce9886c8c2991e5c58694a83626d5d1947c97c822208159d487343d8a85e353448ad7843177446757a7
|
7
|
+
data.tar.gz: 4a89a20e3810e52c23c97d88dd915e2a54263374e3f1a9b8a52ca444f9f1e3b219e63d1367be693a3787bf4f10f6e69f86baf6e9bc97ab1d2f2c7c5b46590760
|
data/.rubocop.yml
ADDED
@@ -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
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
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
|
+
[](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
|
65
|
+
d/dx(e ** x) == e ** x
|
64
66
|
=> true
|
65
67
|
|
66
68
|
# standard normal distribution;
|
67
|
-
f(x) <= (1.0 / (
|
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
|
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
|
-
#do `rake spec`
|
8
|
-
RSpec::Core::RakeTask.new(:spec)
|
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
|
-
|
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 = ['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 =
|
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(/^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
|
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,14 +6,13 @@ require 'dydx/integrand'
|
|
6
6
|
|
7
7
|
module Dydx
|
8
8
|
include Algebra
|
9
|
-
%w(f g h
|
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
|
-
|
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
|
-
|
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
|
data/lib/dydx/algebra.rb
CHANGED
@@ -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
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
data/lib/dydx/algebra/formula.rb
CHANGED
@@ -2,23 +2,44 @@ module Dydx
|
|
2
2
|
module Algebra
|
3
3
|
class Formula
|
4
4
|
include Helper
|
5
|
-
attr_accessor :
|
5
|
+
attr_accessor :operator, :terms
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
|
9
|
-
|
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
|
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.
|
19
|
-
f.d(sym) * g * (f
|
39
|
+
if g.num?
|
40
|
+
f.d(sym) * g * (f ** (g - 1))
|
20
41
|
elsif f == sym
|
21
|
-
g * (f
|
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
|
33
|
-
"( - #{g
|
53
|
+
if formula?(:*) && (f.minus1? || g.minus1?)
|
54
|
+
"( - #{g} )"
|
34
55
|
elsif g.inverse?(operator)
|
35
|
-
"( #{f
|
56
|
+
"( #{f} #{operator.inv} #{g.x} )"
|
36
57
|
elsif f.inverse?(operator)
|
37
|
-
"( #{g
|
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
|
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
|
-
@
|
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
|
data/lib/dydx/algebra/inverse.rb
CHANGED
@@ -29,12 +29,12 @@ module Dydx
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def differentiate(sym
|
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
|
37
|
+
inverse(x.differentiate(sym) * inverse(x ** 2, :*), :+)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
alias_method :d, :differentiate
|
@@ -3,9 +3,9 @@ module Dydx
|
|
3
3
|
module Operator
|
4
4
|
module Parts
|
5
5
|
module Base
|
6
|
-
%w(+ *
|
6
|
+
%w(+ * **).map(&:to_sym).each do |operator|
|
7
7
|
define_method(operator) do |x|
|
8
|
-
::Algebra::Formula.new(self, x
|
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 |
|
7
|
-
define_method(
|
8
|
-
if
|
9
|
-
if
|
10
|
-
|
11
|
-
|
12
|
-
|
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(
|
18
|
+
super(rtm)
|
15
19
|
end
|
16
|
-
elsif formula?(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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?(
|
34
|
-
|
35
|
-
return super(
|
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
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
when
|
45
|
-
|
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(
|
68
|
+
super(rtm)
|
50
69
|
end
|
51
70
|
end
|
52
71
|
end
|
53
72
|
|
54
|
-
%w(
|
55
|
-
define_method(
|
56
|
-
if formula?(
|
57
|
-
|
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(
|
80
|
+
super(rtm)
|
60
81
|
end
|
61
82
|
end
|
62
83
|
end
|