class:`cvxopt.base.matrix` class).
"""
+from copy import copy
from math import sqrt
from cvxopt import matrix
-from cvxopt.lapack import gees, syevr
+from cvxopt.lapack import gees, gesdd, syevr
from . import options
Parameters
----------
- left, right : matrix
- The two matrices to append to one another.
+ left : matrix
+ The "original" matrix, the one that will wind up on the left.
+
+ right : matrix
+ The matrix to be appended on the right of ``left``.
Returns
-------
Parameters
----------
- top, bottom : matrix
- The two matrices to append to one another.
+ top : matrix
+ The "original" matrix, the one that will wind up on top.
+
+ bottom : matrix
+ The matrix to be appended below ``top``.
Returns
-------
domain_dim = symmat.size[0]
eigs = matrix(0, (domain_dim, 1), tc='d')
- syevr(symmat, eigs)
+
+ # Create a copy of ``symmat`` here because ``syevr`` clobbers it.
+ dummy = copy(symmat)
+ syevr(dummy, eigs)
return list(eigs)
Parameters
----------
- vec1, vec2 : matrix
- The two vectors whose inner product you want.
+ vec1 : matrix
+ The first vector, whose inner product with ``vec2`` you want.
+
+ vec2 : matrix
+ The second vector, whose inner product with ``vec1`` you want.
Returns
-------
--------
>>> v = matrix([1,1])
- >>> print('{:.5f}'.format(norm(v)))
- 1.41421
+ >>> norm(v)
+ 1.414...
>>> A = matrix([1,1,1,1], (2,2))
>>> norm(A)
- 2.0
+ 2.0...
"""
return sqrt(inner_product(matrix_or_vector, matrix_or_vector))
+def specnorm(mat):
+ """
+ Return the spectral norm of a matrix.
+
+ The spectral norm of a matrix is its largest singular value, and it
+ corresponds to the operator norm induced by the vector Euclidean norm.
+
+ Parameters
+ ----------
+
+ mat : matrix
+ The matrix whose spectral norm you want.
+
+ Examples:
+
+ >>> specnorm(identity(3))
+ 1.0
+
+ >>> specnorm(5*identity(4))
+ 5.0
+
+ """
+ num_eigs = min(mat.size)
+ eigs = matrix(0, (num_eigs, 1), tc='d')
+ typecode = 'd'
+ if any([isinstance(entry, complex) for entry in mat]):
+ typecode = 'z'
+ dummy = matrix(mat, mat.size, tc=typecode)
+ gesdd(dummy, eigs)
+
+ if len(eigs) > 0:
+ return eigs[0]
+ else:
+ return 0
+
+
def vec(mat):
"""
Create a long vector in column-major order from ``mat``.
"""
return matrix(mat, (len(mat), 1))
+
+
+def condition_number(mat):
+ """
+ Return the condition number of the given matrix.
+
+ The condition number of a matrix quantifies how hard it is to do
+ numerical computation with that matrix. It is usually defined as
+ the ratio of the norm of the matrix to the norm of its inverse, and
+ therefore depends on the norm used. One way to compute the condition
+ number with respect to the 2-norm is as the ratio of the matrix's
+ largest and smallest singular values. Since we have easy access to
+ those singular values, that is the algorithm we use.
+
+ The larger the condition number is, the worse the matrix is.
+
+ Parameters
+ ----------
+ mat : matrix
+ The matrix whose condition number you want.
+
+ Returns
+ -------
+
+ float
+ The nonnegative condition number of ``mat``.
+
+ Examples
+ --------
+
+ >>> condition_number(identity(3))
+ 1.0
+
+ >>> A = matrix([[2,1],[1,2]])
+ >>> abs(condition_number(A) - 3.0) < options.ABS_TOL
+ True
+
+ >>> A = matrix([[2,1j],[-1j,2]])
+ >>> abs(condition_number(A) - 3.0) < options.ABS_TOL
+ True
+
+ """
+ num_eigs = min(mat.size)
+ eigs = matrix(0, (num_eigs, 1), tc='d')
+ typecode = 'd'
+ if any([isinstance(entry, complex) for entry in mat]):
+ typecode = 'z'
+ dummy = matrix(mat, mat.size, tc=typecode)
+ gesdd(dummy, eigs)
+
+ if len(eigs) > 0:
+ return eigs[0]/eigs[-1]
+ else:
+ return 0