Source code for NumericDiff

r"""
'NumericDiff' Module
========================
This module provides very basic way to numerically approximate partial derivatives, gradient and Hessian of a function.
"""

from __future__ import print_function

Infinitesimal = 1e-7


[docs]class Simple(object): r""" A simple class to calculate partial derivatives of a given function. Passing a value for `Infinitesimal` forces the calculations to be done according to the infinitesimal value provided by user. Otherwise, the default value (1.e-7) is used. """ def __init__(self, **kwargs): self.Infinitesimal = kwargs.get('Infinitesimal', Infinitesimal)
[docs] def Diff(self, f, i=0): r""" :param f: a real valued function :param i: the index variable for differentiation :return: partial derivative of :math:`f` with respect to :math:'i^{th}` variable as a function. """ assert i >= 0, "The variable index must be a positive integer for differentiation" from numpy import array def df(x): try: n = len(x) except: n = 1 if i < n: dx_p = list(x) dx_m = list(x) dx_p[i] = x[i] + self.Infinitesimal dx_m[i] = x[i] - self.Infinitesimal return (f(array(dx_p)) - f(array(dx_m))) / (2. * self.Infinitesimal) else: return 0. return df
[docs] def Gradient(self, f): r""" :param f: a real valued function :return: a vector function that returns the gradient vector of `f` at each point. """ from numpy import array def gf(x): try: n = len(x) except: n = 1 gr = [] for i in range(n): dx_p = list(x) dx_m = list(x) dx_p[i] = dx_p[i] + self.Infinitesimal dx_m[i] = dx_m[i] - self.Infinitesimal gr.append((f(dx_p) - f(dx_m)) / (2. * self.Infinitesimal)) return array(gr) return gf
[docs] def Hessian(self, f): r""" :param f: a real valued function :return: the Hessian matrix of :math:`f` at each point """ from numpy import array def hsn(x): try: n = len(x) except: n = 1 hs_mat = [] for i in range(n): hs_row = [] for j in range(n): dx_pp = list(x) dx_mm = list(x) dx_pm = list(x) dx_mp = list(x) dx_pp[i] = dx_pp[i] + self.Infinitesimal dx_pp[j] = dx_pp[j] + self.Infinitesimal dx_pm[i] = dx_pm[i] + self.Infinitesimal dx_pm[j] = dx_pm[j] - self.Infinitesimal dx_mm[i] = dx_mm[i] - self.Infinitesimal dx_mm[j] = dx_mm[j] - self.Infinitesimal dx_mp[i] = dx_mp[i] - self.Infinitesimal dx_mp[j] = dx_mp[j] + self.Infinitesimal hs_row.append((f(dx_pp) - f(dx_mp) - f(dx_pm) + f(dx_mm)) / (4 * self.Infinitesimal ** 2)) hs_mat.append(array(hs_row)) return array(hs_mat) return hsn