class CAS::Op

 ___         _        _
/ __|___ _ _| |_ __ _(_)_ _  ___ _ _ ___

| (__/ _ \ ' \ _/ _` | | ' / -_) '_(_-<

\___\___/_||_\__\__,_|_|_||_\___|_| /__/
 ___
/ _ \ _ __

| (_) | '_ \

\___/| .__/
     |_|

Attributes

x[R]

Argument of the operation

Public Class Methods

init_simplify_dict() click to toggle source

Initializes the simplification dictionary (one for each class)

  • returns: `Hash` with simplification dictionary

# File lib/operators/op.rb, line 234
def self.init_simplify_dict
  @simplify_dict = { }
end
new(x) click to toggle source

Initialize a new empty operation container. This is a virtual class and the other must inherit from this basic container. Some methods raise a `CAS::CASError` if called. The input element is a Numric, to create a constant. `CAS::Op` specifies operations with a single variable

* **argument**: `Numeric` to be converted in `CAS::Constant` or `CAS::Op` child operation
* **returns**: `CAS::Op` instance
# File lib/operators/op.rb, line 46
def initialize(x)
  if x.is_a? Numeric
    x = Op.numeric_to_const x
  end
  CAS::Help.assert(x, CAS::Op)

  @x = x
end
numeric_to_const(x) click to toggle source
# File lib/operators/op.rb, line 55
def self.numeric_to_const(x)
  if CAS::NumericToConst[x]
    return CAS::NumericToConst[x]
  else
    return CAS::const x
  end
end
simplify_dict(k) click to toggle source

Returns an element of a

# File lib/operators/op.rb, line 239
def self.simplify_dict(k)
  @simplify_dict.keys.each do |op|
    return @simplify_dict[op] if op.simplify == k.simplify
  end
  return nil
end

Public Instance Methods

!=(op) click to toggle source

Disequality operator, the standard operator is overloaded :warning: this operates on the graph, not on the math See `CAS::equal`, etc.

* **argument**: `CAS::Op` to be tested against
* **returns**: `FalseClass` if equal, `TrueClass` if differs
# File lib/operators/op.rb, line 274
def !=(op)
  not self.==(op)
end
*(op) click to toggle source

Returns a product of two `CAS::Op`s

* **argument**: `CAS::Op` tree
* **returns**: `CAS::Op` new object
# File lib/operators/op.rb, line 182
def *(op)
  CAS::Prod.new [self, op]
end
**(op) click to toggle source

Returns the power of two `CAS::Op`s

* **argument**: `CAS::Op` tree
* **returns**: `CAS::Op` new object
# File lib/operators/op.rb, line 198
def **(op)
  CAS.pow(self, op)
end
+(op) click to toggle source

Returns a sum of two `CAS::Op`s

* **argument**: `CAS::Op` tree
* **returns**: `CAS::Op` new object
# File lib/operators/op.rb, line 166
def +(op)
  CAS::Sum.new [self, op]
end
-(op) click to toggle source

Returns a difference of two `CAS::Op`s

* **argument**: `CAS::Op` tree
* **returns**: `CAS::Op` new object
# File lib/operators/op.rb, line 174
def -(op)
  CAS::Diff.new self, op
end
-@() click to toggle source

Unary operator for inversion of a `CAS::Op`

* **returns**: `CAS::Op` new object
# File lib/operators/op.rb, line 205
def -@
  CAS.invert(self)
end
/(op) click to toggle source

Returns a division of two `CAS::Op`s

* **argument**: `CAS::Op` tree
* **returns**: `CAS::Op` new object
# File lib/operators/op.rb, line 190
def /(op)
  CAS::Div.new self, op
end
==(op) click to toggle source

Equality operator, the standard operator is overloaded :warning: this operates on the graph, not on the math See `CAS::equal`, etc.

* **argument**: `CAS::Op` to be tested against
* **returns**: `TrueClass` if equal, `FalseClass` if differs
# File lib/operators/op.rb, line 259
def ==(op)
  # CAS::Help.assert(op, CAS::Op)
  if op.is_a? CAS::Op
    return false if op.is_a? CAS::BinaryOp
    return (self.class == op.class and @x == op.x)
  end
  false
end
args() click to toggle source

Returns a list of all `CAS::Variable`s of the current tree

* **returns**: `Array` of `CAS::Variable`s
# File lib/operators/op.rb, line 303
def args
  @x.args.uniq
end
as_proc(bind=nil) click to toggle source

Evaluates the proc against a given context. It is like having a snapshot of the tree transformed in a callable object. Obviously **if the tree changes, the generated proc does notchanges**. The proc takes as input a feed dictionary in which each variable is identified through the `CAS::Variable#name` key.

The proc is evaluated in the context devined by the input `Binding` object If `nil` is passed, the `eval` will run in this local context

* **argument**: `Binding` or `NilClass` that is the context of the Ruby VM
* **returns**: `Proc` object with a single argument as an `Hash`
# File lib/operators/op.rb, line 289
def as_proc(bind=nil)
  args_ext = self.args.map { |e| "#{e} = fd[\"#{e}\"];" }
  code = "Proc.new do |fd|; #{args_ext.join " "} #{self.to_code}; end"
  if bind # All objects have eval value, we bind when not nil
    # CAS::Help.assert(bind, Binding)
    bind.eval(code)
  else
    eval(code)
  end
end
call(f) click to toggle source

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

“` ruby x, y = CAS::vars :x, :y f = (x ** 2) + (y ** 2) f.call({x => 1, y => 2}) # => 2 “`

