symbolic 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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