summaryrefslogtreecommitdiff
path: root/numpy/matrx
diff options
context:
space:
mode:
authorDavid Cournapeau <cournape@gmail.com>2009-09-16 07:12:46 +0000
committerDavid Cournapeau <cournape@gmail.com>2009-09-16 07:12:46 +0000
commitfe002b2916a5928463f7c46c5c4875114228bf7f (patch)
tree1f56e956eae72299b91a84b2cf6874f7ec73d4fa /numpy/matrx
parentec7f9dcddd216019bcf15d162926c4df6355860e (diff)
downloadnumpy-fe002b2916a5928463f7c46c5c4875114228bf7f.tar.gz
Move matrix class into its own module.
Diffstat (limited to 'numpy/matrx')
-rw-r--r--numpy/matrx/__init__.py7
-rw-r--r--numpy/matrx/defmatrix.py677
-rw-r--r--numpy/matrx/setup.py13
-rw-r--r--numpy/matrx/setupscons.py13
-rw-r--r--numpy/matrx/tests/test_defmatrix.py375
-rw-r--r--numpy/matrx/tests/test_numeric.py8
6 files changed, 1093 insertions, 0 deletions
diff --git a/numpy/matrx/__init__.py b/numpy/matrx/__init__.py
new file mode 100644
index 000000000..bdc653b06
--- /dev/null
+++ b/numpy/matrx/__init__.py
@@ -0,0 +1,7 @@
+from defmatrix import *
+
+__all__ = defmatrix.__all__
+
+from numpy.testing import Tester
+test = Tester().test
+bench = Tester().bench
diff --git a/numpy/matrx/defmatrix.py b/numpy/matrx/defmatrix.py
new file mode 100644
index 000000000..dfa7e4a8d
--- /dev/null
+++ b/numpy/matrx/defmatrix.py
@@ -0,0 +1,677 @@
+__all__ = ['matrix', 'bmat', 'mat', 'asmatrix']
+
+import sys
+import numpy.core.numeric as N
+from numpy.core.numeric import concatenate, isscalar, binary_repr, identity, asanyarray
+from numpy.core.numerictypes import issubdtype
+
+# make translation table
+_table = [None]*256
+for k in range(256):
+ _table[k] = chr(k)
+_table = ''.join(_table)
+
+_numchars = '0123456789.-+jeEL'
+_todelete = []
+for k in _table:
+ if k not in _numchars:
+ _todelete.append(k)
+_todelete = ''.join(_todelete)
+del k
+
+def _eval(astr):
+ return eval(astr.translate(_table,_todelete))
+
+def _convert_from_string(data):
+ rows = data.split(';')
+ newdata = []
+ count = 0
+ for row in rows:
+ trow = row.split(',')
+ newrow = []
+ for col in trow:
+ temp = col.split()
+ newrow.extend(map(_eval,temp))
+ if count == 0:
+ Ncols = len(newrow)
+ elif len(newrow) != Ncols:
+ raise ValueError, "Rows not the same size."
+ count += 1
+ newdata.append(newrow)
+ return newdata
+
+def asmatrix(data, dtype=None):
+ """
+ Interpret the input as a matrix.
+
+ Unlike `matrix`, `asmatrix` does not make a copy if the input is already
+ a matrix or an ndarray. Equivalent to ``matrix(data, copy=False)``.
+
+ Parameters
+ ----------
+ data : array_like
+ Input data.
+
+ Returns
+ -------
+ mat : matrix
+ `data` interpreted as a matrix.
+
+ Examples
+ --------
+ >>> x = np.array([[1, 2], [3, 4]])
+
+ >>> m = np.asmatrix(x)
+
+ >>> x[0,0] = 5
+
+ >>> m
+ matrix([[5, 2],
+ [3, 4]])
+
+ """
+ return matrix(data, dtype=dtype, copy=False)
+
+def matrix_power(M,n):
+ """
+ Raise a square matrix to the (integer) power n.
+
+ For positive integers n, the power is computed by repeated matrix
+ squarings and matrix multiplications. If n=0, the identity matrix
+ of the same type as M is returned. If n<0, the inverse is computed
+ and raised to the exponent.
+
+ Parameters
+ ----------
+ M : array_like
+ Must be a square array (that is, of dimension two and with
+ equal sizes).
+ n : integer
+ The exponent can be any integer or long integer, positive
+ negative or zero.
+
+ Returns
+ -------
+ M to the power n
+ The return value is a an array the same shape and size as M;
+ if the exponent was positive or zero then the type of the
+ elements is the same as those of M. If the exponent was negative
+ the elements are floating-point.
+
+ Raises
+ ------
+ LinAlgException
+ If the matrix is not numerically invertible, an exception is raised.
+
+ See Also
+ --------
+ The matrix() class provides an equivalent function as the exponentiation
+ operator.
+
+ Examples
+ --------
+ >>> np.linalg.matrix_power(np.array([[0,1],[-1,0]]),10)
+ array([[-1, 0],
+ [ 0, -1]])
+
+ """
+ M = asanyarray(M)
+ if len(M.shape) != 2 or M.shape[0] != M.shape[1]:
+ raise ValueError("input must be a square array")
+ if not issubdtype(type(n),int):
+ raise TypeError("exponent must be an integer")
+
+ from numpy.linalg import inv
+
+ if n==0:
+ M = M.copy()
+ M[:] = identity(M.shape[0])
+ return M
+ elif n<0:
+ M = inv(M)
+ n *= -1
+
+ result = M
+ if n <= 3:
+ for _ in range(n-1):
+ result=N.dot(result,M)
+ return result
+
+ # binary decomposition to reduce the number of Matrix
+ # multiplications for n > 3.
+ beta = binary_repr(n)
+ Z,q,t = M,0,len(beta)
+ while beta[t-q-1] == '0':
+ Z = N.dot(Z,Z)
+ q += 1
+ result = Z
+ for k in range(q+1,t):
+ Z = N.dot(Z,Z)
+ if beta[t-k-1] == '1':
+ result = N.dot(result,Z)
+ return result
+
+
+class matrix(N.ndarray):
+ """
+ matrix(data, dtype=None, copy=True)
+
+ Returns a matrix from an array-like object, or from a string
+ of data. A matrix is a specialized 2-d array that retains
+ its 2-d nature through operations. It has certain special
+ operators, such as ``*`` (matrix multiplication) and
+ ``**`` (matrix power).
+
+ Parameters
+ ----------
+ data : array_like or string
+ If data is a string, the string is interpreted as a matrix
+ with commas or spaces separating columns, and semicolons
+ separating rows.
+ dtype : data-type
+ Data-type of the output matrix.
+ copy : bool
+ If data is already an ndarray, then this flag determines whether
+ the data is copied, or whether a view is constructed.
+
+ See Also
+ --------
+ array
+
+ Examples
+ --------
+ >>> a = np.matrix('1 2; 3 4')
+ >>> print a
+ [[1 2]
+ [3 4]]
+
+ >>> np.matrix([[1, 2], [3, 4]])
+ matrix([[1, 2],
+ [3, 4]])
+
+ """
+ __array_priority__ = 10.0
+ def __new__(subtype, data, dtype=None, copy=True):
+ if isinstance(data, matrix):
+ dtype2 = data.dtype
+ if (dtype is None):
+ dtype = dtype2
+ if (dtype2 == dtype) and (not copy):
+ return data
+ return data.astype(dtype)
+
+ if isinstance(data, N.ndarray):
+ if dtype is None:
+ intype = data.dtype
+ else:
+ intype = N.dtype(dtype)
+ new = data.view(subtype)
+ if intype != data.dtype:
+ return new.astype(intype)
+ if copy: return new.copy()
+ else: return new
+
+ if isinstance(data, str):
+ data = _convert_from_string(data)
+
+ # now convert data to an array
+ arr = N.array(data, dtype=dtype, copy=copy)
+ ndim = arr.ndim
+ shape = arr.shape
+ if (ndim > 2):
+ raise ValueError, "matrix must be 2-dimensional"
+ elif ndim == 0:
+ shape = (1,1)
+ elif ndim == 1:
+ shape = (1,shape[0])
+
+ order = False
+ if (ndim == 2) and arr.flags.fortran:
+ order = True
+
+ if not (order or arr.flags.contiguous):
+ arr = arr.copy()
+
+ ret = N.ndarray.__new__(subtype, shape, arr.dtype,
+ buffer=arr,
+ order=order)
+ return ret
+
+ def __array_finalize__(self, obj):
+ self._getitem = False
+ if (isinstance(obj, matrix) and obj._getitem): return
+ ndim = self.ndim
+ if (ndim == 2):
+ return
+ if (ndim > 2):
+ newshape = tuple([x for x in self.shape if x > 1])
+ ndim = len(newshape)
+ if ndim == 2:
+ self.shape = newshape
+ return
+ elif (ndim > 2):
+ raise ValueError, "shape too large to be a matrix."
+ else:
+ newshape = self.shape
+ if ndim == 0:
+ self.shape = (1,1)
+ elif ndim == 1:
+ self.shape = (1,newshape[0])
+ return
+
+ def __getitem__(self, index):
+ self._getitem = True
+
+ try:
+ out = N.ndarray.__getitem__(self, index)
+ finally:
+ self._getitem = False
+
+ if not isinstance(out, N.ndarray):
+ return out
+
+ if out.ndim == 0:
+ return out[()]
+ if out.ndim == 1:
+ sh = out.shape[0]
+ # Determine when we should have a column array
+ try:
+ n = len(index)
+ except:
+ n = 0
+ if n > 1 and isscalar(index[1]):
+ out.shape = (sh,1)
+ else:
+ out.shape = (1,sh)
+ return out
+
+ def __mul__(self, other):
+ if isinstance(other,(N.ndarray, list, tuple)) :
+ # This promotes 1-D vectors to row vectors
+ return N.dot(self, asmatrix(other))
+ if isscalar(other) or not hasattr(other, '__rmul__') :
+ return N.dot(self, other)
+ return NotImplemented
+
+ def __rmul__(self, other):
+ return N.dot(other, self)
+
+ def __imul__(self, other):
+ self[:] = self * other
+ return self
+
+ def __pow__(self, other):
+ return matrix_power(self, other)
+
+ def __ipow__(self, other):
+ self[:] = self ** other
+ return self
+
+ def __rpow__(self, other):
+ return NotImplemented
+
+ def __repr__(self):
+ s = repr(self.__array__()).replace('array', 'matrix')
+ # now, 'matrix' has 6 letters, and 'array' 5, so the columns don't
+ # line up anymore. We need to add a space.
+ l = s.splitlines()
+ for i in range(1, len(l)):
+ if l[i]:
+ l[i] = ' ' + l[i]
+ return '\n'.join(l)
+
+ def __str__(self):
+ return str(self.__array__())
+
+ def _align(self, axis):
+ """A convenience function for operations that need to preserve axis
+ orientation.
+ """
+ if axis is None:
+ return self[0,0]
+ elif axis==0:
+ return self
+ elif axis==1:
+ return self.transpose()
+ else:
+ raise ValueError, "unsupported axis"
+
+ # Necessary because base-class tolist expects dimension
+ # reduction by x[0]
+ def tolist(self):
+ return self.__array__().tolist()
+
+ # To preserve orientation of result...
+ def sum(self, axis=None, dtype=None, out=None):
+ """Sum the matrix over the given axis. If the axis is None, sum
+ over all dimensions. This preserves the orientation of the
+ result as a row or column.
+ """
+ return N.ndarray.sum(self, axis, dtype, out)._align(axis)
+
+ def mean(self, axis=None, dtype=None, out=None):
+ """Compute the mean along the specified axis.
+
+ Returns the average of the array elements. The average is taken over
+ the flattened array by default, otherwise over the specified axis.
+
+ Parameters
+ ----------
+ axis : integer
+ Axis along which the means are computed. The default is
+ to compute the standard deviation of the flattened array.
+
+ dtype : type
+ Type to use in computing the means. For arrays of integer type
+ the default is float32, for arrays of float types it is the
+ same as the array type.
+
+ out : ndarray
+ Alternative output array in which to place the result. It must
+ have the same shape as the expected output but the type will be
+ cast if necessary.
+
+ Returns
+ -------
+ mean : The return type varies, see above.
+ A new array holding the result is returned unless out is
+ specified, in which case a reference to out is returned.
+
+ SeeAlso
+ -------
+ var : variance
+ std : standard deviation
+
+ Notes
+ -----
+ The mean is the sum of the elements along the axis divided by the
+ number of elements.
+ """
+ return N.ndarray.mean(self, axis, dtype, out)._align(axis)
+
+ def std(self, axis=None, dtype=None, out=None, ddof=0):
+ """Compute the standard deviation along the specified axis.
+
+ Returns the standard deviation of the array elements, a measure of the
+ spread of a distribution. The standard deviation is computed for the
+ flattened array by default, otherwise over the specified axis.
+
+ Parameters
+ ----------
+ axis : integer
+ Axis along which the standard deviation is computed. The
+ default is to compute the standard deviation of the flattened
+ array.
+ dtype : type
+ Type to use in computing the standard deviation. For arrays of
+ integer type the default is float32, for arrays of float types
+ it is the same as the array type.
+ out : ndarray
+ Alternative output array in which to place the result. It must
+ have the same shape as the expected output but the type will be
+ cast if necessary.
+ ddof : {0, integer}
+ Means Delta Degrees of Freedom. The divisor used in calculations
+ is N-ddof.
+
+ Returns
+ -------
+ standard deviation : The return type varies, see above.
+ A new array holding the result is returned unless out is
+ specified, in which case a reference to out is returned.
+
+ SeeAlso
+ -------
+ var : variance
+ mean : average
+
+ Notes
+ -----
+ The standard deviation is the square root of the
+ average of the squared deviations from the mean, i.e. var =
+ sqrt(mean(abs(x - x.mean())**2)). The computed standard
+ deviation is computed by dividing by the number of elements,
+ N-ddof. The option ddof defaults to zero, that is, a biased
+ estimate. Note that for complex numbers std takes the absolute
+ value before squaring, so that the result is always real
+ and nonnegative.
+
+ """
+ return N.ndarray.std(self, axis, dtype, out, ddof)._align(axis)
+
+ def var(self, axis=None, dtype=None, out=None, ddof=0):
+ """Compute the variance along the specified axis.
+
+ Returns the variance of the array elements, a measure of the spread of
+ a distribution. The variance is computed for the flattened array by
+ default, otherwise over the specified axis.
+
+ Parameters
+ ----------
+ axis : integer
+ Axis along which the variance is computed. The default is to
+ compute the variance of the flattened array.
+ dtype : data-type
+ Type to use in computing the variance. For arrays of integer
+ type the default is float32, for arrays of float types it is
+ the same as the array type.
+ out : ndarray
+ Alternative output array in which to place the result. It must
+ have the same shape as the expected output but the type will be
+ cast if necessary.
+ ddof : {0, integer}
+ Means Delta Degrees of Freedom. The divisor used in calculations
+ is N-ddof.
+
+ Returns
+ -------
+ variance : depends, see above
+ A new array holding the result is returned unless out is
+ specified, in which case a reference to out is returned.
+
+ SeeAlso
+ -------
+ std : standard deviation
+ mean : average
+
+ Notes
+ -----
+
+ The variance is the average of the squared deviations from the
+ mean, i.e. var = mean(abs(x - x.mean())**2). The mean is
+ computed by dividing by N-ddof, where N is the number of elements.
+ The argument ddof defaults to zero; for an unbiased estimate
+ supply ddof=1. Note that for complex numbers the absolute value
+ is taken before squaring, so that the result is always real
+ and nonnegative.
+ """
+ return N.ndarray.var(self, axis, dtype, out, ddof)._align(axis)
+
+ def prod(self, axis=None, dtype=None, out=None):
+ return N.ndarray.prod(self, axis, dtype, out)._align(axis)
+
+ def any(self, axis=None, out=None):
+ """
+ Test whether any array element along a given axis evaluates to True.
+
+ Refer to `numpy.any` for full documentation.
+
+ Parameters
+ ----------
+ axis: int, optional
+ Axis along which logical OR is performed
+ out: ndarray, optional
+ Output to existing array instead of creating new one, must have
+ same shape as expected output
+
+ Returns
+ -------
+ any : bool, ndarray
+ Returns a single bool if `axis` is ``None``; otherwise,
+ returns `ndarray`
+
+ """
+ return N.ndarray.any(self, axis, out)._align(axis)
+
+ def all(self, axis=None, out=None):
+ return N.ndarray.all(self, axis, out)._align(axis)
+
+ def max(self, axis=None, out=None):
+ return N.ndarray.max(self, axis, out)._align(axis)
+
+ def argmax(self, axis=None, out=None):
+ return N.ndarray.argmax(self, axis, out)._align(axis)
+
+ def min(self, axis=None, out=None):
+ return N.ndarray.min(self, axis, out)._align(axis)
+
+ def argmin(self, axis=None, out=None):
+ return N.ndarray.argmin(self, axis, out)._align(axis)
+
+ def ptp(self, axis=None, out=None):
+ return N.ndarray.ptp(self, axis, out)._align(axis)
+
+ def getI(self):
+ M,N = self.shape
+ if M == N:
+ from numpy.dual import inv as func
+ else:
+ from numpy.dual import pinv as func
+ return asmatrix(func(self))
+
+ def getA(self):
+ return self.__array__()
+
+ def getA1(self):
+ return self.__array__().ravel()
+
+ def getT(self):
+ """
+ m.T
+
+ Returns the transpose of m.
+
+ Examples
+ --------
+ >>> m = np.matrix('[1, 2; 3, 4]')
+ >>> m
+ matrix([[1, 2],
+ [3, 4]])
+ >>> m.T
+ matrix([[1, 3],
+ [2, 4]])
+
+ See Also
+ --------
+ transpose
+
+ """
+ return self.transpose()
+
+ def getH(self):
+ if issubclass(self.dtype.type, N.complexfloating):
+ return self.transpose().conjugate()
+ else:
+ return self.transpose()
+
+ T = property(getT, None, doc="transpose")
+ A = property(getA, None, doc="base array")
+ A1 = property(getA1, None, doc="1-d base array")
+ H = property(getH, None, doc="hermitian (conjugate) transpose")
+ I = property(getI, None, doc="inverse")
+
+def _from_string(str,gdict,ldict):
+ rows = str.split(';')
+ rowtup = []
+ for row in rows:
+ trow = row.split(',')
+ newrow = []
+ for x in trow:
+ newrow.extend(x.split())
+ trow = newrow
+ coltup = []
+ for col in trow:
+ col = col.strip()
+ try:
+ thismat = ldict[col]
+ except KeyError:
+ try:
+ thismat = gdict[col]
+ except KeyError:
+ raise KeyError, "%s not found" % (col,)
+
+ coltup.append(thismat)
+ rowtup.append(concatenate(coltup,axis=-1))
+ return concatenate(rowtup,axis=0)
+
+
+def bmat(obj, ldict=None, gdict=None):
+ """
+ Build a matrix object from a string, nested sequence, or array.
+
+ Parameters
+ ----------
+ obj : string, sequence or array
+ Input data. Variables names in the current scope may
+ be referenced, even if `obj` is a string.
+
+ Returns
+ -------
+ out : matrix
+ Returns a matrix object, which is a specialized 2-D array.
+
+ See Also
+ --------
+ matrix
+
+ Examples
+ --------
+ >>> A = np.mat('1 1; 1 1')
+ >>> B = np.mat('2 2; 2 2')
+ >>> C = np.mat('3 4; 5 6')
+ >>> D = np.mat('7 8; 9 0')
+
+ All the following expressions construct the same block matrix:
+
+ >>> np.bmat([[A, B], [C, D]])
+ matrix([[1, 1, 2, 2],
+ [1, 1, 2, 2],
+ [3, 4, 7, 8],
+ [5, 6, 9, 0]])
+ >>> np.bmat(np.r_[np.c_[A, B], np.c_[C, D]])
+ matrix([[1, 1, 2, 2],
+ [1, 1, 2, 2],
+ [3, 4, 7, 8],
+ [5, 6, 9, 0]])
+ >>> np.bmat('A,B; C,D')
+ matrix([[1, 1, 2, 2],
+ [1, 1, 2, 2],
+ [3, 4, 7, 8],
+ [5, 6, 9, 0]])
+
+ """
+ if isinstance(obj, str):
+ if gdict is None:
+ # get previous frame
+ frame = sys._getframe().f_back
+ glob_dict = frame.f_globals
+ loc_dict = frame.f_locals
+ else:
+ glob_dict = gdict
+ loc_dict = ldict
+
+ return matrix(_from_string(obj, glob_dict, loc_dict))
+
+ if isinstance(obj, (tuple, list)):
+ # [[A,B],[C,D]]
+ arr_rows = []
+ for row in obj:
+ if isinstance(row, N.ndarray): # not 2-d
+ return matrix(concatenate(obj,axis=-1))
+ else:
+ arr_rows.append(concatenate(row,axis=-1))
+ return matrix(concatenate(arr_rows,axis=0))
+ if isinstance(obj, N.ndarray):
+ return matrix(obj)
+
+mat = asmatrix
diff --git a/numpy/matrx/setup.py b/numpy/matrx/setup.py
new file mode 100644
index 000000000..ca288b96e
--- /dev/null
+++ b/numpy/matrx/setup.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import os
+
+def configuration(parent_package='', top_path=None):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('matrx', parent_package, top_path)
+ config.add_data_dir('tests')
+ return config
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ config = configuration(top_path='').todict()
+ setup(**config)
diff --git a/numpy/matrx/setupscons.py b/numpy/matrx/setupscons.py
new file mode 100644
index 000000000..ca288b96e
--- /dev/null
+++ b/numpy/matrx/setupscons.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+import os
+
+def configuration(parent_package='', top_path=None):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration('matrx', parent_package, top_path)
+ config.add_data_dir('tests')
+ return config
+
+if __name__ == "__main__":
+ from numpy.distutils.core import setup
+ config = configuration(top_path='').todict()
+ setup(**config)
diff --git a/numpy/matrx/tests/test_defmatrix.py b/numpy/matrx/tests/test_defmatrix.py
new file mode 100644
index 000000000..2cf4914a7
--- /dev/null
+++ b/numpy/matrx/tests/test_defmatrix.py
@@ -0,0 +1,375 @@
+from numpy.testing import *
+from numpy.core import *
+from numpy import matrix, asmatrix, bmat
+from numpy.matrx.defmatrix import matrix_power
+from numpy.matrx import mat
+import numpy as np
+
+class TestCtor(TestCase):
+ def test_basic(self):
+ A = array([[1,2],[3,4]])
+ mA = matrix(A)
+ assert all(mA.A == A)
+
+ B = bmat("A,A;A,A")
+ C = bmat([[A,A], [A,A]])
+ D = array([[1,2,1,2],
+ [3,4,3,4],
+ [1,2,1,2],
+ [3,4,3,4]])
+ assert all(B.A == D)
+ assert all(C.A == D)
+
+ E = array([[5,6],[7,8]])
+ AEresult = matrix([[1,2,5,6],[3,4,7,8]])
+ assert all(bmat([A,E]) == AEresult)
+
+ vec = arange(5)
+ mvec = matrix(vec)
+ assert mvec.shape == (1,5)
+
+ def test_bmat_nondefault_str(self):
+ A = array([[1,2],[3,4]])
+ B = array([[5,6],[7,8]])
+ Aresult = array([[1,2,1,2],
+ [3,4,3,4],
+ [1,2,1,2],
+ [3,4,3,4]])
+ Bresult = array([[5,6,5,6],
+ [7,8,7,8],
+ [5,6,5,6],
+ [7,8,7,8]])
+ mixresult = array([[1,2,5,6],
+ [3,4,7,8],
+ [5,6,1,2],
+ [7,8,3,4]])
+ assert all(bmat("A,A;A,A") == Aresult)
+ assert all(bmat("A,A;A,A",ldict={'A':B}) == Aresult)
+ assert_raises(TypeError, bmat, "A,A;A,A",gdict={'A':B})
+ assert all(bmat("A,A;A,A",ldict={'A':A},gdict={'A':B}) == Aresult)
+ b2 = bmat("A,B;C,D",ldict={'A':A,'B':B},gdict={'C':B,'D':A})
+ assert all(b2 == mixresult)
+
+
+class TestProperties(TestCase):
+ def test_sum(self):
+ """Test whether matrix.sum(axis=1) preserves orientation.
+ Fails in NumPy <= 0.9.6.2127.
+ """
+ M = matrix([[1,2,0,0],
+ [3,4,0,0],
+ [1,2,1,2],
+ [3,4,3,4]])
+ sum0 = matrix([8,12,4,6])
+ sum1 = matrix([3,7,6,14]).T
+ sumall = 30
+ assert_array_equal(sum0, M.sum(axis=0))
+ assert_array_equal(sum1, M.sum(axis=1))
+ assert sumall == M.sum()
+
+
+ def test_prod(self):
+ x = matrix([[1,2,3],[4,5,6]])
+ assert x.prod() == 720
+ assert all(x.prod(0) == matrix([[4,10,18]]))
+ assert all(x.prod(1) == matrix([[6],[120]]))
+
+ y = matrix([0,1,3])
+ assert y.prod() == 0
+
+ def test_max(self):
+ x = matrix([[1,2,3],[4,5,6]])
+ assert x.max() == 6
+ assert all(x.max(0) == matrix([[4,5,6]]))
+ assert all(x.max(1) == matrix([[3],[6]]))
+
+ def test_min(self):
+ x = matrix([[1,2,3],[4,5,6]])
+ assert x.min() == 1
+ assert all(x.min(0) == matrix([[1,2,3]]))
+ assert all(x.min(1) == matrix([[1],[4]]))
+
+ def test_ptp(self):
+ x = np.arange(4).reshape((2,2))
+ assert x.ptp() == 3
+ assert all(x.ptp(0) == array([2, 2]))
+ assert all(x.ptp(1) == array([1, 1]))
+
+ def test_var(self):
+ x = np.arange(9).reshape((3,3))
+ mx = x.view(np.matrix)
+ assert_equal(x.var(ddof=0), mx.var(ddof=0))
+ assert_equal(x.var(ddof=1), mx.var(ddof=1))
+
+ def test_basic(self):
+ import numpy.linalg as linalg
+
+ A = array([[1., 2.],
+ [3., 4.]])
+ mA = matrix(A)
+ assert allclose(linalg.inv(A), mA.I)
+ assert all(array(transpose(A) == mA.T))
+ assert all(array(transpose(A) == mA.H))
+ assert all(A == mA.A)
+
+ B = A + 2j*A
+ mB = matrix(B)
+ assert allclose(linalg.inv(B), mB.I)
+ assert all(array(transpose(B) == mB.T))
+ assert all(array(conjugate(transpose(B)) == mB.H))
+
+ def test_pinv(self):
+ x = matrix(arange(6).reshape(2,3))
+ xpinv = matrix([[-0.77777778, 0.27777778],
+ [-0.11111111, 0.11111111],
+ [ 0.55555556, -0.05555556]])
+ assert_almost_equal(x.I, xpinv)
+
+ def test_comparisons(self):
+ A = arange(100).reshape(10,10)
+ mA = matrix(A)
+ mB = matrix(A) + 0.1
+ assert all(mB == A+0.1)
+ assert all(mB == matrix(A+0.1))
+ assert not any(mB == matrix(A-0.1))
+ assert all(mA < mB)
+ assert all(mA <= mB)
+ assert all(mA <= mA)
+ assert not any(mA < mA)
+
+ assert not any(mB < mA)
+ assert all(mB >= mA)
+ assert all(mB >= mB)
+ assert not any(mB > mB)
+
+ assert all(mA == mA)
+ assert not any(mA == mB)
+ assert all(mB != mA)
+
+ assert not all(abs(mA) > 0)
+ assert all(abs(mB > 0))
+
+ def test_asmatrix(self):
+ A = arange(100).reshape(10,10)
+ mA = asmatrix(A)
+ A[0,0] = -10
+ assert A[0,0] == mA[0,0]
+
+ def test_noaxis(self):
+ A = matrix([[1,0],[0,1]])
+ assert A.sum() == matrix(2)
+ assert A.mean() == matrix(0.5)
+
+ def test_repr(self):
+ A = matrix([[1,0],[0,1]])
+ assert repr(A) == "matrix([[1, 0],\n [0, 1]])"
+
+class TestCasting(TestCase):
+ def test_basic(self):
+ A = arange(100).reshape(10,10)
+ mA = matrix(A)
+
+ mB = mA.copy()
+ O = ones((10,10), float64) * 0.1
+ mB = mB + O
+ assert mB.dtype.type == float64
+ assert all(mA != mB)
+ assert all(mB == mA+0.1)
+
+ mC = mA.copy()
+ O = ones((10,10), complex128)
+ mC = mC * O
+ assert mC.dtype.type == complex128
+ assert all(mA != mB)
+
+
+class TestAlgebra(TestCase):
+ def test_basic(self):
+ import numpy.linalg as linalg
+
+ A = array([[1., 2.],
+ [3., 4.]])
+ mA = matrix(A)
+
+ B = identity(2)
+ for i in xrange(6):
+ assert allclose((mA ** i).A, B)
+ B = dot(B, A)
+
+ Ainv = linalg.inv(A)
+ B = identity(2)
+ for i in xrange(6):
+ assert allclose((mA ** -i).A, B)
+ B = dot(B, Ainv)
+
+ assert allclose((mA * mA).A, dot(A, A))
+ assert allclose((mA + mA).A, (A + A))
+ assert allclose((3*mA).A, (3*A))
+
+ mA2 = matrix(A)
+ mA2 *= 3
+ assert allclose(mA2.A, 3*A)
+
+ def test_pow(self):
+ """Test raising a matrix to an integer power works as expected."""
+ m = matrix("1. 2.; 3. 4.")
+ m2 = m.copy()
+ m2 **= 2
+ mi = m.copy()
+ mi **= -1
+ m4 = m2.copy()
+ m4 **= 2
+ assert_array_almost_equal(m2, m**2)
+ assert_array_almost_equal(m4, np.dot(m2, m2))
+ assert_array_almost_equal(np.dot(mi, m), np.eye(2))
+
+ def test_notimplemented(self):
+ '''Check that 'not implemented' operations produce a failure.'''
+ A = matrix([[1., 2.],
+ [3., 4.]])
+
+ # __rpow__
+ try:
+ 1.0**A
+ except TypeError:
+ pass
+ else:
+ self.fail("matrix.__rpow__ doesn't raise a TypeError")
+
+ # __mul__ with something not a list, ndarray, tuple, or scalar
+ try:
+ A*object()
+ except TypeError:
+ pass
+ else:
+ self.fail("matrix.__mul__ with non-numeric object doesn't raise"
+ "a TypeError")
+
+class TestMatrixReturn(TestCase):
+ def test_instance_methods(self):
+ a = matrix([1.0], dtype='f8')
+ methodargs = {
+ 'astype' : ('intc',),
+ 'clip' : (0.0, 1.0),
+ 'compress' : ([1],),
+ 'repeat' : (1,),
+ 'reshape' : (1,),
+ 'swapaxes' : (0,0)
+ }
+ excluded_methods = [
+ 'argmin', 'choose', 'dump', 'dumps', 'fill', 'getfield',
+ 'getA', 'getA1', 'item', 'nonzero', 'put', 'putmask', 'resize',
+ 'searchsorted', 'setflags', 'setfield', 'sort', 'take',
+ 'tofile', 'tolist', 'tostring', 'all', 'any', 'sum',
+ 'argmax', 'argmin', 'min', 'max', 'mean', 'var', 'ptp',
+ 'prod', 'std', 'ctypes', 'itemset'
+ ]
+ for attrib in dir(a):
+ if attrib.startswith('_') or attrib in excluded_methods:
+ continue
+ f = eval('a.%s' % attrib)
+ if callable(f):
+ # reset contents of a
+ a.astype('f8')
+ a.fill(1.0)
+ if attrib in methodargs:
+ args = methodargs[attrib]
+ else:
+ args = ()
+ b = f(*args)
+ assert type(b) is matrix, "%s" % attrib
+ assert type(a.real) is matrix
+ assert type(a.imag) is matrix
+ c,d = matrix([0.0]).nonzero()
+ assert type(c) is matrix
+ assert type(d) is matrix
+
+
+class TestIndexing(TestCase):
+ def test_basic(self):
+ x = asmatrix(zeros((3,2),float))
+ y = zeros((3,1),float)
+ y[:,0] = [0.8,0.2,0.3]
+ x[:,1] = y>0.5
+ assert_equal(x, [[0,1],[0,0],[0,0]])
+
+
+class TestNewScalarIndexing(TestCase):
+ def setUp(self):
+ self.a = matrix([[1, 2],[3,4]])
+
+ def test_dimesions(self):
+ a = self.a
+ x = a[0]
+ assert_equal(x.ndim, 2)
+
+ def test_array_from_matrix_list(self):
+ a = self.a
+ x = array([a, a])
+ assert_equal(x.shape, [2,2,2])
+
+ def test_array_to_list(self):
+ a = self.a
+ assert_equal(a.tolist(),[[1, 2], [3, 4]])
+
+ def test_fancy_indexing(self):
+ a = self.a
+ x = a[1, [0,1,0]]
+ assert isinstance(x, matrix)
+ assert_equal(x, matrix([[3, 4, 3]]))
+ x = a[[1,0]]
+ assert isinstance(x, matrix)
+ assert_equal(x, matrix([[3, 4], [1, 2]]))
+ x = a[[[1],[0]],[[1,0],[0,1]]]
+ assert isinstance(x, matrix)
+ assert_equal(x, matrix([[4, 3], [1, 2]]))
+
+ def test_matrix_element(self):
+ x = matrix([[1,2,3],[4,5,6]])
+ assert_equal(x[0][0],matrix([[1,2,3]]))
+ assert_equal(x[0][0].shape,(1,3))
+ assert_equal(x[0].shape,(1,3))
+ assert_equal(x[:,0].shape,(2,1))
+
+ x = matrix(0)
+ assert_equal(x[0,0],0)
+ assert_equal(x[0],0)
+ assert_equal(x[:,0].shape,x.shape)
+
+ def test_scalar_indexing(self):
+ x = asmatrix(zeros((3,2),float))
+ assert_equal(x[0,0],x[0][0])
+
+ def test_row_column_indexing(self):
+ x = asmatrix(np.eye(2))
+ assert_array_equal(x[0,:],[[1,0]])
+ assert_array_equal(x[1,:],[[0,1]])
+ assert_array_equal(x[:,0],[[1],[0]])
+ assert_array_equal(x[:,1],[[0],[1]])
+
+ def test_boolean_indexing(self):
+ A = arange(6)
+ A.shape = (3,2)
+ x = asmatrix(A)
+ assert_array_equal(x[:,array([True,False])],x[:,0])
+ assert_array_equal(x[array([True,False,False]),:],x[0,:])
+
+ def test_list_indexing(self):
+ A = arange(6)
+ A.shape = (3,2)
+ x = asmatrix(A)
+ assert_array_equal(x[:,[1,0]],x[:,::-1])
+ assert_array_equal(x[[2,1,0],:],x[::-1,:])
+
+class TestPower(TestCase):
+ def test_returntype(self):
+ a = array([[0,1],[0,0]])
+ assert type(matrix_power(a, 2)) is ndarray
+ a = mat(a)
+ assert type(matrix_power(a, 2)) is matrix
+
+ def test_list(self):
+ assert_array_equal(matrix_power([[0, 1], [0, 0]], 2), [[0, 0], [0, 0]])
+
+if __name__ == "__main__":
+ run_module_suite()
diff --git a/numpy/matrx/tests/test_numeric.py b/numpy/matrx/tests/test_numeric.py
new file mode 100644
index 000000000..0b96bb05a
--- /dev/null
+++ b/numpy/matrx/tests/test_numeric.py
@@ -0,0 +1,8 @@
+from numpy.testing import assert_equal, TestCase
+from numpy.core import ones
+from numpy import matrix
+
+class TestDot(TestCase):
+ def test_matscalar(self):
+ b1 = matrix(ones((3,3),dtype=complex))
+ assert_equal(b1*1.0, b1)