Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/numpy/linalg/linalg.py: 18%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

669 statements  

1"""Lite version of scipy.linalg. 

2 

3Notes 

4----- 

5This module is a lite version of the linalg.py module in SciPy which 

6contains high-level Python interface to the LAPACK library. The lite 

7version only accesses the following LAPACK functions: dgesv, zgesv, 

8dgeev, zgeev, dgesdd, zgesdd, dgelsd, zgelsd, dsyevd, zheevd, dgetrf, 

9zgetrf, dpotrf, zpotrf, dgeqrf, zgeqrf, zungqr, dorgqr. 

10""" 

11 

12__all__ = ['matrix_power', 'solve', 'tensorsolve', 'tensorinv', 'inv', 

13 'cholesky', 'eigvals', 'eigvalsh', 'pinv', 'slogdet', 'det', 

14 'svd', 'eig', 'eigh', 'lstsq', 'norm', 'qr', 'cond', 'matrix_rank', 

15 'LinAlgError', 'multi_dot'] 

16 

17import functools 

18import operator 

19import warnings 

20from typing import NamedTuple, Any 

21 

22from .._utils import set_module 

23from numpy.core import ( 

24 array, asarray, zeros, empty, empty_like, intc, single, double, 

25 csingle, cdouble, inexact, complexfloating, newaxis, all, Inf, dot, 

26 add, multiply, sqrt, sum, isfinite, 

27 finfo, errstate, geterrobj, moveaxis, amin, amax, prod, abs, 

28 atleast_2d, intp, asanyarray, object_, matmul, 

29 swapaxes, divide, count_nonzero, isnan, sign, argsort, sort, 

30 reciprocal 

31) 

32from numpy.core.multiarray import normalize_axis_index 

33from numpy.core import overrides 

34from numpy.lib.twodim_base import triu, eye 

35from numpy.linalg import _umath_linalg 

36 

37from numpy._typing import NDArray 

38 

39class EigResult(NamedTuple): 

40 eigenvalues: NDArray[Any] 

41 eigenvectors: NDArray[Any] 

42 

43class EighResult(NamedTuple): 

44 eigenvalues: NDArray[Any] 

45 eigenvectors: NDArray[Any] 

46 

47class QRResult(NamedTuple): 

48 Q: NDArray[Any] 

49 R: NDArray[Any] 

50 

51class SlogdetResult(NamedTuple): 

52 sign: NDArray[Any] 

53 logabsdet: NDArray[Any] 

54 

55class SVDResult(NamedTuple): 

56 U: NDArray[Any] 

57 S: NDArray[Any] 

58 Vh: NDArray[Any] 

59 

60array_function_dispatch = functools.partial( 

61 overrides.array_function_dispatch, module='numpy.linalg') 

62 

63 

64fortran_int = intc 

65 

66 

67@set_module('numpy.linalg') 

68class LinAlgError(ValueError): 

69 """ 

70 Generic Python-exception-derived object raised by linalg functions. 

71 

72 General purpose exception class, derived from Python's ValueError 

73 class, programmatically raised in linalg functions when a Linear 

74 Algebra-related condition would prevent further correct execution of the 

75 function. 

76 

77 Parameters 

78 ---------- 

79 None 

80 

81 Examples 

82 -------- 

83 >>> from numpy import linalg as LA 

84 >>> LA.inv(np.zeros((2,2))) 

85 Traceback (most recent call last): 

86 File "<stdin>", line 1, in <module> 

87 File "...linalg.py", line 350, 

88 in inv return wrap(solve(a, identity(a.shape[0], dtype=a.dtype))) 

89 File "...linalg.py", line 249, 

90 in solve 

91 raise LinAlgError('Singular matrix') 

92 numpy.linalg.LinAlgError: Singular matrix 

93 

94 """ 

95 

96 

97def _determine_error_states(): 

98 errobj = geterrobj() 

99 bufsize = errobj[0] 

100 

101 with errstate(invalid='call', over='ignore', 

102 divide='ignore', under='ignore'): 

103 invalid_call_errmask = geterrobj()[1] 

104 

105 return [bufsize, invalid_call_errmask, None] 

106 

107# Dealing with errors in _umath_linalg 

108_linalg_error_extobj = _determine_error_states() 

109del _determine_error_states 

110 

111def _raise_linalgerror_singular(err, flag): 

112 raise LinAlgError("Singular matrix") 

113 

114def _raise_linalgerror_nonposdef(err, flag): 

115 raise LinAlgError("Matrix is not positive definite") 

116 

117def _raise_linalgerror_eigenvalues_nonconvergence(err, flag): 

118 raise LinAlgError("Eigenvalues did not converge") 

119 

120def _raise_linalgerror_svd_nonconvergence(err, flag): 

121 raise LinAlgError("SVD did not converge") 

122 

123def _raise_linalgerror_lstsq(err, flag): 

124 raise LinAlgError("SVD did not converge in Linear Least Squares") 

125 

126def _raise_linalgerror_qr(err, flag): 

127 raise LinAlgError("Incorrect argument found while performing " 

128 "QR factorization") 

129 

130def get_linalg_error_extobj(callback): 

131 extobj = list(_linalg_error_extobj) # make a copy 

132 extobj[2] = callback 

133 return extobj 

134 

135def _makearray(a): 

136 new = asarray(a) 

137 wrap = getattr(a, "__array_prepare__", new.__array_wrap__) 

138 return new, wrap 

139 

140def isComplexType(t): 

141 return issubclass(t, complexfloating) 

142 

143_real_types_map = {single : single, 

144 double : double, 

145 csingle : single, 

146 cdouble : double} 

147 

148_complex_types_map = {single : csingle, 

149 double : cdouble, 

150 csingle : csingle, 

151 cdouble : cdouble} 

152 

153def _realType(t, default=double): 

154 return _real_types_map.get(t, default) 

155 

156def _complexType(t, default=cdouble): 

157 return _complex_types_map.get(t, default) 

158 

159def _commonType(*arrays): 

160 # in lite version, use higher precision (always double or cdouble) 

161 result_type = single 

162 is_complex = False 

163 for a in arrays: 

164 type_ = a.dtype.type 

165 if issubclass(type_, inexact): 

166 if isComplexType(type_): 

167 is_complex = True 

168 rt = _realType(type_, default=None) 

169 if rt is double: 

170 result_type = double 

171 elif rt is None: 

172 # unsupported inexact scalar 

173 raise TypeError("array type %s is unsupported in linalg" % 

174 (a.dtype.name,)) 

175 else: 

176 result_type = double 

177 if is_complex: 

178 result_type = _complex_types_map[result_type] 

179 return cdouble, result_type 

180 else: 

181 return double, result_type 

182 

183 

184def _to_native_byte_order(*arrays): 

185 ret = [] 

186 for arr in arrays: 

187 if arr.dtype.byteorder not in ('=', '|'): 

188 ret.append(asarray(arr, dtype=arr.dtype.newbyteorder('='))) 

189 else: 

190 ret.append(arr) 

191 if len(ret) == 1: 

192 return ret[0] 

193 else: 

194 return ret 

195 

196 

197def _assert_2d(*arrays): 

198 for a in arrays: 

199 if a.ndim != 2: 

200 raise LinAlgError('%d-dimensional array given. Array must be ' 

201 'two-dimensional' % a.ndim) 

202 

203def _assert_stacked_2d(*arrays): 

204 for a in arrays: 

205 if a.ndim < 2: 

206 raise LinAlgError('%d-dimensional array given. Array must be ' 

207 'at least two-dimensional' % a.ndim) 

208 

209def _assert_stacked_square(*arrays): 

210 for a in arrays: 

211 m, n = a.shape[-2:] 

212 if m != n: 

213 raise LinAlgError('Last 2 dimensions of the array must be square') 

214 

215def _assert_finite(*arrays): 

216 for a in arrays: 

217 if not isfinite(a).all(): 

218 raise LinAlgError("Array must not contain infs or NaNs") 

219 

220def _is_empty_2d(arr): 

221 # check size first for efficiency 

222 return arr.size == 0 and prod(arr.shape[-2:]) == 0 

223 

224 

225def transpose(a): 

226 """ 

227 Transpose each matrix in a stack of matrices. 

228 

229 Unlike np.transpose, this only swaps the last two axes, rather than all of 

230 them 

231 

232 Parameters 

233 ---------- 

234 a : (...,M,N) array_like 

235 

236 Returns 

237 ------- 

238 aT : (...,N,M) ndarray 

239 """ 

240 return swapaxes(a, -1, -2) 

241 

242# Linear equations 

243 

244def _tensorsolve_dispatcher(a, b, axes=None): 

245 return (a, b) 

246 

247 

248@array_function_dispatch(_tensorsolve_dispatcher) 

249def tensorsolve(a, b, axes=None): 

250 """ 

251 Solve the tensor equation ``a x = b`` for x. 

252 

253 It is assumed that all indices of `x` are summed over in the product, 

254 together with the rightmost indices of `a`, as is done in, for example, 

255 ``tensordot(a, x, axes=x.ndim)``. 

256 

257 Parameters 

258 ---------- 

259 a : array_like 

260 Coefficient tensor, of shape ``b.shape + Q``. `Q`, a tuple, equals 

261 the shape of that sub-tensor of `a` consisting of the appropriate 

262 number of its rightmost indices, and must be such that 

263 ``prod(Q) == prod(b.shape)`` (in which sense `a` is said to be 

264 'square'). 

265 b : array_like 

266 Right-hand tensor, which can be of any shape. 

267 axes : tuple of ints, optional 

268 Axes in `a` to reorder to the right, before inversion. 

269 If None (default), no reordering is done. 

270 

271 Returns 

272 ------- 

273 x : ndarray, shape Q 

274 

275 Raises 

276 ------ 

277 LinAlgError 

278 If `a` is singular or not 'square' (in the above sense). 

279 

280 See Also 

281 -------- 

282 numpy.tensordot, tensorinv, numpy.einsum 

283 

284 Examples 

285 -------- 

286 >>> a = np.eye(2*3*4) 

287 >>> a.shape = (2*3, 4, 2, 3, 4) 

288 >>> b = np.random.randn(2*3, 4) 

289 >>> x = np.linalg.tensorsolve(a, b) 

290 >>> x.shape 

291 (2, 3, 4) 

292 >>> np.allclose(np.tensordot(a, x, axes=3), b) 

293 True 

294 

295 """ 

296 a, wrap = _makearray(a) 

297 b = asarray(b) 

298 an = a.ndim 

299 

300 if axes is not None: 

301 allaxes = list(range(0, an)) 

302 for k in axes: 

303 allaxes.remove(k) 

304 allaxes.insert(an, k) 

305 a = a.transpose(allaxes) 

306 

307 oldshape = a.shape[-(an-b.ndim):] 

308 prod = 1 

309 for k in oldshape: 

310 prod *= k 

311 

312 if a.size != prod ** 2: 

313 raise LinAlgError( 

314 "Input arrays must satisfy the requirement \ 

315 prod(a.shape[b.ndim:]) == prod(a.shape[:b.ndim])" 

316 ) 

317 

318 a = a.reshape(prod, prod) 

319 b = b.ravel() 

320 res = wrap(solve(a, b)) 

321 res.shape = oldshape 

322 return res 

323 

324 

325def _solve_dispatcher(a, b): 

326 return (a, b) 

327 

328 

329@array_function_dispatch(_solve_dispatcher) 

330def solve(a, b): 

331 """ 

332 Solve a linear matrix equation, or system of linear scalar equations. 

333 

334 Computes the "exact" solution, `x`, of the well-determined, i.e., full 

335 rank, linear matrix equation `ax = b`. 

336 

337 Parameters 

338 ---------- 

339 a : (..., M, M) array_like 

340 Coefficient matrix. 

341 b : {(..., M,), (..., M, K)}, array_like 

342 Ordinate or "dependent variable" values. 

343 

344 Returns 

345 ------- 

346 x : {(..., M,), (..., M, K)} ndarray 

347 Solution to the system a x = b. Returned shape is identical to `b`. 

348 

349 Raises 

350 ------ 

351 LinAlgError 

352 If `a` is singular or not square. 

353 

354 See Also 

355 -------- 

356 scipy.linalg.solve : Similar function in SciPy. 

357 

358 Notes 

359 ----- 

360 

361 .. versionadded:: 1.8.0 

362 

363 Broadcasting rules apply, see the `numpy.linalg` documentation for 

364 details. 

365 

366 The solutions are computed using LAPACK routine ``_gesv``. 

367 

368 `a` must be square and of full-rank, i.e., all rows (or, equivalently, 

369 columns) must be linearly independent; if either is not true, use 

370 `lstsq` for the least-squares best "solution" of the 

371 system/equation. 

372 

373 References 

374 ---------- 

375 .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, 

376 FL, Academic Press, Inc., 1980, pg. 22. 

377 

378 Examples 

379 -------- 

380 Solve the system of equations ``x0 + 2 * x1 = 1`` and ``3 * x0 + 5 * x1 = 2``: 

381 

382 >>> a = np.array([[1, 2], [3, 5]]) 

383 >>> b = np.array([1, 2]) 

384 >>> x = np.linalg.solve(a, b) 

385 >>> x 

386 array([-1., 1.]) 

387 

388 Check that the solution is correct: 

389 

390 >>> np.allclose(np.dot(a, x), b) 

391 True 

392 

393 """ 

394 a, _ = _makearray(a) 

395 _assert_stacked_2d(a) 

396 _assert_stacked_square(a) 

397 b, wrap = _makearray(b) 

398 t, result_t = _commonType(a, b) 

399 

400 # We use the b = (..., M,) logic, only if the number of extra dimensions 

401 # match exactly 

402 if b.ndim == a.ndim - 1: 

403 gufunc = _umath_linalg.solve1 

404 else: 

405 gufunc = _umath_linalg.solve 

406 

407 signature = 'DD->D' if isComplexType(t) else 'dd->d' 

408 extobj = get_linalg_error_extobj(_raise_linalgerror_singular) 

409 r = gufunc(a, b, signature=signature, extobj=extobj) 

410 

411 return wrap(r.astype(result_t, copy=False)) 

412 

413 

414def _tensorinv_dispatcher(a, ind=None): 

415 return (a,) 

416 

417 

418@array_function_dispatch(_tensorinv_dispatcher) 

419def tensorinv(a, ind=2): 

