Class: CAS::Sum

Inherits:
NaryOp show all
Defined in:
lib/functions/fnc-sum.rb

Overview

**Sum basic operation**. As for now it is implemented as a simple binary operation. It will be implemented as n-ary op.

Instance Attribute Summary

Attributes inherited from NaryOp

#x

Attributes inherited from Op

#x

Instance Method Summary collapse

Methods inherited from NaryOp

#==, #__reduce_constants, #__reduce_multeplicity, #args, #depend?, #dot_graph, #initialize, #inspect, #subs

Methods inherited from Op

#!=, #*, #**, #-, #-@, #/, #==, #args, #as_proc, #depend?, #dot_graph, #equal, #greater, #greater_equal, init_simplify_dict, #initialize, #inspect, #limit, numeric_to_const, simplify_dict, #simplify_dictionary, #smaller, #smaller_equal, #subs, #to_c_lib

Constructor Details

This class inherits a constructor from CAS::NaryOp

Instance Method Details

#+(op) ⇒ Object

The added element of a sum accumulates inside the vector that holds the elements



52
53
54
55
56
# File 'lib/functions/fnc-sum.rb', line 52

def +(op)
  CAS::Help.assert(op, CAS::Op)
  @x << op
  self
end

#call(f) ⇒ Object

Call resolves the operation tree in a ‘Numeric` (if `Fixnum`) or `Float` (depends upon promotions). As input, it requires an hash with `CAS::Variable` or `CAS::Variable#name` as keys, and a `Numeric` as a value. In this case it will call the `Fixnum#overloaded_plus`, that is the old plus function.

* **argument**: `Hash` with feed dictionary
* **returns**: `Numeric`


66
67
68
69
70
71
72
73
# File 'lib/functions/fnc-sum.rb', line 66

def call(f)
  CAS::Help.assert(f, Hash)
  p = 0
  @x.each do |y|
    p = p.overloaded_plus(y.call(f))
  end
  p
end

#diff(v) ⇒ Object

Performs the sum between arbitrary number of ‘CAS::Op`

“‘

d

—- (f(x) + g(x) + h(x)) = f’(x) + g’(x) + h’(x)

dx

“‘

* **argument**: `CAS::Op` argument of derivative
* **returns**: `CAS::Op` derivative


46
47
48
# File 'lib/functions/fnc-sum.rb', line 46

def diff(v)
  @x.map { |x| x.diff(v) }.inject { |sum_x, dx| sum_x += dx }
end

#reduce_associativityObject

Reduces from an associative point of view, by a segregation of “negative” and positive elements. Negatives comes from Diff operations and Invert operations. All the others are considered positive. This function implements an internal heuristic. Should not be used outside

* **returns**: A `CAS::Diff` or a `CAS::Sum`


119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/functions/fnc-sum.rb', line 119

def reduce_associativity
  pos, neg = [], []

  @x.each do |x_el|
    case x_el
    when CAS::Invert
      neg << x_el.x
    when CAS::Diff
      pos << x_el.x
      neg << x_el.y
    else
      pos << x_el
    end
  end

  pos, neg = self.reduce_associativity_array pos, neg
  pos = self.__reduce_multeplicity(pos)
  neg = self.__reduce_multeplicity neg

  # TODO : Add rules for simplifications
  left, right = nil, nil
  left  = CAS::Sum.new(pos) if pos.size > 1
  left  = pos[0]            if pos.size == 1
  right = CAS::Sum.new(neg) if neg.size > 1
  right = neg[0]            if neg.size == 1

  return  CAS::Zero unless left || right
  return  left unless right
  return  -right unless left
  return left - right
end

#reduce_associativity_array(p_old, n_old) ⇒ Object

Reduce the positive and the negative associative part of the sum to perform the symbolic difference. Does not take into account multeplicity

* **requires**: positive `Array`
* **requires**: negative `Array`
* **returns**: positive, reduced `Array` and negative `Array`


158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/functions/fnc-sum.rb', line 158

def reduce_associativity_array(p_old, n_old)
  p_del, n_del = [], []
  p_old.each do |p|
    n_old.each do |n|
      if p == n
        p_del << p
        n_del << n
      end
    end
  end

  return (p_old - p_del), (n_old - n_del)
end

#simplifyObject

Same as ‘CAS::Op`

Simplifcation engine supports:

* x + 0 = x
* 0 + y = y
* x + x = 2 x
* x + (-x) = 0
* x + (-y) = x - y
* 1 + 2 = 3 (constants reduction)

* **returns**: `CAS::Op` simplified version


94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/functions/fnc-sum.rb', line 94

def simplify
  super
  return @x[0] if @x.size == 1

  # return CAS::Zero if @x == -@y or -@x == @y
  # return (@x - @y.x) if @y.is_a? CAS::Invert
  # return CAS.const(self.call({})) if (@x.is_a? CAS::Constant and @y.is_a? CAS::Constant)
  # Removing Zeros
  @x = @x - [CAS::Zero]
  return CAS::Zero if @x.size == 0
  # Reduce constants
  @x = self.__reduce_constants(@x) do |cs, xs|
    xs + [cs.inject { |t, c| t += c.call({}) }]
  end
  # Multeplicity and associativity executed
  return self.reduce_associativity
end

#to_codeObject

Convert expression to code (internal, for ‘CAS::Op#to_proc` method)

* **returns**: `String` that represent Ruby code to be parsed in `CAS::Op#to_proc`


175
176
177
# File 'lib/functions/fnc-sum.rb', line 175

def to_code
  "(#{@x.map(&:to_code).join(" + ")})"
end

#to_sObject

Convert expression to string

* **returns**: `String` to print on screen


78
79
80
# File 'lib/functions/fnc-sum.rb', line 78

def to_s
  "(#{@x.map(&:to_s).join(" + ")})"
end