"""Linear algebra vector This module implements a basic linear algebra vector class. It demonstrates the following Python features: * Derivation of a user class from a built-in type (list) * Arithmetic operator overloading (__add__, __mul__) * Order-sensitive arithmetic operators (__rmul__) * The isinstance() function * The zip function See help(zip) in the interpreter for details on the last of these. See http://docs.python.org/ref/numeric-types.html for more details on numeric type operator overloading. """ class Vector(list): """Vector This module implements a basic linear algebra vector. A vector consists of an ordered list of N items (x_1, x_2 ... x_N). The value of N is called the dimension of the vector. The len() function returns the dimensionality of this object. Any object which itself defines addition and multiplication operations may be an element of a vector. >>> x = vector.Vector([7, 2.5, 3]) >>> len(x) 3 >>> x[1] 2.5 >>> x[0] = 5 >>> x Vector[5, 2.5, 3] """ def __repr__(self): """Stringification >>> v1 = vector.Vector([1,2,3]) >>> v1 Vector[1, 2, 3] """ return "%s%s" % (self.__class__.__name__, super(Vector, self).__repr__()) def __add__(self, other): """The addition operator Addition for two vectors x and y of the same dimension is defined like so: x + y = (x_1, x_2 ... x_N) + (y_1, y_2 ... y_N) = (x_1 + y_1, x_2 + y_2 ... x_N + y_N) >>> x = vector.Vector([1+2j, 7]) >>> y = vector.Vector([3, 2+1j]) >>> x + y Vector[(4+2j), (9+1j)] """ if not isinstance(other, Vector): raise TypeError, "%s is not a Vector" % other if not len(self) == len(other): raise ValueError, "Incorrect dimension of %s" % other return self.__class__([s+o for (s, o) in zip(self, other)]) def __mul__(self, other): """The multiplication operator Multiplication is defined between a vector and a scalar, or between two vectors of the same dimension. Multiplication for a vector x and a scalar z is defined like so: z * x = x * z = (z*x_1, z*x_2 ... z*x_N) >>> x = vector.Vector([1, 2, 3]) >>> x*2 Vector[2, 4, 6] Multiplication for two vectors x and y of the same dimension is defined like so: x * y = (x_1, x_2 ... x_N) + (y_1, y_2 ... y_N) = (x_1 * y_1, x_2 * y_2 ... x_N * y_N) >>> x = vector.Vector([1, 2, 1.5, -1]) >>> y = vector.Vector([3, 4, 5, 6]) >>> x * y Vector[3, 8, 7.5, -6] The multiplication operator defined here is what in linear algebra would be called the 'dot' or 'inner' product. """ if isinstance(other, Vector): # other is a vector. if not len(self) == len(other): raise ValueError, "Incorrect dimension of %s" % other else: # other is a scalar. other = [other] * len(self) return self.__class__([s*o for (s, o) in zip(self, other)]) def __rmul__(self, other): """The right-multiplication operator This operator is called when the left-hand operand does not support the multiplication operator. It is used to get the correct result for multiplications like the following. >>> x = vector.Vector([1, 2, 3]) >>> 2*x Vector[2, 4, 6] """ return self*other def norm(self): """The length of the vector >>> x = vector.Vector([3, 4]) >>> x.norm() 5.0 """ return sum([x**2 for x in self]) ** 0.5