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

1import numpy as np 

2from numpy.linalg import LinAlgError 

3from .blas import get_blas_funcs 

4from .lapack import get_lapack_funcs 

5 

6__all__ = ['LinAlgError', 'LinAlgWarning', 'norm'] 

7 

8 

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 

15 

16 

17def norm(a, ord=None, axis=None, keepdims=False, check_finite=True): 

18 """ 

19 Matrix or vector norm. 

20 

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. 

25 

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. 

49 

50 Returns 

51 ------- 

52 n : float or ndarray 

53 Norm of the matrix or vector(s). 

54 

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. 

60 

61 The following norms can be calculated: 

62 

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 ===== ============================ ========================== 

78 

79 The Frobenius norm is given by [1]_: 

80 

81 :math:`||A||_F = [\\sum_{i,j} abs(a_{i,j})^2]^{1/2}` 

82 

83 The nuclear norm is the sum of the singular values. 

84 

85 Both the Frobenius and nuclear norm orders are only defined for 

86 matrices. 

87 

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 

92 

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.]]) 

105 

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 

120 

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 

133 

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 

142 

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) 

149 

150 if a.size and a.dtype.char in 'fdFD' and axis is None and not keepdims: 

151 

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) 

156 

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) 

176 

177 # fall back to numpy in every other case 

178 return np.linalg.norm(a, ord=ord, axis=axis, keepdims=keepdims) 

179 

180 

181def _datacopied(arr, original): 

182 """ 

183 Strict check for `arr` not sharing any data with `original`, 

184 under the assumption that arr = asarray(original) 

185 

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