* **argument**: `Hash` with feed dictionary
* **returns**: `Numeric`
# File lib/operators/op.rb, line 112
def call(f)
  CAS::Help.assert(f, Hash)

  @x.call(f)
end
depend?(v) click to toggle source

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
# File lib/operators/op.rb, line 68
def depend?(v)
  CAS::Help.assert(v, CAS::Op)

  @x.depend? v
end
diff(v) click to toggle source

Return the derivative of the operation using the chain rule The input is a `CAS::Op` because it can handle derivatives with respect to functions. E.g.:

“`

f(x) = (ln(x))**2
g(x) = ln(x)

d f(x)
------ = 2 ln(x)
d g(x)

“`

* **argument**: `CAS::Op` object of the derivative
* **returns**: `CAS::Op` a derivated object, or `CAS::Zero` for constants
# File lib/operators/op.rb, line 89
def diff(v)
  CAS::Help.assert(v, CAS::Op)

  if @x.depend? v
    return @x.diff(v)
  end
  CAS::Zero
end
dot_graph() click to toggle source

Return the local Graphviz node of the tree

* **returns**: `String` of local Graphiz node
# File lib/Mr.CAS/graphviz.rb, line 42
def dot_graph
  cls = "#{self.class.to_s.gsub("CAS::", "")}_#{self.object_id}"
  "#{cls} -> #{@x.dot_graph}\n"
end
equal(v) click to toggle source

Shortcut for creating equality condition.

* **argument**: `CAS::Op` ther element of the condition
* **returns**: `CAS::Equal` new instance
# File lib/functions/fnc-conditions.rb, line 344
def equal(v)
  CAS.equal(self, v)
end
greater(v) click to toggle source

Shortcut for creating greater kind condition.

* **argument**: `CAS::Op` ther element of the condition
* **returns**: `CAS::Greater` new instance
# File lib/functions/fnc-conditions.rb, line 352
def greater(v)
  CAS.greater(self, v)
end
greater_equal(v) click to toggle source

Shortcut for creating a greater equal kind condition.

* **argument**: `CAS::Op` ther element of the condition
* **returns**: `CAS::GreaterEqual` new instance
# File lib/functions/fnc-conditions.rb, line 368
def greater_equal(v)
  CAS.greater_equal(self, v)
end
inspect() click to toggle source

Inspector for the current object

* **returns**: `String`
# File lib/operators/op.rb, line 249
def inspect
  "#{self.class}(#{@x.inspect})"
end
limit(a, b, type=:closed) click to toggle source

Shortcut for creating a new box condition. It requires limits and type:

* **argument**: `CAS::Constant` lower limit
* **argument**: `CAs::Constant` upper limit
* **argument**: `Symbol` of condition type it can be:
   - `:closed` for `CAs::BoxConditionClosed`
   - `:open` for `CAs::BoxConditionOpen`
   - `:upper_closed` for `CAs::BoxConditionUpperClosed`
   - `:lower_closed` for `CAs::BoxConditionLowerClosed`
* **returns**: `CAS::BoxCondition` new instance
# File lib/functions/fnc-box-conditions.rb, line 338
def limit(a, b, type=:closed)
  return CAS::box(self, a, b, type)
end
simplify() click to toggle source

Simplification callback. It simplify the subgraph of each node until all possible simplification are performed (thus the execution time is not deterministic).

* **returns**: `CAS::Op` simplified version
# File lib/operators/op.rb, line 214
def simplify
  hash = @x.to_s
  @x = @x.simplify
  while @x.to_s != hash
    hash = @x.to_s
    @x = @x.simplify
  end
end
simplify_dictionary() click to toggle source

Simplify dictionary performs a dictionary simplification that is the class variable `@simplify_dict`

* **returns**: `CAS::Op` self
# File lib/operators/op.rb, line 227
def simplify_dictionary
  self.class.simplify_dict(@x) || self
end
smaller(v) click to toggle source

Shortcut for creating a smaller kind condition.

* **argument**: `CAS::Op` ther element of the condition
* **returns**: `CAS::Smaller` new instance
# File lib/functions/fnc-conditions.rb, line 360
def smaller(v)
  CAS.smaller(self, v)
end
smaller_equal(v) click to toggle source

Shortcut for creating a smaller equal kind condition.

* **argument**: `CAS::Op` ther element of the condition
* **returns**: `CAS::SmallerEqual` new instance
# File lib/functions/fnc-conditions.rb, line 376
def smaller_equal(v)
  CAS.smaller_equal(self, v)
end
subs(dt) click to toggle source

Perform substitution of a part of the graph using a data table:

“` ruby x, y = CAS::vars :x, :y f = (x ** 2) + (y ** 2) puts f # => (x^2) + (y^2) puts f.subs({x => CAS::ln(y)}) # => (ln(y)^2) + (y^2) “`

* **argument**: `Hash` with substitution table
* **returns**: `CAS::Op` (`self`) with substitution performed
# File lib/operators/op.rb, line 131
def subs(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 CAS::CASError, "Impossible subs. Received a #{dt[@x].class} = #{dt[@x]}"
    end
  else
    @x.subs(dt)
  end
  return self
end
to_c_lib(name) click to toggle source
# File lib/Mr.CAS/c-opt.rb, line 229
def to_c_lib(name)
  CAS::Help.assert(name, String)
  [CAS::C_PLUGIN.write_header(self, name), CAS::C_PLUGIN.write_source(self, name)]
end
to_code() click to toggle source

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`
# File lib/operators/op.rb, line 158
def to_code
  "#{@x}"
end
to_s() click to toggle source

Convert expression to string

* **returns**: `String` to print on screen
# File lib/operators/op.rb, line 151
def to_s
  "#{@x}"
end