Chris@87: from __future__ import division, absolute_import, print_function Chris@87: Chris@87: __all__ = ['matrix', 'bmat', 'mat', 'asmatrix'] Chris@87: Chris@87: import sys Chris@87: import numpy.core.numeric as N Chris@87: from numpy.core.numeric import concatenate, isscalar, binary_repr, identity, asanyarray Chris@87: from numpy.core.numerictypes import issubdtype Chris@87: Chris@87: # make translation table Chris@87: _numchars = '0123456789.-+jeEL' Chris@87: Chris@87: if sys.version_info[0] >= 3: Chris@87: class _NumCharTable: Chris@87: def __getitem__(self, i): Chris@87: if chr(i) in _numchars: Chris@87: return chr(i) Chris@87: else: Chris@87: return None Chris@87: _table = _NumCharTable() Chris@87: def _eval(astr): Chris@87: str_ = astr.translate(_table) Chris@87: if not str_: Chris@87: raise TypeError("Invalid data string supplied: " + astr) Chris@87: else: Chris@87: return eval(str_) Chris@87: Chris@87: else: Chris@87: _table = [None]*256 Chris@87: for k in range(256): Chris@87: _table[k] = chr(k) Chris@87: _table = ''.join(_table) Chris@87: Chris@87: _todelete = [] Chris@87: for k in _table: Chris@87: if k not in _numchars: Chris@87: _todelete.append(k) Chris@87: _todelete = ''.join(_todelete) Chris@87: del k Chris@87: Chris@87: def _eval(astr): Chris@87: str_ = astr.translate(_table, _todelete) Chris@87: if not str_: Chris@87: raise TypeError("Invalid data string supplied: " + astr) Chris@87: else: Chris@87: return eval(str_) Chris@87: Chris@87: def _convert_from_string(data): Chris@87: rows = data.split(';') Chris@87: newdata = [] Chris@87: count = 0 Chris@87: for row in rows: Chris@87: trow = row.split(',') Chris@87: newrow = [] Chris@87: for col in trow: Chris@87: temp = col.split() Chris@87: newrow.extend(map(_eval, temp)) Chris@87: if count == 0: Chris@87: Ncols = len(newrow) Chris@87: elif len(newrow) != Ncols: Chris@87: raise ValueError("Rows not the same size.") Chris@87: count += 1 Chris@87: newdata.append(newrow) Chris@87: return newdata Chris@87: Chris@87: def asmatrix(data, dtype=None): Chris@87: """ Chris@87: Interpret the input as a matrix. Chris@87: Chris@87: Unlike `matrix`, `asmatrix` does not make a copy if the input is already Chris@87: a matrix or an ndarray. Equivalent to ``matrix(data, copy=False)``. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: data : array_like Chris@87: Input data. Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: mat : matrix Chris@87: `data` interpreted as a matrix. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.array([[1, 2], [3, 4]]) Chris@87: Chris@87: >>> m = np.asmatrix(x) Chris@87: Chris@87: >>> x[0,0] = 5 Chris@87: Chris@87: >>> m Chris@87: matrix([[5, 2], Chris@87: [3, 4]]) Chris@87: Chris@87: """ Chris@87: return matrix(data, dtype=dtype, copy=False) Chris@87: Chris@87: def matrix_power(M, n): Chris@87: """ Chris@87: Raise a square matrix to the (integer) power `n`. Chris@87: Chris@87: For positive integers `n`, the power is computed by repeated matrix Chris@87: squarings and matrix multiplications. If ``n == 0``, the identity matrix Chris@87: of the same shape as M is returned. If ``n < 0``, the inverse Chris@87: is computed and then raised to the ``abs(n)``. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: M : ndarray or matrix object Chris@87: Matrix to be "powered." Must be square, i.e. ``M.shape == (m, m)``, Chris@87: with `m` a positive integer. Chris@87: n : int Chris@87: The exponent can be any integer or long integer, positive, Chris@87: negative, or zero. Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: M**n : ndarray or matrix object Chris@87: The return value is the same shape and type as `M`; Chris@87: if the exponent is positive or zero then the type of the Chris@87: elements is the same as those of `M`. If the exponent is Chris@87: negative the elements are floating-point. Chris@87: Chris@87: Raises Chris@87: ------ Chris@87: LinAlgError Chris@87: If the matrix is not numerically invertible. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: matrix Chris@87: Provides an equivalent function as the exponentiation operator Chris@87: (``**``, not ``^``). Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> from numpy import linalg as LA Chris@87: >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit Chris@87: >>> LA.matrix_power(i, 3) # should = -i Chris@87: array([[ 0, -1], Chris@87: [ 1, 0]]) Chris@87: >>> LA.matrix_power(np.matrix(i), 3) # matrix arg returns matrix Chris@87: matrix([[ 0, -1], Chris@87: [ 1, 0]]) Chris@87: >>> LA.matrix_power(i, 0) Chris@87: array([[1, 0], Chris@87: [0, 1]]) Chris@87: >>> LA.matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements Chris@87: array([[ 0., 1.], Chris@87: [-1., 0.]]) Chris@87: Chris@87: Somewhat more sophisticated example Chris@87: Chris@87: >>> q = np.zeros((4, 4)) Chris@87: >>> q[0:2, 0:2] = -i Chris@87: >>> q[2:4, 2:4] = i Chris@87: >>> q # one of the three quarternion units not equal to 1 Chris@87: array([[ 0., -1., 0., 0.], Chris@87: [ 1., 0., 0., 0.], Chris@87: [ 0., 0., 0., 1.], Chris@87: [ 0., 0., -1., 0.]]) Chris@87: >>> LA.matrix_power(q, 2) # = -np.eye(4) Chris@87: array([[-1., 0., 0., 0.], Chris@87: [ 0., -1., 0., 0.], Chris@87: [ 0., 0., -1., 0.], Chris@87: [ 0., 0., 0., -1.]]) Chris@87: Chris@87: """ Chris@87: M = asanyarray(M) Chris@87: if len(M.shape) != 2 or M.shape[0] != M.shape[1]: Chris@87: raise ValueError("input must be a square array") Chris@87: if not issubdtype(type(n), int): Chris@87: raise TypeError("exponent must be an integer") Chris@87: Chris@87: from numpy.linalg import inv Chris@87: Chris@87: if n==0: Chris@87: M = M.copy() Chris@87: M[:] = identity(M.shape[0]) Chris@87: return M Chris@87: elif n<0: Chris@87: M = inv(M) Chris@87: n *= -1 Chris@87: Chris@87: result = M Chris@87: if n <= 3: Chris@87: for _ in range(n-1): Chris@87: result=N.dot(result, M) Chris@87: return result Chris@87: Chris@87: # binary decomposition to reduce the number of Matrix Chris@87: # multiplications for n > 3. Chris@87: beta = binary_repr(n) Chris@87: Z, q, t = M, 0, len(beta) Chris@87: while beta[t-q-1] == '0': Chris@87: Z = N.dot(Z, Z) Chris@87: q += 1 Chris@87: result = Z Chris@87: for k in range(q+1, t): Chris@87: Z = N.dot(Z, Z) Chris@87: if beta[t-k-1] == '1': Chris@87: result = N.dot(result, Z) Chris@87: return result Chris@87: Chris@87: Chris@87: class matrix(N.ndarray): Chris@87: """ Chris@87: matrix(data, dtype=None, copy=True) Chris@87: Chris@87: Returns a matrix from an array-like object, or from a string of data. Chris@87: A matrix is a specialized 2-D array that retains its 2-D nature Chris@87: through operations. It has certain special operators, such as ``*`` Chris@87: (matrix multiplication) and ``**`` (matrix power). Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: data : array_like or string Chris@87: If `data` is a string, it is interpreted as a matrix with commas Chris@87: or spaces separating columns, and semicolons separating rows. Chris@87: dtype : data-type Chris@87: Data-type of the output matrix. Chris@87: copy : bool Chris@87: If `data` is already an `ndarray`, then this flag determines Chris@87: whether the data is copied (the default), or whether a view is Chris@87: constructed. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: array Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> a = np.matrix('1 2; 3 4') Chris@87: >>> print a Chris@87: [[1 2] Chris@87: [3 4]] Chris@87: Chris@87: >>> np.matrix([[1, 2], [3, 4]]) Chris@87: matrix([[1, 2], Chris@87: [3, 4]]) Chris@87: Chris@87: """ Chris@87: __array_priority__ = 10.0 Chris@87: def __new__(subtype, data, dtype=None, copy=True): Chris@87: if isinstance(data, matrix): Chris@87: dtype2 = data.dtype Chris@87: if (dtype is None): Chris@87: dtype = dtype2 Chris@87: if (dtype2 == dtype) and (not copy): Chris@87: return data Chris@87: return data.astype(dtype) Chris@87: Chris@87: if isinstance(data, N.ndarray): Chris@87: if dtype is None: Chris@87: intype = data.dtype Chris@87: else: Chris@87: intype = N.dtype(dtype) Chris@87: new = data.view(subtype) Chris@87: if intype != data.dtype: Chris@87: return new.astype(intype) Chris@87: if copy: return new.copy() Chris@87: else: return new Chris@87: Chris@87: if isinstance(data, str): Chris@87: data = _convert_from_string(data) Chris@87: Chris@87: # now convert data to an array Chris@87: arr = N.array(data, dtype=dtype, copy=copy) Chris@87: ndim = arr.ndim Chris@87: shape = arr.shape Chris@87: if (ndim > 2): Chris@87: raise ValueError("matrix must be 2-dimensional") Chris@87: elif ndim == 0: Chris@87: shape = (1, 1) Chris@87: elif ndim == 1: Chris@87: shape = (1, shape[0]) Chris@87: Chris@87: order = False Chris@87: if (ndim == 2) and arr.flags.fortran: Chris@87: order = True Chris@87: Chris@87: if not (order or arr.flags.contiguous): Chris@87: arr = arr.copy() Chris@87: Chris@87: ret = N.ndarray.__new__(subtype, shape, arr.dtype, Chris@87: buffer=arr, Chris@87: order=order) Chris@87: return ret Chris@87: Chris@87: def __array_finalize__(self, obj): Chris@87: self._getitem = False Chris@87: if (isinstance(obj, matrix) and obj._getitem): return Chris@87: ndim = self.ndim Chris@87: if (ndim == 2): Chris@87: return Chris@87: if (ndim > 2): Chris@87: newshape = tuple([x for x in self.shape if x > 1]) Chris@87: ndim = len(newshape) Chris@87: if ndim == 2: Chris@87: self.shape = newshape Chris@87: return Chris@87: elif (ndim > 2): Chris@87: raise ValueError("shape too large to be a matrix.") Chris@87: else: Chris@87: newshape = self.shape Chris@87: if ndim == 0: Chris@87: self.shape = (1, 1) Chris@87: elif ndim == 1: Chris@87: self.shape = (1, newshape[0]) Chris@87: return Chris@87: Chris@87: def __getitem__(self, index): Chris@87: self._getitem = True Chris@87: Chris@87: try: Chris@87: out = N.ndarray.__getitem__(self, index) Chris@87: finally: Chris@87: self._getitem = False Chris@87: Chris@87: if not isinstance(out, N.ndarray): Chris@87: return out Chris@87: Chris@87: if out.ndim == 0: Chris@87: return out[()] Chris@87: if out.ndim == 1: Chris@87: sh = out.shape[0] Chris@87: # Determine when we should have a column array Chris@87: try: Chris@87: n = len(index) Chris@87: except: Chris@87: n = 0 Chris@87: if n > 1 and isscalar(index[1]): Chris@87: out.shape = (sh, 1) Chris@87: else: Chris@87: out.shape = (1, sh) Chris@87: return out Chris@87: Chris@87: def __mul__(self, other): Chris@87: if isinstance(other, (N.ndarray, list, tuple)) : Chris@87: # This promotes 1-D vectors to row vectors Chris@87: return N.dot(self, asmatrix(other)) Chris@87: if isscalar(other) or not hasattr(other, '__rmul__') : Chris@87: return N.dot(self, other) Chris@87: return NotImplemented Chris@87: Chris@87: def __rmul__(self, other): Chris@87: return N.dot(other, self) Chris@87: Chris@87: def __imul__(self, other): Chris@87: self[:] = self * other Chris@87: return self Chris@87: Chris@87: def __pow__(self, other): Chris@87: return matrix_power(self, other) Chris@87: Chris@87: def __ipow__(self, other): Chris@87: self[:] = self ** other Chris@87: return self Chris@87: Chris@87: def __rpow__(self, other): Chris@87: return NotImplemented Chris@87: Chris@87: def __repr__(self): Chris@87: s = repr(self.__array__()).replace('array', 'matrix') Chris@87: # now, 'matrix' has 6 letters, and 'array' 5, so the columns don't Chris@87: # line up anymore. We need to add a space. Chris@87: l = s.splitlines() Chris@87: for i in range(1, len(l)): Chris@87: if l[i]: Chris@87: l[i] = ' ' + l[i] Chris@87: return '\n'.join(l) Chris@87: Chris@87: def __str__(self): Chris@87: return str(self.__array__()) Chris@87: Chris@87: def _align(self, axis): Chris@87: """A convenience function for operations that need to preserve axis Chris@87: orientation. Chris@87: """ Chris@87: if axis is None: Chris@87: return self[0, 0] Chris@87: elif axis==0: Chris@87: return self Chris@87: elif axis==1: Chris@87: return self.transpose() Chris@87: else: Chris@87: raise ValueError("unsupported axis") Chris@87: Chris@87: def _collapse(self, axis): Chris@87: """A convenience function for operations that want to collapse Chris@87: to a scalar like _align, but are using keepdims=True Chris@87: """ Chris@87: if axis is None: Chris@87: return self[0, 0] Chris@87: else: Chris@87: return self Chris@87: Chris@87: # Necessary because base-class tolist expects dimension Chris@87: # reduction by x[0] Chris@87: def tolist(self): Chris@87: """ Chris@87: Return the matrix as a (possibly nested) list. Chris@87: Chris@87: See `ndarray.tolist` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: ndarray.tolist Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.tolist() Chris@87: [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]] Chris@87: Chris@87: """ Chris@87: return self.__array__().tolist() Chris@87: Chris@87: # To preserve orientation of result... Chris@87: def sum(self, axis=None, dtype=None, out=None): Chris@87: """ Chris@87: Returns the sum of the matrix elements, along the given axis. Chris@87: Chris@87: Refer to `numpy.sum` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.sum Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.sum`, except that where an `ndarray` would Chris@87: be returned, a `matrix` object is returned instead. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix([[1, 2], [4, 3]]) Chris@87: >>> x.sum() Chris@87: 10 Chris@87: >>> x.sum(axis=1) Chris@87: matrix([[3], Chris@87: [7]]) Chris@87: >>> x.sum(axis=1, dtype='float') Chris@87: matrix([[ 3.], Chris@87: [ 7.]]) Chris@87: >>> out = np.zeros((1, 2), dtype='float') Chris@87: >>> x.sum(axis=1, dtype='float', out=out) Chris@87: matrix([[ 3.], Chris@87: [ 7.]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.sum(self, axis, dtype, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def mean(self, axis=None, dtype=None, out=None): Chris@87: """ Chris@87: Returns the average of the matrix elements along the given axis. Chris@87: Chris@87: Refer to `numpy.mean` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.mean Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: Same as `ndarray.mean` except that, where that returns an `ndarray`, Chris@87: this returns a `matrix` object. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3, 4))) Chris@87: >>> x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.mean() Chris@87: 5.5 Chris@87: >>> x.mean(0) Chris@87: matrix([[ 4., 5., 6., 7.]]) Chris@87: >>> x.mean(1) Chris@87: matrix([[ 1.5], Chris@87: [ 5.5], Chris@87: [ 9.5]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.mean(self, axis, dtype, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def std(self, axis=None, dtype=None, out=None, ddof=0): Chris@87: """ Chris@87: Return the standard deviation of the array elements along the given axis. Chris@87: Chris@87: Refer to `numpy.std` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.std Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.std`, except that where an `ndarray` would Chris@87: be returned, a `matrix` object is returned instead. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3, 4))) Chris@87: >>> x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.std() Chris@87: 3.4520525295346629 Chris@87: >>> x.std(0) Chris@87: matrix([[ 3.26598632, 3.26598632, 3.26598632, 3.26598632]]) Chris@87: >>> x.std(1) Chris@87: matrix([[ 1.11803399], Chris@87: [ 1.11803399], Chris@87: [ 1.11803399]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.std(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis) Chris@87: Chris@87: def var(self, axis=None, dtype=None, out=None, ddof=0): Chris@87: """ Chris@87: Returns the variance of the matrix elements, along the given axis. Chris@87: Chris@87: Refer to `numpy.var` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.var Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.var`, except that where an `ndarray` would Chris@87: be returned, a `matrix` object is returned instead. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3, 4))) Chris@87: >>> x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.var() Chris@87: 11.916666666666666 Chris@87: >>> x.var(0) Chris@87: matrix([[ 10.66666667, 10.66666667, 10.66666667, 10.66666667]]) Chris@87: >>> x.var(1) Chris@87: matrix([[ 1.25], Chris@87: [ 1.25], Chris@87: [ 1.25]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.var(self, axis, dtype, out, ddof, keepdims=True)._collapse(axis) Chris@87: Chris@87: def prod(self, axis=None, dtype=None, out=None): Chris@87: """ Chris@87: Return the product of the array elements over the given axis. Chris@87: Chris@87: Refer to `prod` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: prod, ndarray.prod Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: Same as `ndarray.prod`, except, where that returns an `ndarray`, this Chris@87: returns a `matrix` object instead. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.prod() Chris@87: 0 Chris@87: >>> x.prod(0) Chris@87: matrix([[ 0, 45, 120, 231]]) Chris@87: >>> x.prod(1) Chris@87: matrix([[ 0], Chris@87: [ 840], Chris@87: [7920]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.prod(self, axis, dtype, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def any(self, axis=None, out=None): Chris@87: """ Chris@87: Test whether any array element along a given axis evaluates to True. Chris@87: Chris@87: Refer to `numpy.any` for full documentation. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: axis : int, optional Chris@87: Axis along which logical OR is performed Chris@87: out : ndarray, optional Chris@87: Output to existing array instead of creating new one, must have Chris@87: same shape as expected output Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: any : bool, ndarray Chris@87: Returns a single bool if `axis` is ``None``; otherwise, Chris@87: returns `ndarray` Chris@87: Chris@87: """ Chris@87: return N.ndarray.any(self, axis, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def all(self, axis=None, out=None): Chris@87: """ Chris@87: Test whether all matrix elements along a given axis evaluate to True. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: See `numpy.all` for complete descriptions Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.all Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.all`, but it returns a `matrix` object. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> y = x[0]; y Chris@87: matrix([[0, 1, 2, 3]]) Chris@87: >>> (x == y) Chris@87: matrix([[ True, True, True, True], Chris@87: [False, False, False, False], Chris@87: [False, False, False, False]], dtype=bool) Chris@87: >>> (x == y).all() Chris@87: False Chris@87: >>> (x == y).all(0) Chris@87: matrix([[False, False, False, False]], dtype=bool) Chris@87: >>> (x == y).all(1) Chris@87: matrix([[ True], Chris@87: [False], Chris@87: [False]], dtype=bool) Chris@87: Chris@87: """ Chris@87: return N.ndarray.all(self, axis, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def max(self, axis=None, out=None): Chris@87: """ Chris@87: Return the maximum value along an axis. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: See `amax` for complete descriptions Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: amax, ndarray.max Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.max`, but returns a `matrix` object Chris@87: where `ndarray.max` would return an ndarray. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.max() Chris@87: 11 Chris@87: >>> x.max(0) Chris@87: matrix([[ 8, 9, 10, 11]]) Chris@87: >>> x.max(1) Chris@87: matrix([[ 3], Chris@87: [ 7], Chris@87: [11]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.max(self, axis, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def argmax(self, axis=None, out=None): Chris@87: """ Chris@87: Indices of the maximum values along an axis. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: See `numpy.argmax` for complete descriptions Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.argmax Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.argmax`, but returns a `matrix` object Chris@87: where `ndarray.argmax` would return an `ndarray`. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.argmax() Chris@87: 11 Chris@87: >>> x.argmax(0) Chris@87: matrix([[2, 2, 2, 2]]) Chris@87: >>> x.argmax(1) Chris@87: matrix([[3], Chris@87: [3], Chris@87: [3]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.argmax(self, axis, out)._align(axis) Chris@87: Chris@87: def min(self, axis=None, out=None): Chris@87: """ Chris@87: Return the minimum value along an axis. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: See `amin` for complete descriptions. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: amin, ndarray.min Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.min`, but returns a `matrix` object Chris@87: where `ndarray.min` would return an ndarray. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = -np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, -1, -2, -3], Chris@87: [ -4, -5, -6, -7], Chris@87: [ -8, -9, -10, -11]]) Chris@87: >>> x.min() Chris@87: -11 Chris@87: >>> x.min(0) Chris@87: matrix([[ -8, -9, -10, -11]]) Chris@87: >>> x.min(1) Chris@87: matrix([[ -3], Chris@87: [ -7], Chris@87: [-11]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.min(self, axis, out, keepdims=True)._collapse(axis) Chris@87: Chris@87: def argmin(self, axis=None, out=None): Chris@87: """ Chris@87: Return the indices of the minimum values along an axis. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: See `numpy.argmin` for complete descriptions. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.argmin Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: This is the same as `ndarray.argmin`, but returns a `matrix` object Chris@87: where `ndarray.argmin` would return an `ndarray`. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = -np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, -1, -2, -3], Chris@87: [ -4, -5, -6, -7], Chris@87: [ -8, -9, -10, -11]]) Chris@87: >>> x.argmin() Chris@87: 11 Chris@87: >>> x.argmin(0) Chris@87: matrix([[2, 2, 2, 2]]) Chris@87: >>> x.argmin(1) Chris@87: matrix([[3], Chris@87: [3], Chris@87: [3]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.argmin(self, axis, out)._align(axis) Chris@87: Chris@87: def ptp(self, axis=None, out=None): Chris@87: """ Chris@87: Peak-to-peak (maximum - minimum) value along the given axis. Chris@87: Chris@87: Refer to `numpy.ptp` for full documentation. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: numpy.ptp Chris@87: Chris@87: Notes Chris@87: ----- Chris@87: Same as `ndarray.ptp`, except, where that would return an `ndarray` object, Chris@87: this returns a `matrix` object. Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.ptp() Chris@87: 11 Chris@87: >>> x.ptp(0) Chris@87: matrix([[8, 8, 8, 8]]) Chris@87: >>> x.ptp(1) Chris@87: matrix([[3], Chris@87: [3], Chris@87: [3]]) Chris@87: Chris@87: """ Chris@87: return N.ndarray.ptp(self, axis, out)._align(axis) Chris@87: Chris@87: def getI(self): Chris@87: """ Chris@87: Returns the (multiplicative) inverse of invertible `self`. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: None Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: ret : matrix object Chris@87: If `self` is non-singular, `ret` is such that ``ret * self`` == Chris@87: ``self * ret`` == ``np.matrix(np.eye(self[0,:].size)`` all return Chris@87: ``True``. Chris@87: Chris@87: Raises Chris@87: ------ Chris@87: numpy.linalg.LinAlgError: Singular matrix Chris@87: If `self` is singular. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: linalg.inv Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> m = np.matrix('[1, 2; 3, 4]'); m Chris@87: matrix([[1, 2], Chris@87: [3, 4]]) Chris@87: >>> m.getI() Chris@87: matrix([[-2. , 1. ], Chris@87: [ 1.5, -0.5]]) Chris@87: >>> m.getI() * m Chris@87: matrix([[ 1., 0.], Chris@87: [ 0., 1.]]) Chris@87: Chris@87: """ Chris@87: M, N = self.shape Chris@87: if M == N: Chris@87: from numpy.dual import inv as func Chris@87: else: Chris@87: from numpy.dual import pinv as func Chris@87: return asmatrix(func(self)) Chris@87: Chris@87: def getA(self): Chris@87: """ Chris@87: Return `self` as an `ndarray` object. Chris@87: Chris@87: Equivalent to ``np.asarray(self)``. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: None Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: ret : ndarray Chris@87: `self` as an `ndarray` Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.getA() Chris@87: array([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: Chris@87: """ Chris@87: return self.__array__() Chris@87: Chris@87: def getA1(self): Chris@87: """ Chris@87: Return `self` as a flattened `ndarray`. Chris@87: Chris@87: Equivalent to ``np.asarray(x).ravel()`` Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: None Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: ret : ndarray Chris@87: `self`, 1-D, as an `ndarray` Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))); x Chris@87: matrix([[ 0, 1, 2, 3], Chris@87: [ 4, 5, 6, 7], Chris@87: [ 8, 9, 10, 11]]) Chris@87: >>> x.getA1() Chris@87: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]) Chris@87: Chris@87: """ Chris@87: return self.__array__().ravel() Chris@87: Chris@87: def getT(self): Chris@87: """ Chris@87: Returns the transpose of the matrix. Chris@87: Chris@87: Does *not* conjugate! For the complex conjugate transpose, use ``.H``. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: None Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: ret : matrix object Chris@87: The (non-conjugated) transpose of the matrix. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: transpose, getH Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> m = np.matrix('[1, 2; 3, 4]') Chris@87: >>> m Chris@87: matrix([[1, 2], Chris@87: [3, 4]]) Chris@87: >>> m.getT() Chris@87: matrix([[1, 3], Chris@87: [2, 4]]) Chris@87: Chris@87: """ Chris@87: return self.transpose() Chris@87: Chris@87: def getH(self): Chris@87: """ Chris@87: Returns the (complex) conjugate transpose of `self`. Chris@87: Chris@87: Equivalent to ``np.transpose(self)`` if `self` is real-valued. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: None Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: ret : matrix object Chris@87: complex conjugate transpose of `self` Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> x = np.matrix(np.arange(12).reshape((3,4))) Chris@87: >>> z = x - 1j*x; z Chris@87: matrix([[ 0. +0.j, 1. -1.j, 2. -2.j, 3. -3.j], Chris@87: [ 4. -4.j, 5. -5.j, 6. -6.j, 7. -7.j], Chris@87: [ 8. -8.j, 9. -9.j, 10.-10.j, 11.-11.j]]) Chris@87: >>> z.getH() Chris@87: matrix([[ 0. +0.j, 4. +4.j, 8. +8.j], Chris@87: [ 1. +1.j, 5. +5.j, 9. +9.j], Chris@87: [ 2. +2.j, 6. +6.j, 10.+10.j], Chris@87: [ 3. +3.j, 7. +7.j, 11.+11.j]]) Chris@87: Chris@87: """ Chris@87: if issubclass(self.dtype.type, N.complexfloating): Chris@87: return self.transpose().conjugate() Chris@87: else: Chris@87: return self.transpose() Chris@87: Chris@87: T = property(getT, None) Chris@87: A = property(getA, None) Chris@87: A1 = property(getA1, None) Chris@87: H = property(getH, None) Chris@87: I = property(getI, None) Chris@87: Chris@87: def _from_string(str, gdict, ldict): Chris@87: rows = str.split(';') Chris@87: rowtup = [] Chris@87: for row in rows: Chris@87: trow = row.split(',') Chris@87: newrow = [] Chris@87: for x in trow: Chris@87: newrow.extend(x.split()) Chris@87: trow = newrow Chris@87: coltup = [] Chris@87: for col in trow: Chris@87: col = col.strip() Chris@87: try: Chris@87: thismat = ldict[col] Chris@87: except KeyError: Chris@87: try: Chris@87: thismat = gdict[col] Chris@87: except KeyError: Chris@87: raise KeyError("%s not found" % (col,)) Chris@87: Chris@87: coltup.append(thismat) Chris@87: rowtup.append(concatenate(coltup, axis=-1)) Chris@87: return concatenate(rowtup, axis=0) Chris@87: Chris@87: Chris@87: def bmat(obj, ldict=None, gdict=None): Chris@87: """ Chris@87: Build a matrix object from a string, nested sequence, or array. Chris@87: Chris@87: Parameters Chris@87: ---------- Chris@87: obj : str or array_like Chris@87: Input data. Names of variables in the current scope may be Chris@87: referenced, even if `obj` is a string. Chris@87: Chris@87: Returns Chris@87: ------- Chris@87: out : matrix Chris@87: Returns a matrix object, which is a specialized 2-D array. Chris@87: Chris@87: See Also Chris@87: -------- Chris@87: matrix Chris@87: Chris@87: Examples Chris@87: -------- Chris@87: >>> A = np.mat('1 1; 1 1') Chris@87: >>> B = np.mat('2 2; 2 2') Chris@87: >>> C = np.mat('3 4; 5 6') Chris@87: >>> D = np.mat('7 8; 9 0') Chris@87: Chris@87: All the following expressions construct the same block matrix: Chris@87: Chris@87: >>> np.bmat([[A, B], [C, D]]) Chris@87: matrix([[1, 1, 2, 2], Chris@87: [1, 1, 2, 2], Chris@87: [3, 4, 7, 8], Chris@87: [5, 6, 9, 0]]) Chris@87: >>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]]) Chris@87: matrix([[1, 1, 2, 2], Chris@87: [1, 1, 2, 2], Chris@87: [3, 4, 7, 8], Chris@87: [5, 6, 9, 0]]) Chris@87: >>> np.bmat('A,B; C,D') Chris@87: matrix([[1, 1, 2, 2], Chris@87: [1, 1, 2, 2], Chris@87: [3, 4, 7, 8], Chris@87: [5, 6, 9, 0]]) Chris@87: Chris@87: """ Chris@87: if isinstance(obj, str): Chris@87: if gdict is None: Chris@87: # get previous frame Chris@87: frame = sys._getframe().f_back Chris@87: glob_dict = frame.f_globals Chris@87: loc_dict = frame.f_locals Chris@87: else: Chris@87: glob_dict = gdict Chris@87: loc_dict = ldict Chris@87: Chris@87: return matrix(_from_string(obj, glob_dict, loc_dict)) Chris@87: Chris@87: if isinstance(obj, (tuple, list)): Chris@87: # [[A,B],[C,D]] Chris@87: arr_rows = [] Chris@87: for row in obj: Chris@87: if isinstance(row, N.ndarray): # not 2-d Chris@87: return matrix(concatenate(obj, axis=-1)) Chris@87: else: Chris@87: arr_rows.append(concatenate(row, axis=-1)) Chris@87: return matrix(concatenate(arr_rows, axis=0)) Chris@87: if isinstance(obj, N.ndarray): Chris@87: return matrix(obj) Chris@87: Chris@87: mat = asmatrix