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

#!=, #*, #**, #+, #-, #[email protected], #/, #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

50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/operators/bary-op.rb', line 50

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


37
38
39
# File 'lib/operators/bary-op.rb', line 37

def x
  @x
end

#yObject (readonly)

Second element of the operation


39
40
41
# File 'lib/operators/bary-op.rb', line 39

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

181
182
183
184
185
186
187
188
# File 'lib/operators/bary-op.rb', line 181

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

166
167
168
# File 'lib/operators/bary-op.rb', line 166

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

#call(_fd) ⇒ Object

Same `CAS::Op#call`

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

Raises:


145
146
147
# File 'lib/operators/bary-op.rb', line 145

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)

69
70
71
72
73
# File 'lib/operators/bary-op.rb', line 69

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)

81
82
83
84
85
86
87
88
89
# File 'lib/operators/bary-op.rb', line 81

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

52
53
54
55
# File 'lib/Mr.CAS/graphviz.rb', line 52

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`

173
174
175
# File 'lib/operators/bary-op.rb', line 173

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

#simplifyObject

Executes simplifications of the two branches of the graph

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

193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/operators/bary-op.rb', line 193

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`

95
96
97
# File 'lib/operators/bary-op.rb', line 95

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`

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

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`

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/operators/bary-op.rb', line 124

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:


159
160
161
# File 'lib/operators/bary-op.rb', line 159

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

#to_sObject

String representation of the tree

* **returns**: `String`

Raises:


152
153
154
# File 'lib/operators/bary-op.rb', line 152

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