420 """ 

421 Compute the 'inverse' of an N-dimensional array. 

422 

423 The result is an inverse for `a` relative to the tensordot operation 

424 ``tensordot(a, b, ind)``, i. e., up to floating-point accuracy, 

425 ``tensordot(tensorinv(a), a, ind)`` is the "identity" tensor for the 

426 tensordot operation. 

427 

428 Parameters 

429 ---------- 

430 a : array_like 

431 Tensor to 'invert'. Its shape must be 'square', i. e., 

432 ``prod(a.shape[:ind]) == prod(a.shape[ind:])``. 

433 ind : int, optional 

434 Number of first indices that are involved in the inverse sum. 

435 Must be a positive integer, default is 2. 

436 

437 Returns 

438 ------- 

439 b : ndarray 

440 `a`'s tensordot inverse, shape ``a.shape[ind:] + a.shape[:ind]``. 

441 

442 Raises 

443 ------ 

444 LinAlgError 

445 If `a` is singular or not 'square' (in the above sense). 

446 

447 See Also 

448 -------- 

449 numpy.tensordot, tensorsolve 

450 

451 Examples 

452 -------- 

453 >>> a = np.eye(4*6) 

454 >>> a.shape = (4, 6, 8, 3) 

455 >>> ainv = np.linalg.tensorinv(a, ind=2) 

456 >>> ainv.shape 

457 (8, 3, 4, 6) 

458 >>> b = np.random.randn(4, 6) 

459 >>> np.allclose(np.tensordot(ainv, b), np.linalg.tensorsolve(a, b)) 

460 True 

461 

462 >>> a = np.eye(4*6) 

463 >>> a.shape = (24, 8, 3) 

464 >>> ainv = np.linalg.tensorinv(a, ind=1) 

465 >>> ainv.shape 

466 (8, 3, 24) 

467 >>> b = np.random.randn(24) 

468 >>> np.allclose(np.tensordot(ainv, b, 1), np.linalg.tensorsolve(a, b)) 

469 True 

470 

471 """ 

472 a = asarray(a) 

473 oldshape = a.shape 

474 prod = 1 

475 if ind > 0: 

476 invshape = oldshape[ind:] + oldshape[:ind] 

477 for k in oldshape[ind:]: 

478 prod *= k 

479 else: 

480 raise ValueError("Invalid ind argument.") 

481 a = a.reshape(prod, -1) 

482 ia = inv(a) 

483 return ia.reshape(*invshape) 

484 

485 

486# Matrix inversion 

487 

488def _unary_dispatcher(a): 

489 return (a,) 

490 

491 

492@array_function_dispatch(_unary_dispatcher) 

493def inv(a): 

494 """ 

495 Compute the (multiplicative) inverse of a matrix. 

496 

497 Given a square matrix `a`, return the matrix `ainv` satisfying 

498 ``dot(a, ainv) = dot(ainv, a) = eye(a.shape[0])``. 

499 

500 Parameters 

501 ---------- 

502 a : (..., M, M) array_like 

503 Matrix to be inverted. 

504 

505 Returns 

506 ------- 

507 ainv : (..., M, M) ndarray or matrix 

508 (Multiplicative) inverse of the matrix `a`. 

509 

510 Raises 

511 ------ 

512 LinAlgError 

513 If `a` is not square or inversion fails. 

514 

515 See Also 

516 -------- 

517 scipy.linalg.inv : Similar function in SciPy. 

518 

519 Notes 

520 ----- 

521 

522 .. versionadded:: 1.8.0 

523 

524 Broadcasting rules apply, see the `numpy.linalg` documentation for 

525 details. 

526 

527 Examples 

528 -------- 

529 >>> from numpy.linalg import inv 

530 >>> a = np.array([[1., 2.], [3., 4.]]) 

531 >>> ainv = inv(a) 

532 >>> np.allclose(np.dot(a, ainv), np.eye(2)) 

533 True 

534 >>> np.allclose(np.dot(ainv, a), np.eye(2)) 

535 True 

536 

537 If a is a matrix object, then the return value is a matrix as well: 

538 

539 >>> ainv = inv(np.matrix(a)) 

540 >>> ainv 

541 matrix([[-2. , 1. ], 

542 [ 1.5, -0.5]]) 

543 

544 Inverses of several matrices can be computed at once: 

545 

546 >>> a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]]) 

547 >>> inv(a) 

548 array([[[-2. , 1. ], 

549 [ 1.5 , -0.5 ]], 

550 [[-1.25, 0.75], 

551 [ 0.75, -0.25]]]) 

552 

553 """ 

554 a, wrap = _makearray(a) 

555 _assert_stacked_2d(a) 

556 _assert_stacked_square(a) 

557 t, result_t = _commonType(a) 

558 

559 signature = 'D->D' if isComplexType(t) else 'd->d' 

560 extobj = get_linalg_error_extobj(_raise_linalgerror_singular) 

561 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj) 

562 return wrap(ainv.astype(result_t, copy=False)) 

563 

564 

565def _matrix_power_dispatcher(a, n): 

566 return (a,) 

567 

568 

569@array_function_dispatch(_matrix_power_dispatcher) 

570def matrix_power(a, n): 

571 """ 

572 Raise a square matrix to the (integer) power `n`. 

573 

574 For positive integers `n`, the power is computed by repeated matrix 

575 squarings and matrix multiplications. If ``n == 0``, the identity matrix 

576 of the same shape as M is returned. If ``n < 0``, the inverse 

577 is computed and then raised to the ``abs(n)``. 

578 

579 .. note:: Stacks of object matrices are not currently supported. 

580 

581 Parameters 

582 ---------- 

583 a : (..., M, M) array_like 

584 Matrix to be "powered". 

585 n : int 

586 The exponent can be any integer or long integer, positive, 

587 negative, or zero. 

588 

589 Returns 

590 ------- 

591 a**n : (..., M, M) ndarray or matrix object 

592 The return value is the same shape and type as `M`; 

593 if the exponent is positive or zero then the type of the 

594 elements is the same as those of `M`. If the exponent is 

595 negative the elements are floating-point. 

596 

597 Raises 

598 ------ 

599 LinAlgError 

600 For matrices that are not square or that (for negative powers) cannot 

601 be inverted numerically. 

602 

603 Examples 

604 -------- 

605 >>> from numpy.linalg import matrix_power 

606 >>> i = np.array([[0, 1], [-1, 0]]) # matrix equiv. of the imaginary unit 

607 >>> matrix_power(i, 3) # should = -i 

608 array([[ 0, -1], 

609 [ 1, 0]]) 

610 >>> matrix_power(i, 0) 

611 array([[1, 0], 

612 [0, 1]]) 

613 >>> matrix_power(i, -3) # should = 1/(-i) = i, but w/ f.p. elements 

614 array([[ 0., 1.], 

615 [-1., 0.]]) 

616 

617 Somewhat more sophisticated example 

618 

619 >>> q = np.zeros((4, 4)) 

620 >>> q[0:2, 0:2] = -i 

621 >>> q[2:4, 2:4] = i 

622 >>> q # one of the three quaternion units not equal to 1 

623 array([[ 0., -1., 0., 0.], 

624 [ 1., 0., 0., 0.], 

625 [ 0., 0., 0., 1.], 

626 [ 0., 0., -1., 0.]]) 

627 >>> matrix_power(q, 2) # = -np.eye(4) 

628 array([[-1., 0., 0., 0.], 

629 [ 0., -1., 0., 0.], 

630 [ 0., 0., -1., 0.], 

631 [ 0., 0., 0., -1.]]) 

632 

633 """ 

634 a = asanyarray(a) 

635 _assert_stacked_2d(a) 

636 _assert_stacked_square(a) 

637 

638 try: 

639 n = operator.index(n) 

640 except TypeError as e: 

641 raise TypeError("exponent must be an integer") from e 

642 

643 # Fall back on dot for object arrays. Object arrays are not supported by 

644 # the current implementation of matmul using einsum 

645 if a.dtype != object: 

646 fmatmul = matmul 

647 elif a.ndim == 2: 

648 fmatmul = dot 

649 else: 

650 raise NotImplementedError( 

651 "matrix_power not supported for stacks of object arrays") 

652 

653 if n == 0: 

654 a = empty_like(a) 

655 a[...] = eye(a.shape[-2], dtype=a.dtype) 

656 return a 

657 

658 elif n < 0: 

659 a = inv(a) 

660 n = abs(n) 

661 

662 # short-cuts. 

663 if n == 1: 

664 return a 

665 

666 elif n == 2: 

667 return fmatmul(a, a) 

668 

669 elif n == 3: 

670 return fmatmul(fmatmul(a, a), a) 

671 

672 # Use binary decomposition to reduce the number of matrix multiplications. 

673 # Here, we iterate over the bits of n, from LSB to MSB, raise `a` to 

674 # increasing powers of 2, and multiply into the result as needed. 

675 z = result = None 

676 while n > 0: 

677 z = a if z is None else fmatmul(z, z) 

678 n, bit = divmod(n, 2) 

679 if bit: 

680 result = z if result is None else fmatmul(result, z) 

681 

682 return result 

683 

684 

685# Cholesky decomposition 

686 

687 

688@array_function_dispatch(_unary_dispatcher) 

689def cholesky(a): 

690 """ 

691 Cholesky decomposition. 

692 

693 Return the Cholesky decomposition, `L * L.H`, of the square matrix `a`, 

694 where `L` is lower-triangular and .H is the conjugate transpose operator 

695 (which is the ordinary transpose if `a` is real-valued). `a` must be 

696 Hermitian (symmetric if real-valued) and positive-definite. No 

697 checking is performed to verify whether `a` is Hermitian or not. 

698 In addition, only the lower-triangular and diagonal elements of `a` 

699 are used. Only `L` is actually returned. 

700 

701 Parameters 

702 ---------- 

703 a : (..., M, M) array_like 

704 Hermitian (symmetric if all elements are real), positive-definite 

705 input matrix. 

706 

707 Returns 

708 ------- 

709 L : (..., M, M) array_like 

710 Lower-triangular Cholesky factor of `a`. Returns a matrix object if 

711 `a` is a matrix object. 

712 

713 Raises 

714 ------ 

715 LinAlgError 

716 If the decomposition fails, for example, if `a` is not 

717 positive-definite. 

718 

719 See Also 

720 -------- 

721 scipy.linalg.cholesky : Similar function in SciPy. 

722 scipy.linalg.cholesky_banded : Cholesky decompose a banded Hermitian 

723 positive-definite matrix. 

724 scipy.linalg.cho_factor : Cholesky decomposition of a matrix, to use in 

725 `scipy.linalg.cho_solve`. 

726 

727 Notes 

728 ----- 

729 

730 .. versionadded:: 1.8.0 

731 

732 Broadcasting rules apply, see the `numpy.linalg` documentation for 

733 details. 

734 

735 The Cholesky decomposition is often used as a fast way of solving 

736 

737 .. math:: A \\mathbf{x} = \\mathbf{b} 

738 

739 (when `A` is both Hermitian/symmetric and positive-definite). 

740 

741 First, we solve for :math:`\\mathbf{y}` in 

742 

743 .. math:: L \\mathbf{y} = \\mathbf{b}, 

744 

745 and then for :math:`\\mathbf{x}` in 

746 

747 .. math:: L.H \\mathbf{x} = \\mathbf{y}. 

748 

749 Examples 

750 -------- 

751 >>> A = np.array([[1,-2j],[2j,5]]) 

752 >>> A 

753 array([[ 1.+0.j, -0.-2.j], 

754 [ 0.+2.j, 5.+0.j]]) 

755 >>> L = np.linalg.cholesky(A) 

756 >>> L 

757 array([[1.+0.j, 0.+0.j], 

758 [0.+2.j, 1.+0.j]]) 

759 >>> np.dot(L, L.T.conj()) # verify that L * L.H = A 

760 array([[1.+0.j, 0.-2.j], 

761 [0.+2.j, 5.+0.j]]) 

762 >>> A = [[1,-2j],[2j,5]] # what happens if A is only array_like? 

763 >>> np.linalg.cholesky(A) # an ndarray object is returned 

764 array([[1.+0.j, 0.+0.j], 

765 [0.+2.j, 1.+0.j]]) 

766 >>> # But a matrix object is returned if A is a matrix object 

767 >>> np.linalg.cholesky(np.matrix(A)) 

768 matrix([[ 1.+0.j, 0.+0.j], 

769 [ 0.+2.j, 1.+0.j]]) 

770 

771 """ 

772 extobj = get_linalg_error_extobj(_raise_linalgerror_nonposdef) 

773 gufunc = _umath_linalg.cholesky_lo 

774 a, wrap = _makearray(a) 

775 _assert_stacked_2d(a) 

776 _assert_stacked_square(a) 

777 t, result_t = _commonType(a) 

778 signature = 'D->D' if isComplexType(t) else 'd->d' 

779 r = gufunc(a, signature=signature, extobj=extobj) 

780 return wrap(r.astype(result_t, copy=False)) 

781 

782 

783# QR decomposition 

784 

785def _qr_dispatcher(a, mode=None): 

786 return (a,) 

787 

788 

789@array_function_dispatch(_qr_dispatcher) 

790def qr(a, mode='reduced'): 

