Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/scipy/linalg/_misc.py: 24%
37 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-12 06:31 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-12 06:31 +0000
1import numpy as np
2from numpy.linalg import LinAlgError
3from .blas import get_blas_funcs
4from .lapack import get_lapack_funcs
6__all__ = ['LinAlgError', 'LinAlgWarning', 'norm']
9class LinAlgWarning(RuntimeWarning):
10 """
11 The warning emitted when a linear algebra related operation is close
12 to fail conditions of the algorithm or loss of accuracy is expected.
13 """
14 pass
17def norm(a, ord=None, axis=None, keepdims=False, check_finite=True):
18 """
19 Matrix or vector norm.
21 This function is able to return one of eight different matrix norms,
22 or one of an infinite number of vector norms (described below), depending
23 on the value of the ``ord`` parameter. For tensors with rank different from
24 1 or 2, only `ord=None` is supported.
26 Parameters
27 ----------
28 a : array_like
29 Input array. If `axis` is None, `a` must be 1-D or 2-D, unless `ord`
30 is None. If both `axis` and `ord` are None, the 2-norm of
31 ``a.ravel`` will be returned.
32 ord : {int, inf, -inf, 'fro', 'nuc', None}, optional
33 Order of the norm (see table under ``Notes``). inf means NumPy's
34 `inf` object.
35 axis : {int, 2-tuple of ints, None}, optional
36 If `axis` is an integer, it specifies the axis of `a` along which to
37 compute the vector norms. If `axis` is a 2-tuple, it specifies the
38 axes that hold 2-D matrices, and the matrix norms of these matrices
39 are computed. If `axis` is None then either a vector norm (when `a`
40 is 1-D) or a matrix norm (when `a` is 2-D) is returned.
41 keepdims : bool, optional
42 If this is set to True, the axes which are normed over are left in the
43 result as dimensions with size one. With this option the result will
44 broadcast correctly against the original `a`.
45 check_finite : bool, optional
46 Whether to check that the input matrix contains only finite numbers.
47 Disabling may give a performance gain, but may result in problems
48 (crashes, non-termination) if the inputs do contain infinities or NaNs.
50 Returns
51 -------
52 n : float or ndarray
53 Norm of the matrix or vector(s).
55 Notes
56 -----
57 For values of ``ord <= 0``, the result is, strictly speaking, not a
58 mathematical 'norm', but it may still be useful for various numerical
59 purposes.
61 The following norms can be calculated:
63 ===== ============================ ==========================
64 ord norm for matrices norm for vectors
65 ===== ============================ ==========================
66 None Frobenius norm 2-norm
67 'fro' Frobenius norm --
68 'nuc' nuclear norm --
69 inf max(sum(abs(a), axis=1)) max(abs(a))
70 -inf min(sum(abs(a), axis=1)) min(abs(a))
71 0 -- sum(a != 0)
72 1 max(sum(abs(a), axis=0)) as below
73 -1 min(sum(abs(a), axis=0)) as below
74 2 2-norm (largest sing. value) as below
75 -2 smallest singular value as below
76 other -- sum(abs(a)**ord)**(1./ord)
77 ===== ============================ ==========================
79 The Frobenius norm is given by [1]_:
81 :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}`
83 The nuclear norm is the sum of the singular values.
85 Both the Frobenius and nuclear norm orders are only defined for
86 matrices.
88 References
89 ----------
90 .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*,
91 Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15
93 Examples
94 --------
95 >>> import numpy as np
96 >>> from scipy.linalg import norm
97 >>> a = np.arange(9) - 4.0
98 >>> a
99 array([-4., -3., -2., -1., 0., 1., 2., 3., 4.])
100 >>> b = a.reshape((3, 3))
101 >>> b
102 array([[-4., -3., -2.],
103 [-1., 0., 1.],
104 [ 2., 3., 4.]])
106 >>> norm(a)
107 7.745966692414834
108 >>> norm(b)
109 7.745966692414834
110 >>> norm(b, 'fro')
111 7.745966692414834
112 >>> norm(a, np.inf)
113 4
114 >>> norm(b, np.inf)
115 9
116 >>> norm(a, -np.inf)
117 0
118 >>> norm(b, -np.inf)
119 2
121 >>> norm(a, 1)
122 20
123 >>> norm(b, 1)
124 7
125 >>> norm(a, -1)
126 -4.6566128774142013e-010
127 >>> norm(b, -1)
128 6
129 >>> norm(a, 2)
130 7.745966692414834
131 >>> norm(b, 2)
132 7.3484692283495345
134 >>> norm(a, -2)
135 0
136 >>> norm(b, -2)
137 1.8570331885190563e-016
138 >>> norm(a, 3)
139 5.8480354764257312
140 >>> norm(a, -3)
141 0
143 """
144 # Differs from numpy only in non-finite handling and the use of blas.
145 if check_finite:
146 a = np.asarray_chkfinite(a)
147 else:
148 a = np.asarray(a)
150 if a.size and a.dtype.char in 'fdFD' and axis is None and not keepdims:
152 if ord in (None, 2) and (a.ndim == 1):
153 # use blas for fast and stable euclidean norm
154 nrm2 = get_blas_funcs('nrm2', dtype=a.dtype, ilp64='preferred')
155 return nrm2(a)
157 if a.ndim == 2:
158 # Use lapack for a couple fast matrix norms.
159 # For some reason the *lange frobenius norm is slow.
160 lange_args = None
161 # Make sure this works if the user uses the axis keywords
162 # to apply the norm to the transpose.
163 if ord == 1:
164 if np.isfortran(a):
165 lange_args = '1', a
166 elif np.isfortran(a.T):
167 lange_args = 'i', a.T
168 elif ord == np.inf:
169 if np.isfortran(a):
170 lange_args = 'i', a
171 elif np.isfortran(a.T):
172 lange_args = '1', a.T
173 if lange_args:
174 lange = get_lapack_funcs('lange', dtype=a.dtype, ilp64='preferred')
175 return lange(*lange_args)
177 # fall back to numpy in every other case
178 return np.linalg.norm(a, ord=ord, axis=axis, keepdims=keepdims)
181def _datacopied(arr, original):
182 """
183 Strict check for `arr` not sharing any data with `original`,
184 under the assumption that arr = asarray(original)
186 """
187 if arr is original:
188 return False
189 if not isinstance(original, np.ndarray) and hasattr(original, '__array__'):
190 return False
191 return arr.base is None