diff --git "a/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/10.4 Matrices sym\303\251triques, valeurs propres, vecteurs propres, th\303\251or\303\250me spectral.ipynb" "b/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/10.4 Matrices sym\303\251triques, valeurs propres, vecteurs propres, th\303\251or\303\250me spectral.ipynb" new file mode 100644 index 0000000..be5ca02 --- /dev/null +++ "b/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/10.4 Matrices sym\303\251triques, valeurs propres, vecteurs propres, th\303\251or\303\250me spectral.ipynb" @@ -0,0 +1,173 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Concepts-clés 10.3\n", + "### DÉFINITION 1: \n", + "Soit $A \\in M_{n \\times n}(\\mathbb{R})$. On dit que $A$ est orthogalement diagonalisable s'il existe une matrice orthogonale $P \\in M_{n \\times n}(\\mathbb{R})$ telle que $P^{-1} A P$ soit diagonale. Aussi, si $V$ désigne un espace euclidien et $T: V \\rightarrow V$ une transformation linéaire de $V$, on dit que $T$ est orthogonalement diagonalisable si $V$ possède une base orthonormée formée de vecteurs propres de $T$.\n", + "### REMARQUE 2: \n", + "Soit $A \\in M_{n \\times n}(\\mathbb{R})$ une matrice orthogonalement diagonalisable et supposons que $P \\in M_{n \\times n}(\\mathbb{R})$ soit comme ci-dessus. Alors $P^{T} A P=P^{-1} A P$\n", + "### PROPOSITION 3:\n", + "Soit $A \\in M_{n \\times n}(\\mathbb{R})$ une matrice orthogonalement diagonalisable. Alors $A$ est une matrice symétrique. \n", + "### REMARQUE 4: \n", + "La réciproque est également vraie!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Concepts-clés 10.4\n", + "### PROPOSITION: \n", + "Soient $A \\in M_{n \\times n}(\\mathbb{R})$ une matrice symétrique et $\\lambda \\neq \\mu$ deux valeurs propres distinctes pour $A .$ Si $u \\in E_{\\lambda}$ et $v \\in E_{\\mu},$ alors $u$ et $v$ sont orthogonaux (pour le produit scalaire usuel de $\\mathbb{R}^{n}$ ). \n", + "### THÉORÈME SPECTRAL: \n", + "Soit $A \\in M_{n \\times n}(\\mathbb{R})$ une matrice symétrique. Alors il existe une matrice $P \\in M_{n \\times n}(\\mathbb{R})$ orthogonale telle que $P^{T} A P$ soit diagonale, i.e. $A$ est orthogonalement diagonalisable.\n", + "### REMARQUE: \n", + "1. Soit $A \\in M_{n \\times n}$ ( $\\mathbb{R}$ ) . Alors $A$ est orthogonalement diagonalisable si et seulement si elle est symétrique.\n", + "2. Soit $A \\in M_{n \\times n}(\\mathbb{R})$ une matrice symétrique. Alors il est possible de factoriser $c_{A}(t)$ en un produit de facteurs linéaires sur $\\mathbb{R}$. En particulier, $c_{A}(t)$ n'admet aucune racine purement complexe. Autrement dit, si $\\alpha$ est une racine de $c_{A}(t),$ alors $\\alpha \\in \\mathbb{R}$\n", + "3. Pour chaque valeur propre $\\lambda \\in \\mathbb{R}$ de $A$, la dimension de l'espace propre $E_{\\lambda}$ est égale à la multiplicité algébrique de $\\lambda$ comme racine de $c_{A}(t)$\n", + "\n", + "### THÉORÈME #: \n", + "Soit $T: V \\rightarrow V$ une transformation linéaire d'un espace euclidien et $\\mathscr{B}$ une base orthonormée (arbitrairement choisie) de $V$. Alors $T$ est orthogonalement diagonalisable si et seulement si $[T]_{\\mathscr{B}}$ est symétrique." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import sympy as sp\n", + "from IPython.display import display, Latex, Markdown, display_latex\n", + "import plotly\n", + "import plotly.graph_objects as go\n", + "import sys, os\n", + "sys.path.append('../Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation')\n", + "from Ch8_lib import *\n", + "sys.path.append('../Librairie')\n", + "import AL_Fct as al\n", + "from Ch10_lib import *\n", + "from sympy import sqrt, sin, cos, pi" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 1\n", + "En utilisant le cours et et les énoncés rappelés ci-dessus, repondez aux questions suivantes." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vf_10_4_1()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vf_10_4_1()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "quest_10_4_2()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "quest_10_4_3()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 2\n", + "En étudiant les ensembles de valeurs propres et de vecteurs propres suivants, dire si les matrices correspondantes sont symétriques ou non, ou si il manque d'informations pour répondre." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exo_2_1_10_4()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exo_2_2_10_4()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exo_2_3_10_4()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exo_2_4_10_4()" + ] + }, + { + "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.2" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git "a/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/Ch10_lib.py" "b/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/Ch10_lib.py" index 232211a..d3de03f 100644 --- "a/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/Ch10_lib.py" +++ "b/Chapitre 10 - Matrices orthogonales, matrices sym\303\251triques/Ch10_lib.py" @@ -1,466 +1,733 @@ import sys, os import numpy as np import sympy as sp from IPython.display import display, Latex, Markdown import plotly import plotly.graph_objects as go sys.path.append('../Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation') from Ch8_lib import * sys.path.append('../Librairie') import AL_Fct as al import ipywidgets as widgets from ipywidgets import interact_manual, Layout from sympy import sqrt +import random def points_on_circle(n, center=np.array([0, 0])): theta = 2 * np.pi / n s_pts = np.zeros((n, 2)) e_pts = np.zeros((n, 2)) for i in range(n): s_pts[i] = [np.cos(i * theta) + center[0], np.sin(i * theta) + center[1]] e_pts[i] = [np.cos((i + 1) * theta) + center[0], np.sin((i + 1) * theta) + center[1]] return np.array(s_pts), np.array(e_pts) def plot_geom_2D(s_pts, e_pts, A): n = len(s_pts) if n != len(e_pts): raise ValueError("start_points and end_points must have same length.") layout = go.Layout(yaxis=dict(scaleanchor="x", scaleratio=1)) display(Latex("On montre la transformation provoquée par la multiplication par la matrice $A = " + al.texMatrix(A) + "$ sur une figure géométrique.")) fig = go.Figure(layout=layout) color = ['black', 'red', 'blue', 'green', 'yellow', 'brown', 'grey', 'cyan', 'orange', 'violet'] n_col = len(color) if n > n_col: color = ['blue'] n_col = 1 for i in range(n): a = np.array(s_pts[i]) b = np.array(e_pts[i]) a2 = A @ a b2 = A @ b if i == 0: show_legend = True else: show_legend = False fig.add_trace(go.Scatter(x=[a[0], b[0]], y=[a[1], b[1]], line=dict(color=color[i % n_col], width=2), mode='lines+markers', showlegend=show_legend, name='Original Figure')) fig.add_trace(go.Scatter(x=[a2[0], b2[0]], y=[a2[1], b2[1]], line=dict(color=color[i % n_col], width=2, dash='dot'), mode='lines+markers', showlegend=show_legend, name='Modified Figure')) fig.show() def is_orthogonal(A): A = sp.Matrix(A) n = A.shape[0] if n != A.shape[1]: raise ValueError("A should be a square matrix") display(Latex("On cherche à savoir si la matrice $A = " + latexp(A) + "$ est orthogonale en utilisant la " + "définition 1.")) if A.is_lower or A.is_upper: for i in range(n): if A[i, i] != 1 and A[i, i] != -1: display(Latex("Les valeurs propres de $A$ sont ses éléments diagonaux. Une des valeurs propres de " + "$A$ est différente de 1 ou -1. Il existe donc un vecteur propres $v$ de $A$ tel " + " que $A v = \lambda v$ avec $\lambda \\neq \pm 1$. Donc dans ce cas on a $\|A v\| " + "\\neq \|v\| $." )) return v = sp.zeros(n, 1) for i in range(n): symb_name = "x_" + str(i + 1) v[i] = sp.symbols(symb_name, real=True) b = A * v b_norm = b.norm() ** 2 v_norm = v.norm() ** 2 display(Latex("Il faut vérifier si $\|A v\| = \|v\|$ pour tout $v \in \mathbb{R}^" + str(n) + "$." + " On utilise le carré des normes pour s'affranchir des racines carrées.")) display(Latex("On calcule d'abord la norme au carré de $v$ et on obtient: $\|v\|^2 = " + sp.latex(v_norm) + "$.")) display(Latex("On calcule ensuite le produit $Av = " + latexp(b) + "$")) if sp.simplify(b_norm) != b_norm: display(Latex("On calcule la norme au carré de $Av$ et on obtient: $\|Av\|^2 = " + sp.latex(b_norm) + "=" + sp.latex(sp.simplify(b_norm)) + "$")) else: display(Latex("On calcule la norme au carré de $Av$ et on obtient: $\|Av\|^2 = " + sp.latex(b_norm) + "$")) if sp.simplify(b_norm - v_norm) == 0: display(Latex("Les normes sont toujours égales. La matrice est donc orthogonale.")) else: display(Latex("Les normes sont différente. La matrice n'est donc pas orthogonale.")) def interactive_is_orthogonal(A): A = sp.Matrix(A) n = A.shape[0] if n != A.shape[1]: raise ValueError("A should be a square matrix") display(Latex("La matrice suivante est-elle orthogonale ? $A = " + latexp(A) + "$")) answer = widgets.RadioButtons(options=["Oui", "Non"], description="Réponse: ", disabled=False) sol = A.transpose()*A - sp.eye(n) == sp.zeros(n) display(answer) def f(): if answer.value == "Oui": answer_bool = True else: answer_bool = False if answer_bool == sol: display(Latex("Correct !")) else: display(Latex("Incorrect")) interact_manual(f) display(Latex("Si vous n'arrivez pas à trouver la solution, vous pouvez afficher la solution détaillée en" " cliquant ici")) def f_sol(): is_orthogonal(A) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' def ortho_diag(A): A = sp.Matrix(A) n = A.shape[0] if A - A.transpose() != sp.zeros(n): display(Latex("La matrice $A = " + latexp(A) + "$ n'est pas orthogonalement diagonalisable car elle n'est pas " "symétrique.")) return eig = A.eigenvals() eig_list = list(eig.keys()) eig_list.sort() display(Latex("On cherche à diagonaliser orthogonalement la matrice $ A = " + latexp(A) + "$.")) default_value_P = str(np.ones(A.shape, dtype=np.int16).tolist()) default_value_P = default_value_P.replace("],", "],\n") default_value_D = str(np.ones(A.shape[0], dtype=np.int16).tolist()) answer_P = widgets.Text(value=default_value_P, description='P: ', disabled=False) answer_D = widgets.Text(value=default_value_D, description='D: ', disabled=False) display(Latex("Pour les réponses aux questions suivantes, ne faites pas d'approximation numériques, " "toutes les valeurs doivent être exactes. Pour les racines carrées " "(utiles pour normaliser les vecteurs), utilisez 'sqrt('votre valeur')'.")) display(Latex("Donnez les éléments diagonaux de la matrice $D$")) display(answer_D) display(Latex("Donnez la matrice P permettant de diagonaliser orthogonalement la matrice $A$ de sorte que " "$ A = PDP^T = PDP^{-1} $")) display(answer_P) def f(): P_user = eval(answer_P.value) P_user = sp.Matrix(P_user) D_diag= eval(answer_D.value) D_diag_order = set(D_diag.copy()) D_diag_order = list(D_diag_order) D_diag_order.sort() D_user = sp.zeros(n) for i in range(n): D_user[i, i] = D_diag[i] D_user = sp.Matrix(D_user) if np.allclose(np.array(D_diag_order, dtype=np.float64), np.array(eig_list, dtype=np.float64)): if P_user*P_user.transpose()-sp.eye(n) == sp.zeros(n): if P_user * D_user * P_user.transpose() - A == sp.zeros(n): display(Latex("Correct !")) else: display(Latex("Incorrect. On a $PDP^{T}\\neq A$ avec $P = " + latexp(P_user) + "$ et $D =" + latexp(D_user) + "$.")) else: display(Latex("La matrice $P = " + latexp(P_user) + "$ n'est pas orthogonale, i.e. $P P^{T} \\neq I$.")) else: display(Latex("Incorrect. " "Les éléments diagonaux de $D$ ne correspondent pas aux valeurs propres de la matrice $A$.")) return interact_manual(f) def correction_ortho_diag(): display(Latex("Pour diagonaliser orthogonalement une matrice, on a applique la méthode donnée dans le cours:")) display(Markdown( "**Méthode**. Soit $A \in M_{n \\times n}(\mathbb{R})$ symétrique. Soit $\mathcal{C}$ la base canonique de $\mathbb{R}^{n}$ " + nl() + "(1) Cherchons le polynôme caractéristique $c_{A}(t)$" + nl() + "(2) Trouver toutes les racines distinctes $\lambda_{1}, \ldots, \lambda_{r} \in \mathbb{R}$ de $c_{A}(t)$ t.q. $c_{A}(t)=\pm\left(t-\lambda_{1}\\right)^{m_{1}} \cdots\left(t-\lambda_{r}\\right)^{m_{r}}$" + nl() + "(3) Pour chaque $i,$ trouver une base $\mathcal{B}_{i}$ de $E_{\lambda_{i}}$" + nl() + "(4) On sait que pour $v \in \mathcal{B}_{i}, w \in \mathcal{B}_{j}, i \\neq j, v \cdot w=0$" + nl() + "(5) Pour chaque $i$, utiliser Gram-Schmidt pour trouver une base orthonormée $\mathcal{B}_{i}^{\prime}$ de $E_{\lambda_{i}}$" + nl() + "(6) $\mathcal{B}^{\prime}=\mathcal{B}_{1}^{\prime} \cup \cdots \cup \mathcal{B}_{r}^{\prime}$ est une base orthonormée de $V$" + nl() + "(7) $P=[\\text { id }]_{C \mathcal{B}^{\prime}}$ est orthogonale et $P^{T} A P=P^{-1} A P$ est diagonale.")) lamda = sp.symbols('lamda') poly_char_exp = sp.expand(A.charpoly(lamda).as_expr()) poly_char_fac = sp.factor(A.charpoly(lamda).as_expr()) poly_char_exp_str = sp.latex(poly_char_exp) poly_char_fac_str = sp.latex(poly_char_fac) display(Latex("Le polynôme caractéristique de $A$ s'exprime comme: $c_A (t) = " + poly_char_exp_str + "$.")) display(Latex("On trouve les racines du polynôme caractéristique et on factorise. On obtient $c_A (t) = " + poly_char_fac_str + "$.")) eig_list_ = list(eig.keys()) mult_list_ = list(eig.values()) display(Latex("On obtient donc les valeurs propres $\lambda$ et leur multiplicité respective $m$: " " $ \lambda = " + sp.latex(eig_list_) + " \hspace{10mm} m = " + sp.latex(mult_list_) + "$.")) display(Markdown("**On trouve une base orthonormée pour tous les espaces propres.**")) final_basis = [] P = sp.Matrix([]) k = 0 for l in eig_list_: basis_orthonorm = [] basis, basic_idx, free_idx = eigen_basis(A, l, prop_basis=None, disp=True, return_=True, dispA=False) for v in basis: if np.all(v == np.round(v)): v = v.astype(np.int16) basis_orthonorm.append(sp.Matrix(v)) basis_orthonorm = sp.GramSchmidt(basis_orthonorm, True) for v in basis_orthonorm: final_basis.append(v) P = P.col_insert(k, v) k+=1 display(Latex("On applique le procédé de Gram-Schmidt pour obtenir des vecteurs de norme 1 et orthogonaux. " "On obtient $" + sp.latex(basis_orthonorm) + "$")) display(Latex("Finalement, on construit la matrice $P$ en utilisant chaque vecteur de base " "trouvé précedemment comme colonne de cette matrice. Cette dernière est bien orthogonale car " "les vecteurs de base sont orthogonaux entre eux et tous de norme unitaire." "On construit la matrice $D$ en plaçant les valeurs propres de $A$ sur la diagonale. " "Le placement des valeurs propres sur la diagonale de $D$" "doit correspondre avec celui des vecteurs propres dans $P$.")) D = sp.zeros(n) i = 0 for idx in range(len(eig_list_)): for _ in range(mult_list_[idx]): D[i, i] = eig_list_[idx] i += 1 display(Latex("On obtient $P = " + latexp(P) + "\hspace{5mm} \mbox{et} \hspace{5mm} D = " + latexp(D) + "$")) display(Latex("On vérifie le résultat par un calcul:")) display(Latex("$P D P^T = "+ latexp(P) + latexp(D) + latexp(P.transpose()) + " = " + latexp(P*D*P.transpose()) + "=A$")) display(Latex("Si vous n'arrivez pas à résoudre l'exercice, vous pouvez afficher la solution étape " "par étape en cliquant ici.")) interact_manual(correction_ortho_diag) def nl(): return "$$ $$" def sol_is_ortho(A): A = sp.Matrix(A) n = A.shape[0] if n != A.shape[1]: display(Latex("La matrice $A = " + latexp(A) + "$ n'est pas carrée !")) return display(Latex("Pour vérifier si la matrice $A$ est orthogonale, on effectue dans cette correction " "le produit de $A$ et de sa transposée $A^T$." " On vérifie ensuite si l'on obtient la matrice identité.")) if sp.simplify(A*A.transpose()-sp.eye(n)) == sp.zeros(n): display(Latex("On a que: $A A^T = " + latexp(A) + latexp(A.transpose()) + "= " + latexp(sp.eye(n)) + "= I_n $")) display(Latex("La matrice $A$ est donc orthogonale.")) else: display(Latex("On a que: $A A^T = " + latexp(A) + latexp(A.transpose()) + "\\neq I_n $")) display(Latex("Par consequent, la matrice $A$ n'est pas orthogonale.")) return def is_ortho_10_2(A): A = sp.Matrix(A) n = A.shape[0] display(Latex("La matrice $A =" + latexp(A) + "$ est-elle orthogonale ?")) answer = widgets.RadioButtons(options=["Oui", "Non"], description="Réponse: ", disabled=False) display(answer) sol = sp.simplify(A * A.transpose() - sp.eye(n)) == sp.zeros(n) if n != A.shape[1]: sol = False def f(): if answer.value == "Oui": answer_bool = True else: answer_bool = False if answer_bool == sol: display(Latex("Correct !")) else: display(Latex("Incorrect")) if sol: display(Latex("La matrice $A$ est orthogonale.")) else: display(Latex("La matrice $A$ n'est pas orthogonale.")) interact_manual(f) def f_sol(): sol_is_ortho(A) display(Latex("Pour afficher la solution, cliquez-ici.")) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' # Vrai faux def vf(sol): """ :param sol: (bool) solution au vrai faux :return: bool si réponse juste (vrai) ou non (faux) """ answer = widgets.RadioButtons(options=["Vrai", "Faux"], description="Réponse: ", disabled=False) def vf_10_2_2(): display(Latex("Soit $A \in M_{n \\times n}(\mathbb{R})$ une matrice orthogonale. On construit la matrice" " $B \in M_{n \\times n}(\mathbb{R})$ en réarrangeant les colonnes de $A$ dans un ordre quelquonque. " "La matrice $B$ est aussi orthogonale.")) answer = widgets.RadioButtons(options=["Vrai", "Faux"], description="Réponse: ", disabled=False) display(answer) def f(): if answer.value=="Vrai": display(Latex("Correct ! En effet, si l'ordre des colonnes est modifié, l'ensemble de ces dernières reste " "toujours une base orthonormée de l'espace $V$. " "La proposition (5) est donc vérifiée pour la matrice $B$.")) else: display(Latex("Incorrect, changez votre réponse !")) interact_manual(f) def vf_10_2_3(): display(Latex("Soit $A \in M_{n \\times n}(\mathbb{R})$ une matrice orthogonale. On construit la matrice" " $B \in M_{n \\times n}(\mathbb{R})$ en réarrangeant les lignes de $A$ dans un ordre quelquonque. " "La matrice $B$ est aussi orthogonale.")) answer = widgets.RadioButtons(options=["Vrai", "Faux"], description="Réponse: ", disabled=False) display(answer) def f(): if answer.value=="Vrai": display(Latex("Correct ! En effet, si l'ordre des lignes est modifié, l'ensemble de ces dernières reste " "toujours une base orthonormée de l'espace $V$. " "La proposition (4) est donc vérifiée pour la matrice $B$.")) else: display(Latex("Incorrect, changez votre réponse !")) interact_manual(f) def vf_10_2_1(): display(Latex("Soit $A \in M_{n \\times n}(\mathbb{R})$ une matrice orthogonale. $A^T$ est aussi orthogonale.")) answer = widgets.RadioButtons(options=["Vrai", "Faux"], description="Réponse: ", disabled=False) display(answer) def f(): if answer.value == "Vrai": display(Latex("Correct ! En effet, comme $A$ est orthogonale, on sait que ses colonnes forment " "une base orthonormée de l'espace $V$. Comme les lignes de $A^T$ sont les colonnes de $A$, " "alors la proposition (4) est vérifiée pour $A^T$, i.e. les lignes de $A^T$ forment une base " "orthonormée de $V$. $A^T$ est donc une matrice orthogonale.")) else: display(Latex("Incorrect, changez votre réponse !")) interact_manual(f) def vf_10_2_4(): display(Latex("Soit $A \in M_{n \\times n}(\mathbb{R})$ une matrice ayant une valeur propre $\lambda = 2$. " "Il est possible que $A$ soit orthogonale.")) answer = widgets.RadioButtons(options=["Vrai", "Faux"], description="Réponse: ", disabled=False) display(answer) def f(): if answer.value == "Faux": display(Latex("Correct ! Etant donné que $A$ a pour valeur propre $\lambda=2$, cela signifique qu'il existe " "un vecteur $v$ tel que $A v = 2 v$. Donc la matrice $A$ ne conserve pas toujours les longeurs lors " "d'une multiplication avec un vecteur. La proposition (1) n'est pas vérifiée." " $A$ ne peut donc pas être orthogonale.")) else: display(Latex("Incorrect, changez votre réponse !")) - interact_manual(f) \ No newline at end of file + interact_manual(f) + + +def vf_10_4_1(): + display(Markdown("**Dire si l'affirmation suivante est vraie ou fausse.**")) + display(Latex("La matrice $A$ est orthogonalement diagonalisable.")) + n_pos = [3, 4, 5] + n = random.choice(n_pos) + sym = bool(random.getrandbits(1)) + A = sp.randMatrix(n, symmetric=sym, percent=70, min=-20, max=20) + + + if sp.simplify(A-A.transpose())==sp.zeros(n): + sol = True + else: + sol = False + + display(Latex("$A = " + latexp(A) + "$")) + + answer = widgets.RadioButtons(options=["Vrai", "Faux"], description="Réponse: ", disabled=False) + display(answer) + + def f(): + if answer.value == "Vrai": + answer_value = True + else: + answer_value = False + + if answer_value == sol: + display(Latex("Correct ! ")) + if sol: + display(Latex("La matrice $A$ est orthogonalement diagonalisable car elle est symétrique.")) + else: + display(Latex("La matrice $A$ n'est pas orthogonalement diagonalisable car elle n'est pas symétrique.")) + else: + display(Latex("Incorrect, changez votre réponse.")) + + interact_manual(f) + + +def quest_10_4_2(): + A = sp.Matrix([[2, -4], [1, -1]]) + charpol = A.charpoly().as_expr() * -1 + + display(Latex("Soit $A$ une matrice carrée ayant pour polynome caractéristique $c_A(\lambda) = " + + sp.latex(charpol) + "$")) + display(Latex("La matrice $A$ est-elle symétrique ?")) + + answer = widgets.RadioButtons(options=["Oui", "Pas nécessairement", "Non"], description="Réponse: ", disabled=False) + display(answer) + + sol = "Non" + + def f(): + if answer.value == sol: + display(Latex("Correct !")) + + else: + display(Latex("Incorrect.")) + + interact_manual(f) + + def f_sol(): + display(Latex("Le polynome caractéristique de $A$ n'admet pas de racine réelle. " + "Donc la matrice $A$ ne peut pas être symétrique.")) + + display(Latex("Pour afficher la solution détaillée, cliquez-ici.")) + im = interact_manual(f_sol) + im.widget.children[0].description = 'Solution' + + +def quest_10_4_3(): + # Non symmetric values + A = sp.Matrix([[0, -1, -4], [0, 0, -2], [0, -2, 0]]) + charpol = A.charpoly().as_expr()*-1 + charpol = charpol.factor() + + display(Latex("Soit $A$ une matrice carrée ayant pour polynome caractéristique $c_A(\lambda) = " + sp.latex(charpol) + "$")) + display(Latex("La matrice $A$ est-elle symétrique ?")) + + answer = widgets.RadioButtons(options=["Oui", "Pas nécessairement", "Non"], description="Réponse: ", disabled=False) + display(answer) + + sol = "Pas nécessairement" + + def f(): + if answer.value == sol: + display(Latex("Correct !")) + + else: + display(Latex("Incorrect.")) + + interact_manual(f) + + def f_sol(): + A2 = sp.Matrix([[0, 0, 0], [0, 2, 0], [0, 0, -2]]) + display(Latex("On sait que le polynome caractéristique d'une matrice symétrique admet uniquement des racines réelles. " + "Or la réciproque est fausse, i.e., les polynomes caractéristiques à racines réelles peuvent être issus de matrices non symétriques. " + nl() + + "On voit que le polynome caractéristique $c_A(\lambda)$ a uniquement des racines réelles mais cela ne suffit pas pour conclure que $A$ est symétrique. ")) + + display(Latex("La bonne réponse est donc: Pas nécessairement")) + + display(Latex("Dans ce cas précis, les matrices $A_1 =" + latexp(A) + "$ et $A_2 = " + latexp(A2) + "$ ont " + "toutes les deux $c_A(\lambda)$ pour polynome caractéristique. On voit que une des matrices est symétrique et l'autre pas.")) + + + display(Latex("Pour afficher la solution détaillée, cliquez-ici.")) + im = interact_manual(f_sol) + im.widget.children[0].description = 'Solution' + + +def exo_2_1_10_4(): + v1 = sp.Matrix([3, 4]) + v2 = sp.Matrix([-1, 1/2]) + display(Latex("La matrice $A \in M_{2 \\times 2}$ ( $\mathbb{R}$ ) a pour valeur propres $3$ et $-2$. " + "$" + latexp(v1) + "\mbox{ et } " + latexp(v2) + "$ sont des vecteurs propres de $A$ respectivement " + "associés aux valeurs propres $3$ et $-2$. ")) + + display(Latex("La matrice $A$ est-elle symétrique ?")) + + answer = widgets.RadioButtons(options=["Oui", "Non", "Manque d'informations"], description="Réponse: ", disabled=False) + display(answer) + + sol = "Non" + + def f(): + if answer.value == sol: + display(Latex("Correct !")) + + else: + display(Latex("Incorrect.")) + + interact_manual(f) + + def f_sol(): + display(Latex("Les vecteurs propres $" + latexp(v1) + "$ et $" + latexp(v2) + + "$ sont associés à des valeurs propres différentes mais ne sont pas orthogonaux. " + "La matrice $A$ ne peut donc pas être symétrique.")) + + display(Latex("Pour afficher la solution détaillée, cliquez ici.")) + im = interact_manual(f_sol) + im.widget.children[0].description = 'Solution' + + +def exo_2_2_10_4(): + v1 = sp.Matrix([1, 0, 2]) + v2 = sp.Matrix([-2, 0, -4]) + v3 = sp.Matrix([2, 5, -1]) + + display(Latex("La matrice $A \in M_{3 \\times 3}$ ( $\mathbb{R}$ ) a pour valeur propres $4$ et $2$. " + "$" + latexp(v1) + ", " + latexp(v2) + "\mbox{ et } " + latexp(v3) + "$ sont des vecteurs propres de $A$ respectivement " + "associés aux valeurs propres $4$, $4$ et $-2$. ")) + + display(Latex("La matrice $A$ est-elle symétrique ?")) + + opt = ["Oui", "Non", "Manque d'informations"] + answer = widgets.RadioButtons(options=opt, description="Réponse: ", disabled=False) + display(answer) + + sol = opt[2] + + def f(): + if answer.value == sol: + display(Latex("Correct !")) + + else: + display(Latex("Incorrect.")) + + interact_manual(f) + + def f_sol(): + display(Latex("Les vecteurs propres associés à des valeurs propres différentes sont bien orthogonaux. " + "Mais on ne connait pas la dimension de l'espace propre associé à $\lambda = 4$ car les deux " + "vecteurs donnés dans l'énoncé, $ " + latexp(v1) + " \mbox{ et } " + latexp(v2) + "$, " + "sont colinéaires." + nl() + + "Pour connaitre la dimension de cette espace, il faudrait une base de ce dernier. " + "Cela permettrait de vérifier si la dimension de l'espace est de 2 et si tous les vecteurs de " + "cet espace sont orthogonaux aux vecteurs composant l'espace propre associé à $\lambda = 2$. " + "Si ces deux conditions étaient vérifiées, la matrice $A$ serait symétrique.")) + + display(Latex("Il manque donc d'informations pour répondre.")) + + display(Latex("Pour afficher la solution détaillée, cliquez ici.")) + im = interact_manual(f_sol) + im.widget.children[0].description = 'Solution' + + +def exo_2_3_10_4(): + v1 = sp.Matrix([1, 0, 1]) + v2 = sp.Matrix([-2, 0, 1]) + v3 = sp.Matrix([0, 3, 0]) + + display(Latex("La matrice $A \in M_{3 \\times 3}$ ( $\mathbb{R}$ ) a pour valeur propres $-1$, $2$ et $4$. " + "$" + latexp(v1) + ", " + latexp(v2) + "\mbox{ et } " + latexp(v3) + "$ sont des vecteurs propres de $A$ respectivement " + "associés aux valeurs propres $-1$, $2$ et $4$. ")) + + display(Latex("La matrice $A$ est-elle symétrique ?")) + + opt = ["Oui", "Non", "Manque d'informations"] + answer = widgets.RadioButtons(options=opt, description="Réponse: ", disabled=False) + display(answer) + + sol = opt[1] + + def f(): + if answer.value == sol: + display(Latex("Correct !")) + + else: + display(Latex("Incorrect.")) + + interact_manual(f) + + def f_sol(): + display(Latex("Les vecteurs propres $" + latexp(v1) + "$ et $" + latexp(v2) + + "$ sont associés à des valeurs propres différentes mais ne sont pas orthogonaux. " + "La matrice $A$ ne peut donc pas être symétrique.")) + + + display(Latex("Pour afficher la solution détaillée, cliquez ici.")) + im = interact_manual(f_sol) + im.widget.children[0].description = 'Solution' + + +def exo_2_4_10_4(): + v1 = sp.Matrix([1, 0, 1]) + v2 = sp.Matrix([-2, 0, 1]) + v3 = sp.Matrix([0, 3, 0]) + + display(Latex("La matrice $A \in M_{3 \\times 3}$ ( $\mathbb{R}$ ) a pour valeur propres $-1$, et $4$. " + "$" + latexp(v1) + ", " + latexp(v2) + "\mbox{ et } " + latexp(v3) + "$ sont des vecteurs propres de $A$ respectivement " + "associés aux valeurs propres $-1$, $-1$ et $4$. ")) + + display(Latex("La matrice $A$ est-elle symétrique ?")) + + opt = ["Oui", "Non", "Manque d'informations"] + answer = widgets.RadioButtons(options=opt, description="Réponse: ", disabled=False) + display(answer) + + sol = opt[0] + + def f(): + if answer.value == sol: + display(Latex("Correct !")) + + else: + display(Latex("Incorrect.")) + + interact_manual(f) + + def f_sol(): + base_1 = sp.GramSchmidt([v1, v2], orthonormal=True) + base_4 = sp.GramSchmidt([v3], orthonormal=True) + + display(Latex("Les vecteurs propres $" + latexp(v1) + "$ et $" + latexp(v2) + "$ associés à $\lambda = -1$ sont linéairement indépendant " + "et orthogonaux au vecteur propre $" + latexp(v3) + "$ associé à $\lambda = 4$. " + "On peut utiliser ces deux ensembles de vecteurs propres pour former des bases des espaces propres " + "associés à $\lambda = -1$ et $\lambda = 4$, respectivement." + "On peut othogonaliser et normaliser ces bases avec le schema de Gram-Schmidt.")) + + display(Latex("On obtient les bases des espaces propres associées respectivement à $\lambda = -1$ et $\lambda = 4$")) + display(Latex("$ " + latexp(base_1[0]) + ", " + latexp(base_1[1]) + "\hspace{15mm} " + latexp(base_4[0]) + "$")) + + + display(Latex("Pour afficher la solution détaillée, cliquez ici.")) + im = interact_manual(f_sol) + im.widget.children[0].description = 'Solution' \ No newline at end of file