791 """ 

792 Compute the qr factorization of a matrix. 

793 

794 Factor the matrix `a` as *qr*, where `q` is orthonormal and `r` is 

795 upper-triangular. 

796 

797 Parameters 

798 ---------- 

799 a : array_like, shape (..., M, N) 

800 An array-like object with the dimensionality of at least 2. 

801 mode : {'reduced', 'complete', 'r', 'raw'}, optional 

802 If K = min(M, N), then 

803 

804 * 'reduced' : returns Q, R with dimensions (..., M, K), (..., K, N) (default) 

805 * 'complete' : returns Q, R with dimensions (..., M, M), (..., M, N) 

806 * 'r' : returns R only with dimensions (..., K, N) 

807 * 'raw' : returns h, tau with dimensions (..., N, M), (..., K,) 

808 

809 The options 'reduced', 'complete, and 'raw' are new in numpy 1.8, 

810 see the notes for more information. The default is 'reduced', and to 

811 maintain backward compatibility with earlier versions of numpy both 

812 it and the old default 'full' can be omitted. Note that array h 

813 returned in 'raw' mode is transposed for calling Fortran. The 

814 'economic' mode is deprecated. The modes 'full' and 'economic' may 

815 be passed using only the first letter for backwards compatibility, 

816 but all others must be spelled out. See the Notes for more 

817 explanation. 

818 

819 

820 Returns 

821 ------- 

822 When mode is 'reduced' or 'complete', the result will be a namedtuple with 

823 the attributes `Q` and `R`. 

824 

825 Q : ndarray of float or complex, optional 

826 A matrix with orthonormal columns. When mode = 'complete' the 

827 result is an orthogonal/unitary matrix depending on whether or not 

828 a is real/complex. The determinant may be either +/- 1 in that 

829 case. In case the number of dimensions in the input array is 

830 greater than 2 then a stack of the matrices with above properties 

831 is returned. 

832 R : ndarray of float or complex, optional 

833 The upper-triangular matrix or a stack of upper-triangular 

834 matrices if the number of dimensions in the input array is greater 

835 than 2. 

836 (h, tau) : ndarrays of np.double or np.cdouble, optional 

837 The array h contains the Householder reflectors that generate q 

838 along with r. The tau array contains scaling factors for the 

839 reflectors. In the deprecated 'economic' mode only h is returned. 

840 

841 Raises 

842 ------ 

843 LinAlgError 

844 If factoring fails. 

845 

846 See Also 

847 -------- 

848 scipy.linalg.qr : Similar function in SciPy. 

849 scipy.linalg.rq : Compute RQ decomposition of a matrix. 

850 

851 Notes 

852 ----- 

853 This is an interface to the LAPACK routines ``dgeqrf``, ``zgeqrf``, 

854 ``dorgqr``, and ``zungqr``. 

855 

856 For more information on the qr factorization, see for example: 

857 https://en.wikipedia.org/wiki/QR_factorization 

858 

859 Subclasses of `ndarray` are preserved except for the 'raw' mode. So if 

860 `a` is of type `matrix`, all the return values will be matrices too. 

861 

862 New 'reduced', 'complete', and 'raw' options for mode were added in 

863 NumPy 1.8.0 and the old option 'full' was made an alias of 'reduced'. In 

864 addition the options 'full' and 'economic' were deprecated. Because 

865 'full' was the previous default and 'reduced' is the new default, 

866 backward compatibility can be maintained by letting `mode` default. 

867 The 'raw' option was added so that LAPACK routines that can multiply 

868 arrays by q using the Householder reflectors can be used. Note that in 

869 this case the returned arrays are of type np.double or np.cdouble and 

870 the h array is transposed to be FORTRAN compatible. No routines using 

871 the 'raw' return are currently exposed by numpy, but some are available 

872 in lapack_lite and just await the necessary work. 

873 

874 Examples 

875 -------- 

876 >>> a = np.random.randn(9, 6) 

877 >>> Q, R = np.linalg.qr(a) 

878 >>> np.allclose(a, np.dot(Q, R)) # a does equal QR 

879 True 

880 >>> R2 = np.linalg.qr(a, mode='r') 

881 >>> np.allclose(R, R2) # mode='r' returns the same R as mode='full' 

882 True 

883 >>> a = np.random.normal(size=(3, 2, 2)) # Stack of 2 x 2 matrices as input 

884 >>> Q, R = np.linalg.qr(a) 

885 >>> Q.shape 

886 (3, 2, 2) 

887 >>> R.shape 

888 (3, 2, 2) 

889 >>> np.allclose(a, np.matmul(Q, R)) 

890 True 

891 

892 Example illustrating a common use of `qr`: solving of least squares 

893 problems 

894 

895 What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for 

896 the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points 

897 and you'll see that it should be y0 = 0, m = 1.) The answer is provided 

898 by solving the over-determined matrix equation ``Ax = b``, where:: 

899 

900 A = array([[0, 1], [1, 1], [1, 1], [2, 1]]) 

901 x = array([[y0], [m]]) 

902 b = array([[1], [0], [2], [1]]) 

903 

904 If A = QR such that Q is orthonormal (which is always possible via 

905 Gram-Schmidt), then ``x = inv(R) * (Q.T) * b``. (In numpy practice, 

906 however, we simply use `lstsq`.) 

907 

908 >>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]]) 

909 >>> A 

910 array([[0, 1], 

911 [1, 1], 

912 [1, 1], 

913 [2, 1]]) 

914 >>> b = np.array([1, 2, 2, 3]) 

915 >>> Q, R = np.linalg.qr(A) 

916 >>> p = np.dot(Q.T, b) 

917 >>> np.dot(np.linalg.inv(R), p) 

918 array([ 1., 1.]) 

919 

920 """ 

921 if mode not in ('reduced', 'complete', 'r', 'raw'): 

922 if mode in ('f', 'full'): 

923 # 2013-04-01, 1.8 

924 msg = "".join(( 

925 "The 'full' option is deprecated in favor of 'reduced'.\n", 

926 "For backward compatibility let mode default.")) 

927 warnings.warn(msg, DeprecationWarning, stacklevel=2) 

928 mode = 'reduced' 

929 elif mode in ('e', 'economic'): 

930 # 2013-04-01, 1.8 

931 msg = "The 'economic' option is deprecated." 

932 warnings.warn(msg, DeprecationWarning, stacklevel=2) 

933 mode = 'economic' 

934 else: 

935 raise ValueError(f"Unrecognized mode '{mode}'") 

936 

937 a, wrap = _makearray(a) 

938 _assert_stacked_2d(a) 

939 m, n = a.shape[-2:] 

940 t, result_t = _commonType(a) 

941 a = a.astype(t, copy=True) 

942 a = _to_native_byte_order(a) 

943 mn = min(m, n) 

944 

945 if m <= n: 

946 gufunc = _umath_linalg.qr_r_raw_m 

947 else: 

948 gufunc = _umath_linalg.qr_r_raw_n 

949 

950 signature = 'D->D' if isComplexType(t) else 'd->d' 

951 extobj = get_linalg_error_extobj(_raise_linalgerror_qr) 

952 tau = gufunc(a, signature=signature, extobj=extobj) 

953 

954 # handle modes that don't return q 

955 if mode == 'r': 

956 r = triu(a[..., :mn, :]) 

957 r = r.astype(result_t, copy=False) 

958 return wrap(r) 

959 

960 if mode == 'raw': 

961 q = transpose(a) 

962 q = q.astype(result_t, copy=False) 

963 tau = tau.astype(result_t, copy=False) 

964 return wrap(q), tau 

965 

966 if mode == 'economic': 

967 a = a.astype(result_t, copy=False) 

968 return wrap(a) 

969 

970 # mc is the number of columns in the resulting q 

971 # matrix. If the mode is complete then it is 

972 # same as number of rows, and if the mode is reduced, 

973 # then it is the minimum of number of rows and columns. 

974 if mode == 'complete' and m > n: 

975 mc = m 

976 gufunc = _umath_linalg.qr_complete 

977 else: 

978 mc = mn 

979 gufunc = _umath_linalg.qr_reduced 

980 

981 signature = 'DD->D' if isComplexType(t) else 'dd->d' 

982 extobj = get_linalg_error_extobj(_raise_linalgerror_qr) 

983 q = gufunc(a, tau, signature=signature, extobj=extobj) 

984 r = triu(a[..., :mc, :]) 

985 

986 q = q.astype(result_t, copy=False) 

987 r = r.astype(result_t, copy=False) 

988 

989 return QRResult(wrap(q), wrap(r)) 

990 

991# Eigenvalues 

992 

993 

994@array_function_dispatch(_unary_dispatcher) 

995def eigvals(a): 

996 """ 

997 Compute the eigenvalues of a general matrix. 

998 

999 Main difference between `eigvals` and `eig`: the eigenvectors aren't 

1000 returned. 

1001 

1002 Parameters 

1003 ---------- 

1004 a : (..., M, M) array_like 

1005 A complex- or real-valued matrix whose eigenvalues will be computed. 

1006 

1007 Returns 

1008 ------- 

1009 w : (..., M,) ndarray 

1010 The eigenvalues, each repeated according to its multiplicity. 

1011 They are not necessarily ordered, nor are they necessarily 

1012 real for real matrices. 

1013 

1014 Raises 

1015 ------ 

1016 LinAlgError 

1017 If the eigenvalue computation does not converge. 

1018 

1019 See Also 

1020 -------- 

1021 eig : eigenvalues and right eigenvectors of general arrays 

1022 eigvalsh : eigenvalues of real symmetric or complex Hermitian 

1023 (conjugate symmetric) arrays. 

1024 eigh : eigenvalues and eigenvectors of real symmetric or complex 

1025 Hermitian (conjugate symmetric) arrays. 

1026 scipy.linalg.eigvals : Similar function in SciPy. 

1027 

1028 Notes 

1029 ----- 

1030 

1031 .. versionadded:: 1.8.0 

1032 

1033 Broadcasting rules apply, see the `numpy.linalg` documentation for 

1034 details. 

1035 

1036 This is implemented using the ``_geev`` LAPACK routines which compute 

1037 the eigenvalues and eigenvectors of general square arrays. 

1038 

1039 Examples 

1040 -------- 

1041 Illustration, using the fact that the eigenvalues of a diagonal matrix 

1042 are its diagonal elements, that multiplying a matrix on the left 

1043 by an orthogonal matrix, `Q`, and on the right by `Q.T` (the transpose 

1044 of `Q`), preserves the eigenvalues of the "middle" matrix. In other words, 

1045 if `Q` is orthogonal, then ``Q * A * Q.T`` has the same eigenvalues as 

1046 ``A``: 

1047 

1048 >>> from numpy import linalg as LA 

1049 >>> x = np.random.random() 

1050 >>> Q = np.array([[np.cos(x), -np.sin(x)], [np.sin(x), np.cos(x)]]) 

1051 >>> LA.norm(Q[0, :]), LA.norm(Q[1, :]), np.dot(Q[0, :],Q[1, :]) 

1052 (1.0, 1.0, 0.0) 

1053 

1054 Now multiply a diagonal matrix by ``Q`` on one side and by ``Q.T`` on the other: 

1055 

1056 >>> D = np.diag((-1,1)) 

1057 >>> LA.eigvals(D) 

1058 array([-1., 1.]) 

1059 >>> A = np.dot(Q, D) 

1060 >>> A = np.dot(A, Q.T) 

1061 >>> LA.eigvals(A) 

1062 array([ 1., -1.]) # random 

1063 

1064 """ 

1065 a, wrap = _makearray(a) 

1066 _assert_stacked_2d(a) 

1067 _assert_stacked_square(a) 

1068 _assert_finite(a) 

1069 t, result_t = _commonType(a) 

1070 

1071 extobj = get_linalg_error_extobj( 

1072 _raise_linalgerror_eigenvalues_nonconvergence) 

1073 signature = 'D->D' if isComplexType(t) else 'd->D' 

1074 w = _umath_linalg.eigvals(a, signature=signature, extobj=extobj) 

1075 

1076 if not isComplexType(t): 

1077 if all(w.imag == 0): 

1078 w = w.real 

1079 result_t = _realType(result_t) 

1080 else: 

1081 result_t = _complexType(result_t) 

1082 

1083 return w.astype(result_t, copy=False) 

1084 

1085 

1086def _eigvalsh_dispatcher(a, UPLO=None): 

1087 return (a,) 

1088 

1089 

1090@array_function_dispatch(_eigvalsh_dispatcher) 

1091def eigvalsh(a, UPLO='L'): 

1092 """ 

1093 Compute the eigenvalues of a complex Hermitian or real symmetric matrix. 

1094 

1095 Main difference from eigh: the eigenvectors are not computed. 

1096 

1097 Parameters 

1098 ---------- 

1099 a : (..., M, M) array_like 

1100 A complex- or real-valued matrix whose eigenvalues are to be 

1101 computed. 

1102 UPLO : {'L', 'U'}, optional 

1103 Specifies whether the calculation is done with the lower triangular 

1104 part of `a` ('L', default) or the upper triangular part ('U'). 

1105 Irrespective of this value only the real parts of the diagonal will 

1106 be considered in the computation to preserve the notion of a Hermitian 

1107 matrix. It therefore follows that the imaginary part of the diagonal 

1108 will always be treated as zero. 

1109 

1110 Returns 

1111 ------- 

1112 w : (..., M,) ndarray 

1113 The eigenvalues in ascending order, each repeated according to 

1114 its multiplicity. 

1115 

1116 Raises 

1117 ------ 

1118 LinAlgError 

1119 If the eigenvalue computation does not converge. 

1120 

1121 See Also 

1122 -------- 

1123 eigh : eigenvalues and eigenvectors of real symmetric or complex Hermitian 

1124 (conjugate symmetric) arrays. 

1125 eigvals : eigenvalues of general real or complex arrays. 

1126 eig : eigenvalues and right eigenvectors of general real or complex 

1127 arrays. 

1128 scipy.linalg.eigvalsh : Similar function in SciPy. 

1129 

1130 Notes 

1131 ----- 

1132 

1133 .. versionadded:: 1.8.0 

1134 

1135 Broadcasting rules apply, see the `numpy.linalg` documentation for 

1136 details. 

1137 

1138 The eigenvalues are computed using LAPACK routines ``_syevd``, ``_heevd``. 

1139 

1140 Examples 

1141 -------- 

1142 >>> from numpy import linalg as LA 

1143 >>> a = np.array([[1, -2j], [2j, 5]]) 

1144 >>> LA.eigvalsh(a) 

1145 array([ 0.17157288, 5.82842712]) # may vary 

1146 

1147 >>> # demonstrate the treatment of the imaginary part of the diagonal 

1148 >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]]) 

1149 >>> a 

1150 array([[5.+2.j, 9.-2.j], 

1151 [0.+2.j, 2.-1.j]]) 

1152 >>> # with UPLO='L' this is numerically equivalent to using LA.eigvals() 

1153 >>> # with: 

1154 >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]]) 

1155 >>> b 

1156 array([[5.+0.j, 0.-2.j], 

1157 [0.+2.j, 2.+0.j]]) 

1158 >>> wa = LA.eigvalsh(a) 

1159 >>> wb = LA.eigvals(b) 

1160 >>> wa; wb 

1161 array([1., 6.]) 

1162 array([6.+0.j, 1.+0.j]) 

1163 

1164 """ 

1165 UPLO = UPLO.upper() 

1166 if UPLO not in ('L', 'U'): 

1167 raise ValueError("UPLO argument must be 'L' or 'U'") 

1168 

