{
    "nbformat": 4,
    "nbformat_minor": 5,
    "metadata": {
        "kernelspec": {
            "display_name": "Python",
            "language": "python",
            "name": "python"
        },
        "language_info": {
            "name": "python"
        }
    },
    "cells": [
        {
            "id": "c5115e77",
            "cell_type": "markdown",
            "source": "<div class='alert alert-warning'>\n\nSciPy's interactive examples with Jupyterlite are experimental and may not always work as expected. Execution of cells containing imports may result in large downloads (up to 60MB of content for the first import from SciPy). Load times when importing from SciPy may take roughly 10-20 seconds. If you notice any problems, feel free to open an [issue](https://github.com/scipy/scipy/issues/new/choose).\n\n</div>",
            "metadata": {}
        },
        {
            "id": "8b998c39",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "import numpy as np\nfrom scipy import linalg\na = np.array([[  3.,  -2.,  -2.],\n              [  6.,  -7.,   4.],\n              [  7.,   8.,  -6.]])\nq, r = linalg.qr(a)",
            "outputs": []
        },
        {
            "id": "fcd14ce8",
            "cell_type": "markdown",
            "source": "Given this QR decomposition, update q and r when 2 rows are inserted.\n",
            "metadata": {}
        },
        {
            "id": "c0b01e2d",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "u = np.array([[  6.,  -9.,  -3.],\n              [ -3.,  10.,   1.]])\nq1, r1 = linalg.qr_insert(q, r, u, 2, 'row')\nq1",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[-0.25445668,  0.02246245,  0.18146236, -0.72798806,  0.60979671],  # may vary (signs)\n       [-0.50891336,  0.23226178, -0.82836478, -0.02837033, -0.00828114],\n       [-0.50891336,  0.35715302,  0.38937158,  0.58110733,  0.35235345],\n       [ 0.25445668, -0.52202743, -0.32165498,  0.36263239,  0.65404509],\n       [-0.59373225, -0.73856549,  0.16065817, -0.0063658 , -0.27595554]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "c1e43244",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "r1",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[-11.78982612,   6.44623587,   3.81685018],  # may vary (signs)\n       [  0.        , -16.01393278,   3.72202865],\n       [  0.        ,   0.        ,  -6.13010256],\n       [  0.        ,   0.        ,   0.        ],\n       [  0.        ,   0.        ,   0.        ]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "804a940f",
            "cell_type": "markdown",
            "source": "The update is equivalent, but faster than the following.\n",
            "metadata": {}
        },
        {
            "id": "e4a33a4f",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "a1 = np.insert(a, 2, u, 0)\na1",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[  3.,  -2.,  -2.],\n       [  6.,  -7.,   4.],\n       [  6.,  -9.,  -3.],\n       [ -3.,  10.,   1.],\n       [  7.,   8.,  -6.]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "a38680bd",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "q_direct, r_direct = linalg.qr(a1)",
            "outputs": []
        },
        {
            "id": "34dc448b",
            "cell_type": "markdown",
            "source": "Check that we have equivalent results:\n",
            "metadata": {}
        },
        {
            "id": "4804b926",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "np.dot(q1, r1)",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "array([[  3.,  -2.,  -2.],\n       [  6.,  -7.,   4.],\n       [  6.,  -9.,  -3.],\n       [ -3.,  10.,   1.],\n       [  7.,   8.,  -6.]])"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "0940891f",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "np.allclose(np.dot(q1, r1), a1)",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "True"
                    },
                    "execution_count": null
                }
            ]
        },
        {
            "id": "056063a6",
            "cell_type": "markdown",
            "source": "And the updated Q is still unitary:\n",
            "metadata": {}
        },
        {
            "id": "d725ef65",
            "cell_type": "code",
            "metadata": {},
            "execution_count": null,
            "source": "np.allclose(np.dot(q1.T, q1), np.eye(5))",
            "outputs": [
                {
                    "output_type": "execute_result",
                    "metadata": {},
                    "data": {
                        "text/plain": "True"
                    },
                    "execution_count": null
                }
            ]
        }
    ]
}