{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false,
    "editable": true,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [],
   "source": [
    "x = np.array([[1., 2., 3.], [4., 5., 6.]])\n",
    "y = np.array([[6., 23.], [-1, 7], [8, 9]])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 2., 3.],\n",
       "       [4., 5., 6.]])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 6., 23.],\n",
       "       [-1.,  7.],\n",
       "       [ 8.,  9.]])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 28.,  64.],\n",
       "       [ 67., 181.]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.dot(y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false,
    "editable": true,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 28.,  64.],\n",
       "       [ 67., 181.]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(x, y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1., 2., 3.],\n",
       "       [4., 5., 6.]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1., 1.])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.ones(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false,
    "editable": true,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 6., 15.])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.dot(x, np.ones(3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false,
    "editable": true,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 6., 15.])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x @ np.ones(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false,
    "editable": true,
    "jupyter": {
     "outputs_hidden": false
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.989,  0.422,  1.605,  0.6  , -0.746],\n",
       "       [-0.569, -0.25 ,  1.426,  0.346, -0.352],\n",
       "       [-0.007, -0.729, -0.951, -0.838, -0.421],\n",
       "       [-0.11 ,  0.652, -0.671,  3.186,  2.627],\n",
       "       [ 1.06 ,  1.435,  1.885, -0.293, -0.186]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from numpy.linalg import inv, qr\n",
    "\n",
    "%precision 3\n",
    "X = np.random.randn(5, 5)\n",
    "X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.989, -0.569, -0.007, -0.11 ,  1.06 ],\n",
       "       [ 0.422, -0.25 , -0.729,  0.652,  1.435],\n",
       "       [ 1.605,  1.426, -0.951, -0.671,  1.885],\n",
       "       [ 0.6  ,  0.346, -0.838,  3.186, -0.293],\n",
       "       [-0.746, -0.352, -0.421,  2.627, -0.186]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X.T  # transpose of matrix X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 2.438,  1.179, -0.321, -1.445,  0.456],\n",
       "       [ 1.179,  3.255,  3.28 ,  2.433,  1.526],\n",
       "       [-0.321,  3.28 ,  9.515, -0.438, -3.413],\n",
       "       [-1.445,  2.433, -0.438, 11.417,  8.209],\n",
       "       [ 0.456,  1.526, -3.413,  8.209,  7.797]])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mat = X.T.dot(X)\n",
    "mat"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 2.438,  1.179, -0.321, -1.445,  0.456],\n",
       "       [ 1.179,  3.255,  3.28 ,  2.433,  1.526],\n",
       "       [-0.321,  3.28 ,  9.515, -0.438, -3.413],\n",
       "       [-1.445,  2.433, -0.438, 11.417,  8.209],\n",
       "       [ 0.456,  1.526, -3.413,  8.209,  7.797]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mat2 = X.T@X\n",
    "mat2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 103.113,  -40.167,  -20.837,  107.207, -120.159],\n",
       "       [ -40.167,   17.14 ,    7.104,  -41.055,   45.328],\n",
       "       [ -20.837,    7.104,    5.123,  -22.4  ,   25.653],\n",
       "       [ 107.207,  -41.055,  -22.4  ,  112.448, -126.427],\n",
       "       [-120.159,   45.328,   25.653, -126.427,  142.618]])"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inv(mat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.000e+00, -7.650e-15, -1.060e-15, -9.814e-15,  1.269e-15],\n",
       "       [ 3.838e-14,  1.000e+00,  4.684e-15, -1.321e-14, -8.564e-14],\n",
       "       [ 3.486e-14, -2.376e-15,  1.000e+00, -3.821e-14, -1.105e-13],\n",
       "       [-2.124e-14,  3.342e-14, -1.116e-14,  1.000e+00, -2.173e-13],\n",
       "       [-1.494e-13,  8.587e-14,  2.401e-14, -1.404e-13,  1.000e+00]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mat.dot(inv(mat))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "Q, R = qr(X)  # decompose matrix X into factors orthogonal Q and upper-triangular R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.561,  0.755, -0.206, -0.926,  0.292],\n",
       "       [ 0.   ,  1.639,  2.096,  1.912,  0.797],\n",
       "       [ 0.   ,  0.   ,  2.254, -2.057, -2.229],\n",
       "       [ 0.   ,  0.   ,  0.   , -1.635, -1.449],\n",
       "       [ 0.   ,  0.   ,  0.   ,  0.   , -0.084]])"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "R"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.634,  0.55 ,  0.143,  0.454,  0.264],\n",
       "       [-0.364,  0.015,  0.585, -0.724,  0.021],\n",
       "       [-0.004, -0.443, -0.011,  0.011,  0.896],\n",
       "       [-0.07 ,  0.43 , -0.705, -0.519,  0.21 ],\n",
       "       [ 0.679,  0.563,  0.375, -0.019,  0.286]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.634, -0.364, -0.004, -0.07 ,  0.679],\n",
       "       [ 0.55 ,  0.015, -0.443,  0.43 ,  0.563],\n",
       "       [ 0.143,  0.585, -0.011, -0.705,  0.375],\n",
       "       [ 0.454, -0.724,  0.011, -0.519, -0.019],\n",
       "       [ 0.264,  0.021,  0.896,  0.21 ,  0.286]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q.T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1.000e+00, -5.031e-16, -1.809e-16,  1.555e-16,  4.086e-16],\n",
       "       [-5.031e-16,  1.000e+00,  1.941e-16, -2.049e-16, -2.225e-16],\n",
       "       [-1.809e-16,  1.941e-16,  1.000e+00,  1.972e-17, -5.444e-17],\n",
       "       [ 1.555e-16, -2.049e-16,  1.972e-17,  1.000e+00,  1.716e-16],\n",
       "       [ 4.086e-16, -2.225e-16, -5.444e-17,  1.716e-16,  1.000e+00]])"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q@Q.T  # should be the identity matrix I"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.634, -0.364, -0.004, -0.07 ,  0.679],\n",
       "       [ 0.55 ,  0.015, -0.443,  0.43 ,  0.563],\n",
       "       [ 0.143,  0.585, -0.011, -0.705,  0.375],\n",
       "       [ 0.454, -0.724,  0.011, -0.519, -0.019],\n",
       "       [ 0.264,  0.021,  0.896,  0.21 ,  0.286]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "inv(Q)  # should equal Q.T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[-0.989,  0.422,  1.605,  0.6  , -0.746],\n",
       "       [-0.569, -0.25 ,  1.426,  0.346, -0.352],\n",
       "       [-0.007, -0.729, -0.951, -0.838, -0.421],\n",
       "       [-0.11 ,  0.652, -0.671,  3.186,  2.627],\n",
       "       [ 1.06 ,  1.435,  1.885, -0.293, -0.186]])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Q@R  # Q@R should equal X"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
