Module: MachineLearningWorkbench::Monkey::Exponentiable

Defined in:
lib/machine_learning_workbench/monkey.rb

Instance Method Summary collapse

Instance Method Details

#exponentialNArray

Matrix exponential: ‘e**self` (not to be confused with `self**n`)

Returns:

Raises:

  • (ArgumentError)


269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/machine_learning_workbench/monkey.rb', line 269

def exponential
  raise ArgumentError if ndim > 2
  # special case: one-dimensional matrix: just exponentiate the values
  return NMath.exp(self) if (ndim == 1) || shape.include?(1)
  # at this point we need to validate it is a square matrix
  raise ArgumentError unless shape.reduce(&:==)

  # Eigenvalue decomposition method from `scipy/linalg/matfuncs.py#expm2` (deprecated)
  # https://github.com/scipy/scipy/commit/236e0740ba951cb455ba8b6a306abb32740131cf
  # s, vr = eig(A)
  # vri = inv(vr)
  # r = dot(dot(vr, diag(exp(s))), vri)

  # TODO: this is a simple but outdated method, switch to Pade approximation
  # https://github.com/scipy/scipy/blob/11509c4a98edded6c59423ac44ca1b7f28fba1fd/scipy/sparse/linalg/matfuncs.py#L557

  # e_values, l_e_vectors, r_e_vectors_t = NLinalg.svd self
  evals, _wi, _vl, r_evecs = NLinalg::Lapack.call(:geev, self, jobvl: false, jobvr: true)
  r_evecs_t = r_evecs#.transpose
  r_evecs_inv = r_evecs_t.invert
  evals_exp_dmat = NMath.exp(evals).diag

  # l_e_vectors.dot(e_vals_exp_dmat).dot(l_e_vectors.invert)#.transpose
  r_evecs_t.dot(evals_exp_dmat).dot(r_evecs_inv)
end