{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6b19e795-908a-481b-8a9f-5241ca8e8fb4",
   "metadata": {},
   "source": [
    "# SVD et compression d'image"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a1fa341-b872-438b-825a-c4d50f939995",
   "metadata": {},
   "source": [
    "L'objectif de ce TP est d'explorer la SVD. Vous commencerez par implémenter un algorithme pour calculer la SVD, puis vous étudierez comment elle est liée à la méthode des moindres carrés. Enfin, vous découvrirez une application moins conventionnelle de la SVD. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5737102e-ca30-40dc-98e9-5f485b02f4f0",
   "metadata": {},
   "source": [
    "## Algorithme de SVD"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64f96a57-6054-4abc-8676-f66516ab8437",
   "metadata": {
    "editable": true,
    "slideshow": {
     "slide_type": ""
    },
    "tags": []
   },
   "source": [
    "Soit $M$ une matrice de $\\mathcal {R}^{n,m}$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21bd6598-7342-43e7-ad66-4f9db15a547c",
   "metadata": {},
   "source": [
    "Dans cette partie, posons $n = 200$ et $m = 2$. On fabriquera la matrice M comme suit :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "2e99eabb-acac-42a3-b8a5-ecd9a7ca57ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "def generate_points(n, P):\n",
    "  \"\"\"Génère n points aléatoires dans le cercle unitaire, multipliés par la matrice P.\n",
    "\n",
    "  Args:\n",
    "    n: Nombre de points à générer.\n",
    "    P: Matrice à multiplier avec les points générés.\n",
    "\n",
    "  Returns:\n",
    "    Un tableau numpy de forme (n, 2) contenant les points générés.\n",
    "  \"\"\"\n",
    "\n",
    "  M = np.zeros((n, 2))\n",
    "  ind = 0\n",
    "\n",
    "  while ind < n:\n",
    "    point = 2 * (0.5 - np.random.rand(1, 2))\n",
    "    if np.linalg.norm(point) < 1:\n",
    "      M[ind, :] = point\n",
    "      ind += 1\n",
    "\n",
    "  return M @ P"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1cbb70cc-81ee-4d11-9937-b18cdf2e8c93",
   "metadata": {},
   "source": [
    "Dans la suite, on choisra $P$ :\n",
    "$$P=\\left(\\begin{matrix} −1.5 & 3.2 \\\\ 1.2 & −0.4 \\end{matrix}\\right)$$"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2647c0c4-263b-467e-9268-349b4708cdfd",
   "metadata": {},
   "source": [
    "Calculer les valeurs propres $\\lambda_i$ et vecteurs propres vi de la matrice $M^T × M$ – avec la fonction dédiée de python\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "id": "12a008aa-a34b-4c5a-b723-42a62ef69588",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 1.86983458 13.22122835]\n"
     ]
    }
   ],
   "source": [
    "### Ecrire le code du calcul\n",
    "P = np.array([[-1.5, 3.2],\n",
    "              [1.2, -0.4]])\n",
    "\n",
    "M = generate_points(10, P)\n",
    "D = M.T@M\n",
    "l, V = np.linalg.eig(D)\n",
    "print(l)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2716aff3-8933-4843-aa44-6f822ea231c8",
   "metadata": {},
   "source": [
    "On pose $S = diag(\\sqrt{\\lambda_i})$ et $V$ la matrice des vecteurs propres.\n",
    "Calculer $U = M × V^T \\times S^{-1}$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "id": "cbbd3398-455d-4893-abc8-6530b76c346d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 2.77555756e-17  5.55111512e-17]\n",
      " [-2.77555756e-17 -5.55111512e-17]\n",
      " [-2.22044605e-16  5.55111512e-17]\n",
      " [-2.22044605e-16 -1.66533454e-16]\n",
      " [ 2.22044605e-16 -5.55111512e-17]\n",
      " [-1.11022302e-16  1.11022302e-16]\n",
      " [-2.22044605e-16  2.22044605e-16]\n",
      " [ 3.46944695e-17  5.55111512e-17]\n",
      " [-5.55111512e-17 -6.93889390e-18]\n",
      " [ 0.00000000e+00 -4.44089210e-16]]\n"
     ]
    }
   ],
   "source": [
    "### Ecrire le code du calcul\n",
    "iS = np.zeros([2,10])\n",
    "\n",
    "np.fill_diagonal(iS, 1./np.sqrt(l))\n",
    "\n",
    "S = np.zeros([10,2])\n",
    "np.fill_diagonal(S, np.sqrt(l))\n",
    "\n",
    "U = M @ V @ iS\n",
    "print(U@S@V.T - M)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f693ef1-829f-408d-9106-027378897543",
   "metadata": {},
   "source": [
    "Vérifier que $U$, $S$ et $V$ correspondent bien au retour de la fonction _svd_ de python !"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "id": "74af6f83-819b-4e44-b09b-4e5e358cde47",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[ 4.88337358e-02  2.70300928e-01  3.83324719e-01  3.60008816e-01\n",
      "  -3.20902428e-01  2.32529879e-01  4.96375028e-01 -4.12835220e-02\n",
      "   7.31880238e-02 -4.87350993e-01]\n",
      " [-4.94041050e-02 -1.41199981e-01 -2.29628315e-01 -4.50561874e-01\n",
      "   1.75023096e-01  1.76002382e-02 -8.51094020e-02  1.40463789e-01\n",
      "  -6.64811140e-02 -8.12127057e-01]\n",
      " [ 1.38975638e-01 -4.30505263e-01  8.39093694e-01 -1.96306801e-01\n",
      "   1.31392643e-01 -6.74259720e-02 -1.67532224e-01  3.95928790e-02\n",
      "  -3.50766808e-02 -7.81655896e-03]\n",
      " [-2.42604729e-02 -5.72755237e-01 -1.79907899e-01  7.40178080e-01\n",
      "   1.43953675e-01 -4.84489761e-02 -1.50873978e-01  6.41401089e-02\n",
      "  -4.31059705e-02 -1.98311439e-01]\n",
      " [-1.27685400e-01  3.48058355e-01  1.32594215e-01  1.58810593e-01\n",
      "   8.91509868e-01  5.75359994e-02  1.40724459e-01 -3.11703313e-02\n",
      "   2.86199925e-02 -7.44900295e-03]\n",
      " [ 1.87687619e-01 -1.48648048e-01 -7.83791884e-02 -6.86837502e-02\n",
      "   6.59766561e-02  9.49162620e-01 -1.05947423e-01  6.01335849e-03\n",
      "  -1.44899760e-02  1.22811991e-01]\n",
      " [ 3.19814062e-01 -4.05282640e-01 -1.82349200e-01 -1.86024978e-01\n",
      "   1.51572632e-01 -1.00752054e-01  7.77215011e-01  2.69144165e-02\n",
      "  -3.62390302e-02  1.62426474e-01]\n",
      " [ 6.12924021e-02  1.29351269e-01  3.15133130e-02  5.83181245e-02\n",
      "  -2.42770700e-02 -6.74594719e-05  1.48562541e-02  9.82455221e-01\n",
      "   8.78483469e-03  9.49308967e-02]\n",
      " [ 1.16175503e-02 -9.84289656e-02 -3.34962567e-02 -4.47527117e-02\n",
      "   2.70675160e-02 -1.14399767e-02 -3.13635079e-02  1.01572533e-02\n",
      "   9.92323393e-01 -1.98969442e-02]\n",
      " [-9.04195077e-01 -2.44339394e-01  6.92609244e-02 -1.05073010e-01\n",
      "  -7.04471952e-02  1.55642529e-01  2.43397694e-01  7.63575720e-02\n",
      "  -3.17125537e-03  1.12346483e-01]]\n"
     ]
    }
   ],
   "source": [
    "### Ecire le code de vérification\n",
    "Uh, Sh, Vh= np.linalg.svd(M)\n",
    "print(Uh)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e78b3359-01cd-480d-bd20-689a1f2b607b",
   "metadata": {},
   "source": [
    "Tracer ensuite tous les points de M, et superposer les droites définies par les colonnes de $V$ et le point $0$.\n",
    "On pourra utiliser _.axis('equal')_ pour afficher le graph dans un repère orthonormal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "id": "a16d3de5-50c2-45a3-ba70-4a948049a9da",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-1.2179812688224987,\n",
       " 1.602422829141944,\n",
       " -3.1398526599576706,\n",
       " 0.8690914958160131)"
      ]
     },
     "execution_count": 139,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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BQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGArhBQAAGIpHw8vs2bPVu3dvNW/eXNddd12tzhk1apRMJpPT1qtXL0+WCQAADMSj4aWsrExDhw5VQkKCW+fFxcWpoKDAsa1fv95DFQIAAKNp4skXnzVrliTpL3/5i1vnmc1mRUREeKAiAABgdA1yzMvmzZsVFham9u3ba8yYMSoqKqq2b2lpqYqLi502AADgvxpceBk0aJBWrVqlL774QvPnz9fOnTvVv39/lZaWVtk/JSVFFovFsUVGRnq5YgAA4E1uh5fk5GSXAbW/3nbt2nXVBQ0bNkwPPvigunTpovj4eP3973/XN998o88//7zK/jNmzJDNZnNseXl5V/3eAACg4XN7zMukSZM0fPjwGvu0bdv2autxYbVa1aZNGx0+fLjK42azWWazud7eDwAANGxuh5fQ0FCFhoZ6opYqnTp1Snl5ebJarV57TwAA0HB5dMxLbm6usrKylJubq/LycmVlZSkrK0vnzp1z9OnYsaPS0tIkSefOndOUKVOUmZmpY8eOafPmzYqPj1doaKiGDBniyVIBAIBBePRR6ZdfflnvvfeeY79bt26SpE2bNqlv376SpJycHNlsNklSYGCgvv76a73//vs6e/asrFar+vXrp9WrVyskJMSTpQIAAIMw2e12u6+LqE/FxcWyWCyy2Wxq0aKFr8sBAAC14M73d4N7VBoAAKAmhBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAohBcAAGAo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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "### Ecrire le code pour faire le graph\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "plt.scatter(M[:,0], M[:,1])\n",
    "plt.quiver(0, 0, V[0,0], V[1,0], angles='xy',scale_units='xy', scale=1)\n",
    "plt.quiver(0, 0, V[0,1], V[1,1], angles='xy',scale_units='xy', scale=1)\n",
    "\n",
    "plt.axis(\"equal\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "811a1be4-0775-4410-ade8-82e44b1ddc5a",
   "metadata": {},
   "source": [
    "Pouvez vous en conclure quelque chose ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bf940d3-a4c2-4c0a-948c-90e6732b6238",
   "metadata": {},
   "source": [
    "## Résolution de système hyperstatique et SVD"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bc891bd-fd79-4f8d-becd-cb2a90d06ed8",
   "metadata": {},
   "source": [
    "La SVD (Décomposition en Valeurs Singulières) est une méthode puissante et robuste pour résoudre des systèmes linéaires surdéterminés, c'est-à-dire lorsque nous avons plus d'équations que d'inconnues. En d'autres termes, nous cherchons à résoudre le système linéaire :\n",
    "\n",
    "$$Mx = b$$\n",
    "\n",
    "où :\n",
    "\n",
    "- $M$ est une matrice de taille $m \\times n$ (avec $m >> n$), représentant les coefficients du système.\n",
    "- $x$ est un vecteur de taille $n \\times 1$, contenant les inconnues.\n",
    "- $b$ est un vecteur de taille $m \\times 1$, représentant les termes connus.\n",
    "\n",
    "En se basant sur la décomposition SVD,$M = U\\Sigma V*$, où $U$ et $V$ sont des matrices unitaires et $\\Sigma$ est une matrice diagonale contenant les valeurs singulières de $M$, la solution des moindres carrés est donnée par :\n",
    "\n",
    "$$x = V\\Sigma^+ U \\times b$$\n",
    "\n",
    "où $\\Sigma^+$ est la pseudo-inverse de $Σ$, obtenue en inversant les valeurs singulières non nulles."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6f421102-dbe8-4e10-82a4-1cee4b69f85b",
   "metadata": {},
   "source": [
    "### Application"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3db19bd3-0faf-40ca-a68e-71c754ff93a5",
   "metadata": {},
   "source": [
    "Étant donné un ensemble de m points de données $(t_i, b_i)$, nous cherchons à déterminer les coefficients d'un polynôme de degré $n-1$ de sorte que la somme des carrés des écarts entre les valeurs du polynôme aux abscisses $t_i$ et les valeurs observées $b_i$ soit minimale.\n",
    "\n",
    "L'objectif est de trouver le polynôme \n",
    "$$p(t) = x_0 +x_1t +x_2 t^2 +\\ldots + x_{n-1}t^{n-1}$$\n",
    "\n",
    "qui approche au mieux les points $(t_i, b_i)$ au sens des moindres carrés."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "623dd9dc-63f2-4a15-b204-abdde6f3b00d",
   "metadata": {},
   "source": [
    "On considère les données suivantes\n",
    "\n",
    "| t | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |\n",
    "|---|----|----|----|----|----|----|----|----|----|----|----|\n",
    "| b | 2  | 7  | 9  | 12 | 13 | 14 | 14 | 13 | 10 | 8  | 4  |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91844fc0-f393-4530-9d43-6bbd3662b59f",
   "metadata": {},
   "source": [
    "Calculer, par SVD, les coefficients du polynôme de degré $2$ approximant les données."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a345691c-865a-4659-939b-40231513bca9",
   "metadata": {},
   "outputs": [],
   "source": [
    "### Code de calcul de"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61f569ff-7f67-420f-95fa-00fabeed8daa",
   "metadata": {},
   "source": [
    "## Compression d’image et SVD"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22845aca-3c28-4ab9-b7d9-b2d7f64075f7",
   "metadata": {},
   "source": [
    "\n",
    "1. Télécharger l’image en noir et blanc [ici](https://negativespace.co/wp-content/uploads/2017/04/negative-space-black-white-london-street-Custom.jpg)\n",
    "2. \n",
    "Importer l'image – par exemple sous le nom M.\n",
    "3. \n",
    "Réenregistrer la matrice résultante en double.\n",
    "4. \n",
    "Faire une SVD de $M$, récupérant les matrices $U$, $S$ et $V$ .\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e573e84d-5787-4f74-89a9-6a447b125f58",
   "metadata": {},
   "outputs": [],
   "source": [
    "### Code de pour la SVD d'une image"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51e1ba5a-5d4b-4b71-a1b0-0f5dfc12befa",
   "metadata": {},
   "source": [
    "5. Faire une boucle affichant le résultat du produit $U (:, i) × S (1 : i, 1 : i) × V (:, 1 : i)^T$\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0f76769e-ed9f-4eed-bd8c-f6913753f700",
   "metadata": {},
   "outputs": [],
   "source": [
    "### Code de l'affichage"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56ceae7e-675d-41c4-a7d1-ce668c4699a1",
   "metadata": {},
   "source": [
    "6. Conclusions sur la compression d’image à l'aide de la SVD ?"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "47099f14-ddef-47be-92a2-65cc842872bf",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