1169 extobj = get_linalg_error_extobj( 

1170 _raise_linalgerror_eigenvalues_nonconvergence) 

1171 if UPLO == 'L': 

1172 gufunc = _umath_linalg.eigvalsh_lo 

1173 else: 

1174 gufunc = _umath_linalg.eigvalsh_up 

1175 

1176 a, wrap = _makearray(a) 

1177 _assert_stacked_2d(a) 

1178 _assert_stacked_square(a) 

1179 t, result_t = _commonType(a) 

1180 signature = 'D->d' if isComplexType(t) else 'd->d' 

1181 w = gufunc(a, signature=signature, extobj=extobj) 

1182 return w.astype(_realType(result_t), copy=False) 

1183 

1184def _convertarray(a): 

1185 t, result_t = _commonType(a) 

1186 a = a.astype(t).T.copy() 

1187 return a, t, result_t 

1188 

1189 

1190# Eigenvectors 

1191 

1192 

1193@array_function_dispatch(_unary_dispatcher) 

1194def eig(a): 

1195 """ 

1196 Compute the eigenvalues and right eigenvectors of a square array. 

1197 

1198 Parameters 

1199 ---------- 

1200 a : (..., M, M) array 

1201 Matrices for which the eigenvalues and right eigenvectors will 

1202 be computed 

1203 

1204 Returns 

1205 ------- 

1206 A namedtuple with the following attributes: 

1207 

1208 eigenvalues : (..., M) array 

1209 The eigenvalues, each repeated according to its multiplicity. 

1210 The eigenvalues are not necessarily ordered. The resulting 

1211 array will be of complex type, unless the imaginary part is 

1212 zero in which case it will be cast to a real type. When `a` 

1213 is real the resulting eigenvalues will be real (0 imaginary 

1214 part) or occur in conjugate pairs 

1215 

1216 eigenvectors : (..., M, M) array 

1217 The normalized (unit "length") eigenvectors, such that the 

1218 column ``eigenvectors[:,i]`` is the eigenvector corresponding to the 

1219 eigenvalue ``eigenvalues[i]``. 

1220 

1221 Raises 

1222 ------ 

1223 LinAlgError 

1224 If the eigenvalue computation does not converge. 

1225 

1226 See Also 

1227 -------- 

1228 eigvals : eigenvalues of a non-symmetric array. 

1229 eigh : eigenvalues and eigenvectors of a real symmetric or complex 

1230 Hermitian (conjugate symmetric) array. 

1231 eigvalsh : eigenvalues of a real symmetric or complex Hermitian 

1232 (conjugate symmetric) array. 

1233 scipy.linalg.eig : Similar function in SciPy that also solves the 

1234 generalized eigenvalue problem. 

1235 scipy.linalg.schur : Best choice for unitary and other non-Hermitian 

1236 normal matrices. 

1237 

1238 Notes 

1239 ----- 

1240 

1241 .. versionadded:: 1.8.0 

1242 

1243 Broadcasting rules apply, see the `numpy.linalg` documentation for 

1244 details. 

1245 

1246 This is implemented using the ``_geev`` LAPACK routines which compute 

1247 the eigenvalues and eigenvectors of general square arrays. 

1248 

1249 The number `w` is an eigenvalue of `a` if there exists a vector `v` such 

1250 that ``a @ v = w * v``. Thus, the arrays `a`, `eigenvalues`, and 

1251 `eigenvectors` satisfy the equations ``a @ eigenvectors[:,i] = 

1252 eigenvalues[i] * eigenvalues[:,i]`` for :math:`i \\in \\{0,...,M-1\\}`. 

1253 

1254 The array `eigenvectors` may not be of maximum rank, that is, some of the 

1255 columns may be linearly dependent, although round-off error may obscure 

1256 that fact. If the eigenvalues are all different, then theoretically the 

1257 eigenvectors are linearly independent and `a` can be diagonalized by a 

1258 similarity transformation using `eigenvectors`, i.e, ``inv(eigenvectors) @ 

1259 a @ eigenvectors`` is diagonal. 

1260 

1261 For non-Hermitian normal matrices the SciPy function `scipy.linalg.schur` 

1262 is preferred because the matrix `eigenvectors` is guaranteed to be 

1263 unitary, which is not the case when using `eig`. The Schur factorization 

1264 produces an upper triangular matrix rather than a diagonal matrix, but for 

1265 normal matrices only the diagonal of the upper triangular matrix is 

1266 needed, the rest is roundoff error. 

1267 

1268 Finally, it is emphasized that `eigenvectors` consists of the *right* (as 

1269 in right-hand side) eigenvectors of `a`. A vector `y` satisfying ``y.T @ a 

1270 = z * y.T`` for some number `z` is called a *left* eigenvector of `a`, 

1271 and, in general, the left and right eigenvectors of a matrix are not 

1272 necessarily the (perhaps conjugate) transposes of each other. 

1273 

1274 References 

1275 ---------- 

1276 G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, FL, 

1277 Academic Press, Inc., 1980, Various pp. 

1278 

1279 Examples 

1280 -------- 

1281 >>> from numpy import linalg as LA 

1282 

1283 (Almost) trivial example with real eigenvalues and eigenvectors. 

1284 

1285 >>> eigenvalues, eigenvectors = LA.eig(np.diag((1, 2, 3))) 

1286 >>> eigenvalues 

1287 array([1., 2., 3.]) 

1288 >>> eigenvectors 

1289 array([[1., 0., 0.], 

1290 [0., 1., 0.], 

1291 [0., 0., 1.]]) 

1292 

1293 Real matrix possessing complex eigenvalues and eigenvectors; note that the 

1294 eigenvalues are complex conjugates of each other. 

1295 

1296 >>> eigenvalues, eigenvectors = LA.eig(np.array([[1, -1], [1, 1]])) 

1297 >>> eigenvalues 

1298 array([1.+1.j, 1.-1.j]) 

1299 >>> eigenvectors 

1300 array([[0.70710678+0.j , 0.70710678-0.j ], 

1301 [0. -0.70710678j, 0. +0.70710678j]]) 

1302 

1303 Complex-valued matrix with real eigenvalues (but complex-valued eigenvectors); 

1304 note that ``a.conj().T == a``, i.e., `a` is Hermitian. 

1305 

1306 >>> a = np.array([[1, 1j], [-1j, 1]]) 

1307 >>> eigenvalues, eigenvectors = LA.eig(a) 

1308 >>> eigenvalues 

1309 array([2.+0.j, 0.+0.j]) 

1310 >>> eigenvectors 

1311 array([[ 0. +0.70710678j, 0.70710678+0.j ], # may vary 

1312 [ 0.70710678+0.j , -0. +0.70710678j]]) 

1313 

1314 Be careful about round-off error! 

1315 

1316 >>> a = np.array([[1 + 1e-9, 0], [0, 1 - 1e-9]]) 

1317 >>> # Theor. eigenvalues are 1 +/- 1e-9 

1318 >>> eigenvalues, eigenvectors = LA.eig(a) 

1319 >>> eigenvalues 

1320 array([1., 1.]) 

1321 >>> eigenvectors 

1322 array([[1., 0.], 

1323 [0., 1.]]) 

1324 

1325 """ 

1326 a, wrap = _makearray(a) 

1327 _assert_stacked_2d(a) 

1328 _assert_stacked_square(a) 

1329 _assert_finite(a) 

1330 t, result_t = _commonType(a) 

1331 

1332 extobj = get_linalg_error_extobj( 

1333 _raise_linalgerror_eigenvalues_nonconvergence) 

1334 signature = 'D->DD' if isComplexType(t) else 'd->DD' 

1335 w, vt = _umath_linalg.eig(a, signature=signature, extobj=extobj) 

1336 

1337 if not isComplexType(t) and all(w.imag == 0.0): 

1338 w = w.real 

1339 vt = vt.real 

1340 result_t = _realType(result_t) 

1341 else: 

1342 result_t = _complexType(result_t) 

1343 

1344 vt = vt.astype(result_t, copy=False) 

1345 return EigResult(w.astype(result_t, copy=False), wrap(vt)) 

1346 

1347 

1348@array_function_dispatch(_eigvalsh_dispatcher) 

1349def eigh(a, UPLO='L'): 

1350 """ 

1351 Return the eigenvalues and eigenvectors of a complex Hermitian 

1352 (conjugate symmetric) or a real symmetric matrix. 

1353 

1354 Returns two objects, a 1-D array containing the eigenvalues of `a`, and 

1355 a 2-D square array or matrix (depending on the input type) of the 

1356 corresponding eigenvectors (in columns). 

1357 

1358 Parameters 

1359 ---------- 

1360 a : (..., M, M) array 

1361 Hermitian or real symmetric matrices whose eigenvalues and 

1362 eigenvectors are to be computed. 

1363 UPLO : {'L', 'U'}, optional 

1364 Specifies whether the calculation is done with the lower triangular 

1365 part of `a` ('L', default) or the upper triangular part ('U'). 

1366 Irrespective of this value only the real parts of the diagonal will 

1367 be considered in the computation to preserve the notion of a Hermitian 

1368 matrix. It therefore follows that the imaginary part of the diagonal 

1369 will always be treated as zero. 

1370 

1371 Returns 

1372 ------- 

1373 A namedtuple with the following attributes: 

1374 

1375 eigenvalues : (..., M) ndarray 

1376 The eigenvalues in ascending order, each repeated according to 

1377 its multiplicity. 

1378 eigenvectors : {(..., M, M) ndarray, (..., M, M) matrix} 

1379 The column ``eigenvectors[:, i]`` is the normalized eigenvector 

1380 corresponding to the eigenvalue ``eigenvalues[i]``. Will return a 

1381 matrix object if `a` is a matrix object. 

1382 

1383 Raises 

1384 ------ 

1385 LinAlgError 

1386 If the eigenvalue computation does not converge. 

1387 

1388 See Also 

1389 -------- 

1390 eigvalsh : eigenvalues of real symmetric or complex Hermitian 

1391 (conjugate symmetric) arrays. 

1392 eig : eigenvalues and right eigenvectors for non-symmetric arrays. 

1393 eigvals : eigenvalues of non-symmetric arrays. 

1394 scipy.linalg.eigh : Similar function in SciPy (but also solves the 

1395 generalized eigenvalue problem). 

1396 

1397 Notes 

1398 ----- 

1399 

1400 .. versionadded:: 1.8.0 

1401 

1402 Broadcasting rules apply, see the `numpy.linalg` documentation for 

1403 details. 

1404 

1405 The eigenvalues/eigenvectors are computed using LAPACK routines ``_syevd``, 

1406 ``_heevd``. 

1407 

1408 The eigenvalues of real symmetric or complex Hermitian matrices are always 

1409 real. [1]_ The array `eigenvalues` of (column) eigenvectors is unitary and 

1410 `a`, `eigenvalues`, and `eigenvectors` satisfy the equations ``dot(a, 

1411 eigenvectors[:, i]) = eigenvalues[i] * eigenvectors[:, i]``. 

1412 

1413 References 

1414 ---------- 

1415 .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, 

1416 FL, Academic Press, Inc., 1980, pg. 222. 

1417 

1418 Examples 

1419 -------- 

1420 >>> from numpy import linalg as LA 

1421 >>> a = np.array([[1, -2j], [2j, 5]]) 

1422 >>> a 

1423 array([[ 1.+0.j, -0.-2.j], 

1424 [ 0.+2.j, 5.+0.j]]) 

1425 >>> eigenvalues, eigenvectors = LA.eigh(a) 

1426 >>> eigenvalues 

1427 array([0.17157288, 5.82842712]) 

1428 >>> eigenvectors 

1429 array([[-0.92387953+0.j , -0.38268343+0.j ], # may vary 

1430 [ 0. +0.38268343j, 0. -0.92387953j]]) 

1431 

1432 >>> np.dot(a, eigenvectors[:, 0]) - eigenvalues[0] * eigenvectors[:, 0] # verify 1st eigenval/vec pair 

1433 array([5.55111512e-17+0.0000000e+00j, 0.00000000e+00+1.2490009e-16j]) 

1434 >>> np.dot(a, eigenvectors[:, 1]) - eigenvalues[1] * eigenvectors[:, 1] # verify 2nd eigenval/vec pair 

1435 array([0.+0.j, 0.+0.j]) 

1436 

1437 >>> A = np.matrix(a) # what happens if input is a matrix object 

1438 >>> A 

1439 matrix([[ 1.+0.j, -0.-2.j], 

1440 [ 0.+2.j, 5.+0.j]]) 

1441 >>> eigenvalues, eigenvectors = LA.eigh(A) 

1442 >>> eigenvalues 

1443 array([0.17157288, 5.82842712]) 

1444 >>> eigenvectors 

1445 matrix([[-0.92387953+0.j , -0.38268343+0.j ], # may vary 

1446 [ 0. +0.38268343j, 0. -0.92387953j]]) 

1447 

1448 >>> # demonstrate the treatment of the imaginary part of the diagonal 

1449 >>> a = np.array([[5+2j, 9-2j], [0+2j, 2-1j]]) 

1450 >>> a 

1451 array([[5.+2.j, 9.-2.j], 

1452 [0.+2.j, 2.-1.j]]) 

1453 >>> # with UPLO='L' this is numerically equivalent to using LA.eig() with: 

1454 >>> b = np.array([[5.+0.j, 0.-2.j], [0.+2.j, 2.-0.j]]) 

1455 >>> b 

1456 array([[5.+0.j, 0.-2.j], 

1457 [0.+2.j, 2.+0.j]]) 

1458 >>> wa, va = LA.eigh(a) 

1459 >>> wb, vb = LA.eig(b) 

1460 >>> wa; wb 

1461 array([1., 6.]) 

1462 array([6.+0.j, 1.+0.j]) 

1463 >>> va; vb 

1464 array([[-0.4472136 +0.j , -0.89442719+0.j ], # may vary 

1465 [ 0. +0.89442719j, 0. -0.4472136j ]]) 

1466 array([[ 0.89442719+0.j , -0. +0.4472136j], 

1467 [-0. +0.4472136j, 0.89442719+0.j ]]) 

1468 

1469 """ 

1470 UPLO = UPLO.upper() 

1471 if UPLO not in ('L', 'U'): 

1472 raise ValueError("UPLO argument must be 'L' or 'U'") 

1473 

1474 a, wrap = _makearray(a) 

1475 _assert_stacked_2d(a) 

1476 _assert_stacked_square(a) 

