Class: CAS::BinaryOp

Inherits:
Op
  • Object
show all
Defined in:
lib/operators/bary-op.rb,
lib/Mr.CAS/graphviz.rb

Overview

Binary operator

Direct Known Subclasses

Diff, Div, Piecewise, Pow

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Op

#!=, #*, #**, #+, #-, #-@, #/, #as_proc, #equal, #greater, #greater_equal, init_simplify_dict, #limit, numeric_to_const, simplify_dict, #simplify_dictionary, #smaller, #smaller_equal, #to_c_lib

Constructor Details

#initialize(x, y) ⇒ BinaryOp

The binary operator inherits from the ‘CAS::Op`, even if it is defined as a node with two possible branches. This is particular of the basic operations. The two basic nodes shares the same interface, so all the operations do not need to know which kind of node they are handling.

* **argument**: `CAS::Op` left argument of the node or `Numeric` to be converted in `CAS::Constant`
* **argument**: `CAS::Op` right argument of the node or `Numeric` to be converted in `CAS::Constant`
* **returns**: `CAS::BinaryOp` instance


27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/operators/bary-op.rb', line 27

def initialize(x, y)
  if x.is_a? Numeric
    x = BinaryOp.numeric_to_const x
  end
  if y.is_a? Numeric
    y = BinaryOp.numeric_to_const y
  end
  CAS::Help.assert(x, CAS::Op)
  CAS::Help.assert(y, CAS::Op)

  @x = x
  @y = y
end

Instance Attribute Details

#xObject (readonly)

First element of the operation



14
15
16
# File 'lib/operators/bary-op.rb', line 14

def x
  @x
end

#yObject (readonly)

Second element of the operation



16
17
18
# File 'lib/operators/bary-op.rb', line 16

def y
  @y
end

Instance Method Details

#==(op) ⇒ Object

Comparison with other ‘CAS::Op`. This is not a math operation.

* **argument**: `CAS::Op` to be compared against
* **returns**: `TrueClass` if equal, `FalseClass` if different


158
159
160
161
162
163
164
165
# File 'lib/operators/bary-op.rb', line 158

def ==(op)
  CAS::Help.assert(op, CAS::Op)
  if op.is_a? CAS::BinaryOp
    return (self.class == op.class and @x == op.x and @y == op.y)
  else
    return false
  end
end

#argsObject

Returns an array of all the variables that are in the graph

* **returns**: `Array` of `CAS::Variable`s


143
144
145
# File 'lib/operators/bary-op.rb', line 143

def args
  (@x.args + @y.args).uniq
end

#call(_fd) ⇒ Object

Same ‘CAS::Op#call`

* **argument**: `Hash` of values
* **returns**: `Numeric` for result

Raises:



122
123
124
# File 'lib/operators/bary-op.rb', line 122

def call(_fd)
  raise CAS::CASError, "Not Implemented. This is a virtual method"
end

#depend?(v) ⇒ Boolean

Return the dependencies of the operation. Requires a ‘CAS::Variable` and it is one of the recursve method (implicit tree resolution)

* **argument**: `CAS::Variable` instance
* **returns**: `TrueClass` if depends, `FalseClass` if not

Returns:

  • (Boolean)


46
47
48
49
50
# File 'lib/operators/bary-op.rb', line 46

def depend?(v)
  CAS::Help.assert(v, CAS::Op)

  @x.depend? v or @y.depend? v
end

#diff(v) ⇒ Object

This method returns an array with the derivatives of the two branches of the node. This method is usually called by child classes, and it is not intended to be used directly.

* **argument**: `CAS::Op` operation to differentiate against
* **returns**: `Array` of differentiated branches ([0] for left, [1] for right)


58
59
60
61
62
63
64
65
66
# File 'lib/operators/bary-op.rb', line 58

def diff(v)
  CAS::Help.assert(v, CAS::Op)
  left, right = CAS::Zero, CAS::Zero

  left = @x.diff(v) if @x.depend? v
  right = @y.diff(v) if @y.depend? v

  return left, right
end

#dot_graphObject

Return the local Graphviz node of the tree

* **returns**: `String` of local Graphiz node


29
30
31
32
# File 'lib/Mr.CAS/graphviz.rb', line 29

def dot_graph
  cls = "#{self.class.to_s.gsub("CAS::", "")}_#{self.object_id}"
  "#{cls} -> #{@x.dot_graph}\n  #{cls} -> #{@y.dot_graph}"
end

#inspectObject

Inspector

* **returns**: `String`


150
151
152
# File 'lib/operators/bary-op.rb', line 150

def inspect
  "#{self.class}(#{@x.inspect}, #{@y.inspect})"
end

#simplifyObject

Executes simplifications of the two branches of the graph

* **returns**: `CAS::BinaryOp` as `self`


170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/operators/bary-op.rb', line 170

def simplify
  hash = @x.to_s
  @x = @x.simplify
  while @x.to_s != hash
    hash = @x.to_s
    @x = @x.simplify
  end
  hash = @y.to_s
  @y = @y.simplify
  while @y.to_s != hash
    hash = @y.to_s
    @y = @y.simplify
  end
end

#subs(dt) ⇒ Object

Substituitions for both branches of the graph, same as ‘CAS::Op#subs`

* **argument**: `Hash` of substitutions
* **returns**: `CAS::BinaryOp`, in practice `self`


72
73
74
# File 'lib/operators/bary-op.rb', line 72

def subs(dt)
  return self.subs_lhs(dt).subs_rhs(dt)
end

#subs_lhs(dt) ⇒ Object

Substituitions for left branch of the graph, same as ‘CAS::Op#subs`

* **argument**: `Hash` of substitutions
* **returns**: `CAS::BinaryOp`, in practice `self`


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/operators/bary-op.rb', line 80

def subs_lhs(dt)
  CAS::Help.assert(dt, Hash)
  sub = dt.keys.select { |e| e == @x }[0]
  if sub
    if dt[sub].is_a? CAS::Op
      @x = dt[sub]
    elsif dt[sub].is_a? Numeric
      @x = CAS::const dt[sub]
    else
      raise CASError, "Impossible subs. Received a #{dt[sub].class} = #{dt[sub]}"
    end
  else
    @x.subs(dt)
  end
  return self
end

#subs_rhs(dt) ⇒ Object

Substituitions for left branch of the graph, same as ‘CAS::Op#subs`

* **argument**: `Hash` of substitutions
* **returns**: `CAS::BinaryOp`, in practice `self`


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/operators/bary-op.rb', line 101

def subs_rhs(dt)
  CAS::Help.assert(dt, Hash)
  sub = dt.keys.select { |e| e == @y }[0]
  if sub
    if dt[sub].is_a? CAS::Op
      @y = dt[sub]
    elsif dt[sub].is_a? Numeric
      @y = CAS::const dt[sub]
    else
      raise CASError, "Impossible subs. Received a #{dt[sub].class} = #{dt[sub]}"
    end
  else
    @y.subs(dt)
  end
  return self
end

#to_codeObject

Code to be used in ‘CAS::BinaryOp#to_proc`

* **returns**: `String`

Raises:



136
137
138
# File 'lib/operators/bary-op.rb', line 136

def to_code
  raise CAS::CASError, "Not implemented. This is a virtual method"
end

#to_sObject

String representation of the tree

* **returns**: `String`

Raises:



129
130
131
# File 'lib/operators/bary-op.rb', line 129

def to_s
  raise CAS::CASError, "Not Implemented. This is a virtual method"
end