diff --git "a/Chapitre 4 - Bases et dimension/4.1-2. D\303\251pendance et ind\303\251pendance lin\303\251aire.ipynb" "b/Chapitre 4 - Bases et dimension/4.1-2. D\303\251pendance et ind\303\251pendance lin\303\251aire.ipynb" index b4242c0..24da799 100644 --- "a/Chapitre 4 - Bases et dimension/4.1-2. D\303\251pendance et ind\303\251pendance lin\303\251aire.ipynb" +++ "b/Chapitre 4 - Bases et dimension/4.1-2. D\303\251pendance et ind\303\251pendance lin\303\251aire.ipynb" @@ -1,214 +1,189 @@ { "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "jupyter": { "outputs_hidden": false }, "pycharm": { "name": "#%%\n" } }, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "from Ch4Functions import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Concepts-clés et théorie\n", "\n", "### DÉFINITION 1\n", "\n", "Soient $V$ un $\\mathbb{R}$-espace vectoriel et $S\\subset V$ une collection de vecteurs dans $V.$ On dit que $S$ est linéairement dépendante (ou liée) s'il existe des vecteurs distincts $v_1,\\ldots,v_r\\in S$ et des scalaires $\\lambda_1,\\ldots,\\lambda_r\\in \\mathbb{R}$ non tous nuls tels que $\\lambda_1v_1+\\cdots+\\lambda_rv_r=0.$ (Autrement dit, s'il existe une combinaison linéaire (non triviale) de vecteurs de $S$ qui se réduit au vecteur nul.) S'il n'existe pas de tels vecteurs dans $S,$ alors on dit que $S$ est linéairement indépendante (ou libre).\n", "\n", "### PROPOSITION 1\n", "\n", "Soient $V$ un $\\mathbb{R}$-espace vectoriel et $v_1,\\ldots,v_r\\in V$ des vecteurs de $V.$ Alors ces derniers sont linéairement dépendants si et seulement s'il existe $1\\leq i\\leq r$ tels que $v_i\\in \\mbox{Vect}(\\{v_1,\\ldots,v_{i-1},v_{i+1},\\ldots,v_r\\}),$ c'est-à-dire si et seulement si l'on peut exprimer un des vecteurs de la liste comme une combinaison linéaire des autres.\n", "\n", "### PROPOSITION 2\n", "\n", "Soient $V$ un $\\mathbb{R}$-espace vectoriel et $S\\subset V$ une famille libre de vecteurs dans $V.$ Alors tout sous-ensemble $T\\subset S$ est aussi libre.\n", "\n", "### PROPOSITION 3\n", "\n", "Soient $V$ un $\\mathbb{R}$-espace vectoriel et $S\\subset V$ une famille liée de vecteurs dans $V.$ Alors toute collection de vecteurs $T$ contenant $S$ est également liée." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 1\n", "\n", "Soient:\n", "\n", "$$v_1 = \\begin{pmatrix} 1 \\\\ 0 \\\\ 2 \\end{pmatrix} \\ \\ v_2 = \\begin{pmatrix} 0 \\\\ 1 \\\\ 0 \\end{pmatrix} \\ \\ v_3 = \\begin{pmatrix} 1 \\\\ 1 \\\\ 1 \\end{pmatrix}$$\n", "\n", "Trouver une combinaison linéaire telle que:\n", "\n", "$$\\lambda_1 v_1 + \\lambda_2 v_2 + \\lambda_3 v_3 = \\begin{pmatrix} 3 \\\\ 5 \\\\ 4 \\end{pmatrix}$$\n", "\n", "Entrez les coefficients $\\lambda_i$ dans le vecteur ci-dessous puis exécutez les deux cellules pour vérifier votre réponse." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "solution = [1, 0, 2] # Réponse à compléter\n", "\n", "ch4_1_2ex1(solution)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 2\n", "\n", "D'après les mêmes données que l'exercice 1, la collection des vecteurs $v_1$, $v_2$, $v_3$ et $\\begin{pmatrix} 3 \\\\ 0 \\\\ 4 \\end{pmatrix}$ est-elle liée ?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_1_2ex2()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 3\n", "\n", "Les collections de vecteurs suivantes sont-elles liées ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### (a)\n", "\n", "$$v_1 = \\begin{pmatrix} 1 \\\\ 1 \\\\ 1 \\end{pmatrix} \\ \\ v_2 = \\begin{pmatrix} 1 \\\\ 2 \\\\ 1 \\end{pmatrix} \\ \\ v_3 = \\begin{pmatrix} 0 \\\\ 1 \\\\ 0 \\end{pmatrix}$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_1_2ex3a()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### (b)\n", "\n", "$$v_1 = \\begin{pmatrix} 1 \\\\ 0 \\\\ 4 \\end{pmatrix} \\ \\ v_2 = \\begin{pmatrix} 6 \\\\ 12 \\\\ 7 \\end{pmatrix} \\ \\ v_3 = \\begin{pmatrix} 0 \\\\ 9 \\\\ 7 \\end{pmatrix} \\ \\ v_4 = \\begin{pmatrix} 1 \\\\ 1 \\\\ 1 \\end{pmatrix}$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_1_2ex3b()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### (c)\n", "\n", "$$v_1 = \\begin{pmatrix} 1 \\\\ 0 \\\\ -1 \\end{pmatrix} \\ \\ v_2 = \\begin{pmatrix} 1 \\\\ 1 \\\\ 0 \\end{pmatrix} \\ \\ v_3 = \\begin{pmatrix} 0 \\\\ 1 \\\\ -1 \\end{pmatrix}$$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_1_2ex3c()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook du chapitre 4.3. Bases et dimension](./4.3.%20Bases%20et%20dimension.ipynb)" ] } ], "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" }, "pycharm": { "stem_cell": { "cell_type": "raw", "metadata": { "collapsed": false }, "source": [] } } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 4 - Bases et dimension/4.10. Rang-colonne et syst\303\250mes d'\303\251quations.ipynb" "b/Chapitre 4 - Bases et dimension/4.10. Rang-colonne et syst\303\250mes d'\303\251quations.ipynb" index 86ad8af..beaaa3b 100644 --- "a/Chapitre 4 - Bases et dimension/4.10. Rang-colonne et syst\303\250mes d'\303\251quations.ipynb" +++ "b/Chapitre 4 - Bases et dimension/4.10. Rang-colonne et syst\303\250mes d'\303\251quations.ipynb" @@ -1,290 +1,290 @@ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "from Ch4Functions import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Concept(s)-clé(s)\n", "\n", "\n", "\n", "### LEMME:\n", "\n", "Soit $S$ un système de $m$ équations linéaires à $n$ inconnues, $A$ la matrice des coefficients de $S$ et $\\hat{A}$ sa matrice augmentée. Alors $S$ possède une solution si et seulement si le rang colonne de $A$ est égal au rang colonne de $\\hat{A}$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice 1\n", "On cherche a résoudre cette equation en utilisant le lemme ci-dessus. L'exercice se fait en plusieurs étapes.\n", "\n", "Soit $S$ un système de $m$ équations linéaires à $n$ inconnues:\n", "\n", "$$\\begin{equation}\n", " \\left\\{\n", " \\begin{aligned}\n", " x_1 + 4x_2 + 3x_3 + 4x_4 = 1 \\\\ \n", " 2x_1 + 6x_2 + 5x_3 + 8x_4 = 1 \\\\\n", " x_1 + x_3 + 4x_4 = 1\n", " \\end{aligned}\n", " \\right.\n", "\\end{equation}$$\n", "\n", "\n", "\n", "#### Etape 1:\n", "Cette équation peut se représenter sous la forme $AX =b$.\n", "Ecrivez $A$ la matrice et le vecteur $b$ dans la cellule suivante en respectant le format suivant pour les matrices et les vecteurs\n", "\n", "$[[ a, b], [c, d]] = \\begin{pmatrix} a & b \\\\ c & d \\end{pmatrix}$\n", "\n", "$[e, f] = \\begin{pmatrix} e \\\\ f \\end{pmatrix}$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# N'oubliez pas d'executer la cellule\n", "A = [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]\n", "b = [0, 0, 0]\n", "\n", "ch4_10ex1_1(A,b) # Ne pas modifier cette ligne" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Etape 2:\n", "Pour calculer le rang colonne de $A$, échelonnez $A^T$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex1_2_1_ech()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**A partir de la forme échelonnée de $A^T$ trouvée ci-dessus, donnez le rang colonne de $A$.**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex1_2_1()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**A partir de la forme échelonnée de $A^T$, trouvez une base de l'espace colonne de $A$.**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# [vect1,vect2,...] avec vect = [a, b, c] n'oubliez pas d'executer la cellule\n", - "base = [[0,0,0], [0,0,0]]\n", + "base = [[1,2,1], [0,1,2]]\n", "\n", "ch4_10ex1_2_2(base)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Etape 3: \n", "Maintenant nous allons utiliser le lemme afin de déterminer si le système possède une solution. Comme nous connaissons une base de l'espace des colonnes de $A$, nous pouvons l'utiliser pour trouver le rang colonne de $\\hat{A}$. Ainsi, au lieu de trouver le rang colonne de \n", "\n", "$$ \\hat{A} = \\begin{pmatrix} 1 & 4 & 3 & 4 & 1 \\\\ 2 & 6 & 5 & 8 & 1 \\\\ 1 & 0 & 1 & 4 & 1\\end{pmatrix}$$\n", "\n", "nous pouvons chercher le rang colonne de \n", "\n", "$$\\begin{pmatrix} 1 & 0 & 1 \\\\ 2 & 1 & 1 \\\\ 1 & 2 & 1\\end{pmatrix}$$\n", "\n", "Pour ceci il faut donc échelonner sa matrice transposée\n", "\n", "$$\\begin{pmatrix} 1 & 2 & 1 \\\\ 0 & 1 & 2 \\\\ 1 & 1 & 1\\end{pmatrix}$$\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex1_3_ech()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex1_3()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Partie 2**\n", "\n", "Une autre manière de voir que le système n'admet pas de solutions est d'échelonner directement la matrice augmentée" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex1_3_2_ech()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 2\n", "\n", "Considérons maintenant le système suivant:\n", "\n", "$$\\begin{equation}\n", " \\left\\{\n", " \\begin{aligned}\n", " x_1 + 4x_2 + 3x_3 + 4x_4 = 2 \\\\ \n", " 2x_1 + 6x_2 + 5x_3 + 8x_4 = 5 \\\\\n", " x_1 + x_3 + 4x_4 = 4\n", " \\end{aligned}\n", " \\right.\n", "\\end{equation}$$\n", "\n", "Seul le vecteur $b$ est différent du système de l'exercice précedent, la matrice $A$ demeure identique.\n", "Nous pouvons donc réutiliser la base de l'espace colonne trouvée dans l'exercice précédent.\n", "Ainsi le rang colonne de suivante nous permet de savoir si le système possède une solution.\n", "\n", "$$\\begin{pmatrix} 1 & 0 &2 \\\\ 2 & 1 & 5 \\\\ 1 & 2 & 4\\end{pmatrix}$$\n", "\n", "pour trouver son rang colonne, il faut échelonner sa matrice transposée:\n", "\n", "$$\\begin{pmatrix} 1 & 2 & 1 \\\\ 0 & 1 & 2 \\\\ 2 & 5 & 4\\end{pmatrix}$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex2_1_ech()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Le système possède il une solution ? " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "jupyter": { "source_hidden": true } }, "outputs": [], "source": [ "ch4_10ex2_2()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook du chapitre 4.11 : Coordonnées par rapport à une base](./4.11.%20Coordonnées%20par%20rapport%20à%20une%20base.ipynb)" ] } ], "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": 4 } diff --git a/Chapitre 4 - Bases et dimension/4.7-8. Dimension d'un sous-espace et d'une somme de sous-espaces.ipynb b/Chapitre 4 - Bases et dimension/4.7-8. Dimension d'un sous-espace et d'une somme de sous-espaces.ipynb index 6612950..74ed19b 100644 --- a/Chapitre 4 - Bases et dimension/4.7-8. Dimension d'un sous-espace et d'une somme de sous-espaces.ipynb +++ b/Chapitre 4 - Bases et dimension/4.7-8. Dimension d'un sous-espace et d'une somme de sous-espaces.ipynb @@ -1,234 +1,234 @@ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from Ch4Functions import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Concepts-clés et théorie\n", "\n", "\n", "\n", "### THÉORÈME 1 :\n", "\n", "Soient $V$ un $\\mathbb{R}$-espace vectoriel de dimension finie et $W$ un sous-espace vectoriel de $V.$ Alors les affirmations suivantes sont vérifiées.\n", "\n", "\n", "\n", "1. Le sous-espace vectoriel $W$ est de dimension finie.\n", "\n", "2. La dimension de $W$ satisfait $\\dim W\\leq \\dim V$.\n", "\n", "3. Si $\\dim W=\\dim V,$ alors $W=V$." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 1\n", "\n", - "Soit un système de $3$ équations à $5$ inconnues.\n", + "Soit un système homogène de $3$ équations à $5$ inconnues.\n", "\n", "Quelles sont les dimensions possibles pour l'espace des solutions ? Cochez toutes les réponses valides (maintenez CTRL pour en sélectionner plusieurs)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex1()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 2\n", "\n", "Soit $S_1$ un système de $2$ équations à $3$ inconnues et dont l'espace de solution forme un plan.\n", "\n", "On définit $S_2$ comme étant le système $S_1$ privé d'une équation.\n", "\n", "Quelle est la dimension de l'espace des solutions de $S_2$ ?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex2()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### EXERCICE 3\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remarquez la propriété suivante :\n", "\n", "- $\\dim(A + B) + \\dim(A \\cap B) = \\dim(A) + \\dim(B)$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3_venn()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Donner dans chaque cas la dimension de la somme des deux espaces vectoriels ; appuyez sur le bouton \"Visualiser\" pour vous aider :" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(a) $\\dim (W + V)$ avec $W$ un plan et $V$ une droite coplanaire à ce plan ; les deux passant par l'origine." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3a()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(b) $\\dim (W + V)$ avec $W$ un plan et $V$ une droite non coplanaire à ce plan ; les deux passant par l'origine." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3b()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(c) $\\dim (V + V)$ avec $V$ une droite passant par l'origine." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3c()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(d) $\\dim (V_1 + V_2)$ avec $V_1$ et $V_2$ deux droites distinctes passant par l'origine." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3d()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(e) $\\dim (W_1 + W_2)$ avec $W_1$ et $W_2$ deux plans distincts passant par l'origine." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3e()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "(f) $\\dim (U + X)$ avec $U$ l'origine et $X$ l'espace $\\mathbb{R}^3$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "ch4_7_8ex3f()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Passez au notebook du chapitre 4.9. Rang-ligne et rang-colonne d'une matrice\n", "](./4.9.%20Rang-ligne%20et%20rang-colonne%20d'une%20matrice.ipynb)" ] } ], "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": 4 } diff --git a/Chapitre 4 - Bases et dimension/Ch4Functions.py b/Chapitre 4 - Bases et dimension/Ch4Functions.py index 789a587..af5ca13 100644 --- a/Chapitre 4 - Bases et dimension/Ch4Functions.py +++ b/Chapitre 4 - Bases et dimension/Ch4Functions.py @@ -1,1404 +1,1455 @@ import sys -sys.path.insert(0,'..') + +sys.path.insert(0, '..') import Librairie.AL_Fct as al + sys.path.pop(0) import numpy as np from IPython.display import display, Markdown, Latex import plotly.graph_objs as go import plotly import ipywidgets as widgets from ipywidgets import interact, interactive, fixed, interact_manual, Layout, VBox, HBox import plotly.express as px import sympy as sp import matplotlib.pyplot as plt from itertools import permutations from IPython.display import display, Latex, Markdown + def ch4_1_2ex1(solution): v = np.array([[1, 0, 2], [0, 1, 0], [1, 1, 1]]).transpose() e = np.array([3, 5, 4]) s = np.array(solution) r = v @ s if np.allclose(e, r): display(Markdown("**Correction:** C'est correct!")) else: - display(Markdown("**Correction:** C'est incorrect car: $\lambda_1 v_1 + \lambda_2 v_2 + \lambda_3 v_3 = \\begin{pmatrix} %s \\\\ %s \\\\ %s \end{pmatrix} \\neq \\begin{pmatrix} %s \\\\ %s \\\\ %s \end{pmatrix}$" % (r[0], r[1], r[2], e[0], e[1], e[2]))) + display(Markdown( + "**Correction:** C'est incorrect car: $\lambda_1 v_1 + \lambda_2 v_2 + \lambda_3 v_3 = \\begin{pmatrix} %s \\\\ %s \\\\ %s \end{pmatrix} \\neq \\begin{pmatrix} %s \\\\ %s \\\\ %s \end{pmatrix}$" % ( + r[0], r[1], r[2], e[0], e[1], e[2]))) w = s * v cumsum = np.cumsum(np.insert(w, 0, 0, axis=1), axis=1).transpose() colors = px.colors.qualitative.Plotly global color_index color_index = 0 data = [] + def addVector(start, v): global color_index color = colors[color_index] color_index = (color_index + 1) % len(colors) end = start + v trace = go.Scatter3d( x=[start[0], end[0], None], y=[start[1], end[1], None], z=[start[2], end[2], None], mode='lines', name=str(v), line=dict(color=color, width=4) ) norm = np.sqrt(np.sum(v * v)) n = v if norm == 0 else v / norm n = 1.5 * n c_end = end - 0.37 * n - cone = go.Cone(x=[c_end[0]], y=[c_end[1]], z=[c_end[2]], u=[n[0]], v=[n[1]], w=[n[2]], name=str(v), colorscale=[[0, color], [1, color]], hoverinfo="none", showscale=False) + cone = go.Cone(x=[c_end[0]], y=[c_end[1]], z=[c_end[2]], u=[n[0]], v=[n[1]], w=[n[2]], name=str(v), + colorscale=[[0, color], [1, color]], hoverinfo="none", showscale=False) data.append(trace) data.append(cone) addVector(np.zeros(3), e) for i in range(len(cumsum) - 1): start = cumsum[i] v = cumsum[i + 1] - start addVector(start, v) fig = go.Figure(data=data) fig.show() + def ch4_1_2ex2(): radio = widgets.RadioButtons( options=['Oui, les vecteurs sont dépendants', 'Non, les vecteurs sont indépendants'], layout={'width': 'max-content'}, value=None, description='Réponse:', ) button = widgets.Button(description='Vérifier') out = widgets.Output() display(radio) display(button) display(out) def verification_2(e): if radio.value is not None: out.clear_output() with out: if radio.value.startswith('Non'): - display(Markdown("C'est incorrect, il existe $\lambda_1$, $\lambda_2$ et $\lambda_3$ tels que $\lambda_1 v_1 + \lambda_2 v_2 + \lambda_3 v_3 - \\begin{pmatrix} 3 \\\\ 0 \\\\ 4 \end{pmatrix} = 0$.")) + display(Markdown( + "C'est incorrect, il existe $\lambda_1$, $\lambda_2$ et $\lambda_3$ tels que $\lambda_1 v_1 + \lambda_2 v_2 + \lambda_3 v_3 - \\begin{pmatrix} 3 \\\\ 0 \\\\ 4 \end{pmatrix} = 0$.")) else: display(Markdown("C'est correct!")) button.on_click(verification_2) + def ch4_1_2ex3(answer): radio = widgets.RadioButtons( options=['Oui, les vecteurs sont dépendants', 'Non, les vecteurs sont indépendants'], layout={'width': 'max-content'}, value=None, description='Réponse:', ) button = widgets.Button(description='Vérifier') out = widgets.Output() display(radio) display(button) display(out) def verification_3(e): if radio.value is not None: out.clear_output() with out: if radio.value.startswith('Oui') == answer: display(Markdown("C'est correct!")) else: display(Markdown("C'est incorrect!")) button.on_click(verification_3) + def ch4_1_2ex3a(): ch4_1_2ex3(True) + def ch4_1_2ex3b(): ch4_1_2ex3(True) + def ch4_1_2ex3c(): ch4_1_2ex3(False) - -def ch4_3ex1(answer, reason, callback, options=['Oui, les vecteurs forment une base', 'Non, les vecteurs ne forment pas une base']): + + +def ch4_3ex1(answer, reason, callback, + options=['Oui, les vecteurs forment une base', 'Non, les vecteurs ne forment pas une base']): radio = widgets.RadioButtons( options=options, layout={'width': 'max-content'}, value=None, description='Réponse:', ) button = widgets.Button(description='Vérifier') out = widgets.Output() display(radio) display(button) display(out) def verification(e): if radio.value is not None: out.clear_output() with out: if options.index(radio.value) == answer: display(Markdown("C'est correct!
%s" % reason)) else: display(Markdown("C'est incorrect!
%s" % reason)) callback() button.on_click(verification) + def plot_vectors(vectors, selected, solution): v = np.array(vectors).transpose() e = np.array(selected) s = np.array(solution) r = v @ s w = s * v - + cumsum = np.cumsum(np.insert(w, 0, 0, axis=1), axis=1).transpose() - + colors = px.colors.qualitative.Plotly global color_index color_index = 0 - + data = [] + def addVector(start, v): global color_index - + color = colors[color_index] color_index = (color_index + 1) % len(colors) - + end = start + v trace = go.Scatter3d( x=[start[0], end[0], None], y=[start[1], end[1], None], z=[start[2], end[2], None], mode='lines', name=str(v), line=dict(color=color, width=4) ) norm = np.sqrt(np.sum(v * v)) n = v if norm == 0 else v / norm n = 0.5 * n c_end = end - 0.37 * n - cone = go.Cone(x=[c_end[0]], y=[c_end[1]], z=[c_end[2]], u=[n[0]], v=[n[1]], w=[n[2]], name=str(v), colorscale=[[0, color], [1, color]], hoverinfo="none", showscale=False) - + cone = go.Cone(x=[c_end[0]], y=[c_end[1]], z=[c_end[2]], u=[n[0]], v=[n[1]], w=[n[2]], name=str(v), + colorscale=[[0, color], [1, color]], hoverinfo="none", showscale=False) + data.append(trace) data.append(cone) - + addVector(np.zeros(3), e) for i in range(len(cumsum) - 1): start = cumsum[i] v = cumsum[i + 1] - start addVector(start, v) fig = go.Figure(data=data) fig.show() - + + def ch4_3ex1a(): ch4_3ex1(1, """ En effet, les quatres vecteurs ne sont pas linéairement indépendants (Déf. 1-2) car il est possible d'exprimer l'un avec une combinaison linéaire des autres. Par exemple : $$\\begin{pmatrix} 1 \\\\ 1 \\\\ 1 \end{pmatrix} = \\begin{pmatrix} 1 \\\\ 0 \\\\ 1 \end{pmatrix} + \\frac{1}{2} \\begin{pmatrix} 0 \\\\ 2 \\\\ 0 \end{pmatrix} + 0 \\begin{pmatrix} 0 \\\\ 0 \\\\ 3 \end{pmatrix}$$ Comme tous les vecteurs sont issus de $\mathbb{R}^3$ on peut facilement représenter la combinaison dans l'espace : """, lambda: plot_vectors([[1, 0, 1], [0, 2, 0], [0, 0, 3]], [1, 1, 1], [1, 0.5, 0])) - + + def ch4_3ex1b(): ch4_3ex1(1, """ On ne peut pas générer $\mathbb{R}^3$ à partir de cet ensemble. En effet, on ne peut par exemple pas obtenir le vecteur $\\begin{pmatrix} 1 \\\\ 0 \\\\ 0 \end{pmatrix} \\in \mathbb{R}^3$ avec une combinaison linéaire de $\\begin{pmatrix} 1 \\\\ 0 \\\\ 1 \end{pmatrix}$ et $\\begin{pmatrix} 0 \\\\ 1 \\\\ 0 \end{pmatrix}$. Graphiquement les deux vecteurs ne peuvent engendrer qu'un plan: """, lambda: plot_vectors([[1, 0, 0]], [0, 1, 0], [1])) - + + def ch4_3ex1c(): ch4_3ex1(0, """ Ces trois vecteurs sont linéairement indépendants, ils engendrent donc $\mathbb{R}^3$ et forment une base de cet espace. """, lambda: None) - + + def ch4_3ex2(): vecs = np.array([[1, 1, 1], [0, 1, 2], [2, 1, 4], [2, 1, 0], [1, 0, -1]]) - + select = widgets.SelectMultiple( options=['v1', 'v2', 'v3', 'v4', 'v5'], description='Sélection :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() def callback(e): - answer = [int(v[1:])-1 for v in select.value] + answer = [int(v[1:]) - 1 for v in select.value] out.clear_output() with out: - if len(answer) == 0: # Empty + if len(answer) == 0: # Empty pass elif len(answer) < 3: display(Markdown("C'est incorrect!
La solution entrée ne permet pas d'engendrer $\mathbb{R}^3$.")) elif len(answer) > 3: display(Markdown("C'est incorrect!
La solution entrée contient des vecteurs qui sont dépendants.")) else: mat = np.array([vecs[answer[0]], vecs[answer[1]], vecs[answer[2]]]).transpose() det = np.linalg.det(mat) if det == 0: - display(Markdown("C'est incorrect!
La solution entrée contient des vecteurs qui sont dépendants.")) - else: # Correct + display( + Markdown("C'est incorrect!
La solution entrée contient des vecteurs qui sont dépendants.")) + else: # Correct display(Markdown("C'est correct!
Il s'agit d'_une_ base de $\mathbb{R}^3$.")) button.on_click(callback) display(select) display(button) display(out) - + def ch4_3ex3(): ch4_3ex1(1, """ Cet ensemble n'est pas une base de $\mathbb{P}^n(\mathbb{R})$ car il ne permet pas (par exemple) de générer les polynômes constants. $\mathbb{P}^n(\mathbb{R})$ est néanmoins engendré par $\{1, x, x^2, x^3, ..., x^{n-1}\}$. """, lambda: None) - + + def ch4_3ex4(): ch4_3ex1(2, """ L'espace engendré par cet ensemble est $M_{2 \\times 2}(\mathbb{R})$ et donc sa dimension est $4$. Attention cet ensemble n'est pas une base de $M_{2 \\times 2}(\mathbb{R})$ car ses éléments sont linéairement dépendants ! """, lambda: None, ['2', '3', '4', '5']) + def ch4_4_5ex1(): vs = np.array([[1, 1, 1], [2, 0, 3], [4, 0, 0], [1, 0, 0]]) - + select = widgets.SelectMultiple( options=['v1', 'v2', 'v3', 'v4'], description='Sélection :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): - answer = [int(v[1:])-1 for v in select.value] + answer = [int(v[1:]) - 1 for v in select.value] out.clear_output() with out: - if len(answer) == 0: # Empty + if len(answer) == 0: # Empty pass elif len(answer) < 3: - display(Markdown("C'est incorrect!
La solution entrée ne permet pas d'engendrer $\\mathbb{R}^3$, et n'est donc pas une base.")) + display(Markdown( + "C'est incorrect!
La solution entrée ne permet pas d'engendrer $\\mathbb{R}^3$, et n'est donc pas une base.")) elif len(answer) > 3: - display(Markdown("C'est incorrect!
La solution entrée engendre $\\mathbb{R}^3$ mais n'est pas une base.")) + display(Markdown( + "C'est incorrect!
La solution entrée engendre $\\mathbb{R}^3$ mais n'est pas une base.")) else: mat = np.array([vs[answer[0]], vs[answer[1]], vs[answer[2]]]).transpose() if np.linalg.matrix_rank(mat) != len(mat): - display(Markdown("C'est incorrect!
La solution entrée ne permet pas d'engendrer $\\mathbb{R}^3$, et n'est donc pas une base.")) - else: # Correct + display(Markdown( + "C'est incorrect!
La solution entrée ne permet pas d'engendrer $\\mathbb{R}^3$, et n'est donc pas une base.")) + else: # Correct display(Markdown("C'est correct!
Il s'agit d'_une_ base de $\\mathbb{R}^3$.")) button.on_click(callback) display(select) display(button) display(out) + def ch4_4_5ex2(v): v = np.array(v) vs = np.array([[1, 4, 3, 0], [1, 0, 0, 1], [0, 1, 1, 0], v.flatten()]) is_base = np.linalg.matrix_rank(vs) == len(vs) - + out = widgets.Output() display(out) - + with out: if is_base: display(Markdown("C'est correct!")) else: display(Markdown("C'est incorrect, ce vecteur ne permet pas de former une base.")) - + + def ch4_6ex1(): text = widgets.IntText( description='Réponse :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): out.clear_output() r = text.value feedback = "" is_correct = False if r == 6: feedback = "Comme la matrice n'est pas nulle, au moins une variable n'est pas libre." elif r >= 7: feedback = "La dimension de l'espace des solutions ne peut excéder la dimension de l'espace des variables." elif r == 5: is_correct = True feedback = "Le nombre maximal de variables libres dans ce système est $5$. Par la proposition 1 on en déduit la dimension maximale de l'espace des solutions du système homogène $AX = 0$." elif r >= 2 and r <= 4: feedback = "Ce n'est pas le nombre maximal de variables libres dans ce système." elif r <= 1: feedback = "Le nombre maximal de variables libres dans ce système ne peut être inférieur à $2$ ($\\text{nb. colonnes} - \\text{nb. lignes}$)." - + correct_text = "C'est correct!
" incorrect_text = "C'est incorrect.
" - + with out: display(Markdown((correct_text if is_correct else incorrect_text) + feedback)) - + button.on_click(callback) - + display(text) display(button) display(out) + def ch4_6ex2(): text = widgets.IntText( description='Réponse :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): out.clear_output() r = text.value - + with out: if r == 2: - display(Markdown("C'est correct!
Le nombre de variables libres est $2$, par la proposition 1 on trouve la dimension de l'espace des solutions.")) + display(Markdown( + "C'est correct!
Le nombre de variables libres est $2$, par la proposition 1 on trouve la dimension de l'espace des solutions.")) else: display(Markdown("C'est incorrect.")) - + button.on_click(callback) - + display(text) display(button) display(out) - + + def ch4_7_8ex3_venn(): ax = plt.gca() r = 5 rd = r / 2 rc = rd * 2 f = 25 a = plt.Circle((-rd, 0), radius=r, color="#fc032c90") b = plt.Circle((rd, 0), radius=r, color="#0377fc90") ax.add_patch(a) ax.add_patch(b) ax.annotate("A", xy=(-rc, 0), fontsize=f, ha='center', va='center') ax.annotate("A ∩ B", xy=(0, 0), fontsize=f, ha='center', va='center') ax.annotate("B", xy=(rc, 0), fontsize=f, ha='center', va='center') plt.axis('scaled') plt.axis('off') plt.show() + def ch4_6ex3(base): base = np.array(base) - + out = widgets.Output() display(out) with out: out.clear_output() feedback = "" is_correct = False - + s = base.shape if len(base) == 0: feedback = "L'ensemble ne peut pas être vide." elif len(s) != 2 or s[1] != 5: feedback = "Le format des vecteurs n'est pas bon." elif s[0] < 2: feedback = "L'ensemble entré ne contient pas assez de vecteurs pour engendrer toutes les solutions du système." elif s[0] > 2: feedback = "L'ensemble entré n'est pas une base." else: expected = np.array(sp.Matrix([[6, 1, -2, 0, 1], [8, 2, -3, 1, 0]]).rref()[0]) actual = np.array(sp.Matrix(base).rref()[0]) - + if not np.array_equal(actual, expected): feedback = "L'ensemble entré n'engendre pas l'espace solution du système." else: is_correct = True - + correct_text = "C'est correct!
" incorrect_text = "C'est incorrect.
" - + display(Markdown((correct_text if is_correct else incorrect_text) + feedback)) + def ch4_7_8ex1(): select = widgets.SelectMultiple( options=['0', '1', '2', '3', '4', '5'], description='Réponse :', disabled=False ) - + button = widgets.Button(description='Vérifier') out = widgets.Output() display(select) display(button) display(out) def verification(e): if len(select.value) > 0: out.clear_output() with out: - other = "
La dimension de l'espace des solutions dépend du nombre de variables libres : dans ce système celle-ci peut être au plus $5-3=2$." - if select.value != ('0', '1', '2'): + other = "
La dimension de l'espace des solutions dépend du nombre de variables libres : " \ + "dans ce système, au moins 2 variables sont libres." + if select.value != ('2', '3', '4', '5'): display(Markdown("C'est incorrect!" + other)) else: display(Markdown("C'est correct." + other)) button.on_click(verification) - + + def ch4_7_8ex2(): text = widgets.IntText(description='Réponse :') button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): out.clear_output() r = text.value - + with out: other = "
En effet, comme la solution de $S_1$ est un plan les deux équations sont dépendantes. La solution de $S_2$ est donc aussi un plan, donc sa dimension est $2$." if r == 2: display(Markdown("C'est correct!" + other)) else: display(Markdown("C'est incorrect." + other)) - + button.on_click(callback) - + display(text) display(button) display(out) def ch4_7_8ex3_cube(name, color): return go.Mesh3d( name=name, x=[-1, -1, 1, 1, -1, -1, 1, 1], y=[-1, 1, 1, -1, -1, 1, 1, -1], z=[-1, -1, -1, -1, 1, 1, 1, 1], i=[7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2], j=[3, 4, 1, 2, 5, 6, 5, 2, 0, 1, 6, 3], k=[0, 7, 2, 3, 6, 7, 1, 1, 5, 5, 7, 6], color=color, opacity=0.25 ) + def ch4_7_8ex3_plane(name, color, variant): ep = 1.25 p1 = ep * np.array([-1, 1, 1, -1]) p2 = ep * np.array([-1, -1, 1, 1]) - pz = np.array([0, 0, 0, 0] if variant == 0 else [0, 0.01, 0.02, 0.03]) # Bug workaround + pz = np.array([0, 0, 0, 0] if variant == 0 else [0, 0.01, 0.02, 0.03]) # Bug workaround ps = list(permutations([p1, p2, pz]))[variant] return go.Mesh3d( name=name, x=ps[0], y=ps[1], z=ps[2], color=color, opacity=0.25 ) + def ch4_7_8ex3_line(name, color, variant): el = 1.5 l1 = [-el, el, None] lz = [0, 0, None] ps = list(permutations([l1, lz, lz]))[variant] return go.Scatter3d( name=name, x=ps[0], y=ps[1], z=ps[2], opacity=0.25, line=dict(color=color, width=4) ) + def ch4_7_8ex3(answer, explanation, plot): text = widgets.IntText(description='Réponse :') button = widgets.Button(description='Vérifier') show = widgets.Button(description='Visualiser') box = widgets.HBox(children=[button, show]) out = widgets.Output() out2 = widgets.Output() - + def callback(e): out.clear_output() r = text.value - + with out: other = "
" + explanation if r == answer: display(Markdown("C'est correct!" + other)) else: display(Markdown("C'est incorrect." + other)) - + def callback2(e): with out2: plot() - + button.on_click(callback) show.on_click(callback2) - + display(text) display(box) display(out) display(out2) + def ch4_7_8ex3a(): - ch4_7_8ex3(2, "$V$ est un sous-ensemble de $W$, donc $\dim (W + V) = \dim W = 2$.", lambda: go.Figure(data=[ch4_7_8ex3_plane('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 0)]).show()) + ch4_7_8ex3(2, "$V$ est un sous-ensemble de $W$, donc $\dim (W + V) = \dim W = 2$.", + lambda: go.Figure(data=[ch4_7_8ex3_plane('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 0)]).show()) + def ch4_7_8ex3b(): - ch4_7_8ex3(3, "$W$ et $V$ sont deux espaces indépendants, donc $\dim (W + V) = \dim W + \dim V = 2 + 1 = 3$.", lambda: go.Figure(data=[ch4_7_8ex3_plane('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 3)]).show()) + ch4_7_8ex3(3, "$W$ et $V$ sont deux espaces indépendants, donc $\dim (W + V) = \dim W + \dim V = 2 + 1 = 3$.", + lambda: go.Figure(data=[ch4_7_8ex3_plane('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 3)]).show()) + def ch4_7_8ex3c(): - ch4_7_8ex3(1, "La somme d'un même espace n'a pas d'effet : $\dim (V + V) = \dim V = 1$.", lambda: go.Figure(data=[ch4_7_8ex3_line('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 0)]).show()) - + ch4_7_8ex3(1, "La somme d'un même espace n'a pas d'effet : $\dim (V + V) = \dim V = 1$.", + lambda: go.Figure(data=[ch4_7_8ex3_line('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 0)]).show()) + + def ch4_7_8ex3d(): - ch4_7_8ex3(2, "$V_1$ et $V_2$ sont deux espaces indépendants, donc $\dim (V_1 + V_2) = \dim V_1 + \dim V_2 = 1 + 1 = 2$.", lambda: go.Figure(data=[ch4_7_8ex3_line('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 2)]).show()) + ch4_7_8ex3(2, + "$V_1$ et $V_2$ sont deux espaces indépendants, donc $\dim (V_1 + V_2) = \dim V_1 + \dim V_2 = 1 + 1 = 2$.", + lambda: go.Figure(data=[ch4_7_8ex3_line('A', 'red', 0), ch4_7_8ex3_line('B', 'blue', 2)]).show()) + def ch4_7_8ex3e(): - ch4_7_8ex3(3, "$\dim (W_1 + W_2) = 2 + 2 - 1 = 3$.", lambda: go.Figure(data=[ch4_7_8ex3_plane('A', 'red', 0), ch4_7_8ex3_plane('B', 'blue', 1)]).show()) - + ch4_7_8ex3(3, "$\dim (W_1 + W_2) = 2 + 2 - 1 = 3$.", + lambda: go.Figure(data=[ch4_7_8ex3_plane('A', 'red', 0), ch4_7_8ex3_plane('B', 'blue', 1)]).show()) + + def ch4_7_8ex3f(): ch4_7_8ex3(3, "$\dim (U + X) = 0 + 3 - 0 = 3$.", lambda: go.Figure(data=[ch4_7_8ex3_cube('B', 'blue')]).show()) - - + + def ch4_9ex1(): r = ['Le rang ligne de 𝐴 est plus petit ou égal à 2 car c\'est un sous-espace vectoriel de ℝ2.', - 'Le rang ligne de 𝐴 est plus petit ou égal à 3 car c\'est un sous-espace vectoriel de ℝ3.', - 'Le rang ligne de 𝐴 est plus petit ou égal à 3 car engendré par 3 vecteurs.', - 'Le rang ligne de 𝐴 est plus petit ou égal à 2 car engendré par 2 vecteurs.', - 'Le rang colonne de A est plus petit ou égal à 2.'] + 'Le rang ligne de 𝐴 est plus petit ou égal à 3 car c\'est un sous-espace vectoriel de ℝ3.', + 'Le rang ligne de 𝐴 est plus petit ou égal à 3 car engendré par 3 vecteurs.', + 'Le rang ligne de 𝐴 est plus petit ou égal à 2 car engendré par 2 vecteurs.', + 'Le rang colonne de A est plus petit ou égal à 2.'] buttons = [] for i in range(5): b = widgets.ToggleButton( value=False, description=r[i], disabled=False, - button_style='', # 'success', 'info', 'warning', 'danger' or '' + button_style='', # 'success', 'info', 'warning', 'danger' or '' tooltip='Description', layout=Layout(width='auto', height='auto') ) buttons.append(b) button = widgets.Button(description='Vérifier', layout=Layout(width='auto', height='auto'), button_style='info' - ) + ) + def callback(e): out.clear_output() - with out: + with out: if (buttons[0].value or buttons[2].value): - print('Mauvaise réponse. \nAttention à ne pas confondre les espaces des lignes et colonnes') + print('Mauvaise réponse. \nAttention à ne pas confondre les espaces des lignes et colonnes') elif (not buttons[1].value) or (not buttons[3].value) or (not buttons[4].value): print('Il manque au moins une réponse.') elif (buttons[1].value and buttons[3].value and buttons[4].value): print('Correct !') buttons.append(button) buttons[5].on_click(callback) - box = VBox(children = buttons) + box = VBox(children=buttons) out = widgets.Output() display(box) display(out) - def ch4_9ex2_1(): text = widgets.IntText( description='Réponse :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() def callback(e): out.clear_output() r = text.value with out: if r == 2: display(Markdown("Correct!")) elif r > 2: display(Markdown("Incorrect, le rang ligne est plus petit.")) else: display(Markdown("Incorrect, le rang ligne est plus grand.")) button.on_click(callback) display(text) display(button) display(out) def ch4_9ex2_2(): options = ['E1', 'E2', 'E3', 'E4'] buttons = [] for i in range(4): b = widgets.ToggleButton( value=False, description=options[i], disabled=False, button_style='', # 'success', 'info', 'warning', 'danger' or '' tooltip='Description' ) buttons.append(b) button = widgets.Button(description='Vérifier', # layout=Layout(width='auto', height='auto'), button_style='info' ) out = widgets.Output() def callback(e): out.clear_output() with out: if buttons[1].value or buttons[2].value or buttons[3].value: display(Markdown("Faux")) elif buttons[0].value: display(Markdown("Correct !")) buttons.append(button) buttons[4].on_click(callback) box = VBox(children=buttons) display(box) display(out) def ch4_9ex2_3(): text = widgets.IntText(description='Réponse :', disabled=False) button = widgets.Button(description='Vérifier') button2 = widgets.Button(description='Solution', disabled=True) box = widgets.HBox(children=[button, button2]) out = widgets.Output() def callback(e): out.clear_output() button2.disabled = False with out: if (text.value == 2): print('Correct !') else: print('Faux, essayez encore ou regardez la solution.') def solution(e): out.clear_output() with out: A = np.array([[1, 2, 3], [0, 1, 2]]) A_t = A.transpose() display(Markdown( 'Pour trouver le rang colonne de $A$, on utilise la remarque 1 et trouve le rang ligne de la transposée de $A$.')) display(Markdown( 'Par les propositions 1 et 2, on échelonne la matrice transposée et on trouve le nombre de lignes contenant des pivots')) M = al.echelonMat('E', A_t) display(Markdown('Ainsi le rang colonne de $A$ est 2.')) button.on_click(callback) button2.on_click(solution) display(text) display(box) display(out) def ch4_10ex1_1(A, b): - A_sol = [[1, 4, 3, 4],[2, 6, 5, 8],[1, 0, 1, 4]] + A_sol = [[1, 4, 3, 4], [2, 6, 5, 8], [1, 0, 1, 4]] b_sol = [[1], [1], [1]] if A == [] or b == []: print("Attention, vous avez laissé au moins une des deux entrée vide") elif not (len(A) == len(b)): print("Les tailles de la matrice et du vecteur ne correspondent pas") else: b = np.reshape(np.array(b), (len(b), 1)).tolist() if A == A_sol: if b == b_sol: print("Correct !") else: print("Le vecteur b est faux, votre reponse correspond au système suivant:") al.printSyst(A, b) elif b == b_sol: print("La Matrice A est fausse, votre reponse correspond au système suivant:") al.printSyst(A, b) else: print("Faux, votre réponse correspond au système suivant:") al.printSyst(A, b) def ch4_10ex1_2_1_ech(): global m display(Latex('Échelonnez la matrice transposée de A')) A_sol = np.array([[1, 4, 3, 4], [2, 6, 5, 8], [1, 0, 1, 4]]) A_sol_t = A_sol.transpose() al.printA(A_sol_t) [i, j, r, alpha] = al.manualEch(A_sol_t) MatriceList = [np.array(A_sol_t)] m = A_sol_t button = widgets.Button(description='Appliquer') out = widgets.Output() def applique(e): global m out.clear_output() with out: m = al.echelonnage(i, j, r, alpha, A_sol_t, m, MatriceList) button.on_click(applique) display(button) display(out) def f_sol(): al.echelonMat('E', A_sol.transpose()) display(Latex("Pour afficher la solution, cliquez-ici.")) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' def ch4_10ex1_2_1(): text_rang = widgets.IntText() box = widgets.VBox([widgets.Label('Rang colonne de A:'), text_rang]) button = widgets.Button(description='Vérifier') out = widgets.Output() def callback(e): out.clear_output() with out: - if(text_rang.value == 2): + if (text_rang.value == 2): display(Latex('Correct !')) else: display(Latex('Faux, essayez encore ou regardez la solution.')) button.on_click(callback) display(box) display(button) display(out) def f_sol(): display(Latex("Le rang colonne de $A$ correspond au nombre de pivot(s) de la forme échelonnée de $A^T$.")) display(Latex("Pour afficher la solution, cliquez-ici.")) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' def ch4_10ex1_2_2(base): base_sol = [[1, 2, 1], [0, 1, 2]] correct = check_basis(base_sol, base) + def f_sol(): display(Latex("Une base de l'espace ligne de $A$ est donnée par les lignes de la forme echelonnée contenant " "un pivots. Pour trouver une base de l'espace colonne $A$, on utilise l'espace ligne de $A^T$.")) display(Latex("Une base de l'espace colone de $A$ est donc:")) print(base_sol) if base_sol == []: display(Latex("L'entrée est vide")) display(Latex("Pour afficher la solution, cliquez-ici.")) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' else: if correct: display(Latex("Correct !")) if base_sol != base: display(Latex("Pour la suite de l'exercice, on utilise la base equivalente suivante:")) print(base_sol) else: display(Latex("Faux")) display(Latex("Pour afficher la solution, cliquez-ici.")) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' def check_basis(sol, prop): """ Checks if prop basis is equivalent to sol basis @param sol: verified basis, 2D numpy array, first dim: vector indexes, second dim: idx of element in a basis vect @param prop: proposed basis @return: boolean """ sol = np.array(sol, dtype=np.float64) prop = np.array(prop, dtype=np.float64) # number of vector in basis n = len(sol) # Check dimension if n != len(prop): return False else: # Check if the sol vector can be written as linear combination of prop vector # Do least squares to solve overdetermined system and check if sol is exact A = np.transpose(prop) lin_comb_ok = np.zeros(n, dtype=bool) for i in range(n): x, _, _, _ = np.linalg.lstsq(A, sol[i], rcond=None) res = np.sum((A @ x - sol[i]) ** 2) lin_comb_ok[i] = res < 10 ** -13 return np.all(lin_comb_ok) def ch4_10ex1_3_ech(): display(Latex("Echelonnez la matrice suivante.")) global m2 A = [[1, 2, 1], [0, 1, 2], [1, 1, 1]] al.printA(A) [i, j, r, alpha] = al.manualEch(A) MatriceList = [np.array(A)] m2 = A button = widgets.Button(description='Appliquer') out = widgets.Output() def callback(e): global m2 out.clear_output() with out: m2 = al.echelonnage(i, j, r, alpha, A, m2, MatriceList) button.on_click(callback) display(button) display(out) def ch4_10ex1_3(): display(Latex("Le système admet-il une solution ?")) radio = widgets.RadioButtons( options=['Oui', 'Non'], description='Réponse:', disabled=False ) button = widgets.Button(description='Vérifier') button2 = widgets.Button(description='Solution', disabled=True) box = widgets.HBox(children=[button, button2]) out = widgets.Output() def callback(e): out.clear_output() button2.disabled = False with out: if (radio.value == "Oui"): print('Mauvaise réponse.') else: print('Correct !') def solution(e): out.clear_output() with out: A = np.array([[1, 2, 1], [0, 1, 2], [0, 0, 1]]) display(Markdown('Après échelonnage, la matrice devient')) al.printA(A) display( Markdown("Ainsi le rang colonne de la matrice augmentée est 3, et le système n'admet pas de solution.")) button2.on_click(solution) button.on_click(callback) display(radio) display(box) display(out) def ch4_10ex1_3_2_ech(): display(Latex("Echelonnez la matrice suivante.")) global m3 A = [[1, 4, 3, 4], [2, 6, 5, 8], [1, 0, 1, 4]] b = [[1], [1], [1]] al.printA(A, b) [i, j, r, alpha] = al.manualEch(A, b) MatriceList = [np.array(A)] RHSList = [np.array(b)] m3 = np.concatenate((A, b), axis=1) button = widgets.Button(description='Appliquer') out = widgets.Output() def callback(e): global m3 out.clear_output() with out: m3 = al.echelonnage(i, j, r, alpha, A, m3, MatriceList, RHSList) button.on_click(callback) display(button) display(out) def ch4_10ex2_1_ech(): global m21 A = [[1, 2, 1], [0, 1, 2], [2, 5, 4]] al.printA(A) [i, j, r, alpha] = al.manualEch(A) MatriceList = [np.array(A)] m21 = A button = widgets.Button(description='Appliquer') out = widgets.Output() def callback(e): global m21 out.clear_output() with out: m21 = al.echelonnage(i, j, r, alpha, A, m21, MatriceList) button.on_click(callback) display(button) display(out) def ch4_10ex2_2(): radio = widgets.RadioButtons( options=['Oui', 'Non'], description='Réponse:', disabled=False ) button = widgets.Button(description='Vérifier') button2 = widgets.Button(description='Solution', disabled=True) box = HBox(children=[button, button2]) out = widgets.Output() def callback(e): out.clear_output() button2.disabled = False with out: if (radio.value == "Oui"): print('Correct !') else: print('Mauvaise réponse.') - def solution(e): out.clear_output() with out: A = np.array([[1, 2, 1], [0, 1, 2], [0, 0, 0]]) display(Markdown('Après échelonnage, la matrice devient')) al.printA(A) display(Markdown( "Ainsi le rang colonne de la matrice augmentée est 2, et d'après le lemme, le système admet une solution.")) button2.on_click(solution) button.on_click(callback) display(radio) display(box) display(out) def ch4_11_plot(base=None, show_grid_lines=False, show_can_base=False, vector_list=[], vector_name_list=[]): - if base is not None: x1 = np.array(base[0]) x2 = np.array(base[1]) n1 = 30 n2 = 20 fig = go.Figure() fig.update_layout(xaxis=dict(range=[-8.5, 8.5], constrain="domain", ), yaxis=dict(range=[-8.5, 8.5], scaleanchor="x", scaleratio=1), showlegend=True) fig.update_xaxes(tick0=0, dtick=2) fig.update_yaxes(tick0=0, dtick=2) if show_grid_lines: grid_x1_x = np.array([[-n1 * x1[0] + i * x2[0] for i in range(-n2, n2)], [n1 * x1[0] + i * x2[0] for i in range(-n2, n2)]]) grid_x1_y = np.array([[-n1 * x1[1] + i * x2[1] for i in range(-n2, n2)], [n1 * x1[1] + i * x2[1] for i in range(-n2, n2)]]) grid_x2_x = np.array([[-n1 * x2[0] + i * x1[0] for i in range(-n2, n2)], [n1 * x2[0] + i * x1[0] for i in range(-n2, n2)]]) grid_x2_y = np.array([[-n1 * x2[1] + i * x1[1] for i in range(-n2, n2)], [n1 * x2[1] + i * x1[1] for i in range(-n2, n2)]]) grid_lines = go.scatter.Line(color='grey', width=0.5) for i in range(2 * n2): fig.add_trace(go.Scatter(x=grid_x1_x[:, i], y=grid_x1_y[:, i], mode='lines', showlegend=False, line=grid_lines)) fig.add_trace(go.Scatter(x=grid_x2_x[:, i], y=grid_x2_y[:, i], mode='lines', showlegend=False, line=grid_lines)) if show_can_base: fig.add_annotation(x=1, # arrows' head y=0, # arrows' head ax=0, # arrows' tail ay=0, # arrows' tail xref='x', yref='y', axref='x', ayref='y', text='', # if you want only the arrow showarrow=True, arrowhead=3, arrowsize=2, arrowwidth=1, arrowcolor='black', ) fig.add_annotation(x=1.3, y=0, text="$x_1$", showarrow=False) fig.add_annotation(x=0, # arrows' head y=1, # arrows' head ax=0, # arrows' tail ay=0, # arrows' tail xref='x', yref='y', axref='x', ayref='y', text='', # if you want only the arrow showarrow=True, arrowhead=3, arrowsize=2, arrowwidth=1, arrowcolor='black' ) fig.add_annotation(x=0, y=1.3, text="$y_1$", showarrow=False) if base is not None: - fig.add_annotation(x=base[0][0], # arrows' head y=base[0][1], # arrows' head ax=0, # arrows' tail ay=0, # arrows' tail xref='x', yref='y', axref='x', ayref='y', text='', # if you want only the arrow showarrow=True, arrowhead=3, arrowsize=2, arrowwidth=1, arrowcolor='blue' ) - fig.add_annotation(x=base[0][0]+0.2, y=base[0][1]+0.2, text="$x_2$", showarrow=False) + fig.add_annotation(x=base[0][0] + 0.2, y=base[0][1] + 0.2, text="$x_2$", showarrow=False) fig.add_annotation(x=base[1][0], # arrows' head y=base[1][1], # arrows' head ax=0, # arrows' tail ay=0, # arrows' tail xref='x', yref='y', axref='x', ayref='y', text='', # if you want only the arrow showarrow=True, arrowhead=3, arrowsize=2, arrowwidth=1, arrowcolor='blue' ) - fig.add_annotation(x=base[1][0]+0.2, y=base[1][1]+0.2, text="$y_2$", showarrow=False) + fig.add_annotation(x=base[1][0] + 0.2, y=base[1][1] + 0.2, text="$y_2$", showarrow=False) color_list = ['red', 'orange', 'grey', 'brown'] for idx, v in enumerate(vector_list): fig.add_trace(go.Scatter(x=[0, v[0]], y=[0, v[1]], mode='lines + markers', showlegend=True, name=vector_name_list[idx], line=dict(color=color_list[idx]), marker=dict(color=color_list[idx]), )) fig.show() return def ch4_11ex1_plot(): ch4_11_plot(base=[[1, 2], [3, 2]], show_can_base=True, show_grid_lines=True, vector_list=[], vector_name_list=[]) return def ch4_11ex1(base): base_solution = [[1, 2], [3, 2]] is_correct = all(item in base_solution for item in base) if is_correct: is_correct = all(item in base for item in base_solution) correct_text = "C'est correct!" incorrect_text = "C'est incorrect." display(correct_text if is_correct else incorrect_text) def ch4_11ex2a_plot(): ch4_11_plot(base=[[1, 2], [3, 2]], show_can_base=True, show_grid_lines=True, vector_list=[[5, 6]], vector_name_list=['v']) return + def ch4_11ex2aB1(vB1): v = [5, 6] if vB1 == v: is_correct = 1 else: is_correct = 0 correct_text = "C'est correct!" incorrect_text = "C'est incorrect." display(correct_text if is_correct else incorrect_text) def ch4_11ex2aB2(vB2): v = [2, 1] if vB2 == v: is_correct = 1 else: is_correct = 0 correct_text = "C'est correct!" incorrect_text = "C'est incorrect." display(correct_text if is_correct else incorrect_text) def ch4_11ex2b_plot(): ch4_11_plot(base=[[1, 2], [3, 2]], show_can_base=True, show_grid_lines=True, vector_list=[[8, 4]], vector_name_list=['u']) return def ch4_11ex2bB1(uB1): u = [8, 4] if uB1 == u: is_correct = 1 else: is_correct = 0 correct_text = "C'est correct!" incorrect_text = "C'est incorrect." display(correct_text if is_correct else incorrect_text) def ch4_11ex2bB2(uB2): u = [-1, 3] if uB2 == u: is_correct = 1 else: is_correct = 0 correct_text = "C'est correct!" incorrect_text = "C'est incorrect." display(correct_text if is_correct else incorrect_text) def ch4_11ex2c_plot(): ch4_11_plot(base=[[1, 2], [3, 2]], show_can_base=True, show_grid_lines=True, vector_list=[[5, 4]], vector_name_list=['w']) return def ch4_11ex2cB1(wB1): w = [5, 4] if wB1 == w: is_correct = 1 else: is_correct = 0 - + correct_text = "C'est correct!" incorrect_text = "C'est incorrect." - + display(correct_text if is_correct else incorrect_text) def ch4_11ex2cB2(wB2): w = [0.5, 1.5] - - if wB2==w: + + if wB2 == w: is_correct = 1 else: is_correct = 0 - + correct_text = "C'est correct!" incorrect_text = "C'est incorrect." - + display(correct_text if is_correct else incorrect_text) def ch4_11ex3B1(sB1): - s = [13,10] - - if sB1==s: + s = [13, 10] + + if sB1 == s: is_correct = 1 else: is_correct = 0 - + correct_text = "C'est correct!" incorrect_text = "C'est incorrect." - + display(correct_text if is_correct else incorrect_text) def ch4_11ex3B2(sB2): - s = [1,4] - - if sB2==s: + s = [1, 4] + + if sB2 == s: is_correct = 1 else: is_correct = 0 - + correct_text = "C'est correct!" incorrect_text = "C'est incorrect." - + display(correct_text if is_correct else incorrect_text) def ch4_12ex1(): style = {'description_width': 'initial'} nbr_ligne = widgets.IntText( description='Nombre de lignes : \n', disabled=False, style=style ) nbr_colonne = widgets.IntText( description='Nombre de colonnes : \n', disabled=False, style=style ) - + button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): out.clear_output() r_l = nbr_ligne.value r_c = nbr_colonne.value with out: if r_l == 5 and r_c == 6: display(Markdown("C'est correct!")) else: display(Markdown("C'est incorrect.")) - + button.on_click(callback) - + display(nbr_ligne) display(nbr_colonne) display(button) display(out) def ch4_12ex2(): text = widgets.IntText( description='Réponse :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): out.clear_output() r = text.value - + with out: if r == 2: display(Markdown("C'est correct!")) else: display(Markdown("C'est incorrect.")) - + button.on_click(callback) - + display(text) display(button) display(out) def ch4_12ex3a(): text = widgets.IntText( description='Réponse :', disabled=False ) button = widgets.Button(description='Vérifier') out = widgets.Output() - + def callback(e): out.clear_output() r = text.value - + with out: if r == 3: display(Markdown("C'est correct!")) else: display(Markdown("C'est incorrect.")) - + button.on_click(callback) - + display(text) display(button) display(out) def ch4_12ex3b(base): base = base + [[1, 4, 0, 2, 0, 1], [0, 1, 1, 2, 1, 0], [0, 0, 1, 3, 3, 2]] base = np.array(base) out = widgets.Output() display(out) with out: out.clear_output() feedback = "" is_correct = False s = base.shape if len(base) == 0: feedback = "Les vecteurs nuls ne peuvent pas ." elif len(s) != 2 or s[1] != 6: feedback = "Le format des vecteurs n'est pas bon." elif s[0] < 6: feedback = "L'ensemble entré ne contient pas assez de vecteurs pour engendrer toutes les solutions du système." elif s[0] > 6: feedback = "L'ensemble entré contient trop de vecteurs pour être une famille libre." else: expected = np.array(sp.Matrix( [[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1]]).rref()[0]) actual = np.array(sp.Matrix(base).rref()[0]) if not np.array_equal(actual, expected): feedback = "L'ensemble entré n'engendre pas l'espace solution du système." else: is_correct = True correct_text = "C'est correct!
" incorrect_text = "C'est incorrect.
" display(Markdown((correct_text if is_correct else incorrect_text) + feedback))