module CAS

Mr.CAS A minmalistic CAS engine with encapsuled graph representation. This will make impossible to perform complex high level simplifications, but it is powerful enough to define simple algorithm in a symbolic way.

Mathematically, this is an implementation of the forward chain rule for automatic differentiaition. Each function is a container of function and the derivation is in the form:

“`

d(f(g(x))
--------- = g'(x) * f'(g(x))
   dx

“`

Author

Matteo Ragni (info@ragni.me)

Copyright

Copyright © 2016 Matteo Ragni

License

Distributed under MIT license terms

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

| (__ | _/ | || / _` | | ' \

\___| |_| |_|\_,_\__, |_|_||_|
                 |___/
 ___               _       _      ___ _           _
/ __|_ _ __ _ _ __| |___ _(_)___ | _ \ |_  _ __ _(_)_ _

| (_ | '_/ _` | '_ \ ' \ V / |_ / | _/ | || / _` | | ' \

\___|_| \__,_| .__/_||_\_/|_/__| |_| |_|\_,_\__, |_|_||_|
             |_|                            |___/
_        _____ ____      ___ _           _

| | __ |_ _|__ /_ __ | _ \ |_ _ __ _(_)_ _ | |__/ _` || | |_ \ \ / | _/ | || / _` | | ' \ |__,_||_| |_/\ |_| |_|_,_, |_|_||_|

|___/
__  __      _   _      _      ___ _           _

| / |__ _| |_| |__ _| |__ | _ \ |_ _ __ _(_)_ _ | |/| / _` | _| / _` | '_ \ | _/ | || / _` | | ' \ |_| |_,_|__|_,_|._/ |_| |_|_,_, |_|_||_|

|___/

Constants

E

E (2.57…) constant representation

Infinity

Infinity constant representation

MinusOne

Minus One (-1) constant representation

NegInfinity

Negative Infinity constant representation

NumericToConst

Series of useful numeric constant, Based upon `Numeric` keys, with `CAs::Constant` value

One

One (1) constant representation

Pi

Pi (3.14…) constant representation

Two

Two (2) constant representation

VERSION

Version of the library Array of three `Fixnum` values:

* Major version
* Minor version
* Patchlevel
Zero

Zero (0) constant representation

Public Class Methods

abs(x) click to toggle source

Shortcut for `CAs::Abs` initializer

* **argument**: `CAs::Op` argument of absolute value
* **returns**: `CAS::Abs` new instance
# File lib/functions/fnc-base.rb, line 512
def self.abs(x)
  CAS::Abs.new x
end
acos(x) click to toggle source

Shortcut for `CAS::Acos#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Acos` operation
# File lib/functions/fnc-trig.rb, line 319
def acos(x)
  CAS::Acos.new x
end
Also aliased as: arccos
arccos(x)
Alias for: acos
arcsin(x)
Alias for: asin
arctan(x)
Alias for: atan
asin(x) click to toggle source

Shortcuts for `CAS::Asin#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Asin` operation
# File lib/functions/fnc-trig.rb, line 161
def asin(x)
  CAS::Asin.new x
end
Also aliased as: arcsin
atan(x) click to toggle source

Shortcut for `CAS::Atan#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Atan` operation
# File lib/functions/fnc-trig.rb, line 484
def atan(x)
  CAS::Atan.new x
end
Also aliased as: arctan
box(x, a, b, type=:closed) click to toggle source

Shortcut for creating a new box condition. It requires four arguments:

* **argument**: `CAS::Op` function for condition
* **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 287
def box(x, a, b, type=:closed)
  case type
  when :closed
    return CAS::BoxConditionClosed.new(x, a, b)
  when :open
    return CAS::BoxConditionOpen.new(x, a, b)
  when :upper_closed
    return CAS::BoxConditionUpperClosed.new(x, a, b)
  when :lower_closed
    return CAS::BoxConditionLowerClosed.new(x, a, b)
  else
    raise CAS::CASError, "Unknown box condition type"
  end
end
Also aliased as: in
const(*val) click to toggle source

Allows to define a series of new constants.

“` ruby a, b = CAS::const 1.0, 100 “`

* **argument**: `Array` of Numeric
* **returns**: `Array` of `CAS::Contant`
# File lib/numbers/constants.rb, line 108
def self.const(*val)
  #(val = [val]) if val.size == 1
  ret = []
  val.each do |n|
    ret << (NumericToConst[n] ? NumericToConst[n] : CAS::Constant.new(n))
  end
  return (ret.size == 1 ? ret[0] : ret)
end
cos(x) click to toggle source

Shortcut for `CAS::Cos#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Cos` operation
# File lib/functions/fnc-trig.rb, line 247
def self.cos(x)
  CAS::Cos.new x
end
declare(name, *xs) click to toggle source

This shortcut allows to declare a new function

* **requires**: `String` or `Symbol` that is the name of the function
* **requires**: `Array` of `CAS::Variable`
* **returns**: a new `CAS::Function` or the old one
# File lib/numbers/functions.rb, line 189
def declare(name, *xs)
  xs.flatten!
  CAS::Function.new(name, xs)
end
equal(x, y) click to toggle source

Shortcut creates a `CAS::Equal` object

# File lib/functions/fnc-conditions.rb, line 300
def self.equal(x, y)
  CAS::Equal.new(x, y)
end
exp(x) click to toggle source

Shortcut for `CAS::Exp#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Exp` operation
# File lib/functions/fnc-trsc.rb, line 92
def self.exp(x)
  CAS::Exp.new x
end
export_dot(fl, op) click to toggle source

Export the input `CAS::Op` graphviz representation to a file.

* **argument**: `String` with filename
* **argument**: `CAS::Op` with the tree
* **returns**: `CAS::Op` in input
# File lib/Mr.CAS/graphviz.rb, line 125
def self.export_dot(fl, op)
  CAS::Help.assert(fl, String)
  CAS::Help.assert(op, CAS::Op)

  File.open(fl, "w") do |f| f.puts CAS.to_dot(op) end
  return op
end
greater(x, y) click to toggle source

Shortcut creates a `CAS::Greater` object

# File lib/functions/fnc-conditions.rb, line 305
def self.greater(x, y)
  CAS::Greater.new(x, y)
end
greater_equal(x, y) click to toggle source

Shortcut creates a `CAS::GreaterEqual` object

# File lib/functions/fnc-conditions.rb, line 310
def self.greater_equal(x, y)
  CAS::GreaterEqual.new(x, y)
end
in(x, a, b, type=:closed)
Alias for: box
invert(x) click to toggle source

Shortcut for `CAs::Invert` initializer

* **argument**: `CAs::Op` argument of the inversion
* **returns**: `CAS::Invert` new instance
# File lib/functions/fnc-base.rb, line 427
def self.invert(x)
  CAS::Invert.new x
end
ln(x) click to toggle source

Shortcut for `CAS::Ln#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Ln` operation
# File lib/functions/fnc-trsc.rb, line 187
def ln(x)
  CAS::Ln.new x
end
Also aliased as: log
log(x)
Alias for: ln
max(x, y) click to toggle source

Shortcut for `CAS::Max` initializer

* **argument**: `CAS::Op` left function
* **argument**: `CAS::Op` right function
* **returns**: `CAS::Max` new instance
# File lib/functions/fnc-piecewise.rb, line 174
def self.max(x, y)
  CAS::Max.new(x, y)
end
min(x, y) click to toggle source

Shortcut for `CAS::Min` initializer

* **argument**: `CAS::Op` left function
* **argument**: `CAS::Op` right function
* **returns**: `CAS::Min` new instance
# File lib/functions/fnc-piecewise.rb, line 183
def self.min(x, y)
  CAS::Min.new(x, y, CAS::smaller_equal(x, y))
end
pow(x, y) click to toggle source

Shortcut for `CAS::Pow` initializer

* **argument**: `CAS::Op` base
* **argument**: `CAS::Op` exponent
* **returns**: `CAS::Pow` new instance
# File lib/functions/fnc-base.rb, line 170
def self.pow(x, y)
  CAS::Pow.new x, y
end
sin(x) click to toggle source

Shortcut for `CAS::Sin#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Sin` operation
# File lib/functions/fnc-trig.rb, line 84
def self.sin(x)
  CAS::Sin.new x
end
smaller(x, y) click to toggle source

Shortcut creates `CAS::Smaller` object

# File lib/functions/fnc-conditions.rb, line 315
def self.smaller(x, y)
  CAS::Smaller.new(x, y)
end
smaller_equal(x, y) click to toggle source

Shortcut creates a `CAs::SmallerEqual` object

# File lib/functions/fnc-conditions.rb, line 320
def self.smaller_equal(x, y)
  CAS::SmallerEqual.new(x, y)
end
sqrt(x) click to toggle source

Shortcut for `CAS::Sqrt` initializer

* **argument**: `CAS::Op` argument of square root
* **returns**: `CAS::Sqrt` new instance
# File lib/functions/fnc-base.rb, line 342
def self.sqrt(x)
  CAS::Sqrt.new x
end
tan(x) click to toggle source

Shortcut for `CAS::Tan#new`

* **argument**: `CAS::Op` argument of the function
* **returns**: `CAS::Tan` operation
# File lib/functions/fnc-trig.rb, line 405
def self.tan(x)
  CAS::Tan.new x
end
to_dot(op) click to toggle source

Return a string representation of the graph that is a Graphviz tree. Requires a `CAS::Op` as argument. In the next releases probably it will be moved inside `CAS::Op`.

* **argument**: `CAS::Op` instance
* **returns**: `String`
# File lib/Mr.CAS/graphviz.rb, line 84
def self.to_dot(op)
  CAS::Help.assert(op, CAS::Op)
  string = op.dot_graph
  labels = ""

  dot_subs_hash = {
    "Sum"                => "+",
    "Diff"               => "-",
    "Prod"               => "×",
    "Div"                => "÷",
    "Sqrt"               => "√(∙)",
    "Abs"                => "|∙|",
    "Invert"             => "-(∙)",
    "Exp"                => "exp(∙)",
    "Log"                => "log(∙)",
    "Pow"                => "(∙)^(∙)",
    "ZERO_CONSTANT"      => "0",
    "ONE_CONSTANT"       => "1",
    "TWO_CONSTANT"       => "2",
    "PI_CONSTANT"        => "π",
    "INFINITY_CONSTANT"  => "∞",
    "E_CONSTANT"         => "e",
    "MINUS_ONE_CONSTANT" => "-1"
  }

  lab = {}
  string.scan(/\w+\_\d+/) do |m|
    if m =~ /(\w+)\_\d+/
      lab[m] = dot_subs_hash[$1] || $1
    end
  end
  lab.each { |k, v| labels += "  #{k} [label=\"#{v}\"]\n" }

  return "digraph Op {\n  #{string}#{labels}}"
end
vars(*name) click to toggle source

Allows to define a series of new variables.

“` ruby x, y = CAS::vars :x, :y “`

* **argument**: `Array` of Numeric
* **returns**: `Array` of `CAS::Variable`
# File lib/numbers/variables.rb, line 194
def self.vars(*name)
  (return CAS::Variable.new(name[0])) if name.size == 1
  ret = []
  name.each do |n|
    ret << CAS::Variable.new(n)
  end
  return ret
end