1477 t, result_t = _commonType(a) 

1478 

1479 extobj = get_linalg_error_extobj( 

1480 _raise_linalgerror_eigenvalues_nonconvergence) 

1481 if UPLO == 'L': 

1482 gufunc = _umath_linalg.eigh_lo 

1483 else: 

1484 gufunc = _umath_linalg.eigh_up 

1485 

1486 signature = 'D->dD' if isComplexType(t) else 'd->dd' 

1487 w, vt = gufunc(a, signature=signature, extobj=extobj) 

1488 w = w.astype(_realType(result_t), copy=False) 

1489 vt = vt.astype(result_t, copy=False) 

1490 return EighResult(w, wrap(vt)) 

1491 

1492 

1493# Singular value decomposition 

1494 

1495def _svd_dispatcher(a, full_matrices=None, compute_uv=None, hermitian=None): 

1496 return (a,) 

1497 

1498 

1499@array_function_dispatch(_svd_dispatcher) 

1500def svd(a, full_matrices=True, compute_uv=True, hermitian=False): 

1501 """ 

1502 Singular Value Decomposition. 

1503 

1504 When `a` is a 2D array, and ``full_matrices=False``, then it is 

1505 factorized as ``u @ np.diag(s) @ vh = (u * s) @ vh``, where 

1506 `u` and the Hermitian transpose of `vh` are 2D arrays with 

1507 orthonormal columns and `s` is a 1D array of `a`'s singular 

1508 values. When `a` is higher-dimensional, SVD is applied in 

1509 stacked mode as explained below. 

1510 

1511 Parameters 

1512 ---------- 

1513 a : (..., M, N) array_like 

1514 A real or complex array with ``a.ndim >= 2``. 

1515 full_matrices : bool, optional 

1516 If True (default), `u` and `vh` have the shapes ``(..., M, M)`` and 

1517 ``(..., N, N)``, respectively. Otherwise, the shapes are 

1518 ``(..., M, K)`` and ``(..., K, N)``, respectively, where 

1519 ``K = min(M, N)``. 

1520 compute_uv : bool, optional 

1521 Whether or not to compute `u` and `vh` in addition to `s`. True 

1522 by default. 

1523 hermitian : bool, optional 

1524 If True, `a` is assumed to be Hermitian (symmetric if real-valued), 

1525 enabling a more efficient method for finding singular values. 

1526 Defaults to False. 

1527 

1528 .. versionadded:: 1.17.0 

1529 

1530 Returns 

1531 ------- 

1532 When `compute_uv` is True, the result is a namedtuple with the following 

1533 attribute names: 

1534 

1535 U : { (..., M, M), (..., M, K) } array 

1536 Unitary array(s). The first ``a.ndim - 2`` dimensions have the same 

1537 size as those of the input `a`. The size of the last two dimensions 

1538 depends on the value of `full_matrices`. Only returned when 

1539 `compute_uv` is True. 

1540 S : (..., K) array 

1541 Vector(s) with the singular values, within each vector sorted in 

1542 descending order. The first ``a.ndim - 2`` dimensions have the same 

1543 size as those of the input `a`. 

1544 Vh : { (..., N, N), (..., K, N) } array 

1545 Unitary array(s). The first ``a.ndim - 2`` dimensions have the same 

1546 size as those of the input `a`. The size of the last two dimensions 

1547 depends on the value of `full_matrices`. Only returned when 

1548 `compute_uv` is True. 

1549 

1550 Raises 

1551 ------ 

1552 LinAlgError 

1553 If SVD computation does not converge. 

1554 

1555 See Also 

1556 -------- 

1557 scipy.linalg.svd : Similar function in SciPy. 

1558 scipy.linalg.svdvals : Compute singular values of a matrix. 

1559 

1560 Notes 

1561 ----- 

1562 

1563 .. versionchanged:: 1.8.0 

1564 Broadcasting rules apply, see the `numpy.linalg` documentation for 

1565 details. 

1566 

1567 The decomposition is performed using LAPACK routine ``_gesdd``. 

1568 

1569 SVD is usually described for the factorization of a 2D matrix :math:`A`. 

1570 The higher-dimensional case will be discussed below. In the 2D case, SVD is 

1571 written as :math:`A = U S V^H`, where :math:`A = a`, :math:`U= u`, 

1572 :math:`S= \\mathtt{np.diag}(s)` and :math:`V^H = vh`. The 1D array `s` 

1573 contains the singular values of `a` and `u` and `vh` are unitary. The rows 

1574 of `vh` are the eigenvectors of :math:`A^H A` and the columns of `u` are 

1575 the eigenvectors of :math:`A A^H`. In both cases the corresponding 

1576 (possibly non-zero) eigenvalues are given by ``s**2``. 

1577 

1578 If `a` has more than two dimensions, then broadcasting rules apply, as 

1579 explained in :ref:`routines.linalg-broadcasting`. This means that SVD is 

1580 working in "stacked" mode: it iterates over all indices of the first 

1581 ``a.ndim - 2`` dimensions and for each combination SVD is applied to the 

1582 last two indices. The matrix `a` can be reconstructed from the 

1583 decomposition with either ``(u * s[..., None, :]) @ vh`` or 

1584 ``u @ (s[..., None] * vh)``. (The ``@`` operator can be replaced by the 

1585 function ``np.matmul`` for python versions below 3.5.) 

1586 

1587 If `a` is a ``matrix`` object (as opposed to an ``ndarray``), then so are 

1588 all the return values. 

1589 

1590 Examples 

1591 -------- 

1592 >>> a = np.random.randn(9, 6) + 1j*np.random.randn(9, 6) 

1593 >>> b = np.random.randn(2, 7, 8, 3) + 1j*np.random.randn(2, 7, 8, 3) 

1594 

1595 Reconstruction based on full SVD, 2D case: 

1596 

1597 >>> U, S, Vh = np.linalg.svd(a, full_matrices=True) 

1598 >>> U.shape, S.shape, Vh.shape 

1599 ((9, 9), (6,), (6, 6)) 

1600 >>> np.allclose(a, np.dot(U[:, :6] * S, Vh)) 

1601 True 

1602 >>> smat = np.zeros((9, 6), dtype=complex) 

1603 >>> smat[:6, :6] = np.diag(S) 

1604 >>> np.allclose(a, np.dot(U, np.dot(smat, Vh))) 

1605 True 

1606 

1607 Reconstruction based on reduced SVD, 2D case: 

1608 

1609 >>> U, S, Vh = np.linalg.svd(a, full_matrices=False) 

1610 >>> U.shape, S.shape, Vh.shape 

1611 ((9, 6), (6,), (6, 6)) 

1612 >>> np.allclose(a, np.dot(U * S, Vh)) 

1613 True 

1614 >>> smat = np.diag(S) 

1615 >>> np.allclose(a, np.dot(U, np.dot(smat, Vh))) 

1616 True 

1617 

1618 Reconstruction based on full SVD, 4D case: 

1619 

1620 >>> U, S, Vh = np.linalg.svd(b, full_matrices=True) 

1621 >>> U.shape, S.shape, Vh.shape 

1622 ((2, 7, 8, 8), (2, 7, 3), (2, 7, 3, 3)) 

1623 >>> np.allclose(b, np.matmul(U[..., :3] * S[..., None, :], Vh)) 

1624 True 

1625 >>> np.allclose(b, np.matmul(U[..., :3], S[..., None] * Vh)) 

1626 True 

1627 

1628 Reconstruction based on reduced SVD, 4D case: 

1629 

1630 >>> U, S, Vh = np.linalg.svd(b, full_matrices=False) 

1631 >>> U.shape, S.shape, Vh.shape 

1632 ((2, 7, 8, 3), (2, 7, 3), (2, 7, 3, 3)) 

1633 >>> np.allclose(b, np.matmul(U * S[..., None, :], Vh)) 

1634 True 

1635 >>> np.allclose(b, np.matmul(U, S[..., None] * Vh)) 

1636 True 

1637 

1638 """ 

1639 import numpy as _nx 

1640 a, wrap = _makearray(a) 

1641 

1642 if hermitian: 

1643 # note: lapack svd returns eigenvalues with s ** 2 sorted descending, 

1644 # but eig returns s sorted ascending, so we re-order the eigenvalues 

1645 # and related arrays to have the correct order 

1646 if compute_uv: 

1647 s, u = eigh(a) 

1648 sgn = sign(s) 

1649 s = abs(s) 

1650 sidx = argsort(s)[..., ::-1] 

1651 sgn = _nx.take_along_axis(sgn, sidx, axis=-1) 

1652 s = _nx.take_along_axis(s, sidx, axis=-1) 

1653 u = _nx.take_along_axis(u, sidx[..., None, :], axis=-1) 

1654 # singular values are unsigned, move the sign into v 

1655 vt = transpose(u * sgn[..., None, :]).conjugate() 

1656 return SVDResult(wrap(u), s, wrap(vt)) 

1657 else: 

1658 s = eigvalsh(a) 

1659 s = abs(s) 

1660 return sort(s)[..., ::-1] 

1661 

1662 _assert_stacked_2d(a) 

1663 t, result_t = _commonType(a) 

1664 

1665 extobj = get_linalg_error_extobj(_raise_linalgerror_svd_nonconvergence) 

1666 

1667 m, n = a.shape[-2:] 

1668 if compute_uv: 

1669 if full_matrices: 

1670 if m < n: 

1671 gufunc = _umath_linalg.svd_m_f 

1672 else: 

1673 gufunc = _umath_linalg.svd_n_f 

1674 else: 

1675 if m < n: 

1676 gufunc = _umath_linalg.svd_m_s 

1677 else: 

1678 gufunc = _umath_linalg.svd_n_s 

1679 

1680 signature = 'D->DdD' if isComplexType(t) else 'd->ddd' 

1681 u, s, vh = gufunc(a, signature=signature, extobj=extobj) 

1682 u = u.astype(result_t, copy=False) 

1683 s = s.astype(_realType(result_t), copy=False) 

1684 vh = vh.astype(result_t, copy=False) 

1685 return SVDResult(wrap(u), s, wrap(vh)) 

1686 else: 

1687 if m < n: 

1688 gufunc = _umath_linalg.svd_m 

1689 else: 

1690 gufunc = _umath_linalg.svd_n 

1691 

1692 signature = 'D->d' if isComplexType(t) else 'd->d' 

1693 s = gufunc(a, signature=signature, extobj=extobj) 

1694 s = s.astype(_realType(result_t), copy=False) 

1695 return s 

1696 

1697 

1698def _cond_dispatcher(x, p=None): 

1699 return (x,) 

1700 

1701 

1702@array_function_dispatch(_cond_dispatcher) 

1703def cond(x, p=None): 

1704 """ 

1705 Compute the condition number of a matrix. 

1706 

1707 This function is capable of returning the condition number using 

1708 one of seven different norms, depending on the value of `p` (see 

1709 Parameters below). 

1710 

1711 Parameters 

1712 ---------- 

1713 x : (..., M, N) array_like 

1714 The matrix whose condition number is sought. 

1715 p : {None, 1, -1, 2, -2, inf, -inf, 'fro'}, optional 

1716 Order of the norm used in the condition number computation: 

1717 

1718 ===== ============================ 

1719 p norm for matrices 

1720 ===== ============================ 

1721 None 2-norm, computed directly using the ``SVD`` 

1722 'fro' Frobenius norm 

1723 inf max(sum(abs(x), axis=1)) 

1724 -inf min(sum(abs(x), axis=1)) 

1725 1 max(sum(abs(x), axis=0)) 

1726 -1 min(sum(abs(x), axis=0)) 

1727 2 2-norm (largest sing. value) 

1728 -2 smallest singular value 

1729 ===== ============================ 

1730 

1731 inf means the `numpy.inf` object, and the Frobenius norm is 

1732 the root-of-sum-of-squares norm. 

1733 

1734 Returns 

1735 ------- 

1736 c : {float, inf} 

1737 The condition number of the matrix. May be infinite. 

1738 

1739 See Also 

1740 -------- 

1741 numpy.linalg.norm 

1742 

1743 Notes 

1744 ----- 

1745 The condition number of `x` is defined as the norm of `x` times the 

1746 norm of the inverse of `x` [1]_; the norm can be the usual L2-norm 

1747 (root-of-sum-of-squares) or one of a number of other matrix norms. 

1748 

1749 References 

1750 ---------- 

1751 .. [1] G. Strang, *Linear Algebra and Its Applications*, Orlando, FL, 

1752 Academic Press, Inc., 1980, pg. 285. 

1753 

1754 Examples 

1755 -------- 

1756 >>> from numpy import linalg as LA 

1757 >>> a = np.array([[1, 0, -1], [0, 1, 0], [1, 0, 1]]) 

1758 >>> a 

1759 array([[ 1, 0, -1], 

1760 [ 0, 1, 0], 

1761 [ 1, 0, 1]]) 

1762 >>> LA.cond(a) 

1763 1.4142135623730951 

1764 >>> LA.cond(a, 'fro') 

1765 3.1622776601683795 

1766 >>> LA.cond(a, np.inf) 

1767 2.0 

1768 >>> LA.cond(a, -np.inf) 

1769 1.0 

1770 >>> LA.cond(a, 1) 

1771 2.0 

1772 >>> LA.cond(a, -1) 

1773 1.0 

1774 >>> LA.cond(a, 2) 

1775 1.4142135623730951 

1776 >>> LA.cond(a, -2) 

1777 0.70710678118654746 # may vary 

1778 >>> min(LA.svd(a, compute_uv=False))*min(LA.svd(LA.inv(a), compute_uv=False)) 

1779 0.70710678118654746 # may vary 

1780 

1781 """ 

1782 x = asarray(x) # in case we have a matrix 

1783 if _is_empty_2d(x): 

1784 raise LinAlgError("cond is not defined on empty arrays") 

1785 if p is None or p == 2 or p == -2: 

1786 s = svd(x, compute_uv=False) 

1787 with errstate(all='ignore'): 

1788 if p == -2: 

1789 r = s[..., -1] / s[..., 0] 

1790 else: 

1791 r = s[..., 0] / s[..., -1] 

1792 else: 

1793 # Call inv(x) ignoring errors. The result array will 

1794 # contain nans in the entries where inversion failed. 

1795 _assert_stacked_2d(x) 

1796 _assert_stacked_square(x) 

1797 t, result_t = _commonType(x) 

1798 signature = 'D->D' if isComplexType(t) else 'd->d' 

1799 with errstate(all='ignore'): 

1800 invx = _umath_linalg.inv(x, signature=signature) 

1801 r = norm(x, p, axis=(-2, -1)) * norm(invx, p, axis=(-2, -1)) 

1802 r = r.astype(result_t, copy=False) 

1803 

1804 # Convert nans to infs unless the original array had nan entries 

1805 r = asarray(r) 

1806 nan_mask = isnan(r) 

1807 if nan_mask.any(): 

1808 nan_mask &= ~isnan(x).any(axis=(-2, -1)) 

1809 if r.ndim > 0: 

1810 r[nan_mask] = Inf 

1811 elif nan_mask: 

1812 r[()] = Inf 

1813 

1814 # Convention is to return scalars instead of 0d arrays 

1815 if r.ndim == 0: 

1816 r = r[()] 

1817 

1818 return r 

1819 

1820 

1821def _matrix_rank_dispatcher(A, tol=None, hermitian=None): 

1822 return (A,) 

1823 

1824 

1825@array_function_dispatch(_matrix_rank_dispatcher) 

1826def matrix_rank(A, tol=None, hermitian=False): 

1827 """ 

1828 Return matrix rank of array using SVD method 

1829 

1830 Rank of the array is the number of singular values of the array that are 

1831 greater than `tol`. 

1832 

1833 .. versionchanged:: 1.14 

1834 Can now operate on stacks of matrices 

1835 

1836 Parameters 

1837 ---------- 

1838 A : {(M,), (..., M, N)} array_like 

1839 Input vector or stack of matrices. 

1840 tol : (...) array_like, float, optional 

1841 Threshold below which SVD values are considered zero. If `tol` is 

1842 None, and ``S`` is an array with singular values for `M`, and 

1843 ``eps`` is the epsilon value for datatype of ``S``, then `tol` is 

1844 set to ``S.max() * max(M, N) * eps``. 

1845 

1846 .. versionchanged:: 1.14 

1847 Broadcasted against the stack of matrices 

1848 hermitian : bool, optional 

1849 If True, `A` is assumed to be Hermitian (symmetric if real-valued), 

1850 enabling a more efficient method for finding singular values. 

1851 Defaults to False. 

1852 

1853 .. versionadded:: 1.14 

1854 

1855 Returns 

1856 ------- 

1857 rank : (...) array_like 

1858 Rank of A. 

1859 

1860 Notes 

1861 ----- 

1862 The default threshold to detect rank deficiency is a test on the magnitude 

1863 of the singular values of `A`. By default, we identify singular values less 

1864 than ``S.max() * max(M, N) * eps`` as indicating rank deficiency (with 

1865 the symbols defined above). This is the algorithm MATLAB uses [1]. It also 

1866 appears in *Numerical recipes* in the discussion of SVD solutions for linear 

1867 least squares [2]. 

1868 

1869 This default threshold is designed to detect rank deficiency accounting for 

1870 the numerical errors of the SVD computation. Imagine that there is a column 

1871 in `A` that is an exact (in floating point) linear combination of other 

1872 columns in `A`. Computing the SVD on `A` will not produce a singular value 

1873 exactly equal to 0 in general: any difference of the smallest SVD value from 

1874 0 will be caused by numerical imprecision in the calculation of the SVD. 

1875 Our threshold for small SVD values takes this numerical imprecision into 

1876 account, and the default threshold will detect such numerical rank 

1877 deficiency. The threshold may declare a matrix `A` rank deficient even if 

1878 the linear combination of some columns of `A` is not exactly equal to 

1879 another column of `A` but only numerically very close to another column of 

1880 `A`. 

1881 

1882 We chose our default threshold because it is in wide use. Other thresholds 

1883 are possible. For example, elsewhere in the 2007 edition of *Numerical 

1884 recipes* there is an alternative threshold of ``S.max() * 

1885 np.finfo(A.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe 

1886 this threshold as being based on "expected roundoff error" (p 71). 

1887 

1888 The thresholds above deal with floating point roundoff error in the 

1889 calculation of the SVD. However, you may have more information about the 

1890 sources of error in `A` that would make you consider other tolerance values 

1891 to detect *effective* rank deficiency. The most useful measure of the 

1892 tolerance depends on the operations you intend to use on your matrix. For 

1893 example, if your data come from uncertain measurements with uncertainties 

1894 greater than floating point epsilon, choosing a tolerance near that 

1895 uncertainty may be preferable. The tolerance may be absolute if the 

1896 uncertainties are absolute rather than relative. 

1897 

1898 References 

1899 ---------- 

1900 .. [1] MATLAB reference documentation, "Rank" 

1901 https://www.mathworks.com/help/techdoc/ref/rank.html 

1902 .. [2] W. H. Press, S. A. Teukolsky, W. T. Vetterling and B. P. Flannery, 

1903 "Numerical Recipes (3rd edition)", Cambridge University Press, 2007, 

1904 page 795. 

1905 

1906 Examples 

1907 -------- 

1908 >>> from numpy.linalg import matrix_rank 

1909 >>> matrix_rank(np.eye(4)) # Full rank matrix 

1910 4 

1911 >>> I=np.eye(4); I[-1,-1] = 0. # rank deficient matrix 

1912 >>> matrix_rank(I) 

1913 3 

1914 >>> matrix_rank(np.ones((4,))) # 1 dimension - rank 1 unless all 0 

1915 1 

1916 >>> matrix_rank(np.zeros((4,))) 

1917 0 

1918 """ 

1919 A = asarray(A) 

1920 if A.ndim < 2: 

1921 return int(not all(A==0)) 

1922 S = svd(A, compute_uv=False, hermitian=hermitian) 

1923 if tol is None: 

1924 tol = S.max(axis=-1, keepdims=True) * max(A.shape[-2:]) * finfo(S.dtype).eps 

1925 else: 

1926 tol = asarray(tol)[..., newaxis] 

1927 return count_nonzero(S > tol, axis=-1) 

1928 

1929 

1930# Generalized inverse 

1931 

1932def _pinv_dispatcher(a, rcond=None, hermitian=None): 

1933 return (a,) 

1934 

1935 

1936@array_function_dispatch(_pinv_dispatcher) 

1937def pinv(a, rcond=1e-15, hermitian=False): 

1938 """ 

1939 Compute the (Moore-Penrose) pseudo-inverse of a matrix. 

1940 

1941 Calculate the generalized inverse of a matrix using its 

1942 singular-value decomposition (SVD) and including all 

1943 *large* singular values. 

1944 

1945 .. versionchanged:: 1.14 

1946 Can now operate on stacks of matrices 

1947 

1948 Parameters 

1949 ---------- 

1950 a : (..., M, N) array_like 

1951 Matrix or stack of matrices to be pseudo-inverted. 

1952 rcond : (...) array_like of float 

1953 Cutoff for small singular values. 

1954 Singular values less than or equal to 

1955 ``rcond * largest_singular_value`` are set to zero. 

1956 Broadcasts against the stack of matrices. 

1957 hermitian : bool, optional 

1958 If True, `a` is assumed to be Hermitian (symmetric if real-valued), 

1959 enabling a more efficient method for finding singular values. 

1960 Defaults to False. 

1961 

1962 .. versionadded:: 1.17.0 

1963 

1964 Returns 

1965 ------- 

1966 B : (..., N, M) ndarray 

1967 The pseudo-inverse of `a`. If `a` is a `matrix` instance, then so 

1968 is `B`. 

1969 

1970 Raises 

1971 ------ 

1972 LinAlgError 

1973 If the SVD computation does not converge. 

1974 

1975 See Also 

1976 -------- 

1977 scipy.linalg.pinv : Similar function in SciPy. 

1978 scipy.linalg.pinvh : Compute the (Moore-Penrose) pseudo-inverse of a 

1979 Hermitian matrix. 

1980 

1981 Notes 

1982 ----- 

1983 The pseudo-inverse of a matrix A, denoted :math:`A^+`, is 

1984 defined as: "the matrix that 'solves' [the least-squares problem] 

1985 :math:`Ax = b`," i.e., if :math:`\\bar{x}` is said solution, then 

1986 :math:`A^+` is that matrix such that :math:`\\bar{x} = A^+b`. 

1987 

1988 It can be shown that if :math:`Q_1 \\Sigma Q_2^T = A` is the singular 

1989 value decomposition of A, then 

1990 :math:`A^+ = Q_2 \\Sigma^+ Q_1^T`, where :math:`Q_{1,2}` are 

1991 orthogonal matrices, :math:`\\Sigma` is a diagonal matrix consisting 

1992 of A's so-called singular values, (followed, typically, by 

1993 zeros), and then :math:`\\Sigma^+` is simply the diagonal matrix 

1994 consisting of the reciprocals of A's singular values 

1995 (again, followed by zeros). [1]_ 

1996 

1997 References 

1998 ---------- 

1999 .. [1] G. Strang, *Linear Algebra and Its Applications*, 2nd Ed., Orlando, 

2000 FL, Academic Press, Inc., 1980, pp. 139-142. 

2001 

2002 Examples 

2003 -------- 

2004 The following example checks that ``a * a+ * a == a`` and 

2005 ``a+ * a * a+ == a+``: 

2006 

2007 >>> a = np.random.randn(9, 6) 

2008 >>> B = np.linalg.pinv(a) 

2009 >>> np.allclose(a, np.dot(a, np.dot(B, a))) 

2010 True 

2011 >>> np.allclose(B, np.dot(B, np.dot(a, B))) 

2012 True 

2013 

2014 """ 

2015 a, wrap = _makearray(a) 

2016 rcond = asarray(rcond) 

2017 if _is_empty_2d(a): 

2018 m, n = a.shape[-2:] 

2019 res = empty(a.shape[:-2] + (n, m), dtype=a.dtype) 

2020 return wrap(res) 

2021 a = a.conjugate() 

2022 u, s, vt = svd(a, full_matrices=False, hermitian=hermitian) 

2023 

2024 # discard small singular values 

2025 cutoff = rcond[..., newaxis] * amax(s, axis=-1, keepdims=True) 

2026 large = s > cutoff 

2027 s = divide(1, s, where=large, out=s) 

2028 s[~large] = 0 

2029 

2030 res = matmul(transpose(vt), multiply(s[..., newaxis], transpose(u))) 

2031 return wrap(res) 

2032 

2033 

2034# Determinant 

2035 

2036 

2037@array_function_dispatch(_unary_dispatcher) 

2038def slogdet(a): 

2039 """ 

2040 Compute the sign and (natural) logarithm of the determinant of an array. 

2041 

2042 If an array has a very small or very large determinant, then a call to 

2043 `det` may overflow or underflow. This routine is more robust against such 

2044 issues, because it computes the logarithm of the determinant rather than 

2045 the determinant itself. 

2046 

2047 Parameters 

2048 ---------- 

2049 a : (..., M, M) array_like 

2050 Input array, has to be a square 2-D array. 

2051 

2052 Returns 

2053 ------- 

2054 A namedtuple with the following attributes: 

2055 

2056 sign : (...) array_like 

2057 A number representing the sign of the determinant. For a real matrix, 

2058 this is 1, 0, or -1. For a complex matrix, this is a complex number 

2059 with absolute value 1 (i.e., it is on the unit circle), or else 0. 

2060 logabsdet : (...) array_like 

2061 The natural log of the absolute value of the determinant. 

2062 

2063 If the determinant is zero, then `sign` will be 0 and `logabsdet` will be 

2064 -Inf. In all cases, the determinant is equal to ``sign * np.exp(logabsdet)``. 

2065 

2066 See Also 

2067 -------- 

2068 det 

2069 

2070 Notes 

2071 ----- 

2072 

2073 .. versionadded:: 1.8.0 

2074 

2075 Broadcasting rules apply, see the `numpy.linalg` documentation for 

2076 details. 

2077 

2078 .. versionadded:: 1.6.0 

2079 

2080 The determinant is computed via LU factorization using the LAPACK 

2081 routine ``z/dgetrf``. 

2082 

2083 

2084 Examples 

2085 -------- 

2086 The determinant of a 2-D array ``[[a, b], [c, d]]`` is ``ad - bc``: 

2087 

2088 >>> a = np.array([[1, 2], [3, 4]]) 

2089 >>> (sign, logabsdet) = np.linalg.slogdet(a) 

2090 >>> (sign, logabsdet) 

2091 (-1, 0.69314718055994529) # may vary 

2092 >>> sign * np.exp(logabsdet) 

2093 -2.0 

2094 

2095 Computing log-determinants for a stack of matrices: 

2096 

2097 >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ]) 

2098 >>> a.shape 

2099 (3, 2, 2) 

2100 >>> sign, logabsdet = np.linalg.slogdet(a) 

2101 >>> (sign, logabsdet) 

2102 (array([-1., -1., -1.]), array([ 0.69314718, 1.09861229, 2.07944154])) 

2103 >>> sign * np.exp(logabsdet) 

2104 array([-2., -3., -8.]) 

2105 

2106 This routine succeeds where ordinary `det` does not: 

2107 

2108 >>> np.linalg.det(np.eye(500) * 0.1) 

2109 0.0 

2110 >>> np.linalg.slogdet(np.eye(500) * 0.1) 

2111 (1, -1151.2925464970228) 

2112 

2113 """ 

2114 a = asarray(a) 

2115 _assert_stacked_2d(a) 

2116 _assert_stacked_square(a) 

2117 t, result_t = _commonType(a) 

2118 real_t = _realType(result_t) 

2119 signature = 'D->Dd' if isComplexType(t) else 'd->dd' 

2120 sign, logdet = _umath_linalg.slogdet(a, signature=signature) 

2121 sign = sign.astype(result_t, copy=False) 

2122 logdet = logdet.astype(real_t, copy=False) 

2123 return SlogdetResult(sign, logdet) 

2124 

2125 

2126@array_function_dispatch(_unary_dispatcher) 

2127def det(a): 

2128 """ 

2129 Compute the determinant of an array. 

2130 

2131 Parameters 

2132 ---------- 

2133 a : (..., M, M) array_like 

2134 Input array to compute determinants for. 

2135 

2136 Returns 

2137 ------- 

2138 det : (...) array_like 

2139 Determinant of `a`. 

2140 

2141 See Also 

2142 -------- 

2143 slogdet : Another way to represent the determinant, more suitable 

2144 for large matrices where underflow/overflow may occur. 

2145 scipy.linalg.det : Similar function in SciPy. 

2146 

2147 Notes 

2148 ----- 

2149 

2150 .. versionadded:: 1.8.0 

2151 

2152 Broadcasting rules apply, see the `numpy.linalg` documentation for 

2153 details. 

2154 

2155 The determinant is computed via LU factorization using the LAPACK 

2156 routine ``z/dgetrf``. 

2157 

2158 Examples 

2159 -------- 

2160 The determinant of a 2-D array [[a, b], [c, d]] is ad - bc: 

2161 

2162 >>> a = np.array([[1, 2], [3, 4]]) 

2163 >>> np.linalg.det(a) 

2164 -2.0 # may vary 

2165 

2166 Computing determinants for a stack of matrices: 

2167 

2168 >>> a = np.array([ [[1, 2], [3, 4]], [[1, 2], [2, 1]], [[1, 3], [3, 1]] ]) 

2169 >>> a.shape 

2170 (3, 2, 2) 

2171 >>> np.linalg.det(a) 

2172 array([-2., -3., -8.]) 

2173 

2174 """ 

2175 a = asarray(a) 

2176 _assert_stacked_2d(a) 

2177 _assert_stacked_square(a) 

2178 t, result_t = _commonType(a) 

2179 signature = 'D->D' if isComplexType(t) else 'd->d' 

2180 r = _umath_linalg.det(a, signature=signature) 

2181 r = r.astype(result_t, copy=False) 

2182 return r 

2183 

2184 

2185# Linear Least Squares 

2186 

2187def _lstsq_dispatcher(a, b, rcond=None): 

2188 return (a, b) 

2189 

2190 

2191@array_function_dispatch(_lstsq_dispatcher) 

2192def lstsq(a, b, rcond="warn"): 

2193 r""" 

2194 Return the least-squares solution to a linear matrix equation. 

2195 

2196 Computes the vector `x` that approximately solves the equation 

2197 ``a @ x = b``. The equation may be under-, well-, or over-determined 

2198 (i.e., the number of linearly independent rows of `a` can be less than, 

2199 equal to, or greater than its number of linearly independent columns). 

2200 If `a` is square and of full rank, then `x` (but for round-off error) 

2201 is the "exact" solution of the equation. Else, `x` minimizes the 

2202 Euclidean 2-norm :math:`||b - ax||`. If there are multiple minimizing 

2203 solutions, the one with the smallest 2-norm :math:`||x||` is returned. 

2204 

2205 Parameters 

2206 ---------- 

2207 a : (M, N) array_like 

2208 "Coefficient" matrix. 

2209 b : {(M,), (M, K)} array_like 

2210 Ordinate or "dependent variable" values. If `b` is two-dimensional, 

2211 the least-squares solution is calculated for each of the `K` columns 

2212 of `b`. 

2213 rcond : float, optional 

2214 Cut-off ratio for small singular values of `a`. 

2215 For the purposes of rank determination, singular values are treated 

2216 as zero if they are smaller than `rcond` times the largest singular 

2217 value of `a`. 

2218 

2219 .. versionchanged:: 1.14.0 

2220 If not set, a FutureWarning is given. The previous default 

2221 of ``-1`` will use the machine precision as `rcond` parameter, 

2222 the new default will use the machine precision times `max(M, N)`. 

2223 To silence the warning and use the new default, use ``rcond=None``, 

2224 to keep using the old behavior, use ``rcond=-1``. 

2225 

2226 Returns 

2227 ------- 

2228 x : {(N,), (N, K)} ndarray 

2229 Least-squares solution. If `b` is two-dimensional, 

2230 the solutions are in the `K` columns of `x`. 

2231 residuals : {(1,), (K,), (0,)} ndarray 

2232 Sums of squared residuals: Squared Euclidean 2-norm for each column in 

2233 ``b - a @ x``. 

2234 If the rank of `a` is < N or M <= N, this is an empty array. 

2235 If `b` is 1-dimensional, this is a (1,) shape array. 

2236 Otherwise the shape is (K,). 

2237 rank : int 

2238 Rank of matrix `a`. 

2239 s : (min(M, N),) ndarray 

2240 Singular values of `a`. 

2241 

2242 Raises 

2243 ------ 

2244 LinAlgError 

2245 If computation does not converge. 

2246 

2247 See Also 

2248 -------- 

2249 scipy.linalg.lstsq : Similar function in SciPy. 

2250 

2251 Notes 

2252 ----- 

2253 If `b` is a matrix, then all array results are returned as matrices. 

2254 

2255 Examples 

2256 -------- 

2257 Fit a line, ``y = mx + c``, through some noisy data-points: 

2258 

2259 >>> x = np.array([0, 1, 2, 3]) 

2260 >>> y = np.array([-1, 0.2, 0.9, 2.1]) 

2261 

2262 By examining the coefficients, we see that the line should have a 

2263 gradient of roughly 1 and cut the y-axis at, more or less, -1. 

2264 

2265 We can rewrite the line equation as ``y = Ap``, where ``A = [[x 1]]`` 

2266 and ``p = [[m], [c]]``. Now use `lstsq` to solve for `p`: 

2267 

2268 >>> A = np.vstack([x, np.ones(len(x))]).T 

2269 >>> A 

2270 array([[ 0., 1.], 

2271 [ 1., 1.], 

2272 [ 2., 1.], 

2273 [ 3., 1.]]) 

2274 

2275 >>> m, c = np.linalg.lstsq(A, y, rcond=None)[0] 

2276 >>> m, c 

2277 (1.0 -0.95) # may vary 

2278 

2279 Plot the data along with the fitted line: 

2280 

2281 >>> import matplotlib.pyplot as plt 

2282 >>> _ = plt.plot(x, y, 'o', label='Original data', markersize=10) 

2283 >>> _ = plt.plot(x, m*x + c, 'r', label='Fitted line') 

2284 >>> _ = plt.legend() 

2285 >>> plt.show() 

2286 

2287 """ 

2288 a, _ = _makearray(a) 

2289 b, wrap = _makearray(b) 

2290 is_1d = b.ndim == 1 

2291 if is_1d: 

2292 b = b[:, newaxis] 

2293 _assert_2d(a, b) 

2294 m, n = a.shape[-2:] 

2295 m2, n_rhs = b.shape[-2:] 

2296 if m != m2: 

2297 raise LinAlgError('Incompatible dimensions') 

2298 

2299 t, result_t = _commonType(a, b) 

2300 result_real_t = _realType(result_t) 

2301 

2302 # Determine default rcond value 

2303 if rcond == "warn": 

2304 # 2017-08-19, 1.14.0 

2305 warnings.warn("`rcond` parameter will change to the default of " 

2306 "machine precision times ``max(M, N)`` where M and N " 

2307 "are the input matrix dimensions.\n" 

2308 "To use the future default and silence this warning " 

2309 "we advise to pass `rcond=None`, to keep using the old, " 

2310 "explicitly pass `rcond=-1`.", 

2311 FutureWarning, stacklevel=2) 

2312 rcond = -1 

2313 if rcond is None: 

2314 rcond = finfo(t).eps * max(n, m) 

2315 

2316 if m <= n: 

2317 gufunc = _umath_linalg.lstsq_m 

2318 else: 

2319 gufunc = _umath_linalg.lstsq_n 

2320 

2321 signature = 'DDd->Ddid' if isComplexType(t) else 'ddd->ddid' 

2322 extobj = get_linalg_error_extobj(_raise_linalgerror_lstsq) 

2323 if n_rhs == 0: 

2324 # lapack can't handle n_rhs = 0 - so allocate the array one larger in that axis 

2325 b = zeros(b.shape[:-2] + (m, n_rhs + 1), dtype=b.dtype) 

2326 x, resids, rank, s = gufunc(a, b, rcond, signature=signature, extobj=extobj) 

2327 if m == 0: 

2328 x[...] = 0 

2329 if n_rhs == 0: 

2330 # remove the item we added 

2331 x = x[..., :n_rhs] 

2332 resids = resids[..., :n_rhs] 

2333 

2334 # remove the axis we added 

2335 if is_1d: 

2336 x = x.squeeze(axis=-1) 

2337 # we probably should squeeze resids too, but we can't 

2338 # without breaking compatibility. 

2339 

2340 # as documented 

2341 if rank != n or m <= n: 

2342 resids = array([], result_real_t) 

2343 

2344 # coerce output arrays 

2345 s = s.astype(result_real_t, copy=False) 

2346 resids = resids.astype(result_real_t, copy=False) 

2347 x = x.astype(result_t, copy=True) # Copying lets the memory in r_parts be freed 

2348 return wrap(x), wrap(resids), rank, s 

2349 

2350 

2351def _multi_svd_norm(x, row_axis, col_axis, op): 

2352 """Compute a function of the singular values of the 2-D matrices in `x`. 

2353 

2354 This is a private utility function used by `numpy.linalg.norm()`. 

2355 

2356 Parameters 

2357 ---------- 

2358 x : ndarray 

2359 row_axis, col_axis : int 

2360 The axes of `x` that hold the 2-D matrices. 

2361 op : callable 

2362 This should be either numpy.amin or `numpy.amax` or `numpy.sum`. 

2363 

2364 Returns 

2365 ------- 

2366 result : float or ndarray 

2367 If `x` is 2-D, the return values is a float. 

2368 Otherwise, it is an array with ``x.ndim - 2`` dimensions. 

2369 The return values are either the minimum or maximum or sum of the 

2370 singular values of the matrices, depending on whether `op` 

2371 is `numpy.amin` or `numpy.amax` or `numpy.sum`. 

2372 

2373 """ 

2374 y = moveaxis(x, (row_axis, col_axis), (-2, -1)) 

2375 result = op(svd(y, compute_uv=False), axis=-1) 

2376 return result 

2377 

2378 

2379def _norm_dispatcher(x, ord=None, axis=None, keepdims=None): 

2380 return (x,) 

2381 

2382 

2383@array_function_dispatch(_norm_dispatcher) 

2384def norm(x, ord=None, axis=None, keepdims=False): 

2385 """ 

2386 Matrix or vector norm. 

2387 

2388 This function is able to return one of eight different matrix norms, 

2389 or one of an infinite number of vector norms (described below), depending 

2390 on the value of the ``ord`` parameter. 

2391 

2392 Parameters 

2393 ---------- 

2394 x : array_like 

2395 Input array. If `axis` is None, `x` must be 1-D or 2-D, unless `ord` 

2396 is None. If both `axis` and `ord` are None, the 2-norm of 

2397 ``x.ravel`` will be returned. 

2398 ord : {non-zero int, inf, -inf, 'fro', 'nuc'}, optional 

2399 Order of the norm (see table under ``Notes``). inf means numpy's 

2400 `inf` object. The default is None. 

2401 axis : {None, int, 2-tuple of ints}, optional. 

2402 If `axis` is an integer, it specifies the axis of `x` along which to 

2403 compute the vector norms. If `axis` is a 2-tuple, it specifies the 

2404 axes that hold 2-D matrices, and the matrix norms of these matrices 

2405 are computed. If `axis` is None then either a vector norm (when `x` 

2406 is 1-D) or a matrix norm (when `x` is 2-D) is returned. The default 

2407 is None. 

2408 

2409 .. versionadded:: 1.8.0 

2410 

2411 keepdims : bool, optional 

2412 If this is set to True, the axes which are normed over are left in the 

2413 result as dimensions with size one. With this option the result will 

2414 broadcast correctly against the original `x`. 

2415 

2416 .. versionadded:: 1.10.0 

2417 

2418 Returns 

2419 ------- 

2420 n : float or ndarray 

2421 Norm of the matrix or vector(s). 

2422 

2423 See Also 

2424 -------- 

2425 scipy.linalg.norm : Similar function in SciPy. 

2426 

2427 Notes 

2428 ----- 

2429 For values of ``ord < 1``, the result is, strictly speaking, not a 

2430 mathematical 'norm', but it may still be useful for various numerical 

2431 purposes. 

2432 

2433 The following norms can be calculated: 

2434 

2435 ===== ============================ ========================== 

2436 ord norm for matrices norm for vectors 

2437 ===== ============================ ========================== 

2438 None Frobenius norm 2-norm 

2439 'fro' Frobenius norm -- 

2440 'nuc' nuclear norm -- 

2441 inf max(sum(abs(x), axis=1)) max(abs(x)) 

2442 -inf min(sum(abs(x), axis=1)) min(abs(x)) 

2443 0 -- sum(x != 0) 

2444 1 max(sum(abs(x), axis=0)) as below 

2445 -1 min(sum(abs(x), axis=0)) as below 

2446 2 2-norm (largest sing. value) as below 

2447 -2 smallest singular value as below 

2448 other -- sum(abs(x)**ord)**(1./ord) 

2449 ===== ============================ ========================== 

2450 

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

2452 

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

2454 

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

2456 

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

2458 matrices and raise a ValueError when ``x.ndim != 2``. 

2459 

2460 References 

2461 ---------- 

2462 .. [1] G. H. Golub and C. F. Van Loan, *Matrix Computations*, 

2463 Baltimore, MD, Johns Hopkins University Press, 1985, pg. 15 

2464 

2465 Examples 

2466 -------- 

2467 >>> from numpy import linalg as LA 

2468 >>> a = np.arange(9) - 4 

2469 >>> a 

2470 array([-4, -3, -2, ..., 2, 3, 4]) 

2471 >>> b = a.reshape((3, 3)) 

2472 >>> b 

2473 array([[-4, -3, -2], 

2474 [-1, 0, 1], 

2475 [ 2, 3, 4]]) 

2476 

2477 >>> LA.norm(a) 

2478 7.745966692414834 

2479 >>> LA.norm(b) 

2480 7.745966692414834 

2481 >>> LA.norm(b, 'fro') 

2482 7.745966692414834 

2483 >>> LA.norm(a, np.inf) 

2484 4.0 

2485 >>> LA.norm(b, np.inf) 

2486 9.0 

2487 >>> LA.norm(a, -np.inf) 

2488 0.0 

2489 >>> LA.norm(b, -np.inf) 

2490 2.0 

2491 

2492 >>> LA.norm(a, 1) 

2493 20.0 

2494 >>> LA.norm(b, 1) 

2495 7.0 

2496 >>> LA.norm(a, -1) 

2497 -4.6566128774142013e-010 

2498 >>> LA.norm(b, -1) 

2499 6.0 

2500 >>> LA.norm(a, 2) 

2501 7.745966692414834 

2502 >>> LA.norm(b, 2) 

2503 7.3484692283495345 

2504 

2505 >>> LA.norm(a, -2) 

2506 0.0 

2507 >>> LA.norm(b, -2) 

2508 1.8570331885190563e-016 # may vary 

2509 >>> LA.norm(a, 3) 

2510 5.8480354764257312 # may vary 

2511 >>> LA.norm(a, -3) 

2512 0.0 

2513 

2514 Using the `axis` argument to compute vector norms: 

2515 

2516 >>> c = np.array([[ 1, 2, 3], 

2517 ... [-1, 1, 4]]) 

2518 >>> LA.norm(c, axis=0) 

2519 array([ 1.41421356, 2.23606798, 5. ]) 

2520 >>> LA.norm(c, axis=1) 

2521 array([ 3.74165739, 4.24264069]) 

2522 >>> LA.norm(c, ord=1, axis=1) 

2523 array([ 6., 6.]) 

2524 

2525 Using the `axis` argument to compute matrix norms: 

2526 

2527 >>> m = np.arange(8).reshape(2,2,2) 

2528 >>> LA.norm(m, axis=(1,2)) 

2529 array([ 3.74165739, 11.22497216]) 

2530 >>> LA.norm(m[0, :, :]), LA.norm(m[1, :, :]) 

2531 (3.7416573867739413, 11.224972160321824) 

2532 

2533 """ 

