Class: CAS::Function

Inherits:
NaryOp show all
Defined in:
lib/numbers/functions.rb,
lib/Mr.CAS/c-opt.rb

Overview

Unknown function class. Will allow to make symbolic differentiation and so on.

Constant Summary collapse

@@container =

Contains all defined functions. Container is a ‘Hash` with name of the function as key and the function as the value

{}

Instance Attribute Summary collapse

Attributes inherited from NaryOp

#x

Attributes inherited from Op

#x

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from NaryOp

#__reduce_constants, #__reduce_multeplicity, #depend?, #dot_graph

Methods inherited from Op

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

Constructor Details

#initialize(name, *xs) ⇒ Function

Initializes a new function. It requires a name and a series of arguments that will be the functions on which it depends.

* **argument**: `String` or `Symbol` name of the variable
* **argument**: `Array` of `CAS::Variable` that are argument of the function
* **returns**: `CAS::Function`


60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/numbers/functions.rb', line 60

def initialize(name, *xs)
  xs.flatten!
  CAS::Help.assert_name name
  xs.each do |x|
    CAS::Help.assert x, CAS::Op
  end
  # raise CASError, "Function #{name} already exists" if CAS::Function.exist? name

  @x = xs.uniq
  @name = name
  @@container[@name] = self
end

Instance Attribute Details

#nameObject (readonly)

The attribute ‘name` identifies the current function. A function with the same name of an existing function connot be defined



52
53
54
# File 'lib/numbers/functions.rb', line 52

def name
  @name
end

Class Method Details

.[](s) ⇒ Object

Returns a function given its name

* **argument**: `Object` name of the function
* **returns**: `CAS::Function` instance if exists, raises a `CAS::CASError`
  if not

Raises:



39
40
41
42
# File 'lib/numbers/functions.rb', line 39

def self.[](s)
  return @@container[s] if self.exist? s
  raise CASError, "Function #{s} not found"
end

.exist?(name) ⇒ Boolean

Returns ‘true` if a function exists in container

* **argument**: `String` or `Symbol` that represent the functions
* **returns**: `TrueClass` if variable exists, `FalseClass` if not

Returns:

  • (Boolean)


24
25
26
27
# File 'lib/numbers/functions.rb', line 24

def self.exist?(name)
  CAS::Help.assert_name name
  (@@container[name] ? true : false)
end

.listObject

Return the ‘Hash` of the functions

* **returns**: `Hash`


19
# File 'lib/numbers/functions.rb', line 19

def self.list; @@container; end

.new(name, *xs) ⇒ Object

Overrides new method. This will return an existing function if in the function container

* **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


78
79
80
81
82
# File 'lib/numbers/functions.rb', line 78

def Function.new(name, *xs)
  a = super
  a.c_name = name
  return a
end

.sizeObject

Return the number of functions defined

* **returns**: `Fixnum`


32
# File 'lib/numbers/functions.rb', line 32

def self.size; @@container.keys.size; end

Instance Method Details

#==(op) ⇒ Object

Checks if two functions can be considered equal (same name, same args)

* **requires**: another op to be checked against
* **returns**: `TrueClass` if functions are equal, `FalseClass` if not equal


176
177
178
179
180
# File 'lib/numbers/functions.rb', line 176

def ==(op)
  return false if not self.class == op.class
  return false if not (@name == op.name and @x.uniq == op.x.uniq)
  true
end

#[](i) ⇒ Object

Get an element in a particular position of the argument

* **requires**: an iterator
* **returns**: element of the argument `CAS::Op` or `NilClass`


104
# File 'lib/numbers/functions.rb', line 104

def [](i); @x[i]; end

#argsObject

Returns an array containing ‘CAS::Variable`s argument of the function Plese note that sub Op will return their args.

* **returns**: `Array` containing `CAs::Variable`


92
93
94
95
96
97
98
# File 'lib/numbers/functions.rb', line 92

def args
  ret = []
  @x.each do |e|
    ret << e.args
  end
  ret.flatten.uniq
end

#c_name=(s) ⇒ Object



213
214
215
216
# File 'lib/Mr.CAS/c-opt.rb', line 213

def c_name=(s)
  CAS::Help.assert_name s
  @c_name = s
end

#call(_v) ⇒ Object

Trying to call a ‘CAS::Function` will always return a `CAS::Error`

* **raises**: `CAS::CASError`

Raises:



156
157
158
# File 'lib/numbers/functions.rb', line 156

def call(_v)
  raise CASError, "Cannot call a #{self.class}"
end

#diff(v) ⇒ Object

Performs the derivative with respect to one of the variable. The new function has a name with respect to a schema that for now is fixed (TODO: make it variable and user defined).

* **requires**: a `CAS::Variable` for derivative
* **returns**: the `CAS::Variable` derivated function


141
142
143
144
145
146
147
148
149
150
151
# File 'lib/numbers/functions.rb', line 141

def diff(v)
  # return CAS.declare :"d#{@name}[#{v}]", @x
  ret = []
  @x.each_with_index do |x, k|
    dx = (x.depend?(v) ? x.diff(v) : CAS::Zero)
    dfx = CAS.declare :"D#{@name}[#{k}]", @x
    ret << dx * dfx
  end
  return CAS::Zero if ret == []
  return ret.inject { |d, e| d += e }
end

#inspectObject

Returns the inspect string of the function, that is similar to ‘CAS::Function#to_s`

* **returns**: inspection `String`


163
# File 'lib/numbers/functions.rb', line 163

def inspect; self.to_s; end

#simplifyObject

Simplifications cannot be performed on anonymous function, thus it will always return the ‘self` `CAS::Function` object

* **returns**: `CAS::Function` self instance


110
# File 'lib/numbers/functions.rb', line 110

def simplify; self; end

#subs(s) ⇒ Object

Substitutions in which a function is involved directly generates a CAS::Error unless the substitution will involve another variable. Example:

“‘ ruby (CAS.declare :f [x, y, z]).subs { x => x ** 2 } # this raises CASError (CAS.declare :f [x, y, z]).subs { x => y } # this returns f(y, z) “`

* **requires**: a substitution `Hash`
* **returns**: a `CAS::Function` with modified argument list
* **raises**: `CASError` if something different with resppect to a `CAS::Variable` is a active substitution


131
132
133
134
# File 'lib/numbers/functions.rb', line 131

def subs(s)
  @x.each { |e| e.subs(s) }
  self
end

#to_codeObject

Tries to convert an anonymous function into Ruby code will always raise a ‘CASError` because it is not possible to generate code for such a fuction

* **raises**: `CAS::CASError`: Ruby code for CAs::Function cannot be generated

Raises:



116
117
118
# File 'lib/numbers/functions.rb', line 116

def to_code
  raise CASError, "Ruby code for #{self.class} cannot be generated"
end

#to_sObject

Returns a description ‘String` for the `CAS::Function`

* **returns**: `String`


168
169
170
# File 'lib/numbers/functions.rb', line 168

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