Skip to content

Instantly share code, notes, and snippets.

@Sibirtsev
Forked from rldotai/vector.py
Created September 15, 2016 03:24
Show Gist options
  • Save Sibirtsev/3f961d53c7cf59e037bf6523162179cf to your computer and use it in GitHub Desktop.
Save Sibirtsev/3f961d53c7cf59e037bf6523162179cf to your computer and use it in GitHub Desktop.
Pure Python Vector class
"""
A simple implementation of vectors in Python modelled after tuples, but having
altered some of the operations to be closer to vector arithmetic.
It targets Python 3.5+ in order to support __matmul__, allowing for dot
products, which I have heard are important in linear algebra.
We check for whether it is operating on a number in order to implement
broadcasting; otherwise it performs the operations elementwise.
We also use `zip_longest` because it performs an implicit check for sequences
of unequal length; it pads the iteration with `None`, which will raise an error
during arithmetic operations.
"""
from itertools import zip_longest
from numbers import Number
from operator import add, floordiv, mul, pow, sub, truediv
class Vector(tuple):
def __abs__(self):
return Vector(abs(x) for x in self)
def __add__(self, other):
if isinstance(other, Number):
return Vector(i + other for i in self)
return Vector(add(a, b) for a, b in zip_longest(self, other))
def __floordiv__(self, other):
if isinstance(other, Number):
return Vector(i // other for i in self)
return Vector(floordiv(a, b) for a, b in zip_longest(self, other))
def __matmul__(self, other):
return sum(mul(a, b) for a, b in zip_longest(self, other))
def __mul__(self, other):
if isinstance(other, Number):
return Vector(i * other for i in self)
return Vector(mul(a, b) for a, b in zip_longest(self, other))
def __neg__(self):
return Vector(-x for x in self)
def __pow__(self, other):
if isinstance(other, Number):
return Vector(i**other for i in self)
return Vector(pow(a, b) for a, b in zip_longest(self, other))
def __sub__(self, other):
if isinstance(other, Number):
return Vector(i - other for i in self)
return Vector(sub(a, b) for a, b in zip_longest(self, other))
def __radd__(self, other):
if isinstance(other, Number):
return Vector(i + other for i in self)
return Vector(add(a, b) for a, b in zip_longest(self, other))
def __rfloordiv__(self, other):
if isinstance(other, Number):
return Vector(i // other for i in self)
return Vector(floordiv(a, b) for a, b in zip_longest(self, other))
def __rmatmul__(self, other):
return sum(mul(a, b) for a, b in zip_longest(self, other))
def __rmul__(self, other):
if isinstance(other, Number):
return Vector(i * other for i in self)
return Vector(mul(a, b) for a, b in zip_longest(self, other))
def __rpow__(self, other):
if isinstance(other, Number):
return Vector(i**other for i in self)
return Vector(pow(a, b) for a, b in zip_longest(self, other))
def __rsub__(self, other):
if isinstance(other, Number):
return Vector(i - other for i in self)
return Vector(sub(a, b) for a, b in zip_longest(self, other))
def __rtruediv__(self, other):
if isinstance(other, Number):
return Vector(i / other for i in self)
return Vector(truediv(a, b) for a, b in zip_longest(self, other))
def __truediv__(self, other):
if isinstance(other, Number):
return Vector(i / other for i in self)
return Vector(truediv(a, b) for a, b in zip_longest(self, other))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment