'full' and 'economic' may
    be passed using only the first letter for backwards compatibility,
    but all others must be spelled out. See the Notes for more
    explanation.


Returns
-------
When mode is 'reduced' or 'complete', the result will be a namedtuple with
the attributes `Q` and `R`.

Q : ndarray of float or complex, optional
    A matrix with orthonormal columns. When mode = 'complete' the
    result is an orthogonal/unitary matrix depending on whether or not
    a is real/complex. The determinant may be either +/- 1 in that
    case. In case the number of dimensions in the input array is
    greater than 2 then a stack of the matrices with above properties
    is returned.
R : ndarray of float or complex, optional
    The upper-triangular matrix or a stack of upper-triangular
    matrices if the number of dimensions in the input array is greater
    than 2.
(h, tau) : ndarrays of np.double or np.cdouble, optional
    The array h contains the Householder reflectors that generate q
    along with r. The tau array contains scaling factors for the
    reflectors. In the deprecated  'economic' mode only h is returned.

Raises
------
LinAlgError
    If factoring fails.

See Also
--------
scipy.linalg.qr : Similar function in SciPy.
scipy.linalg.rq : Compute RQ decomposition of a matrix.

Notes
-----
This is an interface to the LAPACK routines ``dgeqrf``, ``zgeqrf``,
``dorgqr``, and ``zungqr``.

For more information on the qr factorization, see for example:
https://en.wikipedia.org/wiki/QR_factorization

Subclasses of `ndarray` are preserved except for the 'raw' mode. So if
`a` is of type `matrix`, all the return values will be matrices too.

New 'reduced', 'complete', and 'raw' options for mode were added in
NumPy 1.8.0 and the old option 'full' was made an alias of 'reduced'.  In
addition the options 'full' and 'economic' were deprecated.  Because
'full' was the previous default and 'reduced' is the new default,
backward compatibility can be maintained by letting `mode` default.
The 'raw' option was added so that LAPACK routines that can multiply
arrays by q using the Householder reflectors can be used. Note that in
this case the returned arrays are of type np.double or np.cdouble and
the h array is transposed to be FORTRAN compatible.  No routines using
the 'raw' return are currently exposed by numpy, but some are available
in lapack_lite and just await the necessary work.

Examples
--------
>>> import numpy as np
>>> rng = np.random.default_rng()
>>> a = rng.normal(size=(9, 6))
>>> Q, R = np.linalg.qr(a)
>>> np.allclose(a, np.dot(Q, R))  # a does equal QR
True
>>> R2 = np.linalg.qr(a, mode='r')
>>> np.allclose(R, R2)  # mode='r' returns the same R as mode='full'
True
>>> a = np.random.normal(size=(3, 2, 2)) # Stack of 2 x 2 matrices as input
>>> Q, R = np.linalg.qr(a)
>>> Q.shape
(3, 2, 2)
>>> R.shape
(3, 2, 2)
>>> np.allclose(a, np.matmul(Q, R))
True

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

What are the least-squares-best `m` and `y0` in ``y = y0 + mx`` for
the following data: {(0,1), (1,0), (1,2), (2,1)}. (Graph the points
and you'll see that it should be y0 = 0, m = 1.)  The answer is provided
by solving the over-determined matrix equation ``Ax = b``, where::

  A = array([[0, 1], [1, 1], [1, 1], [2, 1]])
  x = array([[y0], [m]])
  b = array([[1], [0], [2], [1]])

If A = QR such that Q is orthonormal (which is always possible via
Gram-Schmidt), then ``x = inv(R) * (Q.T) * b``.  (In numpy practice,
however, we simply use `lstsq`.)

>>> A = np.array([[0, 1], [1, 1], [1, 1], [2, 1]])
>>> A
array([[0, 1],
       [1, 1],
       [1, 1],
       [2, 1]])
>>> b = np.array([1, 2, 2, 3])
>>> Q, R = np.linalg.qr(A)
>>> p = np.dot(Q.T, b)
>>> np.dot(np.linalg.inv(R), p)
array([  1.,   1.])

)