Class: Symbolic::Factors

Inherits:
Expression show all
Defined in:
lib/symbolic/factors.rb

Constant Summary collapse

OPERATION =
:*
IDENTITY =
1

Constants included from Symbolic

OPERATIONS

Instance Attribute Summary

Attributes inherited from Expression

#numeric, #symbolic

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Expression

#==, convert, #initialize, numeric, one, simple?, unite, unite_numeric, unite_symbolic, #variables

Methods included from Symbolic

#*, #**, #+, #[email protected], #-, #[email protected], #/, #coerce, #factorial, #inspect, #operations, #taylor, #to_s

Constructor Details

This class inherits a constructor from Symbolic::Expression

Class Method Details

.add(var1, var2) ⇒ Object


19
20
21
22
23
24
25
26
27
# File 'lib/symbolic/factors.rb', line 19

def add(var1, var2)
  if distributable? var1, var2
    distribute(var1, var2)
  elsif distributable? var2, var1
    distribute(var2, var1)
  else
    super
  end
end

.distributable?(var1, var2) ⇒ Boolean

Returns:

  • (Boolean)

34
35
36
# File 'lib/symbolic/factors.rb', line 34

def distributable?(var1, var2)
  simple?(var1) && var2.is_a?(Summands)
end

.distribute(var1, var2) ⇒ Object


38
39
40
41
42
# File 'lib/symbolic/factors.rb', line 38

def distribute(var1, var2)
  var2.symbolic.map {|k,v| k*v }.inject(var2.numeric*var1) do |sum, it|
    sum + it*var1
  end
end

.factors(factors) ⇒ Object


10
11
12
# File 'lib/symbolic/factors.rb', line 10

def factors(factors)
  factors
end

.power(base, exponent) ⇒ Object


14
15
16
17
# File 'lib/symbolic/factors.rb', line 14

def power(base, exponent)
  simplify_expression! factors = unite_exponents(base, exponent)
  simplify(*factors) || new(*factors)
end

.simplify(numeric, symbolic) ⇒ Object


49
50
51
52
53
54
55
# File 'lib/symbolic/factors.rb', line 49

def simplify(numeric, symbolic)
  if numeric == 0 || symbolic.empty?
    (numeric.round == numeric) ? numeric.to_i : numeric.to_f
  elsif numeric == IDENTITY && symbolic.size == 1 && symbolic.first[1] == 1
    symbolic.first[0]
  end
end

.simplify_expression!(factors) ⇒ Object


44
45
46
47
# File 'lib/symbolic/factors.rb', line 44

def simplify_expression!(factors)
  factors[1].delete_if {|base, exp| (base == IDENTITY) || (exp == 0) }
  factors[0] = 0 if factors[1].any? {|base, _| base == 0 }
end

.subtract(var1, var2) ⇒ Object


29
30
31
32
# File 'lib/symbolic/factors.rb', line 29

def subtract(var1, var2)
  simplify_expression! factors = unite(convert(var1), convert(var2).reverse)
  simplify(*factors) || new(*factors)
end

.summands(summands) ⇒ Object


6
7
8
# File 'lib/symbolic/factors.rb', line 6

def summands(summands)
  one summands
end

.unite_exponents(base, exponent) ⇒ Object


57
58
59
60
61
62
63
# File 'lib/symbolic/factors.rb', line 57

def unite_exponents(base, exponent)
  if base.is_a? Factors
    [base.numeric**exponent, Hash[*base.symbolic.map {|b,e| [b, e*exponent] }.flatten]]
  else
    [IDENTITY, { base => exponent }]
  end
end

Instance Method Details

#diff(wrt) ⇒ Object


88
89
90
91
92
93
94
95
96
97
# File 'lib/symbolic/factors.rb', line 88

def diff(wrt)
  return 0 unless self.variables.include?(wrt) #speed things up a bit
  first_base, first_exp = @symbolic.to_a[0]
  first = first_base ** first_exp #the first factor
  self_without_first = self / first #the expression with the first factor removed
  #product rule to find derivitive
  udv = self_without_first.is_a?(Symbolic) ? first * self_without_first.diff(wrt) : 0
  vdu = first_base.is_a?(Symbolic) ? first_exp * first_base ** (first_exp - 1 ) * first_base.diff(wrt) * self_without_first : 0
  udv + vdu
end

#reverseObject


66
67
68
# File 'lib/symbolic/factors.rb', line 66

def reverse
  self.class.new numeric**-1, Hash[*symbolic.map {|k,v| [k,-v]}.flatten]
end

#subs(to_replace, replacement = nil) ⇒ Object


76
77
78
79
80
81
82
# File 'lib/symbolic/factors.rb', line 76

def subs(to_replace, replacement=nil)
  if replacement == nil and to_replace.is_a?(Hash)
	super(to_replace)
  else
	@symbolic.inject(@numeric){|m,(base,exponential)| m * base.subs(to_replace, replacement) ** exponential.subs(to_replace, replacement)}
  end
end

#valueObject


70
71
72
73
74
# File 'lib/symbolic/factors.rb', line 70

def value
  if variables.all?(&:value)
    @symbolic.inject(numeric) {|value, (base, exp)| value * base.value ** exp.value }
  end
end