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 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::Optimizations module for examples.
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.6'
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"
@@ -2,4 +2,12 @@ class Matrix
2
2
  def value
3
3
  map {|it| it.value }
4
4
  end
5
+
6
+ def variables
7
+ map {|it| it.variables }.to_a.flatten.uniq
8
+ end
9
+
10
+ def symbolic?
11
+ !variables.empty?
12
+ end
5
13
  end
@@ -2,4 +2,12 @@ class Numeric
2
2
  def value
3
3
  self
4
4
  end
5
+
6
+ def variables
7
+ []
8
+ end
9
+
10
+ def symbolic?
11
+ false
12
+ end
5
13
  end
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.is_a?(Operatable)
42
- Optimizations.#{name} self, value
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.is_a?(Operatable)
61
+ if value.symbolic?
62
62
  Symbolic::Method.new value, :#{operation}
63
63
  else
64
64
  non_symbolic_#{operation} value
@@ -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
- value_of(@var1).send @operation, value_of(@var2)
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
- (undefined_variables_of(@var1) + undefined_variables_of(@var2)).uniq
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) || ((%w(+ *).include? @operation) && (object.var1 == @var2 && object.var2 == @var1)))
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 undefined_variables_of(variable)
52
- variable.is_a?(Operatable) ? variable.undefined_variables : []
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
@@ -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
- Optimizations.#{operation_name} self, value
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
1
  module Symbolic
2
- module Optimizations
2
+ module Optimization
3
3
  Symbolic.operations.each do |operation_sign, operation_name|
4
4
  method = <<-CODE
5
5
  def #{operation_name}(var1, var2)
@@ -1,5 +1,5 @@
1
- module Symbolic::Optimizations::Addition
2
- extend Symbolic::Optimizations::Base
1
+ module Symbolic::Optimization::Addition
2
+ extend Symbolic::Optimization::Base
3
3
 
4
4
  def self.optimize_first_arg(var1, var2)
5
5
  if var1 == 0
@@ -1,4 +1,4 @@
1
- module Symbolic::Optimizations::Base
1
+ module Symbolic::Optimization::Base
2
2
  def optimize(var1, var2)
3
3
  optimize_first_arg(var1, var2) || optimize_second_arg(var1, var2)
4
4
  end
@@ -1,5 +1,5 @@
1
- module Symbolic::Optimizations::Division
2
- extend Symbolic::Optimizations::Base
1
+ module Symbolic::Optimization::Division
2
+ extend Symbolic::Optimization::Base
3
3
 
4
4
  def self.optimize_first_arg(var1, var2)
5
5
  if var1 == 0
@@ -1,5 +1,5 @@
1
- module Symbolic::Optimizations::Multiplication
2
- extend Symbolic::Optimizations::Base
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
- optimize_first_arg var2, var1
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
@@ -1,5 +1,5 @@
1
- module Symbolic::Optimizations::Subtraction
2
- extend Symbolic::Optimizations::Base
1
+ module Symbolic::Optimization::Subtraction
2
+ extend Symbolic::Optimization::Base
3
3
 
4
4
  def self.optimize_first_arg(var1, var2)
5
5
  -var2 if var1 == 0
@@ -1,14 +1,7 @@
1
1
  module Symbolic
2
2
  class UnaryMinus < Operatable
3
- attr_reader :variable
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.variable == @variable
37
+ object.is_a?(UnaryMinus) && object.abs == @variable
40
38
  end
41
39
  end
42
40
  end
@@ -16,8 +16,12 @@ module Symbolic
16
16
  @name || 'unnamed_variable'
17
17
  end
18
18
 
19
+ def variables
20
+ [self]
21
+ end
22
+
19
23
  def undefined_variables
20
- value ? [] : [self]
24
+ value ? [] : variables
21
25
  end
22
26
  end
23
27
  end
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.6
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-01 00:00:00 +03:00
12
+ date: 2009-12-03 00:00:00 +03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency