dydx 0.1.314 → 0.1.412
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![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
|
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
|