Skip to content

Instantly share code, notes, and snippets.

@stephane-vanraes
Last active April 19, 2023 07:54
Show Gist options
  • Save stephane-vanraes/b6854b21d5ef73b2fe7188c73bb48b10 to your computer and use it in GitHub Desktop.
Save stephane-vanraes/b6854b21d5ef73b2fe7188c73bb48b10 to your computer and use it in GitHub Desktop.
Automatic Differentiation with Dual Numbers
### The Dual Number Class
#
# A dual number is a number of the format "x + ε" where ε**2 = 0 but ε!= 0
# Given a function F it can be proven that
# F(x + ε) = F(x) + F'(x)
# This allows us to quickly calculate the value of a function and it's first derivative in one go, without having to construct the derivative function first.
# https://en.wikipedia.org/wiki/Dual_number
##
# INCOMPLETE IMPLEMENTATION
# - not possible to divide
# - not possible to take a negative power
##
class Dual:
def __init__(self, real, dual):
self.real = real
self.dual = dual
def __add__(self, other):
if isinstance(other, Dual):
return Dual(self.real + other.real, self.dual + other.dual)
else:
return Dual(self.real + other, self.dual)
def __radd__(self, other):
return self + other
def __sub__(self, other):
if isinstance(other, Dual):
return Dual(self.real - other.real, self.dual - other.dual)
else:
return Dual(self.real - other, self.dual)
def __rsub__(self, other):
return self + other
def __mul__(self, other):
if isinstance(other, Dual):
return Dual(self.real * other.real, (self.real * other.dual) + (self.dual * other.real))
else:
return Dual(self.real * other, self.dual * other)
def __rmul__(self, other):
return self * other
def __pow__(self, other):
if other == 0:
return 1
else:
return self * (self**(other-1))
# Ask for a polynom
fun = input('Enter the polynomial: ')
# Ask for a value of x
x = input('Enter the value for x: ')
# Solve for "x + ε"
d = {}
d['x'] = Dual(real = float(x), dual = 1)
solution = eval(fun, d)
## Output
print("----------------------------------")
print("\nf(x)=" + fun)
print("f(" + str(x) + ")="+str(solution.real))
print("f'(" + str(x) + ")="+str(solution.dual))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment