xref: /aosp_15_r20/external/pytorch/torch/linalg/__init__.py (revision da0073e96a02ea20f0ac840b70461e3646d07c45)
1import torch
2from torch._C import _add_docstr, _linalg  # type: ignore[attr-defined]
3
4LinAlgError = torch._C._LinAlgError  # type: ignore[attr-defined]
5
6Tensor = torch.Tensor
7
8common_notes = {
9    "experimental_warning": """This function is "experimental" and it may change in a future PyTorch release.""",
10    "sync_note": "When inputs are on a CUDA device, this function synchronizes that device with the CPU.",
11    "sync_note_ex": r"When the inputs are on a CUDA device, this function synchronizes only when :attr:`check_errors`\ `= True`.",
12    "sync_note_has_ex": ("When inputs are on a CUDA device, this function synchronizes that device with the CPU. "
13                         "For a version of this function that does not synchronize, see :func:`{}`.")
14}
15
16
17# Note: This not only adds doc strings for functions in the linalg namespace, but
18# also connects the torch.linalg Python namespace to the torch._C._linalg builtins.
19
20cross = _add_docstr(_linalg.linalg_cross, r"""
21linalg.cross(input, other, *, dim=-1, out=None) -> Tensor
22
23
24Computes the cross product of two 3-dimensional vectors.
25
26Supports input of float, double, cfloat and cdouble dtypes. Also supports batches
27of vectors, for which it computes the product along the dimension :attr:`dim`.
28It broadcasts over the batch dimensions.
29
30Args:
31    input (Tensor): the first input tensor.
32    other (Tensor): the second input tensor.
33    dim  (int, optional): the dimension along which to take the cross-product. Default: `-1`.
34
35Keyword args:
36    out (Tensor, optional): the output tensor. Ignored if `None`. Default: `None`.
37
38Example:
39    >>> a = torch.randn(4, 3)
40    >>> a
41    tensor([[-0.3956,  1.1455,  1.6895],
42            [-0.5849,  1.3672,  0.3599],
43            [-1.1626,  0.7180, -0.0521],
44            [-0.1339,  0.9902, -2.0225]])
45    >>> b = torch.randn(4, 3)
46    >>> b
47    tensor([[-0.0257, -1.4725, -1.2251],
48            [-1.1479, -0.7005, -1.9757],
49            [-1.3904,  0.3726, -1.1836],
50            [-0.9688, -0.7153,  0.2159]])
51    >>> torch.linalg.cross(a, b)
52    tensor([[ 1.0844, -0.5281,  0.6120],
53            [-2.4490, -1.5687,  1.9792],
54            [-0.8304, -1.3037,  0.5650],
55            [-1.2329,  1.9883,  1.0551]])
56    >>> a = torch.randn(1, 3)  # a is broadcast to match shape of b
57    >>> a
58    tensor([[-0.9941, -0.5132,  0.5681]])
59    >>> torch.linalg.cross(a, b)
60    tensor([[ 1.4653, -1.2325,  1.4507],
61            [ 1.4119, -2.6163,  0.1073],
62            [ 0.3957, -1.9666, -1.0840],
63            [ 0.2956, -0.3357,  0.2139]])
64""")
65
66cholesky = _add_docstr(_linalg.linalg_cholesky, r"""
67linalg.cholesky(A, *, upper=False, out=None) -> Tensor
68
69Computes the Cholesky decomposition of a complex Hermitian or real symmetric positive-definite matrix.
70
71Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
72the **Cholesky decomposition** of a complex Hermitian or real symmetric positive-definite matrix
73:math:`A \in \mathbb{K}^{n \times n}` is defined as
74
75.. math::
76
77    A = LL^{\text{H}}\mathrlap{\qquad L \in \mathbb{K}^{n \times n}}
78
79where :math:`L` is a lower triangular matrix with real positive diagonal (even in the complex case) and
80:math:`L^{\text{H}}` is the conjugate transpose when :math:`L` is complex, and the transpose when :math:`L` is real-valued.
81
82Supports input of float, double, cfloat and cdouble dtypes.
83Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
84the output has the same batch dimensions.
85
86""" + fr"""
87.. note:: {common_notes["sync_note_has_ex"].format("torch.linalg.cholesky_ex")}
88""" + r"""
89
90.. seealso::
91
92        :func:`torch.linalg.cholesky_ex` for a version of this operation that
93        skips the (slow) error checking by default and instead returns the debug
94        information. This makes it a faster way to check if a matrix is
95        positive-definite.
96
97        :func:`torch.linalg.eigh` for a different decomposition of a Hermitian matrix.
98        The eigenvalue decomposition gives more information about the matrix but it
99        slower to compute than the Cholesky decomposition.
100
101Args:
102    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
103                consisting of symmetric or Hermitian positive-definite matrices.
104
105Keyword args:
106    upper (bool, optional): whether to return an upper triangular matrix.
107        The tensor returned with upper=True is the conjugate transpose of the tensor
108        returned with upper=False.
109    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
110
111Raises:
112    RuntimeError: if the :attr:`A` matrix or any matrix in a batched :attr:`A` is not Hermitian
113                  (resp. symmetric) positive-definite. If :attr:`A` is a batch of matrices,
114                  the error message will include the batch index of the first matrix that fails
115                  to meet this condition.
116
117Examples::
118
119    >>> A = torch.randn(2, 2, dtype=torch.complex128)
120    >>> A = A @ A.T.conj() + torch.eye(2) # creates a Hermitian positive-definite matrix
121    >>> A
122    tensor([[2.5266+0.0000j, 1.9586-2.0626j],
123            [1.9586+2.0626j, 9.4160+0.0000j]], dtype=torch.complex128)
124    >>> L = torch.linalg.cholesky(A)
125    >>> L
126    tensor([[1.5895+0.0000j, 0.0000+0.0000j],
127            [1.2322+1.2976j, 2.4928+0.0000j]], dtype=torch.complex128)
128    >>> torch.dist(L @ L.T.conj(), A)
129    tensor(4.4692e-16, dtype=torch.float64)
130
131    >>> A = torch.randn(3, 2, 2, dtype=torch.float64)
132    >>> A = A @ A.mT + torch.eye(2)  # batch of symmetric positive-definite matrices
133    >>> L = torch.linalg.cholesky(A)
134    >>> torch.dist(L @ L.mT, A)
135    tensor(5.8747e-16, dtype=torch.float64)
136""")
137
138cholesky_ex = _add_docstr(_linalg.linalg_cholesky_ex, r"""
139linalg.cholesky_ex(A, *, upper=False, check_errors=False, out=None) -> (Tensor, Tensor)
140
141Computes the Cholesky decomposition of a complex Hermitian or real
142symmetric positive-definite matrix.
143
144This function skips the (slow) error checking and error message construction
145of :func:`torch.linalg.cholesky`, instead directly returning the LAPACK
146error codes as part of a named tuple ``(L, info)``. This makes this function
147a faster way to check if a matrix is positive-definite, and it provides an
148opportunity to handle decomposition errors more gracefully or performantly
149than :func:`torch.linalg.cholesky` does.
150
151Supports input of float, double, cfloat and cdouble dtypes.
152Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
153the output has the same batch dimensions.
154
155If :attr:`A` is not a Hermitian positive-definite matrix, or if it's a batch of matrices
156and one or more of them is not a Hermitian positive-definite matrix,
157then ``info`` stores a positive integer for the corresponding matrix.
158The positive integer indicates the order of the leading minor that is not positive-definite,
159and the decomposition could not be completed.
160``info`` filled with zeros indicates that the decomposition was successful.
161If ``check_errors=True`` and ``info`` contains positive integers, then a RuntimeError is thrown.
162
163""" + fr"""
164.. note:: {common_notes["sync_note_ex"]}
165
166.. warning:: {common_notes["experimental_warning"]}
167""" + r"""
168
169.. seealso::
170        :func:`torch.linalg.cholesky` is a NumPy compatible variant that always checks for errors.
171
172Args:
173    A (Tensor): the Hermitian `n \times n` matrix or the batch of such matrices of size
174                    `(*, n, n)` where `*` is one or more batch dimensions.
175
176Keyword args:
177    upper (bool, optional): whether to return an upper triangular matrix.
178        The tensor returned with upper=True is the conjugate transpose of the tensor
179        returned with upper=False.
180    check_errors (bool, optional): controls whether to check the content of ``infos``. Default: `False`.
181    out (tuple, optional): tuple of two tensors to write the output to. Ignored if `None`. Default: `None`.
182
183Examples::
184
185    >>> A = torch.randn(2, 2, dtype=torch.complex128)
186    >>> A = A @ A.t().conj()  # creates a Hermitian positive-definite matrix
187    >>> L, info = torch.linalg.cholesky_ex(A)
188    >>> A
189    tensor([[ 2.3792+0.0000j, -0.9023+0.9831j],
190            [-0.9023-0.9831j,  0.8757+0.0000j]], dtype=torch.complex128)
191    >>> L
192    tensor([[ 1.5425+0.0000j,  0.0000+0.0000j],
193            [-0.5850-0.6374j,  0.3567+0.0000j]], dtype=torch.complex128)
194    >>> info
195    tensor(0, dtype=torch.int32)
196
197""")
198
199inv = _add_docstr(_linalg.linalg_inv, r"""
200linalg.inv(A, *, out=None) -> Tensor
201
202Computes the inverse of a square matrix if it exists.
203Throws a `RuntimeError` if the matrix is not invertible.
204
205Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
206for a matrix :math:`A \in \mathbb{K}^{n \times n}`,
207its **inverse matrix** :math:`A^{-1} \in \mathbb{K}^{n \times n}` (if it exists) is defined as
208
209.. math::
210
211    A^{-1}A = AA^{-1} = \mathrm{I}_n
212
213where :math:`\mathrm{I}_n` is the `n`-dimensional identity matrix.
214
215The inverse matrix exists if and only if :math:`A` is `invertible`_. In this case,
216the inverse is unique.
217
218Supports input of float, double, cfloat and cdouble dtypes.
219Also supports batches of matrices, and if :attr:`A` is a batch of matrices
220then the output has the same batch dimensions.
221
222""" + fr"""
223.. note:: {common_notes["sync_note_has_ex"].format("torch.linalg.inv_ex")}
224""" + r"""
225
226.. note::
227    Consider using :func:`torch.linalg.solve` if possible for multiplying a matrix on the left by
228    the inverse, as::
229
230        linalg.solve(A, B) == linalg.inv(A) @ B  # When B is a matrix
231
232    It is always preferred to use :func:`~solve` when possible, as it is faster and more
233    numerically stable than computing the inverse explicitly.
234
235.. seealso::
236
237        :func:`torch.linalg.pinv` computes the pseudoinverse (Moore-Penrose inverse) of matrices
238        of any shape.
239
240        :func:`torch.linalg.solve` computes :attr:`A`\ `.inv() @ \ `:attr:`B` with a
241        numerically stable algorithm.
242
243Args:
244    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
245                consisting of invertible matrices.
246
247Keyword args:
248    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
249
250Raises:
251    RuntimeError: if the matrix :attr:`A` or any matrix in the batch of matrices :attr:`A` is not invertible.
252
253Examples::
254
255    >>> A = torch.randn(4, 4)
256    >>> Ainv = torch.linalg.inv(A)
257    >>> torch.dist(A @ Ainv, torch.eye(4))
258    tensor(1.1921e-07)
259
260    >>> A = torch.randn(2, 3, 4, 4)  # Batch of matrices
261    >>> Ainv = torch.linalg.inv(A)
262    >>> torch.dist(A @ Ainv, torch.eye(4))
263    tensor(1.9073e-06)
264
265    >>> A = torch.randn(4, 4, dtype=torch.complex128)  # Complex matrix
266    >>> Ainv = torch.linalg.inv(A)
267    >>> torch.dist(A @ Ainv, torch.eye(4))
268    tensor(7.5107e-16, dtype=torch.float64)
269
270.. _invertible:
271    https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem
272""")
273
274solve_ex = _add_docstr(_linalg.linalg_solve_ex, r"""
275linalg.solve_ex(A, B, *, left=True, check_errors=False, out=None) -> (Tensor, Tensor)
276
277A version of :func:`~solve` that does not perform error checks unless :attr:`check_errors`\ `= True`.
278It also returns the :attr:`info` tensor returned by `LAPACK's getrf`_.
279
280""" + fr"""
281.. note:: {common_notes["sync_note_ex"]}
282
283.. warning:: {common_notes["experimental_warning"]}
284""" + r"""
285
286Args:
287    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions.
288
289Keyword args:
290    left (bool, optional): whether to solve the system :math:`AX=B` or :math:`XA = B`. Default: `True`.
291    check_errors (bool, optional): controls whether to check the content of ``infos`` and raise
292                                   an error if it is non-zero. Default: `False`.
293    out (tuple, optional): tuple of two tensors to write the output to. Ignored if `None`. Default: `None`.
294
295Returns:
296    A named tuple `(result, info)`.
297
298Examples::
299
300    >>> A = torch.randn(3, 3)
301    >>> Ainv, info = torch.linalg.solve_ex(A)
302    >>> torch.dist(torch.linalg.inv(A), Ainv)
303    tensor(0.)
304    >>> info
305    tensor(0, dtype=torch.int32)
306
307.. _LAPACK's getrf:
308    https://www.netlib.org/lapack/explore-html/dd/d9a/group__double_g_ecomputational_ga0019443faea08275ca60a734d0593e60.html
309""")
310
311inv_ex = _add_docstr(_linalg.linalg_inv_ex, r"""
312linalg.inv_ex(A, *, check_errors=False, out=None) -> (Tensor, Tensor)
313
314Computes the inverse of a square matrix if it is invertible.
315
316Returns a namedtuple ``(inverse, info)``. ``inverse`` contains the result of
317inverting :attr:`A` and ``info`` stores the LAPACK error codes.
318
319If :attr:`A` is not an invertible matrix, or if it's a batch of matrices
320and one or more of them is not an invertible matrix,
321then ``info`` stores a positive integer for the corresponding matrix.
322The positive integer indicates the diagonal element of the LU decomposition of
323the input matrix that is exactly zero.
324``info`` filled with zeros indicates that the inversion was successful.
325If ``check_errors=True`` and ``info`` contains positive integers, then a RuntimeError is thrown.
326
327Supports input of float, double, cfloat and cdouble dtypes.
328Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
329the output has the same batch dimensions.
330
331""" + fr"""
332.. note:: {common_notes["sync_note_ex"]}
333
334.. warning:: {common_notes["experimental_warning"]}
335""" + r"""
336
337.. seealso::
338
339        :func:`torch.linalg.inv` is a NumPy compatible variant that always checks for errors.
340
341Args:
342    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
343                    consisting of square matrices.
344    check_errors (bool, optional): controls whether to check the content of ``info``. Default: `False`.
345
346Keyword args:
347    out (tuple, optional): tuple of two tensors to write the output to. Ignored if `None`. Default: `None`.
348
349Examples::
350
351    >>> A = torch.randn(3, 3)
352    >>> Ainv, info = torch.linalg.inv_ex(A)
353    >>> torch.dist(torch.linalg.inv(A), Ainv)
354    tensor(0.)
355    >>> info
356    tensor(0, dtype=torch.int32)
357
358""")
359
360det = _add_docstr(_linalg.linalg_det, r"""
361linalg.det(A, *, out=None) -> Tensor
362
363Computes the determinant of a square matrix.
364
365Supports input of float, double, cfloat and cdouble dtypes.
366Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
367the output has the same batch dimensions.
368
369.. seealso::
370
371        :func:`torch.linalg.slogdet` computes the sign and natural logarithm of the absolute
372        value of the determinant of square matrices.
373
374Args:
375    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions.
376
377Keyword args:
378    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
379
380Examples::
381
382    >>> A = torch.randn(3, 3)
383    >>> torch.linalg.det(A)
384    tensor(0.0934)
385
386    >>> A = torch.randn(3, 2, 2)
387    >>> torch.linalg.det(A)
388    tensor([1.1990, 0.4099, 0.7386])
389""")
390
391slogdet = _add_docstr(_linalg.linalg_slogdet, r"""
392linalg.slogdet(A, *, out=None) -> (Tensor, Tensor)
393
394Computes the sign and natural logarithm of the absolute value of the determinant of a square matrix.
395
396For complex :attr:`A`, it returns the sign and the natural logarithm of the modulus of the
397determinant, that is, a logarithmic polar decomposition of the determinant.
398
399The determinant can be recovered as `sign * exp(logabsdet)`.
400When a matrix has a determinant of zero, it returns `(0, -inf)`.
401
402Supports input of float, double, cfloat and cdouble dtypes.
403Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
404the output has the same batch dimensions.
405
406.. seealso::
407
408        :func:`torch.linalg.det` computes the determinant of square matrices.
409
410Args:
411    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions.
412
413Keyword args:
414    out (tuple, optional): output tuple of two tensors. Ignored if `None`. Default: `None`.
415
416Returns:
417    A named tuple `(sign, logabsdet)`.
418
419    `sign` will have the same dtype as :attr:`A`.
420
421    `logabsdet` will always be real-valued, even when :attr:`A` is complex.
422
423Examples::
424
425    >>> A = torch.randn(3, 3)
426    >>> A
427    tensor([[ 0.0032, -0.2239, -1.1219],
428            [-0.6690,  0.1161,  0.4053],
429            [-1.6218, -0.9273, -0.0082]])
430    >>> torch.linalg.det(A)
431    tensor(-0.7576)
432    >>> torch.logdet(A)
433    tensor(nan)
434    >>> torch.linalg.slogdet(A)
435    torch.return_types.linalg_slogdet(sign=tensor(-1.), logabsdet=tensor(-0.2776))
436""")
437
438eig = _add_docstr(_linalg.linalg_eig, r"""
439linalg.eig(A, *, out=None) -> (Tensor, Tensor)
440
441Computes the eigenvalue decomposition of a square matrix if it exists.
442
443Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
444the **eigenvalue decomposition** of a square matrix
445:math:`A \in \mathbb{K}^{n \times n}` (if it exists) is defined as
446
447.. math::
448
449    A = V \operatorname{diag}(\Lambda) V^{-1}\mathrlap{\qquad V \in \mathbb{C}^{n \times n}, \Lambda \in \mathbb{C}^n}
450
451This decomposition exists if and only if :math:`A` is `diagonalizable`_.
452This is the case when all its eigenvalues are different.
453
454Supports input of float, double, cfloat and cdouble dtypes.
455Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
456the output has the same batch dimensions.
457
458The returned eigenvalues are not guaranteed to be in any specific order.
459
460.. note:: The eigenvalues and eigenvectors of a real matrix may be complex.
461
462""" + fr"""
463.. note:: {common_notes["sync_note"]}
464""" + r"""
465
466.. warning:: This function assumes that :attr:`A` is `diagonalizable`_ (for example, when all the
467             eigenvalues are different). If it is not diagonalizable, the returned
468             eigenvalues will be correct but :math:`A \neq V \operatorname{diag}(\Lambda)V^{-1}`.
469
470.. warning:: The returned eigenvectors are normalized to have norm `1`.
471             Even then, the eigenvectors of a matrix are not unique, nor are they continuous with respect to
472             :attr:`A`. Due to this lack of uniqueness, different hardware and software may compute
473             different eigenvectors.
474
475             This non-uniqueness is caused by the fact that multiplying an eigenvector by
476             by :math:`e^{i \phi}, \phi \in \mathbb{R}` produces another set of valid eigenvectors
477             of the matrix.  For this reason, the loss function shall not depend on the phase of the
478             eigenvectors, as this quantity is not well-defined.
479             This is checked when computing the gradients of this function. As such,
480             when inputs are on a CUDA device, the computation of the gradients
481             of this function synchronizes that device with the CPU.
482
483
484.. warning:: Gradients computed using the `eigenvectors` tensor will only be finite when
485             :attr:`A` has distinct eigenvalues.
486             Furthermore, if the distance between any two eigenvalues is close to zero,
487             the gradient will be numerically unstable, as it depends on the eigenvalues
488             :math:`\lambda_i` through the computation of
489             :math:`\frac{1}{\min_{i \neq j} \lambda_i - \lambda_j}`.
490
491.. seealso::
492
493        :func:`torch.linalg.eigvals` computes only the eigenvalues.
494        Unlike :func:`torch.linalg.eig`, the gradients of :func:`~eigvals` are always
495        numerically stable.
496
497        :func:`torch.linalg.eigh` for a (faster) function that computes the eigenvalue decomposition
498        for Hermitian and symmetric matrices.
499
500        :func:`torch.linalg.svd` for a function that computes another type of spectral
501        decomposition that works on matrices of any shape.
502
503        :func:`torch.linalg.qr` for another (much faster) decomposition that works on matrices of
504        any shape.
505
506Args:
507    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
508                consisting of diagonalizable matrices.
509
510Keyword args:
511    out (tuple, optional): output tuple of two tensors. Ignored if `None`. Default: `None`.
512
513Returns:
514    A named tuple `(eigenvalues, eigenvectors)` which corresponds to :math:`\Lambda` and :math:`V` above.
515
516    `eigenvalues` and `eigenvectors` will always be complex-valued, even when :attr:`A` is real. The eigenvectors
517    will be given by the columns of `eigenvectors`.
518
519Examples::
520
521    >>> A = torch.randn(2, 2, dtype=torch.complex128)
522    >>> A
523    tensor([[ 0.9828+0.3889j, -0.4617+0.3010j],
524            [ 0.1662-0.7435j, -0.6139+0.0562j]], dtype=torch.complex128)
525    >>> L, V = torch.linalg.eig(A)
526    >>> L
527    tensor([ 1.1226+0.5738j, -0.7537-0.1286j], dtype=torch.complex128)
528    >>> V
529    tensor([[ 0.9218+0.0000j,  0.1882-0.2220j],
530            [-0.0270-0.3867j,  0.9567+0.0000j]], dtype=torch.complex128)
531    >>> torch.dist(V @ torch.diag(L) @ torch.linalg.inv(V), A)
532    tensor(7.7119e-16, dtype=torch.float64)
533
534    >>> A = torch.randn(3, 2, 2, dtype=torch.float64)
535    >>> L, V = torch.linalg.eig(A)
536    >>> torch.dist(V @ torch.diag_embed(L) @ torch.linalg.inv(V), A)
537    tensor(3.2841e-16, dtype=torch.float64)
538
539.. _diagonalizable:
540    https://en.wikipedia.org/wiki/Diagonalizable_matrix#Definition
541""")
542
543eigvals = _add_docstr(_linalg.linalg_eigvals, r"""
544linalg.eigvals(A, *, out=None) -> Tensor
545
546Computes the eigenvalues of a square matrix.
547
548Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
549the **eigenvalues** of a square matrix :math:`A \in \mathbb{K}^{n \times n}` are defined
550as the roots (counted with multiplicity) of the polynomial `p` of degree `n` given by
551
552.. math::
553
554    p(\lambda) = \operatorname{det}(A - \lambda \mathrm{I}_n)\mathrlap{\qquad \lambda \in \mathbb{C}}
555
556where :math:`\mathrm{I}_n` is the `n`-dimensional identity matrix.
557
558Supports input of float, double, cfloat and cdouble dtypes.
559Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
560the output has the same batch dimensions.
561
562The returned eigenvalues are not guaranteed to be in any specific order.
563
564.. note:: The eigenvalues of a real matrix may be complex, as the roots of a real polynomial may be complex.
565
566          The eigenvalues of a matrix are always well-defined, even when the matrix is not diagonalizable.
567
568""" + fr"""
569.. note:: {common_notes["sync_note"]}
570""" + r"""
571
572.. seealso::
573
574        :func:`torch.linalg.eig` computes the full eigenvalue decomposition.
575
576Args:
577    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions.
578
579Keyword args:
580    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
581
582Returns:
583    A complex-valued tensor containing the eigenvalues even when :attr:`A` is real.
584
585Examples::
586
587    >>> A = torch.randn(2, 2, dtype=torch.complex128)
588    >>> L = torch.linalg.eigvals(A)
589    >>> L
590    tensor([ 1.1226+0.5738j, -0.7537-0.1286j], dtype=torch.complex128)
591
592    >>> torch.dist(L, torch.linalg.eig(A).eigenvalues)
593    tensor(2.4576e-07)
594""")
595
596eigh = _add_docstr(_linalg.linalg_eigh, r"""
597linalg.eigh(A, UPLO='L', *, out=None) -> (Tensor, Tensor)
598
599Computes the eigenvalue decomposition of a complex Hermitian or real symmetric matrix.
600
601Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
602the **eigenvalue decomposition** of a complex Hermitian or real symmetric matrix
603:math:`A \in \mathbb{K}^{n \times n}` is defined as
604
605.. math::
606
607    A = Q \operatorname{diag}(\Lambda) Q^{\text{H}}\mathrlap{\qquad Q \in \mathbb{K}^{n \times n}, \Lambda \in \mathbb{R}^n}
608
609where :math:`Q^{\text{H}}` is the conjugate transpose when :math:`Q` is complex, and the transpose when :math:`Q` is real-valued.
610:math:`Q` is orthogonal in the real case and unitary in the complex case.
611
612Supports input of float, double, cfloat and cdouble dtypes.
613Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
614the output has the same batch dimensions.
615
616:attr:`A` is assumed to be Hermitian (resp. symmetric), but this is not checked internally, instead:
617
618- If :attr:`UPLO`\ `= 'L'` (default), only the lower triangular part of the matrix is used in the computation.
619- If :attr:`UPLO`\ `= 'U'`, only the upper triangular part of the matrix is used.
620
621The eigenvalues are returned in ascending order.
622
623""" + fr"""
624.. note:: {common_notes["sync_note"]}
625""" + r"""
626
627.. note:: The eigenvalues of real symmetric or complex Hermitian matrices are always real.
628
629.. warning:: The eigenvectors of a symmetric matrix are not unique, nor are they continuous with
630             respect to :attr:`A`. Due to this lack of uniqueness, different hardware and
631             software may compute different eigenvectors.
632
633             This non-uniqueness is caused by the fact that multiplying an eigenvector by
634             `-1` in the real case or by :math:`e^{i \phi}, \phi \in \mathbb{R}` in the complex
635             case produces another set of valid eigenvectors of the matrix.
636             For this reason, the loss function shall not depend on the phase of the eigenvectors, as
637             this quantity is not well-defined.
638             This is checked for complex inputs when computing the gradients of this function. As such,
639             when inputs are complex and are on a CUDA device, the computation of the gradients
640             of this function synchronizes that device with the CPU.
641
642.. warning:: Gradients computed using the `eigenvectors` tensor will only be finite when
643             :attr:`A` has distinct eigenvalues.
644             Furthermore, if the distance between any two eigenvalues is close to zero,
645             the gradient will be numerically unstable, as it depends on the eigenvalues
646             :math:`\lambda_i` through the computation of
647             :math:`\frac{1}{\min_{i \neq j} \lambda_i - \lambda_j}`.
648
649.. warning:: User may see pytorch crashes if running `eigh` on CUDA devices with CUDA versions before 12.1 update 1
650             with large ill-conditioned matrices as inputs.
651             Refer to :ref:`Linear Algebra Numerical Stability<Linear Algebra Stability>` for more details.
652             If this is the case, user may (1) tune their matrix inputs to be less ill-conditioned,
653             or (2) use :func:`torch.backends.cuda.preferred_linalg_library` to
654             try other supported backends.
655
656.. seealso::
657
658        :func:`torch.linalg.eigvalsh` computes only the eigenvalues of a Hermitian matrix.
659        Unlike :func:`torch.linalg.eigh`, the gradients of :func:`~eigvalsh` are always
660        numerically stable.
661
662        :func:`torch.linalg.cholesky` for a different decomposition of a Hermitian matrix.
663        The Cholesky decomposition gives less information about the matrix but is much faster
664        to compute than the eigenvalue decomposition.
665
666        :func:`torch.linalg.eig` for a (slower) function that computes the eigenvalue decomposition
667        of a not necessarily Hermitian square matrix.
668
669        :func:`torch.linalg.svd` for a (slower) function that computes the more general SVD
670        decomposition of matrices of any shape.
671
672        :func:`torch.linalg.qr` for another (much faster) decomposition that works on general
673        matrices.
674
675Args:
676    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
677                consisting of symmetric or Hermitian matrices.
678    UPLO ('L', 'U', optional): controls whether to use the upper or lower triangular part
679                               of :attr:`A` in the computations. Default: `'L'`.
680
681Keyword args:
682    out (tuple, optional): output tuple of two tensors. Ignored if `None`. Default: `None`.
683
684Returns:
685    A named tuple `(eigenvalues, eigenvectors)` which corresponds to :math:`\Lambda` and :math:`Q` above.
686
687    `eigenvalues` will always be real-valued, even when :attr:`A` is complex.
688    It will also be ordered in ascending order.
689
690    `eigenvectors` will have the same dtype as :attr:`A` and will contain the eigenvectors as its columns.
691
692Examples::
693    >>> A = torch.randn(2, 2, dtype=torch.complex128)
694    >>> A = A + A.T.conj()  # creates a Hermitian matrix
695    >>> A
696    tensor([[2.9228+0.0000j, 0.2029-0.0862j],
697            [0.2029+0.0862j, 0.3464+0.0000j]], dtype=torch.complex128)
698    >>> L, Q = torch.linalg.eigh(A)
699    >>> L
700    tensor([0.3277, 2.9415], dtype=torch.float64)
701    >>> Q
702    tensor([[-0.0846+-0.0000j, -0.9964+0.0000j],
703            [ 0.9170+0.3898j, -0.0779-0.0331j]], dtype=torch.complex128)
704    >>> torch.dist(Q @ torch.diag(L.cdouble()) @ Q.T.conj(), A)
705    tensor(6.1062e-16, dtype=torch.float64)
706
707    >>> A = torch.randn(3, 2, 2, dtype=torch.float64)
708    >>> A = A + A.mT  # creates a batch of symmetric matrices
709    >>> L, Q = torch.linalg.eigh(A)
710    >>> torch.dist(Q @ torch.diag_embed(L) @ Q.mH, A)
711    tensor(1.5423e-15, dtype=torch.float64)
712""")
713
714eigvalsh = _add_docstr(_linalg.linalg_eigvalsh, r"""
715linalg.eigvalsh(A, UPLO='L', *, out=None) -> Tensor
716
717Computes the eigenvalues of a complex Hermitian or real symmetric matrix.
718
719Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
720the **eigenvalues** of a complex Hermitian or real symmetric  matrix :math:`A \in \mathbb{K}^{n \times n}`
721are defined as the roots (counted with multiplicity) of the polynomial `p` of degree `n` given by
722
723.. math::
724
725    p(\lambda) = \operatorname{det}(A - \lambda \mathrm{I}_n)\mathrlap{\qquad \lambda \in \mathbb{R}}
726
727where :math:`\mathrm{I}_n` is the `n`-dimensional identity matrix.
728The eigenvalues of a real symmetric or complex Hermitian matrix are always real.
729
730Supports input of float, double, cfloat and cdouble dtypes.
731Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
732the output has the same batch dimensions.
733
734The eigenvalues are returned in ascending order.
735
736:attr:`A` is assumed to be Hermitian (resp. symmetric), but this is not checked internally, instead:
737
738- If :attr:`UPLO`\ `= 'L'` (default), only the lower triangular part of the matrix is used in the computation.
739- If :attr:`UPLO`\ `= 'U'`, only the upper triangular part of the matrix is used.
740
741""" + fr"""
742.. note:: {common_notes["sync_note"]}
743""" + r"""
744
745.. seealso::
746
747        :func:`torch.linalg.eigh` computes the full eigenvalue decomposition.
748
749Args:
750    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
751                consisting of symmetric or Hermitian matrices.
752    UPLO ('L', 'U', optional): controls whether to use the upper or lower triangular part
753                               of :attr:`A` in the computations. Default: `'L'`.
754
755Keyword args:
756    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
757
758Returns:
759    A real-valued tensor containing the eigenvalues even when :attr:`A` is complex.
760    The eigenvalues are returned in ascending order.
761
762Examples::
763
764    >>> A = torch.randn(2, 2, dtype=torch.complex128)
765    >>> A = A + A.T.conj()  # creates a Hermitian matrix
766    >>> A
767    tensor([[2.9228+0.0000j, 0.2029-0.0862j],
768            [0.2029+0.0862j, 0.3464+0.0000j]], dtype=torch.complex128)
769    >>> torch.linalg.eigvalsh(A)
770    tensor([0.3277, 2.9415], dtype=torch.float64)
771
772    >>> A = torch.randn(3, 2, 2, dtype=torch.float64)
773    >>> A = A + A.mT  # creates a batch of symmetric matrices
774    >>> torch.linalg.eigvalsh(A)
775    tensor([[ 2.5797,  3.4629],
776            [-4.1605,  1.3780],
777            [-3.1113,  2.7381]], dtype=torch.float64)
778""")
779
780householder_product = _add_docstr(_linalg.linalg_householder_product, r"""
781householder_product(A, tau, *, out=None) -> Tensor
782
783Computes the first `n` columns of a product of Householder matrices.
784
785Let :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`, and
786let :math:`A \in \mathbb{K}^{m \times n}` be a matrix with columns :math:`a_i \in \mathbb{K}^m`
787for :math:`i=1,\ldots,m` with :math:`m \geq n`. Denote by :math:`b_i` the vector resulting from
788zeroing out the first :math:`i-1` components of :math:`a_i` and setting to `1` the :math:`i`-th.
789For a vector :math:`\tau \in \mathbb{K}^k` with :math:`k \leq n`, this function computes the
790first :math:`n` columns of the matrix
791
792.. math::
793
794    H_1H_2 ... H_k \qquad\text{with}\qquad H_i = \mathrm{I}_m - \tau_i b_i b_i^{\text{H}}
795
796where :math:`\mathrm{I}_m` is the `m`-dimensional identity matrix and :math:`b^{\text{H}}` is the
797conjugate transpose when :math:`b` is complex, and the transpose when :math:`b` is real-valued.
798The output matrix is the same size as the input matrix :attr:`A`.
799
800See `Representation of Orthogonal or Unitary Matrices`_ for further details.
801
802Supports inputs of float, double, cfloat and cdouble dtypes.
803Also supports batches of matrices, and if the inputs are batches of matrices then
804the output has the same batch dimensions.
805
806.. seealso::
807
808        :func:`torch.geqrf` can be used together with this function to form the `Q` from the
809        :func:`~qr` decomposition.
810
811        :func:`torch.ormqr` is a related function that computes the matrix multiplication
812        of a product of Householder matrices with another matrix.
813        However, that function is not supported by autograd.
814
815.. warning::
816    Gradient computations are only well-defined if :math:`\tau_i \neq \frac{1}{||a_i||^2}`.
817    If this condition is not met, no error will be thrown, but the gradient produced may contain `NaN`.
818
819Args:
820    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
821    tau (Tensor): tensor of shape `(*, k)` where `*` is zero or more batch dimensions.
822
823Keyword args:
824    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
825
826Raises:
827    RuntimeError: if :attr:`A` doesn't satisfy the requirement `m >= n`,
828                  or :attr:`tau` doesn't satisfy the requirement `n >= k`.
829
830Examples::
831
832    >>> A = torch.randn(2, 2)
833    >>> h, tau = torch.geqrf(A)
834    >>> Q = torch.linalg.householder_product(h, tau)
835    >>> torch.dist(Q, torch.linalg.qr(A).Q)
836    tensor(0.)
837
838    >>> h = torch.randn(3, 2, 2, dtype=torch.complex128)
839    >>> tau = torch.randn(3, 1, dtype=torch.complex128)
840    >>> Q = torch.linalg.householder_product(h, tau)
841    >>> Q
842    tensor([[[ 1.8034+0.4184j,  0.2588-1.0174j],
843            [-0.6853+0.7953j,  2.0790+0.5620j]],
844
845            [[ 1.4581+1.6989j, -1.5360+0.1193j],
846            [ 1.3877-0.6691j,  1.3512+1.3024j]],
847
848            [[ 1.4766+0.5783j,  0.0361+0.6587j],
849            [ 0.6396+0.1612j,  1.3693+0.4481j]]], dtype=torch.complex128)
850
851.. _Representation of Orthogonal or Unitary Matrices:
852    https://www.netlib.org/lapack/lug/node128.html
853""")
854
855ldl_factor = _add_docstr(_linalg.linalg_ldl_factor, r"""
856linalg.ldl_factor(A, *, hermitian=False, out=None) -> (Tensor, Tensor)
857
858Computes a compact representation of the LDL factorization of a Hermitian or symmetric (possibly indefinite) matrix.
859
860When :attr:`A` is complex valued it can be Hermitian (:attr:`hermitian`\ `= True`)
861or symmetric (:attr:`hermitian`\ `= False`).
862
863The factorization is of the form the form :math:`A = L D L^T`.
864If :attr:`hermitian` is `True` then transpose operation is the conjugate transpose.
865
866:math:`L` (or :math:`U`) and :math:`D` are stored in compact form in ``LD``.
867They follow the format specified by `LAPACK's sytrf`_ function.
868These tensors may be used in :func:`torch.linalg.ldl_solve` to solve linear systems.
869
870Supports input of float, double, cfloat and cdouble dtypes.
871Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
872the output has the same batch dimensions.
873
874""" + fr"""
875.. note:: {common_notes["sync_note_has_ex"].format("torch.linalg.ldl_factor_ex")}
876""" + r"""
877
878Args:
879    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
880                consisting of symmetric or Hermitian matrices.
881
882Keyword args:
883    hermitian (bool, optional): whether to consider the input to be Hermitian or symmetric.
884                                For real-valued matrices, this switch has no effect. Default: `False`.
885    out (tuple, optional): tuple of two tensors to write the output to. Ignored if `None`. Default: `None`.
886
887Returns:
888    A named tuple `(LD, pivots)`.
889
890Examples::
891
892    >>> A = torch.randn(3, 3)
893    >>> A = A @ A.mT # make symmetric
894    >>> A
895    tensor([[7.2079, 4.2414, 1.9428],
896            [4.2414, 3.4554, 0.3264],
897            [1.9428, 0.3264, 1.3823]])
898    >>> LD, pivots = torch.linalg.ldl_factor(A)
899    >>> LD
900    tensor([[ 7.2079,  0.0000,  0.0000],
901            [ 0.5884,  0.9595,  0.0000],
902            [ 0.2695, -0.8513,  0.1633]])
903    >>> pivots
904    tensor([1, 2, 3], dtype=torch.int32)
905
906.. _LAPACK's sytrf:
907    https://www.netlib.org/lapack/explore-html/d3/db6/group__double_s_ycomputational_gad91bde1212277b3e909eb6af7f64858a.html
908""")
909
910ldl_factor_ex = _add_docstr(_linalg.linalg_ldl_factor_ex, r"""
911linalg.ldl_factor_ex(A, *, hermitian=False, check_errors=False, out=None) -> (Tensor, Tensor, Tensor)
912
913This is a version of :func:`~ldl_factor` that does not perform error checks unless :attr:`check_errors`\ `= True`.
914It also returns the :attr:`info` tensor returned by `LAPACK's sytrf`_.
915``info`` stores integer error codes from the backend library.
916A positive integer indicates the diagonal element of :math:`D` that is zero.
917Division by 0 will occur if the result is used for solving a system of linear equations.
918``info`` filled with zeros indicates that the factorization was successful.
919If ``check_errors=True`` and ``info`` contains positive integers, then a `RuntimeError` is thrown.
920
921""" + fr"""
922.. note:: {common_notes["sync_note_ex"]}
923
924.. warning:: {common_notes["experimental_warning"]}
925""" + r"""
926
927Args:
928    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions
929                consisting of symmetric or Hermitian matrices.
930
931Keyword args:
932    hermitian (bool, optional): whether to consider the input to be Hermitian or symmetric.
933                                For real-valued matrices, this switch has no effect. Default: `False`.
934    check_errors (bool, optional): controls whether to check the content of ``info`` and raise
935                                   an error if it is non-zero. Default: `False`.
936    out (tuple, optional): tuple of three tensors to write the output to. Ignored if `None`. Default: `None`.
937
938Returns:
939    A named tuple `(LD, pivots, info)`.
940
941Examples::
942
943    >>> A = torch.randn(3, 3)
944    >>> A = A @ A.mT # make symmetric
945    >>> A
946    tensor([[7.2079, 4.2414, 1.9428],
947            [4.2414, 3.4554, 0.3264],
948            [1.9428, 0.3264, 1.3823]])
949    >>> LD, pivots, info = torch.linalg.ldl_factor_ex(A)
950    >>> LD
951    tensor([[ 7.2079,  0.0000,  0.0000],
952            [ 0.5884,  0.9595,  0.0000],
953            [ 0.2695, -0.8513,  0.1633]])
954    >>> pivots
955    tensor([1, 2, 3], dtype=torch.int32)
956    >>> info
957    tensor(0, dtype=torch.int32)
958
959.. _LAPACK's sytrf:
960    https://www.netlib.org/lapack/explore-html/d3/db6/group__double_s_ycomputational_gad91bde1212277b3e909eb6af7f64858a.html
961""")
962
963ldl_solve = _add_docstr(_linalg.linalg_ldl_solve, r"""
964linalg.ldl_solve(LD, pivots, B, *, hermitian=False, out=None) -> Tensor
965
966Computes the solution of a system of linear equations using the LDL factorization.
967
968:attr:`LD` and :attr:`pivots` are the compact representation of the LDL factorization and
969are expected to be computed by :func:`torch.linalg.ldl_factor_ex`.
970:attr:`hermitian` argument to this function should be the same
971as the corresponding arguments in :func:`torch.linalg.ldl_factor_ex`.
972
973Supports input of float, double, cfloat and cdouble dtypes.
974Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
975the output has the same batch dimensions.
976
977""" + fr"""
978.. warning:: {common_notes["experimental_warning"]}
979""" + r"""
980
981Args:
982    LD (Tensor): the `n \times n` matrix or the batch of such matrices of size
983                      `(*, n, n)` where `*` is one or more batch dimensions.
984    pivots (Tensor): the pivots corresponding to the LDL factorization of :attr:`LD`.
985    B (Tensor): right-hand side tensor of shape `(*, n, k)`.
986
987Keyword args:
988    hermitian (bool, optional): whether to consider the decomposed matrix to be Hermitian or symmetric.
989                                For real-valued matrices, this switch has no effect. Default: `False`.
990    out (tuple, optional): output tensor. `B` may be passed as `out` and the result is computed in-place on `B`.
991                           Ignored if `None`. Default: `None`.
992
993Examples::
994
995    >>> A = torch.randn(2, 3, 3)
996    >>> A = A @ A.mT # make symmetric
997    >>> LD, pivots, info = torch.linalg.ldl_factor_ex(A)
998    >>> B = torch.randn(2, 3, 4)
999    >>> X = torch.linalg.ldl_solve(LD, pivots, B)
1000    >>> torch.linalg.norm(A @ X - B)
1001    >>> tensor(0.0001)
1002""")
1003
1004lstsq = _add_docstr(_linalg.linalg_lstsq, r"""
1005torch.linalg.lstsq(A, B, rcond=None, *, driver=None) -> (Tensor, Tensor, Tensor, Tensor)
1006
1007Computes a solution to the least squares problem of a system of linear equations.
1008
1009Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
1010the **least squares problem** for a linear system :math:`AX = B` with
1011:math:`A \in \mathbb{K}^{m \times n}, B \in \mathbb{K}^{m \times k}` is defined as
1012
1013.. math::
1014
1015    \min_{X \in \mathbb{K}^{n \times k}} \|AX - B\|_F
1016
1017where :math:`\|-\|_F` denotes the Frobenius norm.
1018
1019Supports inputs of float, double, cfloat and cdouble dtypes.
1020Also supports batches of matrices, and if the inputs are batches of matrices then
1021the output has the same batch dimensions.
1022
1023:attr:`driver` chooses the backend function that will be used.
1024For CPU inputs the valid values are `'gels'`, `'gelsy'`, `'gelsd`, `'gelss'`.
1025To choose the best driver on CPU consider:
1026
1027- If :attr:`A` is well-conditioned (its `condition number`_ is not too large), or you do not mind some precision loss.
1028
1029  - For a general matrix: `'gelsy'` (QR with pivoting) (default)
1030  - If :attr:`A` is full-rank: `'gels'` (QR)
1031
1032- If :attr:`A` is not well-conditioned.
1033
1034  - `'gelsd'` (tridiagonal reduction and SVD)
1035  - But if you run into memory issues: `'gelss'` (full SVD).
1036
1037For CUDA input, the only valid driver is `'gels'`, which assumes that :attr:`A` is full-rank.
1038
1039See also the `full description of these drivers`_
1040
1041:attr:`rcond` is used to determine the effective rank of the matrices in :attr:`A`
1042when :attr:`driver` is one of (`'gelsy'`, `'gelsd'`, `'gelss'`).
1043In this case, if :math:`\sigma_i` are the singular values of `A` in decreasing order,
1044:math:`\sigma_i` will be rounded down to zero if :math:`\sigma_i \leq \text{rcond} \cdot \sigma_1`.
1045If :attr:`rcond`\ `= None` (default), :attr:`rcond` is set to the machine precision of the dtype of :attr:`A` times `max(m, n)`.
1046
1047This function returns the solution to the problem and some extra information in a named tuple of
1048four tensors `(solution, residuals, rank, singular_values)`. For inputs :attr:`A`, :attr:`B`
1049of shape `(*, m, n)`, `(*, m, k)` respectively, it contains
1050
1051- `solution`: the least squares solution. It has shape `(*, n, k)`.
1052- `residuals`: the squared residuals of the solutions, that is, :math:`\|AX - B\|_F^2`.
1053  It has shape equal to the batch dimensions of :attr:`A`.
1054  It is computed when `m > n` and every matrix in :attr:`A` is full-rank,
1055  otherwise, it is an empty tensor.
1056  If :attr:`A` is a batch of matrices and any matrix in the batch is not full rank,
1057  then an empty tensor is returned. This behavior may change in a future PyTorch release.
1058- `rank`: tensor of ranks of the matrices in :attr:`A`.
1059  It has shape equal to the batch dimensions of :attr:`A`.
1060  It is computed when :attr:`driver` is one of (`'gelsy'`, `'gelsd'`, `'gelss'`),
1061  otherwise it is an empty tensor.
1062- `singular_values`: tensor of singular values of the matrices in :attr:`A`.
1063  It has shape `(*, min(m, n))`.
1064  It is computed when :attr:`driver` is one of (`'gelsd'`, `'gelss'`),
1065  otherwise it is an empty tensor.
1066
1067.. note::
1068    This function computes `X = \ `:attr:`A`\ `.pinverse() @ \ `:attr:`B` in a faster and
1069    more numerically stable way than performing the computations separately.
1070
1071.. warning::
1072    The default value of :attr:`rcond` may change in a future PyTorch release.
1073    It is therefore recommended to use a fixed value to avoid potential
1074    breaking changes.
1075
1076Args:
1077    A (Tensor): lhs tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
1078    B (Tensor): rhs tensor of shape `(*, m, k)` where `*` is zero or more batch dimensions.
1079    rcond (float, optional): used to determine the effective rank of :attr:`A`.
1080                             If :attr:`rcond`\ `= None`, :attr:`rcond` is set to the machine
1081                             precision of the dtype of :attr:`A` times `max(m, n)`. Default: `None`.
1082
1083Keyword args:
1084    driver (str, optional): name of the LAPACK/MAGMA method to be used.
1085        If `None`, `'gelsy'` is used for CPU inputs and `'gels'` for CUDA inputs.
1086        Default: `None`.
1087
1088Returns:
1089    A named tuple `(solution, residuals, rank, singular_values)`.
1090
1091Examples::
1092
1093    >>> A = torch.randn(1,3,3)
1094    >>> A
1095    tensor([[[-1.0838,  0.0225,  0.2275],
1096         [ 0.2438,  0.3844,  0.5499],
1097         [ 0.1175, -0.9102,  2.0870]]])
1098    >>> B = torch.randn(2,3,3)
1099    >>> B
1100    tensor([[[-0.6772,  0.7758,  0.5109],
1101         [-1.4382,  1.3769,  1.1818],
1102         [-0.3450,  0.0806,  0.3967]],
1103        [[-1.3994, -0.1521, -0.1473],
1104         [ 1.9194,  1.0458,  0.6705],
1105         [-1.1802, -0.9796,  1.4086]]])
1106    >>> X = torch.linalg.lstsq(A, B).solution # A is broadcasted to shape (2, 3, 3)
1107    >>> torch.dist(X, torch.linalg.pinv(A) @ B)
1108    tensor(1.5152e-06)
1109
1110    >>> S = torch.linalg.lstsq(A, B, driver='gelsd').singular_values
1111    >>> torch.dist(S, torch.linalg.svdvals(A))
1112    tensor(2.3842e-07)
1113
1114    >>> A[:, 0].zero_()  # Decrease the rank of A
1115    >>> rank = torch.linalg.lstsq(A, B).rank
1116    >>> rank
1117    tensor([2])
1118
1119.. _condition number:
1120    https://pytorch.org/docs/main/linalg.html#torch.linalg.cond
1121.. _full description of these drivers:
1122    https://www.netlib.org/lapack/lug/node27.html
1123""")
1124
1125matrix_power = _add_docstr(_linalg.linalg_matrix_power, r"""
1126matrix_power(A, n, *, out=None) -> Tensor
1127
1128Computes the `n`-th power of a square matrix for an integer `n`.
1129
1130Supports input of float, double, cfloat and cdouble dtypes.
1131Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
1132the output has the same batch dimensions.
1133
1134If :attr:`n`\ `= 0`, it returns the identity matrix (or batch) of the same shape
1135as :attr:`A`. If :attr:`n` is negative, it returns the inverse of each matrix
1136(if invertible) raised to the power of `abs(n)`.
1137
1138.. note::
1139    Consider using :func:`torch.linalg.solve` if possible for multiplying a matrix on the left by
1140    a negative power as, if :attr:`n`\ `> 0`::
1141
1142        torch.linalg.solve(matrix_power(A, n), B) == matrix_power(A, -n)  @ B
1143
1144    It is always preferred to use :func:`~solve` when possible, as it is faster and more
1145    numerically stable than computing :math:`A^{-n}` explicitly.
1146
1147.. seealso::
1148
1149        :func:`torch.linalg.solve` computes :attr:`A`\ `.inverse() @ \ `:attr:`B` with a
1150        numerically stable algorithm.
1151
1152Args:
1153    A (Tensor): tensor of shape `(*, m, m)` where `*` is zero or more batch dimensions.
1154    n (int): the exponent.
1155
1156Keyword args:
1157    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1158
1159Raises:
1160    RuntimeError: if :attr:`n`\ `< 0` and the matrix :attr:`A` or any matrix in the
1161                  batch of matrices :attr:`A` is not invertible.
1162
1163Examples::
1164
1165    >>> A = torch.randn(3, 3)
1166    >>> torch.linalg.matrix_power(A, 0)
1167    tensor([[1., 0., 0.],
1168            [0., 1., 0.],
1169            [0., 0., 1.]])
1170    >>> torch.linalg.matrix_power(A, 3)
1171    tensor([[ 1.0756,  0.4980,  0.0100],
1172            [-1.6617,  1.4994, -1.9980],
1173            [-0.4509,  0.2731,  0.8001]])
1174    >>> torch.linalg.matrix_power(A.expand(2, -1, -1), -2)
1175    tensor([[[ 0.2640,  0.4571, -0.5511],
1176            [-1.0163,  0.3491, -1.5292],
1177            [-0.4899,  0.0822,  0.2773]],
1178            [[ 0.2640,  0.4571, -0.5511],
1179            [-1.0163,  0.3491, -1.5292],
1180            [-0.4899,  0.0822,  0.2773]]])
1181""")
1182
1183matrix_rank = _add_docstr(_linalg.linalg_matrix_rank, r"""
1184linalg.matrix_rank(A, *, atol=None, rtol=None, hermitian=False, out=None) -> Tensor
1185
1186Computes the numerical rank of a matrix.
1187
1188The matrix rank is computed as the number of singular values
1189(or eigenvalues in absolute value when :attr:`hermitian`\ `= True`)
1190that are greater than :math:`\max(\text{atol}, \sigma_1 * \text{rtol})` threshold,
1191where :math:`\sigma_1` is the largest singular value (or eigenvalue).
1192
1193Supports input of float, double, cfloat and cdouble dtypes.
1194Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
1195the output has the same batch dimensions.
1196
1197If :attr:`hermitian`\ `= True`, :attr:`A` is assumed to be Hermitian if complex or
1198symmetric if real, but this is not checked internally. Instead, just the lower
1199triangular part of the matrix is used in the computations.
1200
1201If :attr:`rtol` is not specified and :attr:`A` is a matrix of dimensions `(m, n)`,
1202the relative tolerance is set to be :math:`\text{rtol} = \max(m, n) \varepsilon`
1203and :math:`\varepsilon` is the epsilon value for the dtype of :attr:`A` (see :class:`.finfo`).
1204If :attr:`rtol` is not specified and :attr:`atol` is specified to be larger than zero then
1205:attr:`rtol` is set to zero.
1206
1207If :attr:`atol` or :attr:`rtol` is a :class:`torch.Tensor`, its shape must be broadcastable to that
1208of the singular values of :attr:`A` as returned by :func:`torch.linalg.svdvals`.
1209
1210.. note::
1211    This function has NumPy compatible variant `linalg.matrix_rank(A, tol, hermitian=False)`.
1212    However, use of the positional argument :attr:`tol` is deprecated in favor of :attr:`atol` and :attr:`rtol`.
1213
1214""" + fr"""
1215.. note:: The matrix rank is computed using a singular value decomposition
1216          :func:`torch.linalg.svdvals` if :attr:`hermitian`\ `= False` (default) and the eigenvalue
1217          decomposition :func:`torch.linalg.eigvalsh` when :attr:`hermitian`\ `= True`.
1218          {common_notes["sync_note"]}
1219""" + r"""
1220
1221Args:
1222    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
1223    tol (float, Tensor, optional): [NumPy Compat] Alias for :attr:`atol`. Default: `None`.
1224
1225Keyword args:
1226    atol (float, Tensor, optional): the absolute tolerance value. When `None` it's considered to be zero.
1227                                    Default: `None`.
1228    rtol (float, Tensor, optional): the relative tolerance value. See above for the value it takes when `None`.
1229                                    Default: `None`.
1230    hermitian(bool): indicates whether :attr:`A` is Hermitian if complex
1231                     or symmetric if real. Default: `False`.
1232    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1233
1234Examples::
1235
1236    >>> A = torch.eye(10)
1237    >>> torch.linalg.matrix_rank(A)
1238    tensor(10)
1239    >>> B = torch.eye(10)
1240    >>> B[0, 0] = 0
1241    >>> torch.linalg.matrix_rank(B)
1242    tensor(9)
1243
1244    >>> A = torch.randn(4, 3, 2)
1245    >>> torch.linalg.matrix_rank(A)
1246    tensor([2, 2, 2, 2])
1247
1248    >>> A = torch.randn(2, 4, 2, 3)
1249    >>> torch.linalg.matrix_rank(A)
1250    tensor([[2, 2, 2, 2],
1251            [2, 2, 2, 2]])
1252
1253    >>> A = torch.randn(2, 4, 3, 3, dtype=torch.complex64)
1254    >>> torch.linalg.matrix_rank(A)
1255    tensor([[3, 3, 3, 3],
1256            [3, 3, 3, 3]])
1257    >>> torch.linalg.matrix_rank(A, hermitian=True)
1258    tensor([[3, 3, 3, 3],
1259            [3, 3, 3, 3]])
1260    >>> torch.linalg.matrix_rank(A, atol=1.0, rtol=0.0)
1261    tensor([[3, 2, 2, 2],
1262            [1, 2, 1, 2]])
1263    >>> torch.linalg.matrix_rank(A, atol=1.0, rtol=0.0, hermitian=True)
1264    tensor([[2, 2, 2, 1],
1265            [1, 2, 2, 2]])
1266""")
1267
1268norm = _add_docstr(_linalg.linalg_norm, r"""
1269linalg.norm(A, ord=None, dim=None, keepdim=False, *, out=None, dtype=None) -> Tensor
1270
1271Computes a vector or matrix norm.
1272
1273Supports input of float, double, cfloat and cdouble dtypes.
1274
1275Whether this function computes a vector or matrix norm is determined as follows:
1276
1277- If :attr:`dim` is an `int`, the vector norm will be computed.
1278- If :attr:`dim` is a `2`-`tuple`, the matrix norm will be computed.
1279- If :attr:`dim`\ `= None` and :attr:`ord`\ `= None`,
1280  :attr:`A` will be flattened to 1D and the `2`-norm of the resulting vector will be computed.
1281- If :attr:`dim`\ `= None` and :attr:`ord` `!= None`, :attr:`A` must be 1D or 2D.
1282
1283:attr:`ord` defines the norm that is computed. The following norms are supported:
1284
1285======================     =========================  ========================================================
1286:attr:`ord`                norm for matrices          norm for vectors
1287======================     =========================  ========================================================
1288`None` (default)           Frobenius norm             `2`-norm (see below)
1289`'fro'`                    Frobenius norm             -- not supported --
1290`'nuc'`                    nuclear norm               -- not supported --
1291`inf`                      `max(sum(abs(x), dim=1))`  `max(abs(x))`
1292`-inf`                     `min(sum(abs(x), dim=1))`  `min(abs(x))`
1293`0`                        -- not supported --        `sum(x != 0)`
1294`1`                        `max(sum(abs(x), dim=0))`  as below
1295`-1`                       `min(sum(abs(x), dim=0))`  as below
1296`2`                        largest singular value     as below
1297`-2`                       smallest singular value    as below
1298other `int` or `float`     -- not supported --        `sum(abs(x)^{ord})^{(1 / ord)}`
1299======================     =========================  ========================================================
1300
1301where `inf` refers to `float('inf')`, NumPy's `inf` object, or any equivalent object.
1302
1303.. seealso::
1304
1305        :func:`torch.linalg.vector_norm` computes a vector norm.
1306
1307        :func:`torch.linalg.matrix_norm` computes a matrix norm.
1308
1309        The above functions are often clearer and more flexible than using :func:`torch.linalg.norm`.
1310        For example, `torch.linalg.norm(A, ord=1, dim=(0, 1))` always
1311        computes a matrix norm, but with `torch.linalg.vector_norm(A, ord=1, dim=(0, 1))` it is possible
1312        to compute a vector norm over the two dimensions.
1313
1314Args:
1315    A (Tensor): tensor of shape `(*, n)` or `(*, m, n)` where `*` is zero or more batch dimensions
1316    ord (int, float, inf, -inf, 'fro', 'nuc', optional): order of norm. Default: `None`
1317    dim (int, Tuple[int], optional): dimensions over which to compute
1318        the vector or matrix norm. See above for the behavior when :attr:`dim`\ `= None`.
1319        Default: `None`
1320    keepdim (bool, optional): If set to `True`, the reduced dimensions are retained
1321        in the result as dimensions with size one. Default: `False`
1322
1323Keyword args:
1324    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1325    dtype (:class:`torch.dtype`, optional): If specified, the input tensor is cast to
1326        :attr:`dtype` before performing the operation, and the returned tensor's type
1327        will be :attr:`dtype`. Default: `None`
1328
1329Returns:
1330    A real-valued tensor, even when :attr:`A` is complex.
1331
1332Examples::
1333
1334    >>> from torch import linalg as LA
1335    >>> a = torch.arange(9, dtype=torch.float) - 4
1336    >>> a
1337    tensor([-4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
1338    >>> B = a.reshape((3, 3))
1339    >>> B
1340    tensor([[-4., -3., -2.],
1341            [-1.,  0.,  1.],
1342            [ 2.,  3.,  4.]])
1343
1344    >>> LA.norm(a)
1345    tensor(7.7460)
1346    >>> LA.norm(B)
1347    tensor(7.7460)
1348    >>> LA.norm(B, 'fro')
1349    tensor(7.7460)
1350    >>> LA.norm(a, float('inf'))
1351    tensor(4.)
1352    >>> LA.norm(B, float('inf'))
1353    tensor(9.)
1354    >>> LA.norm(a, -float('inf'))
1355    tensor(0.)
1356    >>> LA.norm(B, -float('inf'))
1357    tensor(2.)
1358
1359    >>> LA.norm(a, 1)
1360    tensor(20.)
1361    >>> LA.norm(B, 1)
1362    tensor(7.)
1363    >>> LA.norm(a, -1)
1364    tensor(0.)
1365    >>> LA.norm(B, -1)
1366    tensor(6.)
1367    >>> LA.norm(a, 2)
1368    tensor(7.7460)
1369    >>> LA.norm(B, 2)
1370    tensor(7.3485)
1371
1372    >>> LA.norm(a, -2)
1373    tensor(0.)
1374    >>> LA.norm(B.double(), -2)
1375    tensor(1.8570e-16, dtype=torch.float64)
1376    >>> LA.norm(a, 3)
1377    tensor(5.8480)
1378    >>> LA.norm(a, -3)
1379    tensor(0.)
1380
1381Using the :attr:`dim` argument to compute vector norms::
1382
1383    >>> c = torch.tensor([[1., 2., 3.],
1384    ...                   [-1, 1, 4]])
1385    >>> LA.norm(c, dim=0)
1386    tensor([1.4142, 2.2361, 5.0000])
1387    >>> LA.norm(c, dim=1)
1388    tensor([3.7417, 4.2426])
1389    >>> LA.norm(c, ord=1, dim=1)
1390    tensor([6., 6.])
1391
1392Using the :attr:`dim` argument to compute matrix norms::
1393
1394    >>> A = torch.arange(8, dtype=torch.float).reshape(2, 2, 2)
1395    >>> LA.norm(A, dim=(1,2))
1396    tensor([ 3.7417, 11.2250])
1397    >>> LA.norm(A[0, :, :]), LA.norm(A[1, :, :])
1398    (tensor(3.7417), tensor(11.2250))
1399""")
1400
1401vector_norm = _add_docstr(_linalg.linalg_vector_norm, r"""
1402linalg.vector_norm(x, ord=2, dim=None, keepdim=False, *, dtype=None, out=None) -> Tensor
1403
1404Computes a vector norm.
1405
1406If :attr:`x` is complex valued, it computes the norm of :attr:`x`\ `.abs()`
1407
1408Supports input of float, double, cfloat and cdouble dtypes.
1409
1410This function does not necessarily treat multidimensional :attr:`x` as a batch of
1411vectors, instead:
1412
1413- If :attr:`dim`\ `= None`, :attr:`x` will be flattened before the norm is computed.
1414- If :attr:`dim` is an `int` or a `tuple`, the norm will be computed over these dimensions
1415  and the other dimensions will be treated as batch dimensions.
1416
1417This behavior is for consistency with :func:`torch.linalg.norm`.
1418
1419:attr:`ord` defines the vector norm that is computed. The following norms are supported:
1420
1421======================   ===============================
1422:attr:`ord`              vector norm
1423======================   ===============================
1424`2` (default)            `2`-norm (see below)
1425`inf`                    `max(abs(x))`
1426`-inf`                   `min(abs(x))`
1427`0`                      `sum(x != 0)`
1428other `int` or `float`   `sum(abs(x)^{ord})^{(1 / ord)}`
1429======================   ===============================
1430
1431where `inf` refers to `float('inf')`, NumPy's `inf` object, or any equivalent object.
1432
1433:attr:`dtype` may be used to perform the computation in a more precise dtype.
1434It is semantically equivalent to calling ``linalg.vector_norm(x.to(dtype))``
1435but it is faster in some cases.
1436
1437.. seealso::
1438
1439        :func:`torch.linalg.matrix_norm` computes a matrix norm.
1440
1441Args:
1442    x (Tensor): tensor, flattened by default, but this behavior can be
1443        controlled using :attr:`dim`.
1444    ord (int, float, inf, -inf, 'fro', 'nuc', optional): order of norm. Default: `2`
1445    dim (int, Tuple[int], optional): dimensions over which to compute
1446        the norm. See above for the behavior when :attr:`dim`\ `= None`.
1447        Default: `None`
1448    keepdim (bool, optional): If set to `True`, the reduced dimensions are retained
1449        in the result as dimensions with size one. Default: `False`
1450
1451Keyword args:
1452    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1453    dtype (:class:`torch.dtype`, optional): type used to perform the accumulation and the return.
1454        If specified, :attr:`x` is cast to :attr:`dtype` before performing the operation,
1455        and the returned tensor's type will be :attr:`dtype` if real and of its real counterpart if complex.
1456        :attr:`dtype` may be complex if :attr:`x` is complex, otherwise it must be real.
1457        :attr:`x` should be convertible without narrowing to :attr:`dtype`. Default: None
1458
1459Returns:
1460    A real-valued tensor, even when :attr:`x` is complex.
1461
1462Examples::
1463
1464    >>> from torch import linalg as LA
1465    >>> a = torch.arange(9, dtype=torch.float) - 4
1466    >>> a
1467    tensor([-4., -3., -2., -1.,  0.,  1.,  2.,  3.,  4.])
1468    >>> B = a.reshape((3, 3))
1469    >>> B
1470    tensor([[-4., -3., -2.],
1471            [-1.,  0.,  1.],
1472            [ 2.,  3.,  4.]])
1473    >>> LA.vector_norm(a, ord=3.5)
1474    tensor(5.4345)
1475    >>> LA.vector_norm(B, ord=3.5)
1476    tensor(5.4345)
1477""")
1478
1479matrix_norm = _add_docstr(_linalg.linalg_matrix_norm, r"""
1480linalg.matrix_norm(A, ord='fro', dim=(-2, -1), keepdim=False, *, dtype=None, out=None) -> Tensor
1481
1482Computes a matrix norm.
1483
1484If :attr:`A` is complex valued, it computes the norm of :attr:`A`\ `.abs()`
1485
1486Support input of float, double, cfloat and cdouble dtypes.
1487Also supports batches of matrices: the norm will be computed over the
1488dimensions specified by the 2-tuple :attr:`dim` and the other dimensions will
1489be treated as batch dimensions. The output will have the same batch dimensions.
1490
1491:attr:`ord` defines the matrix norm that is computed. The following norms are supported:
1492
1493======================   ========================================================
1494:attr:`ord`              matrix norm
1495======================   ========================================================
1496`'fro'` (default)        Frobenius norm
1497`'nuc'`                  nuclear norm
1498`inf`                    `max(sum(abs(x), dim=1))`
1499`-inf`                   `min(sum(abs(x), dim=1))`
1500`1`                      `max(sum(abs(x), dim=0))`
1501`-1`                     `min(sum(abs(x), dim=0))`
1502`2`                      largest singular value
1503`-2`                     smallest singular value
1504======================   ========================================================
1505
1506where `inf` refers to `float('inf')`, NumPy's `inf` object, or any equivalent object.
1507
1508Args:
1509    A (Tensor): tensor with two or more dimensions. By default its
1510        shape is interpreted as `(*, m, n)` where `*` is zero or more
1511        batch dimensions, but this behavior can be controlled using :attr:`dim`.
1512    ord (int, inf, -inf, 'fro', 'nuc', optional): order of norm. Default: `'fro'`
1513    dim (Tuple[int, int], optional): dimensions over which to compute the norm. Default: `(-2, -1)`
1514    keepdim (bool, optional): If set to `True`, the reduced dimensions are retained
1515        in the result as dimensions with size one. Default: `False`
1516
1517Keyword args:
1518    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1519    dtype (:class:`torch.dtype`, optional): If specified, the input tensor is cast to
1520        :attr:`dtype` before performing the operation, and the returned tensor's type
1521        will be :attr:`dtype`. Default: `None`
1522
1523Returns:
1524    A real-valued tensor, even when :attr:`A` is complex.
1525
1526Examples::
1527
1528    >>> from torch import linalg as LA
1529    >>> A = torch.arange(9, dtype=torch.float).reshape(3, 3)
1530    >>> A
1531    tensor([[0., 1., 2.],
1532            [3., 4., 5.],
1533            [6., 7., 8.]])
1534    >>> LA.matrix_norm(A)
1535    tensor(14.2829)
1536    >>> LA.matrix_norm(A, ord=-1)
1537    tensor(9.)
1538    >>> B = A.expand(2, -1, -1)
1539    >>> B
1540    tensor([[[0., 1., 2.],
1541            [3., 4., 5.],
1542            [6., 7., 8.]],
1543
1544            [[0., 1., 2.],
1545            [3., 4., 5.],
1546            [6., 7., 8.]]])
1547    >>> LA.matrix_norm(B)
1548    tensor([14.2829, 14.2829])
1549    >>> LA.matrix_norm(B, dim=(0, 2))
1550    tensor([ 3.1623, 10.0000, 17.2627])
1551""")
1552
1553matmul = _add_docstr(_linalg.linalg_matmul, r"""
1554linalg.matmul(input, other, *, out=None) -> Tensor
1555
1556Alias for :func:`torch.matmul`
1557""")
1558
1559diagonal = _add_docstr(_linalg.linalg_diagonal, r"""
1560linalg.diagonal(A, *, offset=0, dim1=-2, dim2=-1) -> Tensor
1561
1562Alias for :func:`torch.diagonal` with defaults :attr:`dim1`\ `= -2`, :attr:`dim2`\ `= -1`.
1563""")
1564
1565multi_dot = _add_docstr(_linalg.linalg_multi_dot, r"""
1566linalg.multi_dot(tensors, *, out=None)
1567
1568Efficiently multiplies two or more matrices by reordering the multiplications so that
1569the fewest arithmetic operations are performed.
1570
1571Supports inputs of float, double, cfloat and cdouble dtypes.
1572This function does not support batched inputs.
1573
1574Every tensor in :attr:`tensors` must be 2D, except for the first and last which
1575may be 1D. If the first tensor is a 1D vector of shape `(n,)` it is treated as a row vector
1576of shape `(1, n)`, similarly if the last tensor is a 1D vector of shape `(n,)` it is treated
1577as a column vector of shape `(n, 1)`.
1578
1579If the first and last tensors are matrices, the output will be a matrix.
1580However, if either is a 1D vector, then the output will be a 1D vector.
1581
1582Differences with `numpy.linalg.multi_dot`:
1583
1584- Unlike `numpy.linalg.multi_dot`, the first and last tensors must either be 1D or 2D
1585  whereas NumPy allows them to be nD
1586
1587.. warning:: This function does not broadcast.
1588
1589.. note:: This function is implemented by chaining :func:`torch.mm` calls after
1590          computing the optimal matrix multiplication order.
1591
1592.. note:: The cost of multiplying two matrices with shapes `(a, b)` and `(b, c)` is
1593          `a * b * c`. Given matrices `A`, `B`, `C` with shapes `(10, 100)`,
1594          `(100, 5)`, `(5, 50)` respectively, we can calculate the cost of different
1595          multiplication orders as follows:
1596
1597          .. math::
1598
1599             \begin{align*}
1600             \operatorname{cost}((AB)C) &= 10 \times 100 \times 5 + 10 \times 5 \times 50 = 7500 \\
1601             \operatorname{cost}(A(BC)) &= 10 \times 100 \times 50 + 100 \times 5 \times 50 = 75000
1602             \end{align*}
1603
1604          In this case, multiplying `A` and `B` first followed by `C` is 10 times faster.
1605
1606Args:
1607    tensors (Sequence[Tensor]): two or more tensors to multiply. The first and last
1608        tensors may be 1D or 2D. Every other tensor must be 2D.
1609
1610Keyword args:
1611    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1612
1613Examples::
1614
1615    >>> from torch.linalg import multi_dot
1616
1617    >>> multi_dot([torch.tensor([1, 2]), torch.tensor([2, 3])])
1618    tensor(8)
1619    >>> multi_dot([torch.tensor([[1, 2]]), torch.tensor([2, 3])])
1620    tensor([8])
1621    >>> multi_dot([torch.tensor([[1, 2]]), torch.tensor([[2], [3]])])
1622    tensor([[8]])
1623
1624    >>> A = torch.arange(2 * 3).view(2, 3)
1625    >>> B = torch.arange(3 * 2).view(3, 2)
1626    >>> C = torch.arange(2 * 2).view(2, 2)
1627    >>> multi_dot((A, B, C))
1628    tensor([[ 26,  49],
1629            [ 80, 148]])
1630""")
1631
1632svd = _add_docstr(_linalg.linalg_svd, r"""
1633linalg.svd(A, full_matrices=True, *, driver=None, out=None) -> (Tensor, Tensor, Tensor)
1634
1635Computes the singular value decomposition (SVD) of a matrix.
1636
1637Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
1638the **full SVD** of a matrix
1639:math:`A \in \mathbb{K}^{m \times n}`, if `k = min(m,n)`, is defined as
1640
1641.. math::
1642
1643    A = U \operatorname{diag}(S) V^{\text{H}}
1644    \mathrlap{\qquad U \in \mathbb{K}^{m \times m}, S \in \mathbb{R}^k, V \in \mathbb{K}^{n \times n}}
1645
1646where :math:`\operatorname{diag}(S) \in \mathbb{K}^{m \times n}`,
1647:math:`V^{\text{H}}` is the conjugate transpose when :math:`V` is complex, and the transpose when :math:`V` is real-valued.
1648The matrices  :math:`U`, :math:`V` (and thus :math:`V^{\text{H}}`) are orthogonal in the real case, and unitary in the complex case.
1649
1650When `m > n` (resp. `m < n`) we can drop the last `m - n` (resp. `n - m`) columns of `U` (resp. `V`) to form the **reduced SVD**:
1651
1652.. math::
1653
1654    A = U \operatorname{diag}(S) V^{\text{H}}
1655    \mathrlap{\qquad U \in \mathbb{K}^{m \times k}, S \in \mathbb{R}^k, V \in \mathbb{K}^{k \times n}}
1656
1657where :math:`\operatorname{diag}(S) \in \mathbb{K}^{k \times k}`.
1658In this case, :math:`U` and :math:`V` also have orthonormal columns.
1659
1660Supports input of float, double, cfloat and cdouble dtypes.
1661Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
1662the output has the same batch dimensions.
1663
1664The returned decomposition is a named tuple `(U, S, Vh)`
1665which corresponds to :math:`U`, :math:`S`, :math:`V^{\text{H}}` above.
1666
1667The singular values are returned in descending order.
1668
1669The parameter :attr:`full_matrices` chooses between the full (default) and reduced SVD.
1670
1671The :attr:`driver` kwarg may be used in CUDA with a cuSOLVER backend to choose the algorithm used to compute the SVD.
1672The choice of a driver is a trade-off between accuracy and speed.
1673
1674- If :attr:`A` is well-conditioned (its `condition number`_ is not too large), or you do not mind some precision loss.
1675
1676  - For a general matrix: `'gesvdj'` (Jacobi method)
1677  - If :attr:`A` is tall or wide (`m >> n` or `m << n`): `'gesvda'` (Approximate method)
1678
1679- If :attr:`A` is not well-conditioned or precision is relevant: `'gesvd'` (QR based)
1680
1681By default (:attr:`driver`\ `= None`), we call `'gesvdj'` and, if it fails, we fallback to `'gesvd'`.
1682
1683Differences with `numpy.linalg.svd`:
1684
1685- Unlike `numpy.linalg.svd`, this function always returns a tuple of three tensors
1686  and it doesn't support `compute_uv` argument.
1687  Please use :func:`torch.linalg.svdvals`, which computes only the singular values,
1688  instead of `compute_uv=False`.
1689
1690.. note:: When :attr:`full_matrices`\ `= True`, the gradients with respect to `U[..., :, min(m, n):]`
1691          and `Vh[..., min(m, n):, :]` will be ignored, as those vectors can be arbitrary bases
1692          of the corresponding subspaces.
1693
1694.. warning:: The returned tensors `U` and `V` are not unique, nor are they continuous with
1695             respect to :attr:`A`.
1696             Due to this lack of uniqueness, different hardware and software may compute
1697             different singular vectors.
1698
1699             This non-uniqueness is caused by the fact that multiplying any pair of singular
1700             vectors :math:`u_k, v_k` by `-1` in the real case or by
1701             :math:`e^{i \phi}, \phi \in \mathbb{R}` in the complex case produces another two
1702             valid singular vectors of the matrix.
1703             For this reason, the loss function shall not depend on this :math:`e^{i \phi}` quantity,
1704             as it is not well-defined.
1705             This is checked for complex inputs when computing the gradients of this function. As such,
1706             when inputs are complex and are on a CUDA device, the computation of the gradients
1707             of this function synchronizes that device with the CPU.
1708
1709.. warning:: Gradients computed using `U` or `Vh` will only be finite when
1710             :attr:`A` does not have repeated singular values. If :attr:`A` is rectangular,
1711             additionally, zero must also not be one of its singular values.
1712             Furthermore, if the distance between any two singular values is close to zero,
1713             the gradient will be numerically unstable, as it depends on the singular values
1714             :math:`\sigma_i` through the computation of
1715             :math:`\frac{1}{\min_{i \neq j} \sigma_i^2 - \sigma_j^2}`.
1716             In the rectangular case, the gradient will also be numerically unstable when
1717             :attr:`A` has small singular values, as it also depends on the computation of
1718             :math:`\frac{1}{\sigma_i}`.
1719
1720.. seealso::
1721
1722        :func:`torch.linalg.svdvals` computes only the singular values.
1723        Unlike :func:`torch.linalg.svd`, the gradients of :func:`~svdvals` are always
1724        numerically stable.
1725
1726        :func:`torch.linalg.eig` for a function that computes another type of spectral
1727        decomposition of a matrix. The eigendecomposition works just on square matrices.
1728
1729        :func:`torch.linalg.eigh` for a (faster) function that computes the eigenvalue decomposition
1730        for Hermitian and symmetric matrices.
1731
1732        :func:`torch.linalg.qr` for another (much faster) decomposition that works on general
1733        matrices.
1734
1735Args:
1736    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
1737    full_matrices (bool, optional): controls whether to compute the full or reduced
1738                                    SVD, and consequently,
1739                                    the shape of the returned tensors
1740                                    `U` and `Vh`. Default: `True`.
1741
1742Keyword args:
1743    driver (str, optional): name of the cuSOLVER method to be used. This keyword argument only works on CUDA inputs.
1744        Available options are: `None`, `gesvd`, `gesvdj`, and `gesvda`.
1745        Default: `None`.
1746    out (tuple, optional): output tuple of three tensors. Ignored if `None`.
1747
1748Returns:
1749    A named tuple `(U, S, Vh)` which corresponds to :math:`U`, :math:`S`, :math:`V^{\text{H}}` above.
1750
1751    `S` will always be real-valued, even when :attr:`A` is complex.
1752    It will also be ordered in descending order.
1753
1754    `U` and `Vh` will have the same dtype as :attr:`A`. The left / right singular vectors will be given by
1755    the columns of `U` and the rows of `Vh` respectively.
1756
1757Examples::
1758
1759    >>> A = torch.randn(5, 3)
1760    >>> U, S, Vh = torch.linalg.svd(A, full_matrices=False)
1761    >>> U.shape, S.shape, Vh.shape
1762    (torch.Size([5, 3]), torch.Size([3]), torch.Size([3, 3]))
1763    >>> torch.dist(A, U @ torch.diag(S) @ Vh)
1764    tensor(1.0486e-06)
1765
1766    >>> U, S, Vh = torch.linalg.svd(A)
1767    >>> U.shape, S.shape, Vh.shape
1768    (torch.Size([5, 5]), torch.Size([3]), torch.Size([3, 3]))
1769    >>> torch.dist(A, U[:, :3] @ torch.diag(S) @ Vh)
1770    tensor(1.0486e-06)
1771
1772    >>> A = torch.randn(7, 5, 3)
1773    >>> U, S, Vh = torch.linalg.svd(A, full_matrices=False)
1774    >>> torch.dist(A, U @ torch.diag_embed(S) @ Vh)
1775    tensor(3.0957e-06)
1776
1777.. _condition number:
1778    https://pytorch.org/docs/main/linalg.html#torch.linalg.cond
1779.. _the resulting vectors will span the same subspace:
1780    https://en.wikipedia.org/wiki/Singular_value_decomposition#Singular_values,_singular_vectors,_and_their_relation_to_the_SVD
1781""")
1782
1783svdvals = _add_docstr(_linalg.linalg_svdvals, r"""
1784linalg.svdvals(A, *, driver=None, out=None) -> Tensor
1785
1786Computes the singular values of a matrix.
1787
1788Supports input of float, double, cfloat and cdouble dtypes.
1789Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
1790the output has the same batch dimensions.
1791
1792The singular values are returned in descending order.
1793
1794.. note:: This function is equivalent to NumPy's `linalg.svd(A, compute_uv=False)`.
1795
1796""" + fr"""
1797.. note:: {common_notes["sync_note"]}
1798""" + r"""
1799
1800.. seealso::
1801
1802        :func:`torch.linalg.svd` computes the full singular value decomposition.
1803
1804Args:
1805    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
1806
1807Keyword args:
1808    driver (str, optional): name of the cuSOLVER method to be used. This keyword argument only works on CUDA inputs.
1809        Available options are: `None`, `gesvd`, `gesvdj`, and `gesvda`.
1810        Check :func:`torch.linalg.svd` for details.
1811        Default: `None`.
1812    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1813
1814Returns:
1815    A real-valued tensor, even when :attr:`A` is complex.
1816
1817Examples::
1818
1819    >>> A = torch.randn(5, 3)
1820    >>> S = torch.linalg.svdvals(A)
1821    >>> S
1822    tensor([2.5139, 2.1087, 1.1066])
1823
1824    >>> torch.dist(S, torch.linalg.svd(A, full_matrices=False).S)
1825    tensor(2.4576e-07)
1826""")
1827
1828cond = _add_docstr(_linalg.linalg_cond, r"""
1829linalg.cond(A, p=None, *, out=None) -> Tensor
1830
1831Computes the condition number of a matrix with respect to a matrix norm.
1832
1833Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
1834the **condition number** :math:`\kappa` of a matrix
1835:math:`A \in \mathbb{K}^{n \times n}` is defined as
1836
1837.. math::
1838
1839    \kappa(A) = \|A\|_p\|A^{-1}\|_p
1840
1841The condition number of :attr:`A` measures the numerical stability of the linear system `AX = B`
1842with respect to a matrix norm.
1843
1844Supports input of float, double, cfloat and cdouble dtypes.
1845Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
1846the output has the same batch dimensions.
1847
1848:attr:`p` defines the matrix norm that is computed. The following norms are supported:
1849
1850=========    =================================
1851:attr:`p`    matrix norm
1852=========    =================================
1853`None`       `2`-norm (largest singular value)
1854`'fro'`      Frobenius norm
1855`'nuc'`      nuclear norm
1856`inf`        `max(sum(abs(x), dim=1))`
1857`-inf`       `min(sum(abs(x), dim=1))`
1858`1`          `max(sum(abs(x), dim=0))`
1859`-1`         `min(sum(abs(x), dim=0))`
1860`2`          largest singular value
1861`-2`         smallest singular value
1862=========    =================================
1863
1864where `inf` refers to `float('inf')`, NumPy's `inf` object, or any equivalent object.
1865
1866For :attr:`p` is one of `('fro', 'nuc', inf, -inf, 1, -1)`, this function uses
1867:func:`torch.linalg.norm` and :func:`torch.linalg.inv`.
1868As such, in this case, the matrix (or every matrix in the batch) :attr:`A` has to be square
1869and invertible.
1870
1871For :attr:`p` in `(2, -2)`, this function can be computed in terms of the singular values
1872:math:`\sigma_1 \geq \ldots \geq \sigma_n`
1873
1874.. math::
1875
1876    \kappa_2(A) = \frac{\sigma_1}{\sigma_n}\qquad \kappa_{-2}(A) = \frac{\sigma_n}{\sigma_1}
1877
1878In these cases, it is computed using :func:`torch.linalg.svdvals`. For these norms, the matrix
1879(or every matrix in the batch) :attr:`A` may have any shape.
1880
1881.. note :: When inputs are on a CUDA device, this function synchronizes that device with the CPU
1882           if :attr:`p` is one of `('fro', 'nuc', inf, -inf, 1, -1)`.
1883
1884.. seealso::
1885
1886        :func:`torch.linalg.solve` for a function that solves linear systems of square matrices.
1887
1888        :func:`torch.linalg.lstsq` for a function that solves linear systems of general matrices.
1889
1890Args:
1891    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions
1892                    for :attr:`p` in `(2, -2)`, and of shape `(*, n, n)` where every matrix
1893                    is invertible for :attr:`p` in `('fro', 'nuc', inf, -inf, 1, -1)`.
1894    p (int, inf, -inf, 'fro', 'nuc', optional):
1895        the type of the matrix norm to use in the computations (see above). Default: `None`
1896
1897Keyword args:
1898    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
1899
1900Returns:
1901    A real-valued tensor, even when :attr:`A` is complex.
1902
1903Raises:
1904    RuntimeError:
1905        if :attr:`p` is one of `('fro', 'nuc', inf, -inf, 1, -1)`
1906        and the :attr:`A` matrix or any matrix in the batch :attr:`A` is not square
1907        or invertible.
1908
1909Examples::
1910
1911    >>> A = torch.randn(3, 4, 4, dtype=torch.complex64)
1912    >>> torch.linalg.cond(A)
1913    >>> A = torch.tensor([[1., 0, -1], [0, 1, 0], [1, 0, 1]])
1914    >>> torch.linalg.cond(A)
1915    tensor([1.4142])
1916    >>> torch.linalg.cond(A, 'fro')
1917    tensor(3.1623)
1918    >>> torch.linalg.cond(A, 'nuc')
1919    tensor(9.2426)
1920    >>> torch.linalg.cond(A, float('inf'))
1921    tensor(2.)
1922    >>> torch.linalg.cond(A, float('-inf'))
1923    tensor(1.)
1924    >>> torch.linalg.cond(A, 1)
1925    tensor(2.)
1926    >>> torch.linalg.cond(A, -1)
1927    tensor(1.)
1928    >>> torch.linalg.cond(A, 2)
1929    tensor([1.4142])
1930    >>> torch.linalg.cond(A, -2)
1931    tensor([0.7071])
1932
1933    >>> A = torch.randn(2, 3, 3)
1934    >>> torch.linalg.cond(A)
1935    tensor([[9.5917],
1936            [3.2538]])
1937    >>> A = torch.randn(2, 3, 3, dtype=torch.complex64)
1938    >>> torch.linalg.cond(A)
1939    tensor([[4.6245],
1940            [4.5671]])
1941""")
1942
1943pinv = _add_docstr(_linalg.linalg_pinv, r"""
1944linalg.pinv(A, *, atol=None, rtol=None, hermitian=False, out=None) -> Tensor
1945
1946Computes the pseudoinverse (Moore-Penrose inverse) of a matrix.
1947
1948The pseudoinverse may be `defined algebraically`_
1949but it is more computationally convenient to understand it `through the SVD`_
1950
1951Supports input of float, double, cfloat and cdouble dtypes.
1952Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
1953the output has the same batch dimensions.
1954
1955If :attr:`hermitian`\ `= True`, :attr:`A` is assumed to be Hermitian if complex or
1956symmetric if real, but this is not checked internally. Instead, just the lower
1957triangular part of the matrix is used in the computations.
1958
1959The singular values (or the norm of the eigenvalues when :attr:`hermitian`\ `= True`)
1960that are below :math:`\max(\text{atol}, \sigma_1 \cdot \text{rtol})` threshold are
1961treated as zero and discarded in the computation,
1962where :math:`\sigma_1` is the largest singular value (or eigenvalue).
1963
1964If :attr:`rtol` is not specified and :attr:`A` is a matrix of dimensions `(m, n)`,
1965the relative tolerance is set to be :math:`\text{rtol} = \max(m, n) \varepsilon`
1966and :math:`\varepsilon` is the epsilon value for the dtype of :attr:`A` (see :class:`.finfo`).
1967If :attr:`rtol` is not specified and :attr:`atol` is specified to be larger than zero then
1968:attr:`rtol` is set to zero.
1969
1970If :attr:`atol` or :attr:`rtol` is a :class:`torch.Tensor`, its shape must be broadcastable to that
1971of the singular values of :attr:`A` as returned by :func:`torch.linalg.svd`.
1972
1973.. note:: This function uses :func:`torch.linalg.svd` if :attr:`hermitian`\ `= False` and
1974          :func:`torch.linalg.eigh` if :attr:`hermitian`\ `= True`.
1975          For CUDA inputs, this function synchronizes that device with the CPU.
1976
1977.. note::
1978    Consider using :func:`torch.linalg.lstsq` if possible for multiplying a matrix on the left by
1979    the pseudoinverse, as::
1980
1981        torch.linalg.lstsq(A, B).solution == A.pinv() @ B
1982
1983    It is always preferred to use :func:`~lstsq` when possible, as it is faster and more
1984    numerically stable than computing the pseudoinverse explicitly.
1985
1986.. note::
1987    This function has NumPy compatible variant `linalg.pinv(A, rcond, hermitian=False)`.
1988    However, use of the positional argument :attr:`rcond` is deprecated in favor of :attr:`rtol`.
1989
1990.. warning::
1991    This function uses internally :func:`torch.linalg.svd` (or :func:`torch.linalg.eigh`
1992    when :attr:`hermitian`\ `= True`), so its derivative has the same problems as those of these
1993    functions. See the warnings in :func:`torch.linalg.svd` and :func:`torch.linalg.eigh` for
1994    more details.
1995
1996.. seealso::
1997
1998        :func:`torch.linalg.inv` computes the inverse of a square matrix.
1999
2000        :func:`torch.linalg.lstsq` computes :attr:`A`\ `.pinv() @ \ `:attr:`B` with a
2001        numerically stable algorithm.
2002
2003Args:
2004    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
2005    rcond (float, Tensor, optional): [NumPy Compat]. Alias for :attr:`rtol`. Default: `None`.
2006
2007Keyword args:
2008    atol (float, Tensor, optional): the absolute tolerance value. When `None` it's considered to be zero.
2009                                    Default: `None`.
2010    rtol (float, Tensor, optional): the relative tolerance value. See above for the value it takes when `None`.
2011                                    Default: `None`.
2012    hermitian(bool, optional): indicates whether :attr:`A` is Hermitian if complex
2013                               or symmetric if real. Default: `False`.
2014    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
2015
2016Examples::
2017
2018    >>> A = torch.randn(3, 5)
2019    >>> A
2020    tensor([[ 0.5495,  0.0979, -1.4092, -0.1128,  0.4132],
2021            [-1.1143, -0.3662,  0.3042,  1.6374, -0.9294],
2022            [-0.3269, -0.5745, -0.0382, -0.5922, -0.6759]])
2023    >>> torch.linalg.pinv(A)
2024    tensor([[ 0.0600, -0.1933, -0.2090],
2025            [-0.0903, -0.0817, -0.4752],
2026            [-0.7124, -0.1631, -0.2272],
2027            [ 0.1356,  0.3933, -0.5023],
2028            [-0.0308, -0.1725, -0.5216]])
2029
2030    >>> A = torch.randn(2, 6, 3)
2031    >>> Apinv = torch.linalg.pinv(A)
2032    >>> torch.dist(Apinv @ A, torch.eye(3))
2033    tensor(8.5633e-07)
2034
2035    >>> A = torch.randn(3, 3, dtype=torch.complex64)
2036    >>> A = A + A.T.conj()  # creates a Hermitian matrix
2037    >>> Apinv = torch.linalg.pinv(A, hermitian=True)
2038    >>> torch.dist(Apinv @ A, torch.eye(3))
2039    tensor(1.0830e-06)
2040
2041.. _defined algebraically:
2042    https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse#Existence_and_uniqueness
2043.. _through the SVD:
2044    https://en.wikipedia.org/wiki/Moore%E2%80%93Penrose_inverse#Singular_value_decomposition_(SVD)
2045""")
2046
2047matrix_exp = _add_docstr(_linalg.linalg_matrix_exp, r"""
2048linalg.matrix_exp(A) -> Tensor
2049
2050Computes the matrix exponential of a square matrix.
2051
2052Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
2053this function computes the **matrix exponential** of :math:`A \in \mathbb{K}^{n \times n}`, which is defined as
2054
2055.. math::
2056    \mathrm{matrix\_exp}(A) = \sum_{k=0}^\infty \frac{1}{k!}A^k \in \mathbb{K}^{n \times n}.
2057
2058If the matrix :math:`A` has eigenvalues :math:`\lambda_i \in \mathbb{C}`,
2059the matrix :math:`\mathrm{matrix\_exp}(A)` has eigenvalues :math:`e^{\lambda_i} \in \mathbb{C}`.
2060
2061Supports input of bfloat16, float, double, cfloat and cdouble dtypes.
2062Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
2063the output has the same batch dimensions.
2064
2065Args:
2066    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions.
2067
2068Example::
2069
2070    >>> A = torch.empty(2, 2, 2)
2071    >>> A[0, :, :] = torch.eye(2, 2)
2072    >>> A[1, :, :] = 2 * torch.eye(2, 2)
2073    >>> A
2074    tensor([[[1., 0.],
2075             [0., 1.]],
2076
2077            [[2., 0.],
2078             [0., 2.]]])
2079    >>> torch.linalg.matrix_exp(A)
2080    tensor([[[2.7183, 0.0000],
2081             [0.0000, 2.7183]],
2082
2083             [[7.3891, 0.0000],
2084              [0.0000, 7.3891]]])
2085
2086    >>> import math
2087    >>> A = torch.tensor([[0, math.pi/3], [-math.pi/3, 0]]) # A is skew-symmetric
2088    >>> torch.linalg.matrix_exp(A) # matrix_exp(A) = [[cos(pi/3), sin(pi/3)], [-sin(pi/3), cos(pi/3)]]
2089    tensor([[ 0.5000,  0.8660],
2090            [-0.8660,  0.5000]])
2091""")
2092
2093
2094solve = _add_docstr(_linalg.linalg_solve, r"""
2095linalg.solve(A, B, *, left=True, out=None) -> Tensor
2096
2097Computes the solution of a square system of linear equations with a unique solution.
2098
2099Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
2100this function computes the solution :math:`X \in \mathbb{K}^{n \times k}` of the **linear system** associated to
2101:math:`A \in \mathbb{K}^{n \times n}, B \in \mathbb{K}^{n \times k}`, which is defined as
2102
2103.. math:: AX = B
2104
2105If :attr:`left`\ `= False`, this function returns the matrix :math:`X \in \mathbb{K}^{n \times k}` that solves the system
2106
2107.. math::
2108
2109    XA = B\mathrlap{\qquad A \in \mathbb{K}^{k \times k}, B \in \mathbb{K}^{n \times k}.}
2110
2111This system of linear equations has one solution if and only if :math:`A` is `invertible`_.
2112This function assumes that :math:`A` is invertible.
2113
2114Supports inputs of float, double, cfloat and cdouble dtypes.
2115Also supports batches of matrices, and if the inputs are batches of matrices then
2116the output has the same batch dimensions.
2117
2118Letting `*` be zero or more batch dimensions,
2119
2120- If :attr:`A` has shape `(*, n, n)` and :attr:`B` has shape `(*, n)` (a batch of vectors) or shape
2121  `(*, n, k)` (a batch of matrices or "multiple right-hand sides"), this function returns `X` of shape
2122  `(*, n)` or `(*, n, k)` respectively.
2123- Otherwise, if :attr:`A` has shape `(*, n, n)` and  :attr:`B` has shape `(n,)`  or `(n, k)`, :attr:`B`
2124  is broadcasted to have shape `(*, n)` or `(*, n, k)` respectively.
2125  This function then returns the solution of the resulting batch of systems of linear equations.
2126
2127.. note::
2128    This function computes `X = \ `:attr:`A`\ `.inverse() @ \ `:attr:`B` in a faster and
2129    more numerically stable way than performing the computations separately.
2130
2131.. note::
2132    It is possible to compute the solution of the system :math:`XA = B` by passing the inputs
2133    :attr:`A` and :attr:`B` transposed and transposing the output returned by this function.
2134
2135.. note::
2136    :attr:`A` is allowed to be a non-batched `torch.sparse_csr_tensor`, but only with `left=True`.
2137
2138""" + fr"""
2139.. note:: {common_notes["sync_note_has_ex"].format("torch.linalg.solve_ex")}
2140""" + r"""
2141
2142.. seealso::
2143
2144        :func:`torch.linalg.solve_triangular` computes the solution of a triangular system of linear
2145        equations with a unique solution.
2146
2147Args:
2148    A (Tensor): tensor of shape `(*, n, n)` where `*` is zero or more batch dimensions.
2149    B (Tensor): right-hand side tensor of shape `(*, n)` or  `(*, n, k)` or `(n,)` or `(n, k)`
2150                according to the rules described above
2151
2152Keyword args:
2153    left (bool, optional): whether to solve the system :math:`AX=B` or :math:`XA = B`. Default: `True`.
2154    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
2155
2156Raises:
2157    RuntimeError: if the :attr:`A` matrix is not invertible or any matrix in a batched :attr:`A`
2158                  is not invertible.
2159
2160Examples::
2161
2162    >>> A = torch.randn(3, 3)
2163    >>> b = torch.randn(3)
2164    >>> x = torch.linalg.solve(A, b)
2165    >>> torch.allclose(A @ x, b)
2166    True
2167    >>> A = torch.randn(2, 3, 3)
2168    >>> B = torch.randn(2, 3, 4)
2169    >>> X = torch.linalg.solve(A, B)
2170    >>> X.shape
2171    torch.Size([2, 3, 4])
2172    >>> torch.allclose(A @ X, B)
2173    True
2174
2175    >>> A = torch.randn(2, 3, 3)
2176    >>> b = torch.randn(3, 1)
2177    >>> x = torch.linalg.solve(A, b) # b is broadcasted to size (2, 3, 1)
2178    >>> x.shape
2179    torch.Size([2, 3, 1])
2180    >>> torch.allclose(A @ x, b)
2181    True
2182    >>> b = torch.randn(3)
2183    >>> x = torch.linalg.solve(A, b) # b is broadcasted to size (2, 3)
2184    >>> x.shape
2185    torch.Size([2, 3])
2186    >>> Ax = A @ x.unsqueeze(-1)
2187    >>> torch.allclose(Ax, b.unsqueeze(-1).expand_as(Ax))
2188    True
2189
2190.. _invertible:
2191    https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem
2192""")
2193
2194solve_triangular = _add_docstr(_linalg.linalg_solve_triangular, r"""
2195linalg.solve_triangular(A, B, *, upper, left=True, unitriangular=False, out=None) -> Tensor
2196
2197Computes the solution of a triangular system of linear equations with a unique solution.
2198
2199Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
2200this function computes the solution :math:`X \in \mathbb{K}^{n \times k}` of the **linear system**
2201associated to the triangular matrix :math:`A \in \mathbb{K}^{n \times n}` without zeros on the diagonal
2202(that is, it is `invertible`_) and the rectangular matrix , :math:`B \in \mathbb{K}^{n \times k}`,
2203which is defined as
2204
2205.. math:: AX = B
2206
2207The argument :attr:`upper` signals whether :math:`A` is upper or lower triangular.
2208
2209If :attr:`left`\ `= False`, this function returns the matrix :math:`X \in \mathbb{K}^{n \times k}` that
2210solves the system
2211
2212.. math::
2213
2214    XA = B\mathrlap{\qquad A \in \mathbb{K}^{k \times k}, B \in \mathbb{K}^{n \times k}.}
2215
2216If :attr:`upper`\ `= True` (resp. `False`) just the upper (resp. lower) triangular half of :attr:`A`
2217will be accessed. The elements below the main diagonal will be considered to be zero and will not be accessed.
2218
2219If :attr:`unitriangular`\ `= True`, the diagonal of :attr:`A` is assumed to be ones and will not be accessed.
2220
2221The result may contain `NaN` s if the diagonal of :attr:`A` contains zeros or elements that
2222are very close to zero and :attr:`unitriangular`\ `= False` (default) or if the input matrix
2223has very small eigenvalues.
2224
2225Supports inputs of float, double, cfloat and cdouble dtypes.
2226Also supports batches of matrices, and if the inputs are batches of matrices then
2227the output has the same batch dimensions.
2228
2229.. seealso::
2230
2231        :func:`torch.linalg.solve` computes the solution of a general square system of linear
2232        equations with a unique solution.
2233
2234Args:
2235    A (Tensor): tensor of shape `(*, n, n)` (or `(*, k, k)` if :attr:`left`\ `= False`)
2236                where `*` is zero or more batch dimensions.
2237    B (Tensor): right-hand side tensor of shape `(*, n, k)`.
2238
2239Keyword args:
2240    upper (bool): whether :attr:`A` is an upper or lower triangular matrix.
2241    left (bool, optional): whether to solve the system :math:`AX=B` or :math:`XA = B`. Default: `True`.
2242    unitriangular (bool, optional): if `True`, the diagonal elements of :attr:`A` are assumed to be
2243                                    all equal to `1`. Default: `False`.
2244    out (Tensor, optional): output tensor. `B` may be passed as `out` and the result is computed in-place on `B`.
2245                            Ignored if `None`. Default: `None`.
2246
2247Examples::
2248
2249    >>> A = torch.randn(3, 3).triu_()
2250    >>> B = torch.randn(3, 4)
2251    >>> X = torch.linalg.solve_triangular(A, B, upper=True)
2252    >>> torch.allclose(A @ X, B)
2253    True
2254
2255    >>> A = torch.randn(2, 3, 3).tril_()
2256    >>> B = torch.randn(2, 3, 4)
2257    >>> X = torch.linalg.solve_triangular(A, B, upper=False)
2258    >>> torch.allclose(A @ X, B)
2259    True
2260
2261    >>> A = torch.randn(2, 4, 4).tril_()
2262    >>> B = torch.randn(2, 3, 4)
2263    >>> X = torch.linalg.solve_triangular(A, B, upper=False, left=False)
2264    >>> torch.allclose(X @ A, B)
2265    True
2266
2267.. _invertible:
2268    https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem
2269""")
2270
2271lu_factor = _add_docstr(_linalg.linalg_lu_factor, r"""
2272linalg.lu_factor(A, *, bool pivot=True, out=None) -> (Tensor, Tensor)
2273
2274Computes a compact representation of the LU factorization with partial pivoting of a matrix.
2275
2276This function computes a compact representation of the decomposition given by :func:`torch.linalg.lu`.
2277If the matrix is square, this representation may be used in :func:`torch.linalg.lu_solve`
2278to solve system of linear equations that share the matrix :attr:`A`.
2279
2280The returned decomposition is represented as a named tuple `(LU, pivots)`.
2281The ``LU`` matrix has the same shape as the input matrix ``A``. Its upper and lower triangular
2282parts encode the non-constant elements of ``L`` and ``U`` of the LU decomposition of ``A``.
2283
2284The returned permutation matrix is represented by a 1-indexed vector. `pivots[i] == j` represents
2285that in the `i`-th step of the algorithm, the `i`-th row was permuted with the `j-1`-th row.
2286
2287On CUDA, one may use :attr:`pivot`\ `= False`. In this case, this function returns the LU
2288decomposition without pivoting if it exists.
2289
2290Supports inputs of float, double, cfloat and cdouble dtypes.
2291Also supports batches of matrices, and if the inputs are batches of matrices then
2292the output has the same batch dimensions.
2293
2294""" + fr"""
2295.. note:: {common_notes["sync_note_has_ex"].format("torch.linalg.lu_factor_ex")}
2296""" + r"""
2297.. warning:: The LU decomposition is almost never unique, as often there are different permutation
2298             matrices that can yield different LU decompositions.
2299             As such, different platforms, like SciPy, or inputs on different devices,
2300             may produce different valid decompositions.
2301
2302             Gradient computations are only supported if the input matrix is full-rank.
2303             If this condition is not met, no error will be thrown, but the gradient may not be finite.
2304             This is because the LU decomposition with pivoting is not differentiable at these points.
2305
2306.. seealso::
2307
2308        :func:`torch.linalg.lu_solve` solves a system of linear equations given the output of this
2309        function provided the input matrix was square and invertible.
2310
2311        :func:`torch.lu_unpack` unpacks the tensors returned by :func:`~lu_factor` into the three
2312        matrices `P, L, U` that form the decomposition.
2313
2314        :func:`torch.linalg.lu` computes the LU decomposition with partial pivoting of a possibly
2315        non-square matrix. It is a composition of :func:`~lu_factor` and :func:`torch.lu_unpack`.
2316
2317        :func:`torch.linalg.solve` solves a system of linear equations. It is a composition
2318        of :func:`~lu_factor` and :func:`~lu_solve`.
2319
2320Args:
2321    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
2322
2323Keyword args:
2324    pivot (bool, optional): Whether to compute the LU decomposition with partial pivoting, or the regular LU
2325                            decomposition. :attr:`pivot`\ `= False` not supported on CPU. Default: `True`.
2326    out (tuple, optional): tuple of two tensors to write the output to. Ignored if `None`. Default: `None`.
2327
2328Returns:
2329    A named tuple `(LU, pivots)`.
2330
2331Raises:
2332    RuntimeError: if the :attr:`A` matrix is not invertible or any matrix in a batched :attr:`A`
2333                  is not invertible.
2334
2335Examples::
2336
2337    >>> A = torch.randn(2, 3, 3)
2338    >>> B1 = torch.randn(2, 3, 4)
2339    >>> B2 = torch.randn(2, 3, 7)
2340    >>> LU, pivots = torch.linalg.lu_factor(A)
2341    >>> X1 = torch.linalg.lu_solve(LU, pivots, B1)
2342    >>> X2 = torch.linalg.lu_solve(LU, pivots, B2)
2343    >>> torch.allclose(A @ X1, B1)
2344    True
2345    >>> torch.allclose(A @ X2, B2)
2346    True
2347
2348.. _invertible:
2349    https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem
2350""")
2351
2352lu_factor_ex = _add_docstr(_linalg.linalg_lu_factor_ex, r"""
2353linalg.lu_factor_ex(A, *, pivot=True, check_errors=False, out=None) -> (Tensor, Tensor, Tensor)
2354
2355This is a version of :func:`~lu_factor` that does not perform error checks unless :attr:`check_errors`\ `= True`.
2356It also returns the :attr:`info` tensor returned by `LAPACK's getrf`_.
2357
2358""" + fr"""
2359.. note:: {common_notes["sync_note_ex"]}
2360
2361.. warning:: {common_notes["experimental_warning"]}
2362""" + r"""
2363
2364Args:
2365    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
2366
2367Keyword args:
2368    pivot (bool, optional): Whether to compute the LU decomposition with partial pivoting, or the regular LU
2369                            decomposition. :attr:`pivot`\ `= False` not supported on CPU. Default: `True`.
2370    check_errors (bool, optional): controls whether to check the content of ``infos`` and raise
2371                                   an error if it is non-zero. Default: `False`.
2372    out (tuple, optional): tuple of three tensors to write the output to. Ignored if `None`. Default: `None`.
2373
2374Returns:
2375    A named tuple `(LU, pivots, info)`.
2376
2377.. _LAPACK's getrf:
2378    https://www.netlib.org/lapack/explore-html/dd/d9a/group__double_g_ecomputational_ga0019443faea08275ca60a734d0593e60.html
2379""")
2380
2381lu_solve = _add_docstr(_linalg.linalg_lu_solve, r"""
2382linalg.lu_solve(LU, pivots, B, *, left=True, adjoint=False, out=None) -> Tensor
2383
2384Computes the solution of a square system of linear equations with a unique solution given an LU decomposition.
2385
2386Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
2387this function computes the solution :math:`X \in \mathbb{K}^{n \times k}` of the **linear system** associated to
2388:math:`A \in \mathbb{K}^{n \times n}, B \in \mathbb{K}^{n \times k}`, which is defined as
2389
2390.. math:: AX = B
2391
2392where :math:`A` is given factorized as returned by :func:`~lu_factor`.
2393
2394If :attr:`left`\ `= False`, this function returns the matrix :math:`X \in \mathbb{K}^{n \times k}` that solves the system
2395
2396.. math::
2397
2398    XA = B\mathrlap{\qquad A \in \mathbb{K}^{k \times k}, B \in \mathbb{K}^{n \times k}.}
2399
2400If  :attr:`adjoint`\ `= True` (and :attr:`left`\ `= True`), given an LU factorization of :math:`A`
2401this function function returns the :math:`X \in \mathbb{K}^{n \times k}` that solves the system
2402
2403.. math::
2404
2405    A^{\text{H}}X = B\mathrlap{\qquad A \in \mathbb{K}^{k \times k}, B \in \mathbb{K}^{n \times k}.}
2406
2407where :math:`A^{\text{H}}` is the conjugate transpose when :math:`A` is complex, and the
2408transpose when :math:`A` is real-valued. The :attr:`left`\ `= False` case is analogous.
2409
2410Supports inputs of float, double, cfloat and cdouble dtypes.
2411Also supports batches of matrices, and if the inputs are batches of matrices then
2412the output has the same batch dimensions.
2413
2414Args:
2415    LU (Tensor): tensor of shape `(*, n, n)` (or `(*, k, k)` if :attr:`left`\ `= True`)
2416                 where `*` is zero or more batch dimensions as returned by :func:`~lu_factor`.
2417    pivots (Tensor): tensor of shape `(*, n)` (or `(*, k)` if :attr:`left`\ `= True`)
2418                     where `*` is zero or more batch dimensions as returned by :func:`~lu_factor`.
2419    B (Tensor): right-hand side tensor of shape `(*, n, k)`.
2420
2421Keyword args:
2422    left (bool, optional): whether to solve the system :math:`AX=B` or :math:`XA = B`. Default: `True`.
2423    adjoint (bool, optional): whether to solve the system :math:`AX=B` or :math:`A^{\text{H}}X = B`. Default: `False`.
2424    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
2425
2426Examples::
2427
2428    >>> A = torch.randn(3, 3)
2429    >>> LU, pivots = torch.linalg.lu_factor(A)
2430    >>> B = torch.randn(3, 2)
2431    >>> X = torch.linalg.lu_solve(LU, pivots, B)
2432    >>> torch.allclose(A @ X, B)
2433    True
2434
2435    >>> B = torch.randn(3, 3, 2)   # Broadcasting rules apply: A is broadcasted
2436    >>> X = torch.linalg.lu_solve(LU, pivots, B)
2437    >>> torch.allclose(A @ X, B)
2438    True
2439
2440    >>> B = torch.randn(3, 5, 3)
2441    >>> X = torch.linalg.lu_solve(LU, pivots, B, left=False)
2442    >>> torch.allclose(X @ A, B)
2443    True
2444
2445    >>> B = torch.randn(3, 3, 4)   # Now solve for A^T
2446    >>> X = torch.linalg.lu_solve(LU, pivots, B, adjoint=True)
2447    >>> torch.allclose(A.mT @ X, B)
2448    True
2449
2450.. _invertible:
2451    https://en.wikipedia.org/wiki/Invertible_matrix#The_invertible_matrix_theorem
2452""")
2453
2454lu = _add_docstr(_linalg.linalg_lu, r"""
2455lu(A, *, pivot=True, out=None) -> (Tensor, Tensor, Tensor)
2456
2457Computes the LU decomposition with partial pivoting of a matrix.
2458
2459Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
2460the **LU decomposition with partial pivoting** of a matrix
2461:math:`A \in \mathbb{K}^{m \times n}` is defined as
2462
2463.. math::
2464
2465    A = PLU\mathrlap{\qquad P \in \mathbb{K}^{m \times m}, L \in \mathbb{K}^{m \times k}, U \in \mathbb{K}^{k \times n}}
2466
2467where `k = min(m,n)`, :math:`P` is a `permutation matrix`_, :math:`L` is lower triangular with ones on the diagonal
2468and :math:`U` is upper triangular.
2469
2470If :attr:`pivot`\ `= False` and :attr:`A` is on GPU, then the **LU decomposition without pivoting** is computed
2471
2472.. math::
2473
2474    A = LU\mathrlap{\qquad L \in \mathbb{K}^{m \times k}, U \in \mathbb{K}^{k \times n}}
2475
2476When :attr:`pivot`\ `= False`, the returned matrix :attr:`P` will be empty.
2477The LU decomposition without pivoting `may not exist`_ if any of the principal minors of :attr:`A` is singular.
2478In this case, the output matrix may contain `inf` or `NaN`.
2479
2480Supports input of float, double, cfloat and cdouble dtypes.
2481Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
2482the output has the same batch dimensions.
2483
2484.. seealso::
2485
2486        :func:`torch.linalg.solve` solves a system of linear equations using the LU decomposition
2487        with partial pivoting.
2488
2489.. warning:: The LU decomposition is almost never unique, as often there are different permutation
2490             matrices that can yield different LU decompositions.
2491             As such, different platforms, like SciPy, or inputs on different devices,
2492             may produce different valid decompositions.
2493
2494.. warning:: Gradient computations are only supported if the input matrix is full-rank.
2495             If this condition is not met, no error will be thrown, but the gradient
2496             may not be finite.
2497             This is because the LU decomposition with pivoting is not differentiable at these points.
2498
2499Args:
2500    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
2501    pivot (bool, optional): Controls whether to compute the LU decomposition with partial pivoting or
2502        no pivoting. Default: `True`.
2503
2504Keyword args:
2505    out (tuple, optional): output tuple of three tensors. Ignored if `None`. Default: `None`.
2506
2507Returns:
2508    A named tuple `(P, L, U)`.
2509
2510Examples::
2511
2512    >>> A = torch.randn(3, 2)
2513    >>> P, L, U = torch.linalg.lu(A)
2514    >>> P
2515    tensor([[0., 1., 0.],
2516            [0., 0., 1.],
2517            [1., 0., 0.]])
2518    >>> L
2519    tensor([[1.0000, 0.0000],
2520            [0.5007, 1.0000],
2521            [0.0633, 0.9755]])
2522    >>> U
2523    tensor([[0.3771, 0.0489],
2524            [0.0000, 0.9644]])
2525    >>> torch.dist(A, P @ L @ U)
2526    tensor(5.9605e-08)
2527
2528    >>> A = torch.randn(2, 5, 7, device="cuda")
2529    >>> P, L, U = torch.linalg.lu(A, pivot=False)
2530    >>> P
2531    tensor([], device='cuda:0')
2532    >>> torch.dist(A, L @ U)
2533    tensor(1.0376e-06, device='cuda:0')
2534
2535.. _permutation matrix:
2536    https://en.wikipedia.org/wiki/Permutation_matrix
2537.. _may not exist:
2538    https://en.wikipedia.org/wiki/LU_decomposition#Definitions
2539""")
2540
2541tensorinv = _add_docstr(_linalg.linalg_tensorinv, r"""
2542linalg.tensorinv(A, ind=2, *, out=None) -> Tensor
2543
2544Computes the multiplicative inverse of :func:`torch.tensordot`.
2545
2546If `m` is the product of the first :attr:`ind` dimensions of :attr:`A` and `n` is the product of
2547the rest of the dimensions, this function expects `m` and `n` to be equal.
2548If this is the case, it computes a tensor `X` such that
2549`tensordot(\ `:attr:`A`\ `, X, \ `:attr:`ind`\ `)` is the identity matrix in dimension `m`.
2550`X` will have the shape of :attr:`A` but with the first :attr:`ind` dimensions pushed back to the end
2551
2552.. code:: text
2553
2554    X.shape == A.shape[ind:] + A.shape[:ind]
2555
2556Supports input of float, double, cfloat and cdouble dtypes.
2557
2558.. note:: When :attr:`A` is a `2`-dimensional tensor and :attr:`ind`\ `= 1`,
2559          this function computes the (multiplicative) inverse of :attr:`A`
2560          (see :func:`torch.linalg.inv`).
2561
2562.. note::
2563    Consider using :func:`torch.linalg.tensorsolve` if possible for multiplying a tensor on the left
2564    by the tensor inverse, as::
2565
2566        linalg.tensorsolve(A, B) == torch.tensordot(linalg.tensorinv(A), B)  # When B is a tensor with shape A.shape[:B.ndim]
2567
2568    It is always preferred to use :func:`~tensorsolve` when possible, as it is faster and more
2569    numerically stable than computing the pseudoinverse explicitly.
2570
2571.. seealso::
2572
2573        :func:`torch.linalg.tensorsolve` computes
2574        `torch.tensordot(tensorinv(\ `:attr:`A`\ `), \ `:attr:`B`\ `)`.
2575
2576Args:
2577    A (Tensor): tensor to invert. Its shape must satisfy
2578                    `prod(\ `:attr:`A`\ `.shape[:\ `:attr:`ind`\ `]) ==
2579                    prod(\ `:attr:`A`\ `.shape[\ `:attr:`ind`\ `:])`.
2580    ind (int): index at which to compute the inverse of :func:`torch.tensordot`. Default: `2`.
2581
2582Keyword args:
2583    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
2584
2585Raises:
2586    RuntimeError: if the reshaped :attr:`A` is not invertible or the product of the first
2587                  :attr:`ind` dimensions is not equal to the product of the rest.
2588
2589Examples::
2590
2591    >>> A = torch.eye(4 * 6).reshape((4, 6, 8, 3))
2592    >>> Ainv = torch.linalg.tensorinv(A, ind=2)
2593    >>> Ainv.shape
2594    torch.Size([8, 3, 4, 6])
2595    >>> B = torch.randn(4, 6)
2596    >>> torch.allclose(torch.tensordot(Ainv, B), torch.linalg.tensorsolve(A, B))
2597    True
2598
2599    >>> A = torch.randn(4, 4)
2600    >>> Atensorinv = torch.linalg.tensorinv(A, ind=1)
2601    >>> Ainv = torch.linalg.inv(A)
2602    >>> torch.allclose(Atensorinv, Ainv)
2603    True
2604""")
2605
2606tensorsolve = _add_docstr(_linalg.linalg_tensorsolve, r"""
2607linalg.tensorsolve(A, B, dims=None, *, out=None) -> Tensor
2608
2609Computes the solution `X` to the system `torch.tensordot(A, X) = B`.
2610
2611If `m` is the product of the first :attr:`B`\ `.ndim`  dimensions of :attr:`A` and
2612`n` is the product of the rest of the dimensions, this function expects `m` and `n` to be equal.
2613
2614The returned tensor `x` satisfies
2615`tensordot(\ `:attr:`A`\ `, x, dims=x.ndim) == \ `:attr:`B`.
2616`x` has shape :attr:`A`\ `[B.ndim:]`.
2617
2618If :attr:`dims` is specified, :attr:`A` will be reshaped as
2619
2620.. code:: text
2621
2622    A = movedim(A, dims, range(len(dims) - A.ndim + 1, 0))
2623
2624Supports inputs of float, double, cfloat and cdouble dtypes.
2625
2626.. seealso::
2627
2628        :func:`torch.linalg.tensorinv` computes the multiplicative inverse of
2629        :func:`torch.tensordot`.
2630
2631Args:
2632    A (Tensor): tensor to solve for. Its shape must satisfy
2633                    `prod(\ `:attr:`A`\ `.shape[:\ `:attr:`B`\ `.ndim]) ==
2634                    prod(\ `:attr:`A`\ `.shape[\ `:attr:`B`\ `.ndim:])`.
2635    B (Tensor): tensor of shape :attr:`A`\ `.shape[:\ `:attr:`B`\ `.ndim]`.
2636    dims (Tuple[int], optional): dimensions of :attr:`A` to be moved.
2637        If `None`, no dimensions are moved. Default: `None`.
2638
2639Keyword args:
2640    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
2641
2642Raises:
2643    RuntimeError: if the reshaped :attr:`A`\ `.view(m, m)` with `m` as above  is not
2644                  invertible or the product of the first :attr:`ind` dimensions is not equal
2645                  to the product of the rest of the dimensions.
2646
2647Examples::
2648
2649    >>> A = torch.eye(2 * 3 * 4).reshape((2 * 3, 4, 2, 3, 4))
2650    >>> B = torch.randn(2 * 3, 4)
2651    >>> X = torch.linalg.tensorsolve(A, B)
2652    >>> X.shape
2653    torch.Size([2, 3, 4])
2654    >>> torch.allclose(torch.tensordot(A, X, dims=X.ndim), B)
2655    True
2656
2657    >>> A = torch.randn(6, 4, 4, 3, 2)
2658    >>> B = torch.randn(4, 3, 2)
2659    >>> X = torch.linalg.tensorsolve(A, B, dims=(0, 2))
2660    >>> X.shape
2661    torch.Size([6, 4])
2662    >>> A = A.permute(1, 3, 4, 0, 2)
2663    >>> A.shape[B.ndim:]
2664    torch.Size([6, 4])
2665    >>> torch.allclose(torch.tensordot(A, X, dims=X.ndim), B, atol=1e-6)
2666    True
2667""")
2668
2669qr = _add_docstr(_linalg.linalg_qr, r"""
2670qr(A, mode='reduced', *, out=None) -> (Tensor, Tensor)
2671
2672Computes the QR decomposition of a matrix.
2673
2674Letting :math:`\mathbb{K}` be :math:`\mathbb{R}` or :math:`\mathbb{C}`,
2675the **full QR decomposition** of a matrix
2676:math:`A \in \mathbb{K}^{m \times n}` is defined as
2677
2678.. math::
2679
2680    A = QR\mathrlap{\qquad Q \in \mathbb{K}^{m \times m}, R \in \mathbb{K}^{m \times n}}
2681
2682where :math:`Q` is orthogonal in the real case and unitary in the complex case,
2683and :math:`R` is upper triangular with real diagonal (even in the complex case).
2684
2685When `m > n` (tall matrix), as `R` is upper triangular, its last `m - n` rows are zero.
2686In this case, we can drop the last `m - n` columns of `Q` to form the
2687**reduced QR decomposition**:
2688
2689.. math::
2690
2691    A = QR\mathrlap{\qquad Q \in \mathbb{K}^{m \times n}, R \in \mathbb{K}^{n \times n}}
2692
2693The reduced QR decomposition agrees with the full QR decomposition when `n >= m` (wide matrix).
2694
2695Supports input of float, double, cfloat and cdouble dtypes.
2696Also supports batches of matrices, and if :attr:`A` is a batch of matrices then
2697the output has the same batch dimensions.
2698
2699The parameter :attr:`mode` chooses between the full and reduced QR decomposition.
2700If :attr:`A` has shape `(*, m, n)`, denoting `k = min(m, n)`
2701
2702- :attr:`mode`\ `= 'reduced'` (default): Returns `(Q, R)` of shapes `(*, m, k)`, `(*, k, n)` respectively.
2703  It is always differentiable.
2704- :attr:`mode`\ `= 'complete'`: Returns `(Q, R)` of shapes `(*, m, m)`, `(*, m, n)` respectively.
2705  It is differentiable for `m <= n`.
2706- :attr:`mode`\ `= 'r'`: Computes only the reduced `R`. Returns `(Q, R)` with `Q` empty and `R` of shape `(*, k, n)`.
2707  It is never differentiable.
2708
2709Differences with `numpy.linalg.qr`:
2710
2711- :attr:`mode`\ `= 'raw'` is not implemented.
2712- Unlike `numpy.linalg.qr`, this function always returns a tuple of two tensors.
2713  When :attr:`mode`\ `= 'r'`, the `Q` tensor is an empty tensor.
2714
2715.. warning:: The elements in the diagonal of `R` are not necessarily positive.
2716             As such, the returned QR decomposition is only unique up to the sign of the diagonal of `R`.
2717             Therefore, different platforms, like NumPy, or inputs on different devices,
2718             may produce different valid decompositions.
2719
2720.. warning:: The QR decomposition is only well-defined if the first `k = min(m, n)` columns
2721             of every matrix in :attr:`A` are linearly independent.
2722             If this condition is not met, no error will be thrown, but the QR produced
2723             may be incorrect and its autodiff may fail or produce incorrect results.
2724
2725Args:
2726    A (Tensor): tensor of shape `(*, m, n)` where `*` is zero or more batch dimensions.
2727    mode (str, optional): one of `'reduced'`, `'complete'`, `'r'`.
2728                          Controls the shape of the returned tensors. Default: `'reduced'`.
2729
2730Keyword args:
2731    out (tuple, optional): output tuple of two tensors. Ignored if `None`. Default: `None`.
2732
2733Returns:
2734    A named tuple `(Q, R)`.
2735
2736Examples::
2737
2738    >>> A = torch.tensor([[12., -51, 4], [6, 167, -68], [-4, 24, -41]])
2739    >>> Q, R = torch.linalg.qr(A)
2740    >>> Q
2741    tensor([[-0.8571,  0.3943,  0.3314],
2742            [-0.4286, -0.9029, -0.0343],
2743            [ 0.2857, -0.1714,  0.9429]])
2744    >>> R
2745    tensor([[ -14.0000,  -21.0000,   14.0000],
2746            [   0.0000, -175.0000,   70.0000],
2747            [   0.0000,    0.0000,  -35.0000]])
2748    >>> (Q @ R).round()
2749    tensor([[  12.,  -51.,    4.],
2750            [   6.,  167.,  -68.],
2751            [  -4.,   24.,  -41.]])
2752    >>> (Q.T @ Q).round()
2753    tensor([[ 1.,  0.,  0.],
2754            [ 0.,  1., -0.],
2755            [ 0., -0.,  1.]])
2756    >>> Q2, R2 = torch.linalg.qr(A, mode='r')
2757    >>> Q2
2758    tensor([])
2759    >>> torch.equal(R, R2)
2760    True
2761    >>> A = torch.randn(3, 4, 5)
2762    >>> Q, R = torch.linalg.qr(A, mode='complete')
2763    >>> torch.dist(Q @ R, A)
2764    tensor(1.6099e-06)
2765    >>> torch.dist(Q.mT @ Q, torch.eye(4))
2766    tensor(6.2158e-07)
2767""")
2768
2769vander = _add_docstr(_linalg.linalg_vander, r"""
2770vander(x, N=None) -> Tensor
2771
2772Generates a Vandermonde matrix.
2773
2774Returns the Vandermonde matrix :math:`V`
2775
2776.. math::
2777
2778    V = \begin{pmatrix}
2779            1 & x_1 & x_1^2 & \dots & x_1^{N-1}\\
2780            1 & x_2 & x_2^2 & \dots & x_2^{N-1}\\
2781            1 & x_3 & x_3^2 & \dots & x_3^{N-1}\\
2782            \vdots & \vdots & \vdots & \ddots &\vdots \\
2783            1 & x_n & x_n^2 & \dots & x_n^{N-1}
2784        \end{pmatrix}.
2785
2786for `N > 1`.
2787If :attr:`N`\ `= None`, then `N = x.size(-1)` so that the output is a square matrix.
2788
2789Supports inputs of float, double, cfloat, cdouble, and integral dtypes.
2790Also supports batches of vectors, and if :attr:`x` is a batch of vectors then
2791the output has the same batch dimensions.
2792
2793Differences with `numpy.vander`:
2794
2795- Unlike `numpy.vander`, this function returns the powers of :attr:`x` in ascending order.
2796  To get them in the reverse order call ``linalg.vander(x, N).flip(-1)``.
2797
2798Args:
2799    x (Tensor): tensor of shape `(*, n)` where `*` is zero or more batch dimensions
2800                consisting of vectors.
2801
2802Keyword args:
2803    N (int, optional): Number of columns in the output. Default: `x.size(-1)`
2804
2805Example::
2806
2807    >>> x = torch.tensor([1, 2, 3, 5])
2808    >>> linalg.vander(x)
2809    tensor([[  1,   1,   1,   1],
2810            [  1,   2,   4,   8],
2811            [  1,   3,   9,  27],
2812            [  1,   5,  25, 125]])
2813    >>> linalg.vander(x, N=3)
2814    tensor([[ 1,  1,  1],
2815            [ 1,  2,  4],
2816            [ 1,  3,  9],
2817            [ 1,  5, 25]])
2818""")
2819
2820vecdot = _add_docstr(_linalg.linalg_vecdot, r"""
2821linalg.vecdot(x, y, *, dim=-1, out=None) -> Tensor
2822
2823Computes the dot product of two batches of vectors along a dimension.
2824
2825In symbols, this function computes
2826
2827.. math::
2828
2829    \sum_{i=1}^n \overline{x_i}y_i.
2830
2831over the dimension :attr:`dim` where :math:`\overline{x_i}` denotes the conjugate for complex
2832vectors, and it is the identity for real vectors.
2833
2834Supports input of half, bfloat16, float, double, cfloat, cdouble and integral dtypes.
2835It also supports broadcasting.
2836
2837Args:
2838    x (Tensor): first batch of vectors of shape `(*, n)`.
2839    y (Tensor): second batch of vectors of shape `(*, n)`.
2840
2841Keyword args:
2842    dim (int): Dimension along which to compute the dot product. Default: `-1`.
2843    out (Tensor, optional): output tensor. Ignored if `None`. Default: `None`.
2844
2845Examples::
2846
2847    >>> v1 = torch.randn(3, 2)
2848    >>> v2 = torch.randn(3, 2)
2849    >>> linalg.vecdot(v1, v2)
2850    tensor([ 0.3223,  0.2815, -0.1944])
2851    >>> torch.vdot(v1[0], v2[0])
2852    tensor(0.3223)
2853""")
2854