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, #inspect

Methods inherited from Op

#!=, #*, #**, #+, #-, #-@, #/, #as_proc, #depend?, #dot_graph, #equal, #greater, #greater_equal, init_simplify_dict, #inspect, #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`


83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/numbers/functions.rb', line 83

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



75
76
77
# File 'lib/numbers/functions.rb', line 75

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:



62
63
64
65
# File 'lib/numbers/functions.rb', line 62

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)


47
48
49
50
# File 'lib/numbers/functions.rb', line 47

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

.listObject

Return the ‘Hash` of the functions

* **returns**: `Hash`


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

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


101
102
103
104
105
# File 'lib/numbers/functions.rb', line 101

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

.sizeObject

Return the number of functions defined

* **returns**: `Fixnum`


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

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


203
204
205
206
207
# File 'lib/numbers/functions.rb', line 203

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`


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

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`


115
116
117
118
119
120
121
# File 'lib/numbers/functions.rb', line 115

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

#c_name=(s) ⇒ Object



236
237
238
239
# File 'lib/Mr.CAS/c-opt.rb', line 236

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:



181
182
183
# File 'lib/numbers/functions.rb', line 181

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


164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/numbers/functions.rb', line 164

def diff(v)
  # return CAS.declare :"d#{@name}[#{v}]", @x
  ret = []
  @x.each_with_index do |y, k|
    dy = (y.depend?(v) ? y.diff(v) : CAS::Zero)
    dfy = CAS.declare :"D#{@name}[#{k}]", @x
    ret << (dy * dfy)
  end
  return CAS::Zero if ret == []
  a = ret[0]
  ret[1..-1].each { |e| a += e } if ret.size > 1
  return a
end

#simplifyObject

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

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


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

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


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

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:



139
140
141
# File 'lib/numbers/functions.rb', line 139

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`


195
196
197
# File 'lib/numbers/functions.rb', line 195

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