symbolic 0.1.6 → 0.1.7
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.
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/lib/extensions/matrix.rb +8 -0
- data/lib/extensions/numeric.rb +8 -0
- data/lib/symbolic/core.rb +3 -3
- data/lib/symbolic/expression.rb +13 -10
- data/lib/symbolic/operatable.rb +9 -1
- data/lib/symbolic/optimizations.rb +1 -1
- data/lib/symbolic/optimizations/addition.rb +2 -2
- data/lib/symbolic/optimizations/base.rb +1 -1
- data/lib/symbolic/optimizations/division.rb +2 -2
- data/lib/symbolic/optimizations/multiplication.rb +7 -3
- data/lib/symbolic/optimizations/subtraction.rb +2 -2
- data/lib/symbolic/unary_minus.rb +8 -10
- data/lib/symbolic/variable.rb +5 -1
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -8,7 +8,7 @@ gem install symbolic
|
|
8
8
|
|
9
9
|
Symbolic math can be really helpful if you want to simplify some giant equation or if you don't want to get a performance hit re-evaluating big math expressions every time when few variables change.
|
10
10
|
|
11
|
-
Currently I've implemented only naive optimizations to simplify math expressions, but it's pretty simple to add your own - see Symbolic::
|
11
|
+
Currently I've implemented only naive optimizations to simplify math expressions, but it's pretty simple to add your own - see Symbolic::Optimization module for examples.
|
12
12
|
|
13
13
|
== Examples:
|
14
14
|
x = var :name => 'x'
|
data/Rakefile
CHANGED
@@ -5,7 +5,7 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "symbolic"
|
8
|
-
gem.version = '0.1.
|
8
|
+
gem.version = '0.1.7'
|
9
9
|
gem.summary = 'Symbolic math for ruby'
|
10
10
|
gem.description = %Q{Symbolic math can be really helpful if you want to simplify some giant equation or if you don't want to get a performance hit re-evaluating big math expressions every time when few variables change.}
|
11
11
|
gem.email = "ravwar@gmail.com"
|
data/lib/extensions/matrix.rb
CHANGED
data/lib/extensions/numeric.rb
CHANGED
data/lib/symbolic/core.rb
CHANGED
@@ -38,8 +38,8 @@ module Symbolic
|
|
38
38
|
alias non_symbolic_#{name} #{sign}
|
39
39
|
|
40
40
|
def #{sign}(value)
|
41
|
-
if value.
|
42
|
-
|
41
|
+
if value.symbolic?
|
42
|
+
Optimization.#{name} self, value
|
43
43
|
else
|
44
44
|
non_symbolic_#{name}(value)
|
45
45
|
end
|
@@ -58,7 +58,7 @@ module Symbolic
|
|
58
58
|
alias non_symbolic_#{operation} #{operation}
|
59
59
|
|
60
60
|
def #{operation}(value)
|
61
|
-
if value.
|
61
|
+
if value.symbolic?
|
62
62
|
Symbolic::Method.new value, :#{operation}
|
63
63
|
else
|
64
64
|
non_symbolic_#{operation} value
|
data/lib/symbolic/expression.rb
CHANGED
@@ -3,7 +3,6 @@ module Symbolic
|
|
3
3
|
attr_reader :var1, :var2, :operation
|
4
4
|
|
5
5
|
def initialize(var1, var2, operation)
|
6
|
-
var1, var2 = var2, var1 if operation == '*' && var2.is_a?(Numeric)
|
7
6
|
@var1, @var2, @operation = var1, var2, operation
|
8
7
|
end
|
9
8
|
|
@@ -23,19 +22,27 @@ module Symbolic
|
|
23
22
|
@operation == '*'
|
24
23
|
end
|
25
24
|
|
25
|
+
def divide?
|
26
|
+
@operation == '/'
|
27
|
+
end
|
28
|
+
|
26
29
|
def value
|
27
30
|
if undefined_variables.empty?
|
28
|
-
|
31
|
+
@var1.value.send @operation, @var2.value
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
35
|
+
def variables
|
36
|
+
variables_of(@var1) | variables_of(@var2)
|
37
|
+
end
|
38
|
+
|
32
39
|
def undefined_variables
|
33
|
-
|
40
|
+
variables.select &:undefined?
|
34
41
|
end
|
35
42
|
|
36
43
|
def ==(object)
|
37
44
|
object.is_a?(Expression) && (object.operation == @operation) &&
|
38
|
-
((object.var1 == @var1 && object.var2 == @var2) || ((
|
45
|
+
((object.var1 == @var1 && object.var2 == @var2) || ((plus? || multiply?) && (object.var1 == @var2 && object.var2 == @var1)))
|
39
46
|
end
|
40
47
|
|
41
48
|
private
|
@@ -48,12 +55,8 @@ module Symbolic
|
|
48
55
|
%w(* /).include?(@operation) && (var.is_a?(UnaryMinus) || var.is_a?(Expression) && (var.plus? || var.minus?))
|
49
56
|
end
|
50
57
|
|
51
|
-
def
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
def value_of(variable)
|
56
|
-
variable.is_a?(Operatable) ? variable.value : variable
|
58
|
+
def variables_of(object)
|
59
|
+
object.symbolic? ? object.variables : []
|
57
60
|
end
|
58
61
|
end
|
59
62
|
end
|
data/lib/symbolic/operatable.rb
CHANGED
@@ -11,10 +11,18 @@ module Symbolic
|
|
11
11
|
Symbolic.operations.each do |operation_sign, operation_name|
|
12
12
|
method = <<-CODE
|
13
13
|
def #{operation_sign}(value)
|
14
|
-
|
14
|
+
Optimization.#{operation_name} self, value
|
15
15
|
end
|
16
16
|
CODE
|
17
17
|
class_eval method, __FILE__, __LINE__
|
18
18
|
end
|
19
|
+
|
20
|
+
def undefined?
|
21
|
+
!value
|
22
|
+
end
|
23
|
+
|
24
|
+
def symbolic?
|
25
|
+
true
|
26
|
+
end
|
19
27
|
end
|
20
28
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module Symbolic::
|
2
|
-
extend Symbolic::
|
1
|
+
module Symbolic::Optimization::Multiplication
|
2
|
+
extend Symbolic::Optimization::Base
|
3
3
|
|
4
4
|
def self.optimize_first_arg(var1, var2)
|
5
5
|
if var1 == 0
|
@@ -12,6 +12,10 @@ module Symbolic::Optimizations::Multiplication
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.optimize_second_arg(var1, var2)
|
15
|
-
|
15
|
+
if var2.is_a? Numeric
|
16
|
+
var2 * var1
|
17
|
+
else
|
18
|
+
optimize_first_arg var2, var1
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
data/lib/symbolic/unary_minus.rb
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
module Symbolic
|
2
2
|
class UnaryMinus < Operatable
|
3
|
-
|
4
|
-
|
5
|
-
def self.create(expression)
|
6
|
-
# move to optimizations module
|
7
|
-
if expression.is_a? UnaryMinus
|
8
|
-
expression.variable
|
9
|
-
else
|
10
|
-
new expression
|
11
|
-
end
|
3
|
+
def self.create(var)
|
4
|
+
var.is_a?(UnaryMinus) ? var.abs : new(var)
|
12
5
|
end
|
13
6
|
|
14
7
|
def initialize(variable)
|
@@ -24,6 +17,7 @@ module Symbolic
|
|
24
17
|
end
|
25
18
|
|
26
19
|
def abs
|
20
|
+
# add a common method for Operatable which will point to an instance of Abs(magnitude) class
|
27
21
|
@variable
|
28
22
|
end
|
29
23
|
|
@@ -31,12 +25,16 @@ module Symbolic
|
|
31
25
|
-@variable.value if undefined_variables.empty?
|
32
26
|
end
|
33
27
|
|
28
|
+
def variables
|
29
|
+
[@variable]
|
30
|
+
end
|
31
|
+
|
34
32
|
def undefined_variables
|
35
33
|
@variable.undefined_variables
|
36
34
|
end
|
37
35
|
|
38
36
|
def ==(object)
|
39
|
-
object.is_a?(UnaryMinus) && object.
|
37
|
+
object.is_a?(UnaryMinus) && object.abs == @variable
|
40
38
|
end
|
41
39
|
end
|
42
40
|
end
|
data/lib/symbolic/variable.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: symbolic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- brainopia
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-03 00:00:00 +03:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|