{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "P6HwDJLFSPCl"
      },
      "source": [
        "<h1><center>Introduction to quantum science and technology - QUANT 400</center></h1>\n",
        "\n",
        "<p><center> <b>Lecturer:</b> <i>Prof. G. Carleo</i> </center><p>\n",
        "    \n",
        "<p><center> <b>Assistant: </b> <i>friederike.metz@epfl.ch"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dzNng6vCL9eP"
      },
      "source": [
        "## Exercise 0: Python Tutorial With Jupyter Notebook"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0vJLt3JRL9eR"
      },
      "source": [
        "This is a tutorial on the basics of the Python language and the usage of Jupyter notebooks. If you are not familiar with the concepts here, I highly recommend you to carefully go through this notebook. I will not recap Python in the Tutorial sessions and except that you are familiar with the concepts introduced here."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2vLL2n82SPCp"
      },
      "source": [
        "## What is a Jupyter Notebook?"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "52a3a82gSPCp"
      },
      "source": [
        "A Jupyter notebook is made up of a number of cells. Each cell can contain Python code. There are two main types of cells: `Code` cells and `Markdown` cells. This particular cell is a `Markdown` cell. You can execute a particular cell by double clicking on it and pressing `Shift-Enter`. When you do so, if the cell is a `Code` cell, the code in the cell will run, and the output of the cell will be displayed beneath the cell, and if the cell is a `Markdown` cell, the markdown text will get rendered beneath the cell.\n",
        "\n",
        "Go ahead and try executing this cell."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "R49qvFCzSPCq"
      },
      "source": [
        "The cell below is a `Code` cell. Go ahead and click it, then execute it."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0O80Cn5xSPCq",
        "outputId": "d612e735-1609-4e16-89ad-59a4cd1e9885"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "1\n"
          ]
        }
      ],
      "source": [
        "x = 1\n",
        "print(x)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ojzPLVqtSPCr"
      },
      "source": [
        "Global variables are shared between cells. Try executing the cell below:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ND0yhBB9SPCr",
        "outputId": "8492e66c-c36a-4217-a776-ee3df20ba662"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2\n"
          ]
        }
      ],
      "source": [
        "y = 2 * x\n",
        "print(y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C-HJ_LaBSPCs"
      },
      "source": [
        "### Keyboard Shortcuts\n",
        "\n",
        "There are a few keyboard shortcuts you should be aware of to make your notebook experience more pleasant. To escape editing of a cell, press `esc`. Escaping a `Markdown` cell won't render it, so make sure to execute it if you wish to render the markdown.\n",
        "\n",
        "You can navigate between cells by pressing your arrow keys. Executing a cell automatically shifts the cell cursor down 1 cell if one exists, or creates a new cell below the current one if none exist.\n",
        "\n",
        "* To place a cell below the current one, press `b`.\n",
        "* To place a cell above the current one, press `a`.\n",
        "* To delete a cell, press `dd`.\n",
        "* To convert a cell to `Markdown` press `m`. Note you have to be in `esc` mode.\n",
        "* To convert it back to `Code` press `y`. Note you have to be in `esc` mode.\n",
        "\n",
        "Get familiar with these keyboard shortcuts, they really help!"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UliWoDHmSPCs"
      },
      "source": [
        "You can restart a notebook and clear all cells by clicking `Kernel -> Restart & Clear Output`. If you don't want to clear cell outputs, just hit `Kernel -> Restart`.\n",
        "\n",
        "By convention, Jupyter notebooks are expected to be run from top to bottom. Failing to execute some cells or executing cells out of order can result in errors. After restarting the notebook, try running the `y = 2 * x` cell 2 cells above and observe what happens."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_fV8-winSPCs"
      },
      "source": [
        "After you have modified a Jupyter notebook for one of the assignments by modifying or executing some of its cells, remember to save your changes! You can save with the `Command/Control + s` shortcut or by clicking `File -> Save and Checkpoint`."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "v2ry_n5pSPCt"
      },
      "source": [
        "This has only been a brief introduction to Jupyter notebooks, but it should be enough to get you up and running on the assignments for this course."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qVrTo-LhL9eS"
      },
      "source": [
        "## Python Tutorial"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9t1gKp9PL9eV"
      },
      "source": [
        "Python is a great general-purpose programming language on its own, but with the help of a few popular libraries (numpy, scipy, matplotlib) it becomes a powerful environment for scientific computing.\n",
        "\n",
        "We expect that many of you will have some experience with Python and numpy; for the rest of you, this section will serve as a quick crash course both on the Python programming language and on the use of Python for scientific computing."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U1PvreR9L9eW"
      },
      "source": [
        "In this tutorial, we will cover:\n",
        "\n",
        "* Basic Python: Basic data types (Containers, Lists, Dictionaries, Tuples), Functions\n",
        "* Numpy: Arrays, Array indexing, Datatypes, Array math, Broadcasting\n",
        "* Scipy: Sparce matrices\n",
        "* Matplotlib: Plotting"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JAFKYgrpL9eY"
      },
      "source": [
        "## Basics of Python"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RbFS6tdgL9ea"
      },
      "source": [
        "Python is a high-level, dynamically typed multiparadigm programming language. Python code is often said to be almost like pseudocode, since it allows you to express very powerful ideas in very few lines of code while being very readable. As an example, here is an implementation of the classic quicksort algorithm in Python:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cYb0pjh1L9eb",
        "outputId": "469d0933-af81-4154-e5b1-d7994d8eb882"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[1, 1, 2, 3, 6, 8, 10]\n"
          ]
        }
      ],
      "source": [
        "def quicksort(arr):\n",
        "    if len(arr) <= 1:\n",
        "        return arr\n",
        "    pivot = arr[len(arr) // 2]\n",
        "    left = [x for x in arr if x < pivot]\n",
        "    middle = [x for x in arr if x == pivot]\n",
        "    right = [x for x in arr if x > pivot]\n",
        "    return quicksort(left) + middle + quicksort(right)\n",
        "\n",
        "print(quicksort([3,6,8,10,1,2,1]))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NwS_hu4xL9eo"
      },
      "source": [
        "### Basic data types"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DL5sMSZ9L9eq"
      },
      "source": [
        "#### Numbers"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MGS0XEWoL9er"
      },
      "source": [
        "Integers and floats work as you would expect from other languages:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KheDr_zDL9es",
        "outputId": "69bc5066-c904-4bb5-fd5c-9733907c32ce"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "3 <class 'int'>\n"
          ]
        }
      ],
      "source": [
        "x = 3\n",
        "print(x, type(x))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "sk_8DFcuL9ey",
        "outputId": "c5241878-b15f-47c7-cf4a-97b517cd4cd6"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "4\n",
            "2\n",
            "6\n",
            "9\n"
          ]
        }
      ],
      "source": [
        "print(x + 1)   # Addition\n",
        "print(x - 1)   # Subtraction\n",
        "print(x * 2)   # Multiplication\n",
        "print(x ** 2)  # Exponentiation"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "U4Jl8K0tL9e4",
        "outputId": "8b211e81-bfe6-4f2d-dd68-1f4ac342c767"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "4\n",
            "8\n"
          ]
        }
      ],
      "source": [
        "x += 1\n",
        "print(x)\n",
        "x *= 2\n",
        "print(x)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "w-nZ0Sg_L9e9",
        "outputId": "7a9a6510-9f75-459d-dc82-ed78a2a8e6eb"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<class 'float'>\n",
            "2.5 3.5 5.0 6.25\n"
          ]
        }
      ],
      "source": [
        "y = 2.5\n",
        "print(type(y))\n",
        "print(y, y + 1, y * 2, y ** 2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "r2A9ApyaL9fB"
      },
      "source": [
        "Note that unlike many languages, Python does not have unary increment (x++) or decrement (x--) operators.\n",
        "\n",
        "Python also has built-in types for long integers and complex numbers; you can find all of the details in the [documentation](https://docs.python.org/3/library/stdtypes.html)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EqRS7qhBL9fC"
      },
      "source": [
        "#### Booleans"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Nv_LIVOJL9fD"
      },
      "source": [
        "Python implements all of the usual operators for Boolean logic, but uses English words rather than symbols (`&&`, `||`, etc.):"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "RvoImwgGL9fE",
        "outputId": "9a24a6d7-085a-4110-a80f-adadfbe956ff"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<class 'bool'>\n"
          ]
        }
      ],
      "source": [
        "t, f = True, False\n",
        "print(type(t))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YQgmQfOgL9fI"
      },
      "source": [
        "Now we let's look at the operations:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "6zYm7WzCL9fK",
        "outputId": "c755bffc-4202-42e9-ccda-cdbff972a21d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "False\n",
            "True\n",
            "False\n",
            "True\n"
          ]
        }
      ],
      "source": [
        "print(t and f) # Logical AND;\n",
        "print(t or f)  # Logical OR;\n",
        "print(not t)   # Logical NOT;\n",
        "print(t != f)  # Logical XOR;"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UQnQWFEyL9fP"
      },
      "source": [
        "#### Strings"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "AijEDtPFL9fP",
        "outputId": "808c1536-e66f-404a-ffae-6821a1b4d689"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "hello 5\n"
          ]
        }
      ],
      "source": [
        "hello = 'hello'   # String literals can use single quotes\n",
        "world = \"world\"   # or double quotes; it does not matter\n",
        "print(hello, len(hello))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "saDeaA7hL9fT",
        "outputId": "e56ee281-97b3-4912-8d0f-2666efef6e8c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "hello world\n"
          ]
        }
      ],
      "source": [
        "hw = hello + ' ' + world  # String concatenation\n",
        "print(hw)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "06cayXLtL9fi"
      },
      "source": [
        "You can find a list of all string methods in the [documentation](https://docs.python.org/3/library/stdtypes.html#string-methods)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "p-6hClFjL9fk"
      },
      "source": [
        "### Containers"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FD9H18eQL9fk"
      },
      "source": [
        "Python includes several built-in container types: lists, dictionaries, sets, and tuples."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UsIWOe0LL9fn"
      },
      "source": [
        "#### Lists"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wzxX7rgWL9fn"
      },
      "source": [
        "A list is the Python equivalent of an array, but is resizeable and can contain elements of different types:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "hk3A8pPcL9fp",
        "outputId": "8d4cda85-9a1e-4b91-ce60-268c64bc4dbd"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[3, 1, 2] 2\n",
            "2\n"
          ]
        }
      ],
      "source": [
        "xs = [3, 1, 2]   # Create a list\n",
        "print(xs, xs[2])\n",
        "print(xs[-1])     # Negative indices count from the end of the list; prints \"2\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "YCjCy_0_L9ft",
        "outputId": "8cfe69b7-c1f3-4f1a-8510-379375ca7901"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[3, 1, 'foo']\n"
          ]
        }
      ],
      "source": [
        "xs[2] = 'foo'    # Lists can contain elements of different types\n",
        "print(xs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "vJ0x5cF-L9fx",
        "outputId": "7bbdeb4c-17d5-4daa-8a6a-6696dc1a39fc"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[3, 1, 'foo', 'bar']\n"
          ]
        }
      ],
      "source": [
        "xs.append('bar') # Add a new element to the end of the list\n",
        "print(xs)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cxVCNRTNL9f1",
        "outputId": "ac97b9e6-12df-4235-d52b-0ad42d2f8570"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "bar [3, 1, 'foo']\n"
          ]
        }
      ],
      "source": [
        "x = xs.pop()     # Remove and return the last element of the list\n",
        "print(x, xs)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ilyoyO34L9f4"
      },
      "source": [
        "As usual, you can find all the gory details about lists in the [documentation](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ovahhxd_L9f5"
      },
      "source": [
        "#### Slicing"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YeSYKhv9L9f6"
      },
      "source": [
        "In addition to accessing list elements one at a time, Python provides concise syntax to access sublists; this is known as slicing:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ninq666bL9f6",
        "outputId": "21cb64c6-5443-41df-95c2-ed58981729ab"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[0, 1, 2, 3, 4]\n",
            "[2, 3]\n",
            "[2, 3, 4]\n",
            "[0, 1]\n",
            "[0, 1, 2, 3, 4]\n",
            "[0, 1, 2, 3]\n",
            "[0, 1, 8, 9, 4]\n"
          ]
        }
      ],
      "source": [
        "nums = list(range(5))    # range is a built-in function that creates a list of integers\n",
        "print(nums)         # Prints \"[0, 1, 2, 3, 4]\"\n",
        "print(nums[2:4])    # Get a slice from index 2 to 4 (exclusive); prints \"[2, 3]\"\n",
        "print(nums[2:])     # Get a slice from index 2 to the end; prints \"[2, 3, 4]\"\n",
        "print(nums[:2])     # Get a slice from the start to index 2 (exclusive); prints \"[0, 1]\"\n",
        "print(nums[:])      # Get a slice of the whole list; prints [\"0, 1, 2, 3, 4]\"\n",
        "print(nums[:-1])    # Slice indices can be negative; prints [\"0, 1, 2, 3]\"\n",
        "nums[2:4] = [8, 9] # Assign a new sublist to a slice\n",
        "print(nums)         # Prints \"[0, 1, 8, 9, 4]\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UONpMhF4L9f_"
      },
      "source": [
        "#### Loops"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_DYz1j6QL9f_"
      },
      "source": [
        "You can loop over the elements of a list like this:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4cCOysfWL9gA",
        "outputId": "007ee286-2e36-4495-c889-62c461b20b0b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "cat\n",
            "dog\n",
            "monkey\n"
          ]
        }
      ],
      "source": [
        "animals = ['cat', 'dog', 'monkey']\n",
        "for animal in animals:\n",
        "    print(animal)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KxIaQs7pL9gE"
      },
      "source": [
        "If you want access to the index of each element within the body of a loop, use the built-in `enumerate` function:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JjGnDluWL9gF",
        "outputId": "0f211f25-3c4f-426a-f9d1-50fd9a5dc580"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0 cat\n",
            "1 dog\n",
            "2 monkey\n"
          ]
        }
      ],
      "source": [
        "animals = ['cat', 'dog', 'monkey']\n",
        "for idx, animal in enumerate(animals):\n",
        "    print(idx, animal)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "arrLCcMyL9gK"
      },
      "source": [
        "#### List comprehensions"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5Qn2jU_pL9gL"
      },
      "source": [
        "When programming, frequently we want to transform one type of data into another. As a simple example, consider the following code that computes square numbers:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "IVNEwoMXL9gL",
        "outputId": "5f788802-a59f-4c07-f602-dcc5cec56f67"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[0, 1, 4, 9, 16]\n"
          ]
        }
      ],
      "source": [
        "nums = [0, 1, 2, 3, 4]\n",
        "squares = []\n",
        "for x in nums:\n",
        "    squares.append(x ** 2)\n",
        "print(squares)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "7DmKVUFaL9gQ"
      },
      "source": [
        "You can make this code simpler using a list comprehension:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "kZxsUfV6L9gR",
        "outputId": "b32f5441-6f52-480c-d087-f478033a6de3"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[0, 1, 4, 9, 16]\n"
          ]
        }
      ],
      "source": [
        "nums = [0, 1, 2, 3, 4]\n",
        "squares = [x ** 2 for x in nums]\n",
        "print(squares)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-D8ARK7tL9gV"
      },
      "source": [
        "List comprehensions can also contain conditions:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yUtgOyyYL9gV",
        "outputId": "8d9a5712-c8ba-448e-b270-dd712a2282fd"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[0, 4, 16]\n"
          ]
        }
      ],
      "source": [
        "nums = [0, 1, 2, 3, 4]\n",
        "even_squares = [x ** 2 for x in nums if x % 2 == 0]\n",
        "print(even_squares)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "H8xsUEFpL9gZ"
      },
      "source": [
        "#### Dictionaries"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kkjAGMAJL9ga"
      },
      "source": [
        "A dictionary stores (key, value) pairs, similar to a `Map` in Java or an object in Javascript. You can use it like this:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "XBYI1MrYL9gb",
        "outputId": "e03e54d8-49e5-4bf8-e906-73aeb19ec0f7"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "cute\n",
            "True\n"
          ]
        }
      ],
      "source": [
        "d = {'cat': 'cute', 'dog': 'furry'}  # Create a new dictionary with some data\n",
        "print(d['cat'])       # Get an entry from a dictionary; prints \"cute\"\n",
        "print('cat' in d)     # Check if a dictionary has a given key; prints \"True\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "pS7e-G-HL9gf",
        "outputId": "58a5a8f2-c980-4d61-b5de-e5cb5867a5bc"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "wet\n"
          ]
        }
      ],
      "source": [
        "d['fish'] = 'wet'    # Set an entry in a dictionary\n",
        "print(d['fish'])      # Prints \"wet\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 166
        },
        "id": "tFY065ItL9gi",
        "outputId": "413ec635-9a80-45c4-df4c-c5c344d78941"
      },
      "outputs": [
        {
          "ename": "KeyError",
          "evalue": "'monkey'",
          "output_type": "error",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
            "Cell \u001b[0;32mIn[24], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43md\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mmonkey\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m]\u001b[49m)  \u001b[38;5;66;03m# KeyError: 'monkey' not a key of d\u001b[39;00m\n",
            "\u001b[0;31mKeyError\u001b[0m: 'monkey'"
          ]
        }
      ],
      "source": [
        "print(d['monkey'])  # KeyError: 'monkey' not a key of d"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "8TjbEWqML9gl",
        "outputId": "70f5f2b0-60d5-46c3-fefc-8f074a498bb1"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "N/A\n",
            "wet\n"
          ]
        }
      ],
      "source": [
        "print(d.get('monkey', 'N/A'))  # Get an element with a default; prints \"N/A\"\n",
        "print(d.get('fish', 'N/A'))    # Get an element with a default; prints \"wet\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0EItdNBJL9go",
        "outputId": "9600e9ea-b9e9-48b9-8993-b2d59e42b030"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "N/A\n"
          ]
        }
      ],
      "source": [
        "del d['fish']        # Remove an element from a dictionary\n",
        "print(d.get('fish', 'N/A')) # \"fish\" is no longer a key; prints \"N/A\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "wqm4dRZNL9gr"
      },
      "source": [
        "You can find all you need to know about dictionaries in the [documentation](https://docs.python.org/3/library/stdtypes.html#mapping-types-dict)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "IxwEqHlGL9gr"
      },
      "source": [
        "It is easy to iterate over the keys in a dictionary:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "rYfz7ZKNL9gs",
        "outputId": "fb7b20d8-2aee-451c-9b4b-e61acf881e3b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "A person has 2 legs\n",
            "A cat has 4 legs\n",
            "A spider has 8 legs\n"
          ]
        }
      ],
      "source": [
        "d = {'person': 2, 'cat': 4, 'spider': 8}\n",
        "for animal, legs in d.items():\n",
        "    print('A {} has {} legs'.format(animal, legs))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qPsHSKB1L9hF"
      },
      "source": [
        "#### Tuples"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kucc0LKVL9hG"
      },
      "source": [
        "A tuple is an (immutable) ordered list of values. A tuple is in many ways similar to a list; one of the most important differences is that tuples can be used as keys in dictionaries and as elements of sets, while lists cannot. Here is a trivial example:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "9wHUyTKxL9hH",
        "outputId": "8338d44c-353c-4f6a-a353-d67982401df2"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<class 'tuple'>\n",
            "5\n",
            "1\n"
          ]
        }
      ],
      "source": [
        "d = {(x, x + 1): x for x in range(10)}  # Create a dictionary with tuple keys\n",
        "t = (5, 6)       # Create a tuple\n",
        "print(type(t))\n",
        "print(d[t])\n",
        "print(d[(1, 2)])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 166
        },
        "id": "HoO8zYKzL9hJ",
        "outputId": "f96d8e27-3133-4d51-ed0e-9fad29233137"
      },
      "outputs": [
        {
          "ename": "TypeError",
          "evalue": "'tuple' object does not support item assignment",
          "output_type": "error",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
            "Cell \u001b[0;32mIn[29], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mt\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n",
            "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment"
          ]
        }
      ],
      "source": [
        "t[0] = 1"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "AXA4jrEOL9hM"
      },
      "source": [
        "### Functions"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WaRms-QfL9hN"
      },
      "source": [
        "Python functions are defined using the `def` keyword. For example:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "kiMDUr58L9hN",
        "outputId": "c83b2843-d9a7-400b-ba3f-4be00fe93a1c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "negative\n",
            "zero\n",
            "positive\n"
          ]
        }
      ],
      "source": [
        "def sign(x):\n",
        "    if x > 0:\n",
        "        return 'positive'\n",
        "    elif x < 0:\n",
        "        return 'negative'\n",
        "    else:\n",
        "        return 'zero'\n",
        "\n",
        "for x in [-1, 0, 1]:\n",
        "    print(sign(x))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U-QJFt8TL9hR"
      },
      "source": [
        "We will often define functions to take optional keyword arguments, like this:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PfsZ3DazL9hR",
        "outputId": "b7e3c42c-97b3-470b-c057-40e23fc6acc1"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Hello, Bob!\n",
            "HELLO, FRED\n"
          ]
        }
      ],
      "source": [
        "def hello(name, loud=False):\n",
        "    if loud:\n",
        "        print('HELLO, {}'.format(name.upper()))\n",
        "    else:\n",
        "        print('Hello, {}!'.format(name))\n",
        "\n",
        "hello('Bob')\n",
        "hello('Fred', loud=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3cfrOV4dL9hW"
      },
      "source": [
        "## Numpy"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fY12nHhyL9hX"
      },
      "source": [
        "Numpy is the core library for scientific computing in Python. It provides a high-performance multidimensional array object, and tools for working with these arrays. If you are already familiar with MATLAB, you might find this [tutorial](http://wiki.scipy.org/NumPy_for_Matlab_Users) useful to get started with Numpy."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lZMyAdqhL9hY"
      },
      "source": [
        "To use Numpy, we first need to import the `numpy` package:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "metadata": {
        "id": "58QdX8BLL9hZ"
      },
      "outputs": [],
      "source": [
        "import numpy as np"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DDx6v1EdL9hb"
      },
      "source": [
        "### Arrays"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f-Zv3f7LL9hc"
      },
      "source": [
        "A numpy array is a grid of values, all of the same type, and is indexed by a tuple of nonnegative integers. The number of dimensions is the rank of the array; the shape of an array is a tuple of integers giving the size of the array along each dimension."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_eMTRnZRL9hc"
      },
      "source": [
        "We can initialize numpy arrays from nested Python lists, and access elements using square brackets:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-l3JrGxCL9hc",
        "outputId": "61a09686-e09c-418d-9e89-bec233e4c226"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<class 'numpy.ndarray'> (3,) 1 2 3\n",
            "[5 2 3]\n"
          ]
        }
      ],
      "source": [
        "a = np.array([1, 2, 3])  # Create a rank 1 array\n",
        "print(type(a), a.shape, a[0], a[1], a[2])\n",
        "a[0] = 5                 # Change an element of the array\n",
        "print(a)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ma6mk-kdL9hh",
        "outputId": "2a44fd8e-221c-4d3d-9b60-5706fe3b5e4b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1 2 3]\n",
            " [4 5 6]]\n"
          ]
        }
      ],
      "source": [
        "b = np.array([[1,2,3],[4,5,6]])   # Create a rank 2 array\n",
        "print(b)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 35,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "ymfSHAwtL9hj",
        "outputId": "aa6408a4-86e4-4dad-f8c7-f28485ae583b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "(2, 3)\n",
            "1 2 4\n"
          ]
        }
      ],
      "source": [
        "print(b.shape)\n",
        "print(b[0, 0], b[0, 1], b[1, 0])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "F2qwdyvuL9hn"
      },
      "source": [
        "Numpy also provides many functions to create arrays:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 36,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mVTN_EBqL9hn",
        "outputId": "130a3bbb-87a2-4a29-eb5c-351b0082cd76"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[0. 0.]\n",
            " [0. 0.]]\n"
          ]
        }
      ],
      "source": [
        "a = np.zeros((2,2))  # Create an array of all zeros\n",
        "print(a)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 37,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "skiKlNmlL9h5",
        "outputId": "a57b5521-ee87-48a3-bf3b-616d9e0c8545"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1. 1.]]\n"
          ]
        }
      ],
      "source": [
        "b = np.ones((1,2))   # Create an array of all ones\n",
        "print(b)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 38,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-QcALHvkL9h9",
        "outputId": "00da8b56-25bc-429b-bea7-f3d50a1ba3b6"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1. 0.]\n",
            " [0. 1.]]\n"
          ]
        }
      ],
      "source": [
        "d = np.eye(2)        # Create a 2x2 identity matrix\n",
        "print(d)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 39,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "RCpaYg9qL9iA",
        "outputId": "9a45832a-cb73-4cd2-f6e1-95ed8a93427d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[0.41285238 0.07196405]\n",
            " [0.44921372 0.93513325]]\n"
          ]
        }
      ],
      "source": [
        "e = np.random.random((2,2)) # Create an array filled with random values\n",
        "print(e)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jI5qcSDfL9iC"
      },
      "source": [
        "### Array indexing"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "M-E4MUeVL9iC"
      },
      "source": [
        "Numpy offers several ways to index into arrays."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "QYv4JyIEL9iD"
      },
      "source": [
        "Slicing: Similar to Python lists, numpy arrays can be sliced. Since arrays may be multidimensional, you must specify a slice for each dimension of the array:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 40,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "wLWA0udwL9iD",
        "outputId": "a38b5162-53e0-4395-ea14-aa7635bbc805"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[2 3]\n",
            " [6 7]]\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "# Create the following rank 2 array with shape (3, 4)\n",
        "# [[ 1  2  3  4]\n",
        "#  [ 5  6  7  8]\n",
        "#  [ 9 10 11 12]]\n",
        "a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])\n",
        "\n",
        "# Use slicing to pull out the subarray consisting of the first 2 rows\n",
        "# and columns 1 and 2; b is the following array of shape (2, 2):\n",
        "# [[2 3]\n",
        "#  [6 7]]\n",
        "b = a[:2, 1:3]\n",
        "print(b)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KahhtZKYL9iF"
      },
      "source": [
        "A slice of an array is a view into the same data, so modifying it will modify the original array."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 41,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1kmtaFHuL9iG",
        "outputId": "fc643266-f356-43c4-b4d4-3542543ba63f"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "2\n",
            "77\n"
          ]
        }
      ],
      "source": [
        "print(a[0, 1])\n",
        "b[0, 0] = 77    # b[0, 0] is the same piece of data as a[0, 1]\n",
        "print(a[0, 1])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_Zcf3zi-L9iI"
      },
      "source": [
        "You can also mix integer indexing with slice indexing. However, doing so will yield an array of lower rank than the original array. Note that this is quite different from the way that MATLAB handles array slicing:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 42,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "G6lfbPuxL9iJ",
        "outputId": "d8dbb219-dd10-4eca-8262-039a81768dc7"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 1  2  3  4]\n",
            " [ 5  6  7  8]\n",
            " [ 9 10 11 12]]\n"
          ]
        }
      ],
      "source": [
        "# Create the following rank 2 array with shape (3, 4)\n",
        "a = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]])\n",
        "print(a)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NCye3NXhL9iL"
      },
      "source": [
        "Two ways of accessing the data in the middle row of the array.\n",
        "Mixing integer indexing with slices yields an array of lower rank,\n",
        "while using only slices yields an array of the same rank as the\n",
        "original array:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 43,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "EOiEMsmNL9iL",
        "outputId": "5dbc8926-f0d6-461e-9179-29aff5306a4f"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[5 6 7 8] (4,)\n",
            "[[5 6 7 8]] (1, 4)\n",
            "[[5 6 7 8]] (1, 4)\n"
          ]
        }
      ],
      "source": [
        "row_r1 = a[1, :]    # Rank 1 view of the second row of a\n",
        "row_r2 = a[1:2, :]  # Rank 2 view of the second row of a\n",
        "row_r3 = a[[1], :]  # Rank 2 view of the second row of a\n",
        "print(row_r1, row_r1.shape)\n",
        "print(row_r2, row_r2.shape)\n",
        "print(row_r3, row_r3.shape)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 44,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JXu73pfDL9iN",
        "outputId": "0032ab65-54a2-4158-93c0-1e89ebd624d9"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[ 2  6 10] (3,)\n",
            "\n",
            "[[ 2]\n",
            " [ 6]\n",
            " [10]] (3, 1)\n"
          ]
        }
      ],
      "source": [
        "# We can make the same distinction when accessing columns of an array:\n",
        "col_r1 = a[:, 1]\n",
        "col_r2 = a[:, 1:2]\n",
        "print(col_r1, col_r1.shape)\n",
        "print()\n",
        "print(col_r2, col_r2.shape)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jTctwqdQL9ih"
      },
      "source": [
        "### Datatypes"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kSZQ1WkIL9ih"
      },
      "source": [
        "Every numpy array is a grid of elements of the same type. Numpy provides a large set of numeric datatypes that you can use to construct arrays. Numpy tries to guess a datatype when you create an array, but functions that construct arrays usually also include an optional argument to explicitly specify the datatype. Here is an example:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 45,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "4za4O0m5L9ih",
        "outputId": "383c7d02-3e14-4f20-e53f-2895a4b283a9"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "int64 float64 int64\n"
          ]
        }
      ],
      "source": [
        "x = np.array([1, 2])  # Let numpy choose the datatype\n",
        "y = np.array([1.0, 2.0])  # Let numpy choose the datatype\n",
        "z = np.array([1, 2], dtype=np.int64)  # Force a particular datatype\n",
        "\n",
        "print(x.dtype, y.dtype, z.dtype)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RLVIsZQpL9ik"
      },
      "source": [
        "You can read all about numpy datatypes in the [documentation](http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "TuB-fdhIL9ik"
      },
      "source": [
        "### Array math"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "18e8V8elL9ik"
      },
      "source": [
        "Basic mathematical functions operate elementwise on arrays, and are available both as operator overloads and as functions in the numpy module:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 46,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "gHKvBrSKL9il",
        "outputId": "108f921e-af97-495a-b07b-f8c16fe56088"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 6.  8.]\n",
            " [10. 12.]]\n",
            "[[ 6.  8.]\n",
            " [10. 12.]]\n"
          ]
        }
      ],
      "source": [
        "x = np.array([[1,2],[3,4]], dtype=np.float64)\n",
        "y = np.array([[5,6],[7,8]], dtype=np.float64)\n",
        "\n",
        "# Elementwise sum; both produce the array\n",
        "print(x + y)\n",
        "print(np.add(x, y))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 47,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1fZtIAMxL9in",
        "outputId": "d9dbd120-3223-4699-b100-e18c4fbb2f57"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[-4. -4.]\n",
            " [-4. -4.]]\n",
            "[[-4. -4.]\n",
            " [-4. -4.]]\n"
          ]
        }
      ],
      "source": [
        "# Elementwise difference; both produce the array\n",
        "print(x - y)\n",
        "print(np.subtract(x, y))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 48,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "nil4AScML9io",
        "outputId": "29e35708-7740-493a-e66b-f716144eab06"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 5. 12.]\n",
            " [21. 32.]]\n",
            "[[ 5. 12.]\n",
            " [21. 32.]]\n"
          ]
        }
      ],
      "source": [
        "# Elementwise product; both produce the array\n",
        "print(x * y)\n",
        "print(np.multiply(x, y))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 49,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "0JoA4lH6L9ip",
        "outputId": "78c9be00-aa1b-4465-ebfc-5eea2d6e5545"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[0.2        0.33333333]\n",
            " [0.42857143 0.5       ]]\n",
            "[[0.2        0.33333333]\n",
            " [0.42857143 0.5       ]]\n"
          ]
        }
      ],
      "source": [
        "# Elementwise division; both produce the array\n",
        "# [[ 0.2         0.33333333]\n",
        "#  [ 0.42857143  0.5       ]]\n",
        "print(x / y)\n",
        "print(np.divide(x, y))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 50,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "g0iZuA6bL9ir",
        "outputId": "67e0e098-579d-43c5-a973-9f70db7fd13c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1.         1.41421356]\n",
            " [1.73205081 2.        ]]\n"
          ]
        }
      ],
      "source": [
        "# Elementwise square root; produces the array\n",
        "# [[ 1.          1.41421356]\n",
        "#  [ 1.73205081  2.        ]]\n",
        "print(np.sqrt(x))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "a5d_uujuL9it"
      },
      "source": [
        "Note that unlike MATLAB, `*` is elementwise multiplication, not matrix multiplication. We instead use the dot function to compute inner products of vectors, to multiply a vector by a matrix, and to multiply matrices. dot is available both as a function in the numpy module and as an instance method of array objects:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 51,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "I3FnmoSeL9iu",
        "outputId": "e3c0ba3d-4574-477a-8d82-aec8eb23973d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "219\n",
            "219\n"
          ]
        }
      ],
      "source": [
        "x = np.array([[1,2],[3,4]])\n",
        "y = np.array([[5,6],[7,8]])\n",
        "\n",
        "v = np.array([9,10])\n",
        "w = np.array([11, 12])\n",
        "\n",
        "# Inner product of vectors; both produce 219\n",
        "print(v.dot(w))\n",
        "print(np.dot(v, w))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vmxPbrHASVeA"
      },
      "source": [
        "You can also use the `@` operator which is equivalent to numpy's `dot` operator."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 52,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "vyrWA-mXSdtt",
        "outputId": "4bfb7eae-23d7-4135-fa70-103aa30d256b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "219\n"
          ]
        }
      ],
      "source": [
        "print(v @ w)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 53,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "zvUODeTxL9iw",
        "outputId": "eb5bc840-9d85-4758-d7dc-5f81e055fa9d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[29 67]\n",
            "[29 67]\n",
            "[29 67]\n"
          ]
        }
      ],
      "source": [
        "# Matrix / vector product; both produce the rank 1 array [29 67]\n",
        "print(x.dot(v))\n",
        "print(np.dot(x, v))\n",
        "print(x @ v)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 54,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3V_3NzNEL9iy",
        "outputId": "35e5e264-233d-4a16-dd02-ac228eb7676d"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[19 22]\n",
            " [43 50]]\n",
            "[[19 22]\n",
            " [43 50]]\n",
            "[[19 22]\n",
            " [43 50]]\n"
          ]
        }
      ],
      "source": [
        "# Matrix / matrix product; both produce the rank 2 array\n",
        "# [[19 22]\n",
        "#  [43 50]]\n",
        "print(x.dot(y))\n",
        "print(np.dot(x, y))\n",
        "print(x @ y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FbE-1If_L9i0"
      },
      "source": [
        "Numpy provides many useful functions for performing computations on arrays; one of the most useful is `sum`:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 55,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "DZUdZvPrL9i0",
        "outputId": "45c310bb-3320-43a6-c807-8238e1e9500f"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "10\n",
            "[4 6]\n",
            "[3 7]\n"
          ]
        }
      ],
      "source": [
        "x = np.array([[1,2],[3,4]])\n",
        "\n",
        "print(np.sum(x))  # Compute sum of all elements; prints \"10\"\n",
        "print(np.sum(x, axis=0))  # Compute sum of each column; prints \"[4 6]\"\n",
        "print(np.sum(x, axis=1))  # Compute sum of each row; prints \"[3 7]\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ahdVW4iUL9i3"
      },
      "source": [
        "You can find the full list of mathematical functions provided by numpy in the [documentation](http://docs.scipy.org/doc/numpy/reference/routines.math.html).\n",
        "\n",
        "Apart from computing mathematical functions using arrays, we frequently need to reshape or otherwise manipulate data in arrays. The simplest example of this type of operation is transposing a matrix; to transpose a matrix, simply use the T attribute of an array object:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 56,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "63Yl1f3oL9i3",
        "outputId": "af9aa9cc-2de5-4dc7-de34-cb1a18c0e14e"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1 2]\n",
            " [3 4]]\n",
            "transpose\n",
            " [[1 3]\n",
            " [2 4]]\n"
          ]
        }
      ],
      "source": [
        "print(x)\n",
        "print(\"transpose\\n\", x.T)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 57,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mkk03eNIL9i4",
        "outputId": "bde3ed1f-2b3e-407a-8f7f-1669f20d9cde"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1 2 3]]\n",
            "transpose\n",
            " [[1]\n",
            " [2]\n",
            " [3]]\n"
          ]
        }
      ],
      "source": [
        "v = np.array([[1,2,3]])\n",
        "print(v )\n",
        "print(\"transpose\\n\", v.T)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "REfLrUTcL9i7"
      },
      "source": [
        "### (Broadcasting)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EygGAMWqL9i7"
      },
      "source": [
        "Broadcasting is a powerful mechanism that allows numpy to work with arrays of different shapes when performing arithmetic operations. Frequently we have a smaller array and a larger array, and we want to use the smaller array multiple times to perform some operation on the larger array.\n",
        "\n",
        "For example, suppose that we want to add a constant vector to each row of a matrix. We could do it like this:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 58,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "WEEvkV1ZL9i7",
        "outputId": "111aebcc-d6a1-4201-9573-777cddcda4e7"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 2  2  4]\n",
            " [ 5  5  7]\n",
            " [ 8  8 10]\n",
            " [11 11 13]]\n"
          ]
        }
      ],
      "source": [
        "# We will add the vector v to each row of the matrix x,\n",
        "# storing the result in the matrix y\n",
        "x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])\n",
        "v = np.array([1, 0, 1])\n",
        "y = np.empty_like(x)   # Create an empty matrix with the same shape as x\n",
        "\n",
        "# Add the vector v to each row of the matrix x with an explicit loop\n",
        "for i in range(4):\n",
        "    y[i, :] = x[i, :] + v\n",
        "\n",
        "print(y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "2OlXXupEL9i-"
      },
      "source": [
        "This works; however when the matrix `x` is very large, computing an explicit loop in Python could be slow."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "zHos6RJnL9jB"
      },
      "source": [
        "Numpy broadcasting allows us to perform this computation without actually creating multiple copies of v or running a loop. Consider this version, using broadcasting:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 59,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "vnYFb-gYL9jC",
        "outputId": "2d79f906-e30f-46e0-f42c-2ae65d9e6154"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 2  2  4]\n",
            " [ 5  5  7]\n",
            " [ 8  8 10]\n",
            " [11 11 13]]\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\n",
        "\n",
        "# We will add the vector v to each row of the matrix x,\n",
        "# storing the result in the matrix y\n",
        "x = np.array([[1,2,3], [4,5,6], [7,8,9], [10, 11, 12]])\n",
        "v = np.array([1, 0, 1])\n",
        "y = x + v  # Add v to each row of x using broadcasting\n",
        "print(y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "08YyIURKL9jH"
      },
      "source": [
        "The line `y = x + v` works even though `x` has shape `(4, 3)` and `v` has shape `(3,)` due to broadcasting; this line works as if v actually had shape `(4, 3)`, where each row was a copy of `v`, and the sum was performed elementwise.\n",
        "\n",
        "Broadcasting two arrays together follows these rules:\n",
        "\n",
        "1. If the arrays do not have the same rank, prepend the shape of the lower rank array with 1s until both shapes have the same length.\n",
        "2. The two arrays are said to be compatible in a dimension if they have the same size in the dimension, or if one of the arrays has size 1 in that dimension.\n",
        "3. The arrays can be broadcast together if they are compatible in all dimensions.\n",
        "4. After broadcasting, each array behaves as if it had shape equal to the elementwise maximum of shapes of the two input arrays.\n",
        "5. In any dimension where one array had size 1 and the other array had size greater than 1, the first array behaves as if it were copied along that dimension\n",
        "\n",
        "If this explanation does not make sense, try reading the explanation from the [documentation](http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html) or this [explanation](http://wiki.scipy.org/EricsBroadcastingDoc).\n",
        "\n",
        "Functions that support broadcasting are known as universal functions. You can find the list of all universal functions in the [documentation](http://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs).\n",
        "\n",
        "Here are some applications of broadcasting:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 60,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "EmQnwoM9L9jH",
        "outputId": "b60735aa-c4a2-4390-9ccb-6e0ab928480b"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 4  5]\n",
            " [ 8 10]\n",
            " [12 15]]\n"
          ]
        }
      ],
      "source": [
        "# Compute outer product of vectors\n",
        "v = np.array([1,2,3])  # v has shape (3,)\n",
        "w = np.array([4,5])    # w has shape (2,)\n",
        "# To compute an outer product, we first reshape v to be a column\n",
        "# vector of shape (3, 1); we can then broadcast it against w to yield\n",
        "# an output of shape (3, 2), which is the outer product of v and w:\n",
        "\n",
        "print(np.reshape(v, (3, 1)) * w)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 61,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PgotmpcnL9jK",
        "outputId": "e56516b0-2843-4018-fdd7-71952874d38c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[2 4 6]\n",
            " [5 7 9]]\n"
          ]
        }
      ],
      "source": [
        "# Add a vector to each row of a matrix\n",
        "x = np.array([[1,2,3], [4,5,6]])\n",
        "# x has shape (2, 3) and v has shape (3,) so they broadcast to (2, 3),\n",
        "# giving the following matrix:\n",
        "\n",
        "print(x + v)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 62,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "T5hKS1QaL9jK",
        "outputId": "d4dbab01-8abd-4d73-89c4-e92702ac530c"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 5  6  7]\n",
            " [ 9 10 11]]\n"
          ]
        }
      ],
      "source": [
        "# Add a vector to each column of a matrix\n",
        "# x has shape (2, 3) and w has shape (2,).\n",
        "# If we transpose x then it has shape (3, 2) and can be broadcast\n",
        "# against w to yield a result of shape (3, 2); transposing this result\n",
        "# yields the final result of shape (2, 3) which is the matrix x with\n",
        "# the vector w added to each column. Gives the following matrix:\n",
        "\n",
        "print((x.T + w).T)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 63,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JDUrZUl6L9jN",
        "outputId": "61b37e1c-a9b9-4f94-e28e-6ce01583e511"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 5  6  7]\n",
            " [ 9 10 11]]\n"
          ]
        }
      ],
      "source": [
        "# Another solution is to reshape w to be a row vector of shape (2, 1);\n",
        "# we can then broadcast it directly against x to produce the same\n",
        "# output.\n",
        "print(x + np.reshape(w, (2, 1)))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 64,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "VzrEo4KGL9jP",
        "outputId": "571d6312-7d62-4e05-bc9e-db423db41a9e"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[ 2  4  6]\n",
            " [ 8 10 12]]\n"
          ]
        }
      ],
      "source": [
        "# Multiply a matrix by a constant:\n",
        "# x has shape (2, 3). Numpy treats scalars as arrays of shape ();\n",
        "# these can be broadcast together to shape (2, 3), producing the\n",
        "# following array:\n",
        "print(x * 2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "89e2FXxFL9jQ"
      },
      "source": [
        "Broadcasting typically makes your code more concise and faster, so you should strive to use it where possible."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "iF3ZtwVNL9jQ"
      },
      "source": [
        "This brief overview has touched on many of the important things that you need to know about numpy, but is far from complete. Check out the [numpy reference](http://docs.scipy.org/doc/numpy/reference/) to find out much more about numpy."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "aIKM72lrSPC7"
      },
      "source": [
        "## SciPy"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "W0ESUZZESPC7"
      },
      "source": [
        "**Numpy** provides a high-performance multidimensional array and basic tools to compute with and manipulate these arrays.\n",
        "\n",
        "**SciPy** builds on this, and provides a large number of functions that operate on numpy arrays and are useful for different types of scientific and engineering applications.\n",
        "\n",
        "The best way to get familiar with SciPy is to [browse the documentation](https://docs.scipy.org/doc/scipy/reference/index.html)."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "XJ3rPHskSPC7"
      },
      "source": [
        "### The problem with matrices"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "PDsyB69ZSPC7"
      },
      "source": [
        "We have seen how to create a 2D array using NumPy in the previous section.\n",
        "2D arrays in which most of the values are non-zero values are called **dense matrices**.\n",
        "\n",
        "In this course, we will have to manipulate matrices (e.g. find the eigenvalues and eigenvectors of a matrix), but the basic problem with most of the linear algebra techniques is that they scale\n",
        "badly for large matrices.\n",
        "\n",
        "As an example, ordinary Gaussian elimination (LU factorization), Gram–Schmidt and other factorization algorithms, and techniques that computes all the eigenvalues and eigenvectors, all require\n",
        "$∼ n^3$ operations and $∼ n^2$ storage for $n \\, \\times \\, n$ matrices."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Joqb-kj0SPC8"
      },
      "source": [
        "## Sparse matrices"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0UyxRGvxSPC8"
      },
      "source": [
        "However, in physics and machine learning it's common to work with matrices in which most of the values are zeroes: those matrices are called [**sparse**](https://en.wikipedia.org/wiki/Sparse_matrix).\n",
        "\n",
        "It is computationally expensive to represent and work with sparse matrices as though they are dense, and much improvement in performance can be achieved by using representations and operations that specifically handle the matrix sparsity.\n",
        "\n",
        "Using the sparsity of matrices, we can store on laptops matrices that would easily make us run out of memory if they were considered as dense.\n",
        "\n",
        "Let's see a simple comparison between dense and sparsse matrices:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 65,
      "metadata": {
        "id": "pd7P_gIXSPC8"
      },
      "outputs": [],
      "source": [
        "from scipy.sparse import csr_matrix"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 66,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "kunOHtgZSPC8",
        "outputId": "5f49b447-b328-4949-b468-c8971b80d2f7"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1 0 0 1 0 0]\n",
            " [0 0 2 0 0 1]\n",
            " [0 0 0 2 0 0]]\n",
            "The size of the array is:  144  bytes\n"
          ]
        }
      ],
      "source": [
        "# create dense matrix\n",
        "A = np.array([[1, 0, 0, 1, 0, 0], [0, 0, 2, 0, 0, 1], [0, 0, 0, 2, 0, 0]])\n",
        "print(A)\n",
        "# Print also the size of the array\n",
        "print(\"The size of the array is: \",A.nbytes,\" bytes\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 67,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "bmOpbc6GSPC8",
        "outputId": "e4f609cd-1ca5-4be3-e2fc-91dab5685480"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "<Compressed Sparse Row sparse matrix of dtype 'int64'\n",
            "\twith 5 stored elements and shape (3, 6)>\n",
            "  Coords\tValues\n",
            "  (0, 0)\t1\n",
            "  (0, 3)\t1\n",
            "  (1, 2)\t2\n",
            "  (1, 5)\t1\n",
            "  (2, 3)\t2\n",
            "The size of the array is:  40  bytes\n"
          ]
        }
      ],
      "source": [
        "# convert to sparse matrix (CSR method)\n",
        "S = csr_matrix(A)\n",
        "print(S)\n",
        "# Print also the size of the array\n",
        "print(\"The size of the array is: \",S.data.nbytes,\" bytes\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 68,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "QI8O9ZetSPC8",
        "outputId": "121dfeb8-68d8-4151-b30e-541f4cfee3e2"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "[[1 0 0 1 0 0]\n",
            " [0 0 2 0 0 1]\n",
            " [0 0 0 2 0 0]]\n",
            "The size of the array is:  144  bytes\n"
          ]
        }
      ],
      "source": [
        "# reconstruct dense matrix\n",
        "B = S.todense()\n",
        "print(B)\n",
        "# Print also the size of the array\n",
        "print(\"The size of the array is: \",B.data.nbytes,\" bytes\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lHBwFizwSPC8"
      },
      "source": [
        "As you can see, even for this small example we can appreciate the difference in memory usage between a dense and a sparse matrix.\n",
        "The gap between the two methods becomes bigger and bigger as the matrix size increases."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "There are three common sparse matrix formats: Compressed Sparse Row (CSR), Compressed Sparse Column (CSC), and Coordinate List (COO).\n",
        "\n",
        "The CSR format (employed above) uses three arrays:\n",
        "* `values`: Stores the non-zero values.\n",
        "* `col indices`: Stores the column indices of the non-zero values.\n",
        "* `row ptr`: Stores the starting position of each row in the values array.\n",
        "\n",
        "Check [Wikipedia](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_(CSR,_CRS_or_Yale_format)) for examples.\n",
        "\n",
        "Each storage format has its advantages and use cases. CSR is efficient for row-wise operations and is the most commonly used format in many sparse linear algebra libraries."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Also many linear algebra operations like matrix vector multiplication can be done considerably faster in the sparse matrix format as long as the matrix containes sufficiently many zeros."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 69,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Sparse: 0.000901 seconds\n",
            "Dense: 0.061798 seconds\n"
          ]
        }
      ],
      "source": [
        "import scipy.sparse as sp\n",
        "import time\n",
        "\n",
        "n = 10000\n",
        "A_csr = sp.random(n, n, density=0.01, format='csr')\n",
        "A_dense = A_csr.toarray()\n",
        "x = np.random.rand(n)\n",
        "\n",
        "start = time.time()\n",
        "y = A_csr @ x\n",
        "end = time.time()\n",
        "print(f\"Sparse: {(end - start):.6f} seconds\")\n",
        "\n",
        "start = time.time()\n",
        "y = A_dense @ x\n",
        "end = time.time()\n",
        "print(f\"Dense: {(end - start):.6f} seconds\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tEINf4bEL9jR"
      },
      "source": [
        "## Matplotlib"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "0hgVWLaXL9jR"
      },
      "source": [
        "Matplotlib is a plotting library. In this section give a brief introduction to the `matplotlib.pyplot` module, which provides a plotting system similar to that of MATLAB."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 70,
      "metadata": {
        "id": "cmh_7c6KL9jR"
      },
      "outputs": [],
      "source": [
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jOsaA5hGL9jS"
      },
      "source": [
        "By running this special iPython command, we will be displaying plots inline:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 71,
      "metadata": {
        "id": "ijpsmwGnL9jT"
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U5Z_oMoLL9jV"
      },
      "source": [
        "### Plotting"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6QyFJ7dhL9jV"
      },
      "source": [
        "The most important function in `matplotlib` is plot, which allows you to plot 2D data. Here is a simple example:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 72,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 282
        },
        "id": "pua52BGeL9jW",
        "outputId": "811531d5-481e-479e-cb67-2f8e5da250a4"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "[<matplotlib.lines.Line2D at 0x11ae8bf90>]"
            ]
          },
          "execution_count": 72,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "# Compute the x and y coordinates for points on a sine curve\n",
        "x = np.arange(0, 3 * np.pi, 0.1)\n",
        "y = np.sin(x)\n",
        "\n",
        "# Plot the points using matplotlib\n",
        "plt.plot(x, y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9W2VAcLiL9jX"
      },
      "source": [
        "With just a little bit of extra work we can easily plot multiple lines at once, and add a title, legend, and axis labels:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 73,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 312
        },
        "id": "TfCQHJ5AL9jY",
        "outputId": "b2ab9271-43af-4488-f32e-3171929416e5"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "<matplotlib.legend.Legend at 0x11aa1c2d0>"
            ]
          },
          "execution_count": 73,
          "metadata": {},
          "output_type": "execute_result"
        },
        {
          "data": {
            "image/png": "iVBORw0KGgoAAAANSUhEUgAAAksAAAHHCAYAAACvJxw8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACr60lEQVR4nOzdd1hU1/bw8e/M0DtIE0WsiNgr0djFFlNML6aZxNybXNNM9f3d9F5ukpvEm957TDUxMfbee0UFsSAdpPeZef84nEEUGNCBM2V9nmcejsPMmYXizDp7r722zmw2mxFCCCGEEA3Sax2AEEIIIYQ9k2RJCCGEEKIJkiwJIYQQQjRBkiUhhBBCiCZIsiSEEEII0QRJloQQQgghmiDJkhBCCCFEEyRZEkIIIYRogiRLQgghhBBNkGRJCGETnTt35tZbb9U6jFY1duxYxo4dq3UYjXrqqafQ6XRahyGE05FkSQjRpD179nDVVVcRExODl5cXHTp0YOLEibz99ttah2bXjEYjn376KWPHjiUkJARPT086d+7MzJkz2bp1q9bhCSFaQCd7wwkhGrN+/XrGjRtHp06duOWWW4iMjOTEiRNs3LiRlJQUkpOTLY+trKxEr9fj7u6uYcStSx1VWrlyZZOPKy8v54orrmDRokWMHj2aSy65hJCQEI4ePcoPP/zAoUOHOH78OB07drRpfDU1NdTU1ODl5WXT8wrh6ty0DkAIYb+ef/55AgMD2bJlC0FBQfW+l52dXe/Pnp6ebRiZfXv44YdZtGgRb7zxBvfff3+97z355JO88cYbrfK6bm5uuLnJ27oQtibTcEKIRqWkpNC7d++zEiWA8PDwen8+s2bps88+Q6fTsW7dOubMmUNYWBi+vr5cfvnl5OTknHW+v/76i1GjRuHr64u/vz/Tpk1j3759VmPMz8/noYceom/fvvj5+REQEMDUqVPZtWtXvcetXLkSnU7HDz/8wPPPP0/Hjh3x8vJiwoQJ9UbIVB988AHdunXD29ubYcOGsWbNGquxAKSlpfH+++8zceLEsxIlAIPBwEMPPVRvVGnHjh1MnTqVgIAA/Pz8mDBhAhs3bqz3vOrqap5++ml69OiBl5cX7dq1Y+TIkSxZssTymIZqlnQ6HbNnz+bXX3+lT58+eHp60rt3bxYtWnRWbCdPnuS2224jIiLC8rhPPvmkWT+3EM5MLkGEEI2KiYlhw4YN7N27lz59+pzTOe655x6Cg4N58sknOXr0KG+++SazZ8/m+++/tzzmyy+/5JZbbmHy5Mm8/PLLlJWV8e677zJy5Eh27NhB586dGz3/kSNH+PXXX7n66qvp0qULWVlZvP/++4wZM4b9+/cTFRVV7/EvvfQSer2ehx56iMLCQl555RVmzJjBpk2bLI/5+OOP+cc//sGIESO4//77OXLkCJdeeikhISFER0c3+fP+9ddf1NTUcNNNNzXr72ffvn2MGjWKgIAAHnnkEdzd3Xn//fcZO3Ysq1atIiEhAVASoRdffJE77riDYcOGUVRUxNatW9m+fTsTJ05s8jXWrl3Lzz//zN13342/vz9vvfUWV155JcePH6ddu3YAZGVlccEFF1iSq7CwMP766y9uv/12ioqKGkz8hHAZZiGEaMTixYvNBoPBbDAYzMOHDzc/8sgj5r///ttcVVV11mNjYmLMt9xyi+XPn376qRkwJyYmmk0mk+X+Bx54wGwwGMwFBQVms9lsLi4uNgcFBZlnzZpV73yZmZnmwMDAs+4/U0VFhdloNNa7LzU11ezp6Wl+5plnLPetWLHCDJh79eplrqystNz/3//+1wyY9+zZYzabzeaqqipzeHi4ecCAAfUe98EHH5gB85gxY5qM54EHHjAD5h07djT5ONX06dPNHh4e5pSUFMt96enpZn9/f/Po0aMt9/Xv3988bdq0Js/15JNPms98WwfMHh4e5uTkZMt9u3btMgPmt99+23Lf7bffbm7fvr05Nze33vOvu+46c2BgoLmsrKxZP48Qzkim4YQQjZo4cSIbNmzg0ksvZdeuXbzyyitMnjyZDh06sGDBgmad484776w3NTRq1CiMRiPHjh0DYMmSJRQUFHD99deTm5truRkMBhISElixYkWT5/f09ESvV97KjEYjeXl5+Pn50bNnT7Zv337W42fOnImHh0e9eEAZoQLYunUr2dnZ/POf/6z3uFtvvZXAwECrP29RUREA/v7+Vh9rNBpZvHgx06dPp2vXrpb727dvzw033MDatWst5wsKCmLfvn0cPnzY6nnPlJiYSLdu3Sx/7tevHwEBAZaf2Ww289NPP3HJJZdgNpvr/TtMnjyZwsLCBv8uhXAVkiwJIZo0dOhQfv75Z06dOsXmzZuZO3cuxcXFXHXVVezfv9/q8zt16lTv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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "y_sin = np.sin(x)\n",
        "y_cos = np.cos(x)\n",
        "\n",
        "# Plot the points using matplotlib\n",
        "plt.plot(x, y_sin)\n",
        "plt.plot(x, y_cos)\n",
        "plt.xlabel('x axis label')\n",
        "plt.ylabel('y axis label')\n",
        "plt.title('Sine and Cosine')\n",
        "plt.legend(['Sine', 'Cosine'])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gLtsST5SL9jc"
      },
      "source": [
        "You can read much more about Matplotlib in the [documentation](https://matplotlib.org/stable/)."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.10"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