2534 x = asarray(x) 

2535 

2536 if not issubclass(x.dtype.type, (inexact, object_)): 

2537 x = x.astype(float) 

2538 

2539 # Immediately handle some default, simple, fast, and common cases. 

2540 if axis is None: 

2541 ndim = x.ndim 

2542 if ((ord is None) or 

2543 (ord in ('f', 'fro') and ndim == 2) or 

2544 (ord == 2 and ndim == 1)): 

2545 

2546 x = x.ravel(order='K') 

2547 if isComplexType(x.dtype.type): 

2548 x_real = x.real 

2549 x_imag = x.imag 

2550 sqnorm = x_real.dot(x_real) + x_imag.dot(x_imag) 

2551 else: 

2552 sqnorm = x.dot(x) 

2553 ret = sqrt(sqnorm) 

2554 if keepdims: 

2555 ret = ret.reshape(ndim*[1]) 

2556 return ret 

2557 

2558 # Normalize the `axis` argument to a tuple. 

2559 nd = x.ndim 

2560 if axis is None: 

2561 axis = tuple(range(nd)) 

2562 elif not isinstance(axis, tuple): 

2563 try: 

2564 axis = int(axis) 

2565 except Exception as e: 

2566 raise TypeError("'axis' must be None, an integer or a tuple of integers") from e 

2567 axis = (axis,) 

2568 

2569 if len(axis) == 1: 

2570 if ord == Inf: 

2571 return abs(x).max(axis=axis, keepdims=keepdims) 

2572 elif ord == -Inf: 

2573 return abs(x).min(axis=axis, keepdims=keepdims) 

2574 elif ord == 0: 

2575 # Zero norm 

2576 return (x != 0).astype(x.real.dtype).sum(axis=axis, keepdims=keepdims) 

2577 elif ord == 1: 

2578 # special case for speedup 

2579 return add.reduce(abs(x), axis=axis, keepdims=keepdims) 

2580 elif ord is None or ord == 2: 

2581 # special case for speedup 

2582 s = (x.conj() * x).real 

2583 return sqrt(add.reduce(s, axis=axis, keepdims=keepdims)) 

2584 # None of the str-type keywords for ord ('fro', 'nuc') 

2585 # are valid for vectors 

2586 elif isinstance(ord, str): 

2587 raise ValueError(f"Invalid norm order '{ord}' for vectors") 

2588 else: 

2589 absx = abs(x) 

2590 absx **= ord 

2591 ret = add.reduce(absx, axis=axis, keepdims=keepdims) 

2592 ret **= reciprocal(ord, dtype=ret.dtype) 

2593 return ret 

2594 elif len(axis) == 2: 

2595 row_axis, col_axis = axis 

2596 row_axis = normalize_axis_index(row_axis, nd) 

2597 col_axis = normalize_axis_index(col_axis, nd) 

2598 if row_axis == col_axis: 

2599 raise ValueError('Duplicate axes given.') 

2600 if ord == 2: 

2601 ret = _multi_svd_norm(x, row_axis, col_axis, amax) 

2602 elif ord == -2: 

2603 ret = _multi_svd_norm(x, row_axis, col_axis, amin) 

2604 elif ord == 1: 

2605 if col_axis > row_axis: 

2606 col_axis -= 1 

2607 ret = add.reduce(abs(x), axis=row_axis).max(axis=col_axis) 

2608 elif ord == Inf: 

2609 if row_axis > col_axis: 

2610 row_axis -= 1 

2611 ret = add.reduce(abs(x), axis=col_axis).max(axis=row_axis) 

2612 elif ord == -1: 

2613 if col_axis > row_axis: 

2614 col_axis -= 1 

2615 ret = add.reduce(abs(x), axis=row_axis).min(axis=col_axis) 

2616 elif ord == -Inf: 

2617 if row_axis > col_axis: 

2618 row_axis -= 1 

2619 ret = add.reduce(abs(x), axis=col_axis).min(axis=row_axis) 

2620 elif ord in [None, 'fro', 'f']: 

2621 ret = sqrt(add.reduce((x.conj() * x).real, axis=axis)) 

2622 elif ord == 'nuc': 

2623 ret = _multi_svd_norm(x, row_axis, col_axis, sum) 

2624 else: 

2625 raise ValueError("Invalid norm order for matrices.") 

2626 if keepdims: 

2627 ret_shape = list(x.shape) 

2628 ret_shape[axis[0]] = 1 

2629 ret_shape[axis[1]] = 1 

2630 ret = ret.reshape(ret_shape) 

2631 return ret 

2632 else: 

2633 raise ValueError("Improper number of dimensions to norm.") 

2634 

2635 

2636# multi_dot 

2637 

2638def _multidot_dispatcher(arrays, *, out=None): 

2639 yield from arrays 

2640 yield out 

2641 

2642 

2643@array_function_dispatch(_multidot_dispatcher) 

2644def multi_dot(arrays, *, out=None): 

2645 """ 

2646 Compute the dot product of two or more arrays in a single function call, 

2647 while automatically selecting the fastest evaluation order. 

2648 

2649 `multi_dot` chains `numpy.dot` and uses optimal parenthesization 

2650 of the matrices [1]_ [2]_. Depending on the shapes of the matrices, 

2651 this can speed up the multiplication a lot. 

2652 

2653 If the first argument is 1-D it is treated as a row vector. 

2654 If the last argument is 1-D it is treated as a column vector. 

2655 The other arguments must be 2-D. 

2656 

2657 Think of `multi_dot` as:: 

2658 

2659 def multi_dot(arrays): return functools.reduce(np.dot, arrays) 

2660 

2661 

2662 Parameters 

2663 ---------- 

2664 arrays : sequence of array_like 

2665 If the first argument is 1-D it is treated as row vector. 

2666 If the last argument is 1-D it is treated as column vector. 

2667 The other arguments must be 2-D. 

2668 out : ndarray, optional 

2669 Output argument. This must have the exact kind that would be returned 

2670 if it was not used. In particular, it must have the right type, must be 

2671 C-contiguous, and its dtype must be the dtype that would be returned 

2672 for `dot(a, b)`. This is a performance feature. Therefore, if these 

2673 conditions are not met, an exception is raised, instead of attempting 

2674 to be flexible. 

2675 

2676 .. versionadded:: 1.19.0 

2677 

2678 Returns 

2679 ------- 

2680 output : ndarray 

2681 Returns the dot product of the supplied arrays. 

2682 

2683 See Also 

2684 -------- 

2685 numpy.dot : dot multiplication with two arguments. 

2686 

2687 References 

2688 ---------- 

2689 

2690 .. [1] Cormen, "Introduction to Algorithms", Chapter 15.2, p. 370-378 

2691 .. [2] https://en.wikipedia.org/wiki/Matrix_chain_multiplication 

2692 

2693 Examples 

2694 -------- 

2695 `multi_dot` allows you to write:: 

2696 

2697 >>> from numpy.linalg import multi_dot 

2698 >>> # Prepare some data 

2699 >>> A = np.random.random((10000, 100)) 

2700 >>> B = np.random.random((100, 1000)) 

2701 >>> C = np.random.random((1000, 5)) 

2702 >>> D = np.random.random((5, 333)) 

2703 >>> # the actual dot multiplication 

2704 >>> _ = multi_dot([A, B, C, D]) 

2705 

2706 instead of:: 

2707 

2708 >>> _ = np.dot(np.dot(np.dot(A, B), C), D) 

2709 >>> # or 

2710 >>> _ = A.dot(B).dot(C).dot(D) 

2711 

2712 Notes 

2713 ----- 

2714 The cost for a matrix multiplication can be calculated with the 

2715 following function:: 

2716 

2717 def cost(A, B): 

2718 return A.shape[0] * A.shape[1] * B.shape[1] 

2719 

2720 Assume we have three matrices 

2721 :math:`A_{10x100}, B_{100x5}, C_{5x50}`. 

2722 

2723 The costs for the two different parenthesizations are as follows:: 

2724 

2725 cost((AB)C) = 10*100*5 + 10*5*50 = 5000 + 2500 = 7500 

2726 cost(A(BC)) = 10*100*50 + 100*5*50 = 50000 + 25000 = 75000 

2727 

2728 """ 

2729 n = len(arrays) 

2730 # optimization only makes sense for len(arrays) > 2 

2731 if n < 2: 

2732 raise ValueError("Expecting at least two arrays.") 

2733 elif n == 2: 

2734 return dot(arrays[0], arrays[1], out=out) 

2735 

2736 arrays = [asanyarray(a) for a in arrays] 

2737 

2738 # save original ndim to reshape the result array into the proper form later 

2739 ndim_first, ndim_last = arrays[0].ndim, arrays[-1].ndim 

2740 # Explicitly convert vectors to 2D arrays to keep the logic of the internal 

2741 # _multi_dot_* functions as simple as possible. 

2742 if arrays[0].ndim == 1: 

2743 arrays[0] = atleast_2d(arrays[0]) 

2744 if arrays[-1].ndim == 1: 

2745 arrays[-1] = atleast_2d(arrays[-1]).T 

2746 _assert_2d(*arrays) 

2747 

2748 # _multi_dot_three is much faster than _multi_dot_matrix_chain_order 

2749 if n == 3: 

2750 result = _multi_dot_three(arrays[0], arrays[1], arrays[2], out=out) 

2751 else: 

2752 order = _multi_dot_matrix_chain_order(arrays) 

2753 result = _multi_dot(arrays, order, 0, n - 1, out=out) 

2754 

2755 # return proper shape 

2756 if ndim_first == 1 and ndim_last == 1: 

2757 return result[0, 0] # scalar 

2758 elif ndim_first == 1 or ndim_last == 1: 

2759 return result.ravel() # 1-D 

2760 else: 

2761 return result 

2762 

2763 

2764def _multi_dot_three(A, B, C, out=None): 

2765 """ 

2766 Find the best order for three arrays and do the multiplication. 

2767 

2768 For three arguments `_multi_dot_three` is approximately 15 times faster 

2769 than `_multi_dot_matrix_chain_order` 

2770 

2771 """ 

2772 a0, a1b0 = A.shape 

2773 b1c0, c1 = C.shape 

2774 # cost1 = cost((AB)C) = a0*a1b0*b1c0 + a0*b1c0*c1 

2775 cost1 = a0 * b1c0 * (a1b0 + c1) 

2776 # cost2 = cost(A(BC)) = a1b0*b1c0*c1 + a0*a1b0*c1 

2777 cost2 = a1b0 * c1 * (a0 + b1c0) 

2778 

2779 if cost1 < cost2: 

2780 return dot(dot(A, B), C, out=out) 

2781 else: 

2782 return dot(A, dot(B, C), out=out) 

2783 

2784 

2785def _multi_dot_matrix_chain_order(arrays, return_costs=False): 

2786 """ 

2787 Return a np.array that encodes the optimal order of mutiplications. 

2788 

2789 The optimal order array is then used by `_multi_dot()` to do the 

2790 multiplication. 

2791 

2792 Also return the cost matrix if `return_costs` is `True` 

2793 

2794 The implementation CLOSELY follows Cormen, "Introduction to Algorithms", 

2795 Chapter 15.2, p. 370-378. Note that Cormen uses 1-based indices. 

2796 

2797 cost[i, j] = min([ 

2798 cost[prefix] + cost[suffix] + cost_mult(prefix, suffix) 

2799 for k in range(i, j)]) 

2800 

2801 """ 

2802 n = len(arrays) 

2803 # p stores the dimensions of the matrices 

2804 # Example for p: A_{10x100}, B_{100x5}, C_{5x50} --> p = [10, 100, 5, 50] 

2805 p = [a.shape[0] for a in arrays] + [arrays[-1].shape[1]] 

2806 # m is a matrix of costs of the subproblems 

2807 # m[i,j]: min number of scalar multiplications needed to compute A_{i..j} 

2808 m = zeros((n, n), dtype=double) 

2809 # s is the actual ordering 

2810 # s[i, j] is the value of k at which we split the product A_i..A_j 

2811 s = empty((n, n), dtype=intp) 

2812 

2813 for l in range(1, n): 

2814 for i in range(n - l): 

2815 j = i + l 

2816 m[i, j] = Inf 

2817 for k in range(i, j): 

2818 q = m[i, k] + m[k+1, j] + p[i]*p[k+1]*p[j+1] 

2819 if q < m[i, j]: 

2820 m[i, j] = q 

2821 s[i, j] = k # Note that Cormen uses 1-based index 

2822 

2823 return (s, m) if return_costs else s 

2824 

2825 

2826def _multi_dot(arrays, order, i, j, out=None): 

2827 """Actually do the multiplication with the given order.""" 

2828 if i == j: 

2829 # the initial call with non-None out should never get here 

2830 assert out is None 

2831 

2832 return arrays[i] 

2833 else: 

2834 return dot(_multi_dot(arrays, order, i, order[i, j]), 

2835 _multi_dot(arrays, order, order[i, j] + 1, j), 

2836 out=out)