{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "3791fd4b",
   "metadata": {},
   "source": [
    "# Feuille d'exercices 8 -- avancé\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "```{admonition} Objectifs\n",
    "* Polynômes\n",
    "* Réduction matricielle\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "```{warning} \n",
    "Ces exercices sont prévus pour les étudiant·e·s ayant déjà réussi la feuille d'exercices \"classiques\".\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "## Exercice 5 : représentation symbolique de racines\n",
    "\n",
    "\n",
    "\n",
    "**Question 1.** Construire le polynôme $P(X) = X^2 - 2$ à coefficients entiers, puis vérifier qu'il n'a aucune solution rationnelle (dans $\\mathbb{Q}$) mais deux solutions réelles que l'on réprésentera comme des flottants de `RR`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19bf7104",
   "metadata": {},
   "outputs": [],
   "source": [
    "Poly_ZZ = PolynomialRing(QQ, \"X\")\n",
    "X = Poly_ZZ.gen() \n",
    "\n",
    "P = X**2 - 2\n",
    "\n",
    "Poly_QQ = PolynomialRing(QQ, \"X\")\n",
    "Poly_RR = PolynomialRing(RR, \"X\")\n",
    "\n",
    "P_QQ = Poly_QQ(P)\n",
    "P_RR = Poly_RR(P)\n",
    "\n",
    "print(P_QQ.roots())\n",
    "print(P_RR.roots())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bddb910",
   "metadata": {},
   "source": [
    "On souhaite maintenant voir les racines de $P$ comme $\\pm \\sqrt{2}$ en manipulant la valeur exacte de cette expression. Pour cela, Sagemath possède un anneau particulier, noté `SR` (pour `Symbolic Ring`) : celui des expressions symboliques.\n",
    "\n",
    "\n",
    "\n",
    "**Question 2.** Calculer les racines de $P$ dans `SR`. Stocker l'une de ces racines dans une variable `r`, puis l'élever au carré, et vérifier qu'on obtient bien la valeur exacte $2$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d0d77a07",
   "metadata": {},
   "outputs": [],
   "source": [
    "L = P.roots(SR)\n",
    "print(L)\n",
    "\n",
    "r = L[0][0]\n",
    "print(r)\n",
    "print(r.parent())\n",
    "\n",
    "d = r**2\n",
    "print(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8b483f5",
   "metadata": {},
   "source": [
    "**Question 3.** Même question avec $Q(X) = X^2 + 2$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3c47ce95",
   "metadata": {},
   "outputs": [],
   "source": [
    "Q = X**2 + 2\n",
    "L = Q.roots(SR)\n",
    "L"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "38308bee",
   "metadata": {},
   "source": [
    "**Question 4.** Soit $A(X) = X^4 - X^2 + X - 1$. Trouver une expression symbolique des racines de $A$. On pourra obtenir une meilleure visualisation de cette expression grâce à la fonction ``show()``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "917d2a01",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = X**4 - X**2 + X - 1\n",
    "L = A.roots(SR)\n",
    "# show(L)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a98120a5",
   "metadata": {},
   "source": [
    "## Exercice 6 : décomposition de polynôme pair/impair\n",
    "\n",
    "Un polynôme est **pair** si tous ses coefficients de degré impair sont nuls. Il est **impair** si ses coefficients de degré pair sont tous nuls.\n",
    "\n",
    "\n",
    "**Question 1 :** Écrire une fonction `est_pair(P)` qui teste si un polynôme `P` est pair."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5a173b37",
   "metadata": {},
   "outputs": [],
   "source": [
    "def est_pair(P):\n",
    "    return all(P[i] == 0 for i in range(1, P.degree()+1, 2))\n",
    "\n",
    "R.<X> = PolynomialRing(ZZ, \"X\")\n",
    "print(est_pair(X**2 + X + 1))\n",
    "print(est_pair(X**6 -3*X**2))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1314a385",
   "metadata": {},
   "source": [
    "**Question 2 :** Tracer le graphe de plusieurs polynômes pairs sur un même graphique. Puis, expliquer quelle propriété géométrique ces polynômes respectent.\n",
    "\n",
    "\n",
    "Voici une manière \"automatisée\" de produire ce genre de graphique :"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e1954d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# on définit une liste de 4 couleurs\n",
    "colors = [ \"blue\", \"red\", \"green\", \"orange\"]\n",
    "\n",
    "# on part du graphique vide\n",
    "graphique = plot([]) \n",
    "\n",
    "# on va rajouter 4 tracés\n",
    "for i in range(4):\n",
    "    # on tire un polynôme aléatoirement, \n",
    "    # et on le compose avec X^2 pour avoir un polynome pair\n",
    "    P = R.random_element()\n",
    "    Q = P(X**2)\n",
    "    \n",
    "    # on vérifie que Q(X) est pair (au cas où)\n",
    "    if not(est_pair(Q)):\n",
    "        print(\"Erreur\")\n",
    "    \n",
    "    # on ajoute au graphique le graphe du i-ème polynôme avec la i-ème couleur\n",
    "    graphique += plot(Q, xmin =-2, xmax=2, ymin=-10, ymax=10, color=colors[i])\n",
    "    \n",
    "graphique.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "651aa613",
   "metadata": {},
   "source": [
    "On observe que tous les graphes sont symétriques par rapport à l'axe des ordonnées.\n",
    "\n",
    "\n",
    "**Question 3 :** Reprendre les questions précédentes avec des polynômes impairs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dbade737",
   "metadata": {},
   "outputs": [],
   "source": [
    "def est_impair(P):\n",
    "    return all(P[i] == 0 for i in range(0, P.degree()+1, 2))\n",
    "\n",
    "\n",
    "R.<X> = PolynomialRing(ZZ, \"X\")\n",
    "print(est_impair(X**3 + X))\n",
    "print(est_impair(X**5 -3*X**2 + 2*X))\n",
    "\n",
    "\n",
    "# on part du graphique vide\n",
    "graphique = plot([]) \n",
    "\n",
    "# on va rajouter 4 tracés\n",
    "for i in range(4):\n",
    "    # on tire un polynôme aléatoirement, \n",
    "    # et on le compose avec X^2 puis on le multiplie par X pour avoir un polynome pair\n",
    "    P = R.random_element()\n",
    "    Q = X * P(X**2)\n",
    "    \n",
    "    # on vérifie que Q(X) est pair (au cas où)\n",
    "    if not(est_impair(Q)):\n",
    "        print(\"Erreur\")\n",
    "    \n",
    "    # on ajoute au graphique le graphe du i-ème polynôme avec la i-ème couleur\n",
    "    graphique += plot(Q, xmin =-2, xmax=2, ymin=-10, ymax=10, color=colors[i])\n",
    "    \n",
    "graphique.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "766c18ee",
   "metadata": {},
   "source": [
    "On observe que tous les graphes sont symétriques par rapport à l'origine.\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "**Décomposition paire/impaire.** Tout polynôme $F(X) \\in \\mathbb{R}[X]$ admet une unique décomposition sous la forme d'une somme d'un polynôme pair et d'un polynôme impair. Cette décomposition est donnée par : $F(X) = P(X) + Q(X)$ où \n",
    "\n",
    "\n",
    "$$\n",
    "\\left\\{\n",
    "\\begin{array}{lll}\n",
    "P(X) &= \\frac{F(X)+F(-X)}{2}  & \\;\\text{ est pair} \\\\\n",
    "Q(X) &= \\frac{F(X)-F(-X)}{2}  & \\;\\text{ est impair} \\\\\n",
    "\\end{array}\n",
    "\\right.\n",
    "$$\n",
    "\n",
    "**Question 4 :** Écrire une fonction `decomposition(F)` qui prend en entrée un polynôme `F`, et qui retourne sa décompositon en polynômes pair et impair sous la forme d'une liste de deux polynômes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "65453914",
   "metadata": {},
   "outputs": [],
   "source": [
    "def decomposition(F):\n",
    "    return [ (F(X) + F(-X))/2, (F(X) - F(-X))/2 ] \n",
    "    \n",
    "F = R.random_element(11)\n",
    "P, Q = decomposition(F)\n",
    "print(est_pair(P) and est_impair(Q))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Sagemath",
   "language": "python",
   "name": "sagemath"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
