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 5e29319..55f3b1f 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,1199 +1,1199 @@
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 A.shape[0]!=2 or A.shape[1]!=2:
raise ValueError("A should be a 2 by 2 numpy array")
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."))
if np.allclose(A @ A.transpose(), np.eye(2)):
display(Latex("La matrice $A = " + al.texMatrix(A) + "$ est une matrice orthogonale." ))
else:
display(Latex("La matrice $A = " + al.texMatrix(A) + "$ n'est pas une matrice orthogonale." ))
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'approximations numériques, "
"toutes les valeurs doivent être exactes. Pour les racines carrées "
"(utiles pour normaliser les vecteurs), utilisez 'sqrt('votre valeur')', ex: sqrt(2)."))
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 et rappelée plus haut"))
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."))
im = interact_manual(correction_ortho_diag)
im.widget.children[0].description = 'Solution'
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'
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)
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$ admet une ou des racine(s) non réelle(s). "
"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("On voit que l'espace $V = \mathbb{R}^3$ possède une base othornormée composée de vecteurs propres de $A$. "
"La transformation associée à la matrice $A$ est donc orthogonalement diagonalisable et $A$ est donc 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 ex_3_1_10_4():
l_1 = 2
l_2 = -1
v_1 = sp.Matrix([1, -1])
display(Latex("Trouver une matrice $A \in M_{2 \\times 2} (\mathbb{R})$ symétrique ayant pour valeurs propres 2 "
"et -1 et $" + latexp(v_1) + "$ comme vecteur propres associé à $\lambda = 2$."))
default_value_A = str(np.ones((2, 2), dtype=np.int16).tolist())
answer = widgets.Text(value=default_value_A, description='A: ', disabled=False, display='flex')
display(answer)
def f():
A = eval(answer.value)
A = sp.Matrix(A)
if A.shape[0] != 2 or A.shape[1] != 2:
display(Latex("Incorrect, la matrice doit être carrée et 2x2."))
return
if sp.simplify(A - A.transpose()) != sp.zeros(2):
display(Latex("Incorrect, la matrice n'est pas symétrique !"))
return
eig = A.eigenvals()
eig_list = list(eig.keys())
if l_1 not in eig_list or l_2 not in eig_list:
if l_1 not in eig_list:
display(Latex("Incorrect, 2 n'est pas une valeur propre de la matrice rentrée."))
if l_2 not in eig_list:
display(Latex("Incorrect, -1 n'est pas une valeur propre de la matrice rentrée."))
return
A_v = A*v_1
if sp.simplify(A_v - l_1 * v_1) != sp.zeros(2, 1):
display(Latex("Incorrect, le vecteur $" + latexp(v1) + "$ n'est pas un vecteur propre de $A$ associé à "
"la valeur propre $\lambda = 2$."))
return
display(Latex("Correct !"))
interact_manual(f)
def f_sol():
display(Latex("On utilise la formule $A=PDP^T$ pour constuire la matrice symetrique $A$. $P$ est une matrice "
"orthogonale composée de vecteurs propres de $A$ et $D$ est une matrice diagonale avec les valeurs"
" propres de $A$ sur la diagonale. "))
D = sp.Matrix([[2, 0],[0, -1]])
display(Latex("On construit simplement la matrice $D =" + latexp(D) + "$"))
v_2 = sp.Matrix([1, 1])
display(Latex("On ne dispose pas d'informations sur les vecteurs propres associés à $\lambda = -1$. "
"Mais pour obtenir une matrice symétrique on sait que $P$ est orthogonale, "
"donc il faut trouver un vecteur propre orthogonal à $" + latexp(v_1) + "$. Simplement, on prend $" + latexp(v_2) + "$."))
display(Latex("On normalise les deux vecteurs propres orthogonaux et on forme les colonnes de $P$. "
"Chaque vecteur est placé dans la même colonne que sa valeur propre correspondante dans $D$."))
P = sp.Matrix([[1, 1], [-1, 1]])/sp.sqrt(2)
display(Latex("On obtient $P = " + latexp(P) + "$."))
A = P*D*P.transpose()
display(Latex("$A = P D P^T = " + latexp(P) + latexp(D) + latexp(P.transpose()) + "=" + latexp(A) +"$"))
display(Latex("Pour afficher la solution détaillée, cliquez ici."))
im = interact_manual(f_sol)
im.widget.children[0].description = 'Solution'
def ch10_7_ex_1_1():
x1, x2, x3, x4 = sp.symbols("x_1 x_2 x_3 x_4")
Q = x1**2 - 5*x1*x2 + x1*x3 - x1*x4 + 4*x2**2 + 2*x2*x3 - 4*x2*x4 + x3**2 + x3*x4 - x4**2
sol = "Oui"
display(Latex("Le polynôme $Q = " + sp.latex(Q) + "$ est-il une forme quadratique ?"))
answer = widgets.RadioButtons(options=["Oui", "Non"], description="Réponse : ", disabled=False)
display(answer)
def f():
if answer.value == sol:
display(Latex("Correct ! "))
display(Latex("Le polynôme $Q = "+ sp.latex(Q) + "$ est une forme quadratique car "
"il contient uniquement des termes d'ordre 2."))
else:
display(Latex("Incorrect, changez votre réponse."))
interact_manual(f)
def ch10_7_ex_1_2():
x1, x2, x3 = sp.symbols("x_1 x_2 x_3")
Q = (x1 + x2)**2 + (x3 - 1)**2
sol = "Non"
display(Latex("Le polynôme $Q = " + sp.latex(Q) + "$ est-il une forme quadratique ?"))
answer = widgets.RadioButtons(options=["Oui", "Non"], description="Réponse : ", disabled=False)
display(answer)
def f():
if answer.value == sol:
display(Latex("Correct ! "))
display(Latex("Le polynôme $Q = " + sp.latex(Q) + "$ n'est pas une forme quadratique car "
"il ne contient pas uniquement des termes d'ordre 2."))
display(Latex("On peut developper $Q$ pour expliciter l'ordre de chaque terme."))
display(Latex("$$ Q = " + sp.latex(Q.expand()) + "$$"))
else:
display(Latex("Incorrect, changez votre réponse."))
interact_manual(f)
def ch10_7_ex_1_3():
x1, x2, x3 = sp.symbols("x_1 x_2 x_3")
Q = 3 * x1 ** 2 + x1 * x2 + x2 ** 2 + 2 * x2 * x3 - x1 * x3 + x3 ** 3
sol = "Non"
display(Latex("Le polynôme $Q = " + sp.latex(Q) + "$ est-il une forme quadratique ?"))
answer = widgets.RadioButtons(options=["Oui", "Non"], description="Réponse : ", disabled=False)
display(answer)
def f():
if answer.value == sol:
display(Latex("Correct ! "))
display(Latex("Le polynôme $Q = " + sp.latex(Q) + "$ n'est pas une forme quadratique car "
"il ne contient pas uniquement des termes d'ordre 2."))
else:
display(Latex("Incorrect, changez votre réponse."))
interact_manual(f)
def ch10_7_ex_2(n):
x1, x2, x3, x4, x5 = sp.symbols("x_1 x_2 x_3 x_4 x_5")
x_list = [sp.Matrix([x1, x2]), sp.Matrix([x1, x2, x3]), sp.Matrix([x1, x2, x3, x4])]
A1 = sp.Matrix([[-2, 3], [3, 4]])
A2 = sp.Matrix([[1, 0, 3], [0, -2, -1/4], [3, -1/4, 4]])
A3 = sp.Matrix([[-1, -1, 3, 0],
[-1, -2, 0, 4],
[3, 0, 0, -1],
[0, 4, -1, 2]])
A_list = [A1, A2, A3]
A = A_list[n-1]
x = x_list[n-1]
Q = x.dot(A * x).expand()
display(Latex("Rentrez la matrice symétrique $A$ telle que $\mathbf{x}^T A \mathbf{x} = Q(\mathbf{x})$ "
"avec $\mathbf{x} = " + latexp(x) + "$"))
display(Latex("où $Q(\mathbf{x}) = " + sp.latex(Q) + "$"))
default_value_A = str(np.ones(A.shape, dtype=np.int16).tolist())
answer = widgets.Text(value=default_value_A, description='A = ', disabled=False,
layout=widgets.Layout(width='600px'))
display(answer)
def f():
A_user = eval(answer.value)
A_user = sp.Matrix(A_user)
display(Latex("Vous avez rentré la matrice $A_{user} = " + latexp(A_user) + "$"))
if A_user.shape != A.shape:
display(Latex("Incorrect, la matrice $A$ n'a pas les bonnes dimensions."))
return
if sp.simplify(A_user - A_user.transpose()) != sp.zeros(A.shape[0]):
display(Latex("Incorrect, la matrice rentrée n'est pas symétrique. "))
return
Q_user = x.dot(A_user * x).expand()
if sp.simplify(Q_user - Q) == 0:
display(Latex("Correct !"))
else:
display(Latex("Incorrect, avec votre matrice on obtient $ Q_{user}(\mathbf{x}) = "
+ sp.latex(Q_user) + "\\neq Q(\mathbf{x}) $"))
interact_manual(f)
def f_sol():
display(Latex("La matrice $A = " + latexp(A) + "$ est telle que $Q(\mathbf{x}) = \mathbf{x}^T A \mathbf{x} $"))
display(Latex("Pour afficher la solution, cliquez ici."))
im = interact_manual(f_sol)
im.widget.children[0].description = 'Solution'
def plot_quad(A, n_points=50j, lims=2):
A_sp = sp.Matrix(A)
eig = A_sp.eigenvects()
# Create list with principal axis
p_axis = []
for x in eig:
v_list = sp.GramSchmidt(x[2], orthonormal=True)
for v in v_list:
p_axis.append(np.array(v).astype(np.float64).flatten())
A = np.array(A)
if A.shape == (3, 3):
X, Y, Z = np.mgrid[-lims:lims:n_points, -lims:lims:n_points, -lims:lims:n_points]
# ellipsoid
values = A[0, 0] * X * X + A[1, 1] * Y * Y + A[2, 2] * Z * Z + (A[0, 1]+A[1, 0])* X * Y + (A[0, 2] + A[2, 0]) * X * Z + (A[1, 2] + A[1, 2]) * Y * Z
layout = go.Layout(scene=go.layout.Scene(aspectmode="cube"))
fig = go.Figure(data=go.Isosurface(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
isomin=1,
isomax=1,
showscale=False,
opacity=0.5,
caps=dict(x_show=False, y_show=False),
showlegend=True,
name='Quadrique'
),
layout=layout)
fig.add_trace(go.Scatter3d(x=[0, p_axis[0][0]],
y=[0, p_axis[0][1]],
z=[0, p_axis[0][2]],
line=dict(width=2, color='black'),
mode='lines+markers',
marker=dict(size=3),
showlegend=True,
name='Axes principaux',
))
fig.add_trace(go.Scatter3d(x=[0, p_axis[1][0]],
y=[0, p_axis[1][1]],
z=[0, p_axis[1][2]],
line=dict(width=2, color='black'),
mode='lines+markers',
marker=dict(size=3),
showlegend=False,
name='Principal axis 2',
))
fig.add_trace(go.Scatter3d(x=[0, p_axis[2][0]],
y=[0, p_axis[2][1]],
z=[0, p_axis[2][2]],
mode='lines+markers',
line=dict(width=2, color='black'),
marker=dict(size=3),
showlegend=False,
name='Principal axis 3',
))
elif A.shape == (2, 2):
X, Y = np.mgrid[-lims:lims:n_points, -lims:lims:n_points]
Z = A[0, 0] * X * X + A[1, 1] * Y * Y + (A[1, 0] + A[0, 1]) * X * Y
fig = go.Figure(data=go.Contour(
x=X[:, 0],
y=Y[0, :],
z=Z,
contours=dict(start=1, end=1),
contours_coloring='lines',
line_width=2,
opacity=0.5,
showscale=False, showlegend=True,
name='Quadrique'),
)
fig.update_layout(xaxis=dict(range=[-lims, lims], constrain="domain",), yaxis = dict(scaleanchor= "x", scaleratio = 1,))
fig.add_trace(go.Scatter(x=[0, p_axis[0][0]],
- y=[0, p_axis[0][1]],
- mode='lines+markers',
- line=dict(width=2, color='black'),
- marker=dict(size=3),
- showlegend=True,
- name='Axes principaux',
- ))
+ y=[0, p_axis[0][1]],
+ mode='lines+markers',
+ line=dict(width=2, color='black'),
+ marker=dict(size=3),
+ showlegend=True,
+ name='Axes principaux',
+ ))
fig.add_trace(go.Scatter(x=[0, p_axis[1][0]],
y=[0, p_axis[1][1]],
mode='lines+markers',
line=dict(width=2, color='black'),
marker=dict(size=3),
showlegend=False,
name = 'Principal axis 2',
))
else:
return
fig.show()
def ex1_10_8(n):
A_list = [sp.Matrix([[5, 2], [2, 5]]), sp.Matrix([[3, 2, 0], [2, 0, 0], [0, 0, 2]])]
x1, x2, x3 = sp.symbols("x_1 x_2 x_3")
x_list = [sp.Matrix([x1, x2]), sp.Matrix([x1, x2, x3])]
A = A_list[n-1]
x = x_list[n-1]
Q = x.dot(A * x).expand()
display(Latex("$Q(x) = " + sp.latex(Q) + "$"))
display(Latex("Donnez les coefficients $d_1, ..., d_n$ et la matrice $S$ de changement de variable tel "
"que $x = Sy$. "))
default_value_d = str(np.ones(A.shape[0], dtype=np.int16).tolist())
default_value_S = str(np.ones(A.shape, dtype=np.int16).tolist())
answer_d = widgets.Text(value=default_value_d, description='d = ', disabled=False,
layout=widgets.Layout(width='600px'))
answer_S = widgets.Text(value=default_value_S, description='S = ', disabled=False,
layout=widgets.Layout(width='600px'))
display(answer_d)
display(answer_S)
def f():
d_user = eval(answer_d.value)
d_user = np.array(d_user, dtype=np.int16)
D_user = np.diag(d_user)
D_user = sp.Matrix(D_user)
S_user = eval(answer_S.value)
S_user = sp.Matrix(S_user)
display(Latex("Vous avez rentré la matrice suivante: $S_{user} = " + latexp(S_user) + "$"))
A_user = S_user * D_user * S_user.transpose()
if sp.simplify(A-A_user) == sp.zeros(A.shape[0]):
display(Latex("Correct !"))
else:
display(Latex("Incorrect."))
interact_manual(f)
def f_sol():
display(Latex("On commence par trouver la matrice symétrique $A$ telle que $Q(x) = x^T A x$ avec "
"$x = " + latexp(x) + "$."))
display(Latex("Par identification, on trouve $A = " + latexp(A) + "$."))
display(Latex("Ensuite, l'exercice consiste simplement à diagonaliser orthogonalement la matrice symétrique "
"$A$."))
display(Latex("En effet, si on a $D = S^T A S$, avec $D$ diagonale, en effectuant le changement de variable "
"$x = Sy$, on obtient : " + nl() + " $Q(x) = x^T A x = (Sy)^T A (Sy) = y^T S^T A S y = y^T D y = "
"d_1 y_1^2 + d_2 y_2^2 + ... + d_n y_n^2 $ "))
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 = A.eigenvals()
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 all ints
if np.all(v == np.round(v)):
v = v.astype(np.int16)
# if there is some float
else:
for idx, el in enumerate(v):
v = sp.Matrix(v)
q = sp.Rational(el)
# If rational are not too high and weird
if abs(q.numerator()) < 100 and abs(q.denominator()) < 100:
v[idx] = q
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 $S$ 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 $S$."))
D = sp.zeros(A.shape[0])
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 $S = " + latexp(P) + "\hspace{5mm} \mbox{et} \hspace{5mm} D = " + latexp(D) + "$"))
display(Latex("On vérifie le résultat par un calcul :"))
display(Latex(
"$S D S^T = " + latexp(P) + latexp(D) + latexp(P.transpose()) + " = " + latexp(P * D * P.transpose()) +
"=A$"))
display(Latex("Pour afficher la solution, cliquez ici."))
im = interact_manual(f_sol)
im.widget.children[0].description = 'Solution'
def f_plot():
A_np = np.array(A, dtype=np.float64)
plot_quad(A_np)
if A.shape[0]==2 or A.shape[0]==3:
display(Latex("Pour visualiser la quadrique associée et les axes principaux, cliquez ici"))
im = interact_manual(f_plot)
im.widget.children[0].description = 'Plot'
\ No newline at end of file
diff --git "a/Chapitre 4 - Bases et dimension/4.11. Coordonn\303\251es par rapport \303\240 une base.ipynb" "b/Chapitre 4 - Bases et dimension/4.11. Coordonn\303\251es par rapport \303\240 une base.ipynb"
index 5e59aaf..335d8a1 100644
--- "a/Chapitre 4 - Bases et dimension/4.11. Coordonn\303\251es par rapport \303\240 une base.ipynb"
+++ "b/Chapitre 4 - Bases et dimension/4.11. Coordonn\303\251es par rapport \303\240 une base.ipynb"
@@ -1,302 +1,305 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from Ch4Functions import *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Concept(s)-clé(s)\n",
"\n",
"### DÉFINITION 1 :\n",
- "Soient $V$ un $\\mathbb{R}$ -espace vectoriel de dimension finie $n, \\mathscr{B}=\\left(v_{1}, \\ldots, v_{n}\\right)$ une base ordonnée de $V$ et $v \\in V$. Comme $\\mathscr{B}$ est une base de $V,$ il existe des uniques scalaires $\\alpha_{1}, \\ldots, \\alpha_{n} \\in \\mathbb{R}$ tels que $v=\\alpha_{1} v_{1}+\\cdots+\\alpha_{n} v_{n} .$ On appelle $\\alpha_{1}, \\ldots, \\alpha_{n}$ les coordonnées de $v$ par rapport $\\dot{a}$ la base $\\mathscr{B}$ et on écrit\n",
+ "Soient $V$ un $\\mathbb{R}$-espace vectoriel de dimension finie $n, \\mathscr{B}=\\left(v_{1}, \\ldots, v_{n}\\right)$ une base ordonnée de $V$ et $v \\in V$. Comme $\\mathscr{B}$ est une base de $V,$ il existe des uniques scalaires $\\alpha_{1}, \\ldots, \\alpha_{n} \\in \\mathbb{R}$ tels que $v=\\alpha_{1} v_{1}+\\cdots+\\alpha_{n} v_{n} .$ On appelle $\\alpha_{1}, \\ldots, \\alpha_{n}$ les coordonnées de $v$ par rapport $\\dot{a}$ la base $\\mathscr{B}$ et on écrit\n",
"$$\n",
"[v]_{\\mathscr{B}}=\\left(\\begin{array}{c}\n",
"\\alpha_{1} \\\\\n",
"\\alpha_{2} \\\\\n",
"\\vdots \\\\\n",
"\\alpha_{n}\n",
"\\end{array}\\right)\n",
"$$\n",
"\n",
"### PROPOSITION 2 :\n",
"Soient $V$ un $\\mathbb{R}$-espace vectoriel de dimension finie $n$ et $\\mathscr{B}=\\left(v_{1}, \\ldots, v_{n}\\right)$ une base ordonnée de $V$. Alors les deux affirmations suivantes sont vérifiées.\n",
"1. Pour tous $v_{1}, v_{2} \\in V,$ on a $\\left[v_{1}+v_{2}\\right]_{\\mathscr{B}}=\\left[v_{1}\\right]_{\\mathscr{B}}+\\left[v_{2}\\right]_{\\mathscr{B}}$\n",
"2. Pour tout $v \\in V$ et tout $\\lambda \\in \\mathbb{R},$ on a $[\\lambda v]_{\\mathscr{B}}=\\lambda[v]_{\\mathscr{B}}$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercice 1:\n",
"\n",
- "Soit $\\mathbb{R}^2$ l'espace du plan. La base la plus évidente de cet espace vectoriel est la base orthonormée $\\mathscr{B} = \\left\\{\\left(\\begin{array}{l}1 \\\\ 0 \\end{array}\\right),\\left(\\begin{array}{l}0 \\\\ 1 \\end{array}\\right)\\right\\}$. Cette base est représentée dans le graphique suivant."
+ "Soit $\\mathbb{R}^2$ l'espace du plan. La base la plus évidente de cet espace vectoriel est la base canonique $\\mathscr{B} = \\left\\{\\left(\\begin{array}{l}1 \\\\ 0 \\end{array}\\right), \\left(\\begin{array}{l}0 \\\\ 1 \\end{array}\\right)\\right\\}$. Cette base est représentée dans le graphique suivant."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
- "#ici un graph pas distordu (graph 1)"
+ "ch4_11_plot(show_can_base=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Quelle base de $\\mathbb{R}^2$ est représentée ci-dessous?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
- "#ici un graph avec grille distordue (graph 2)"
+ "ch4_11ex1_plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les vecteurs qui forment la base réprésentée ci-dessus\n",
"# Par exemple : [[1, 2], [3, 4]]\n",
- "base = [[-2,1],[4,1]]\n",
+ "base = [[0, 0],[0, 0]]\n",
"\n",
"ch4_11ex1(base)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercice 2\n",
"\n",
- "a) Soit le vecteur $\\textbf{v}$ représenté dans le graph suivant, $\\mathscr{B}_1$ la base orthonormée de $\\mathbb{R}^2$ et $\\mathscr{B}_2 = ((1,2),(3,2))$. Quelles sont les coordonnées de de $\\textbf{v}$ dans $\\mathscr{B}_1$? "
+ "a) Soit le vecteur $\\textbf{v}$ représenté dans le graph suivant, $\\mathscr{B}_1$ la base canonique de $\\mathbb{R}^2$ et $\\mathscr{B}_2 = \\left\\{\\left(\\begin{array}{l}1 \\\\ 2 \\end{array}\\right),\\left(\\begin{array}{l}3 \\\\ 2 \\end{array}\\right)\\right\\}$. Quelles sont les coordonnées de de $\\textbf{v}$ dans $\\mathscr{B}_1$? "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
- "#ici graph avec v desssus (graph 3)"
+ "#ici graph avec v desssus (graph 3)\n",
+ "ch4_11ex2a_plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur v dans la base B1\n",
"# Par exemple : [1,2]\n",
- "vB1 = [5,6]\n",
+ "vB1 = [0, 0]\n",
"\n",
"ch4_11ex2aB1(vB1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Et dans $\\mathscr{B}_2$?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur v dans la base B2\n",
"# Par exemple : [1,2]\n",
- "vB2 = [2,1]\n",
+ "vB2 = [0, 0]\n",
"\n",
"ch4_11ex2aB2(vB2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"b) Avec les mêmes bases, quelles sont les coordonnées du vecteur $\\textbf{u}$ dans $\\mathscr{B}_1$?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
- "#ici graph avec u desssus (graph 4)"
+ "#ici graph avec u desssus (graph 4)\n",
+ "ch4_11ex2b_plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur u dans la base B1\n",
"# Par exemple : [1,2]\n",
- "uB1 = [8,4]\n",
+ "uB1 = [0, 0]\n",
"\n",
"ch4_11ex2bB1(uB1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Et dans $\\mathscr{B}_2$?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur u dans la base B2\n",
"# Par exemple : [1,2]\n",
- "uB2 = [-1,3]\n",
+ "uB2 = [0, 0]\n",
"\n",
"ch4_11ex2bB2(uB2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"c) Toujours avec les mêmes bases, quelles sont les coordonnées du vecteur $\\textbf{w}$ dans $\\mathscr{B}_1$?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
- "#ici graph avec w desssus (graph 5)"
+ "#ici graph avec w desssus (graph 5)\n",
+ "ch4_11ex2c_plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur w dans la base B1\n",
"# Par exemple : [1,2]\n",
- "wB1 = [5,4]\n",
+ "wB1 = [0, 0]\n",
"\n",
"ch4_11ex2cB1(wB1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Et dans $\\mathscr{B}_2$?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur w dans la base B2\n",
"# Par exemple : [1,2]\n",
- "wB2 = [.5,1.5]\n",
+ "wB2 = [0, 0]\n",
"\n",
"ch4_11ex2cB2(wB2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercice 3\n",
"\n",
- "Considérons maintenant le vecteur $\\textbf{s}$ tel que $\\textbf{s} = \\textbf{v}+\\textbf{u}$. A l'aide de la proposition 2 et de l'exerciceprécédent, déduire les coordonnées de $\\textbf{s}$ dans $\\mathscr{B}_1$."
+ "Considérons maintenant le vecteur $\\textbf{s}$ tel que $\\textbf{s} = \\textbf{v}+\\textbf{u}$. A l'aide de la proposition 2 et de l'exercice précédent, déduire les coordonnées de $\\textbf{s}$ dans $\\mathscr{B}_1$."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur s dans la base B1\n",
"# Par exemple : [1,2]\n",
- "sB1 = [13,10]\n",
+ "sB1 = [0, 0]\n",
"\n",
"ch4_11ex3B1(sB1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Et dans $\\mathscr{B}_2$?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Entrez les coordonnées du vecteur s dans la base B2\n",
"# Par exemple : [1,2]\n",
- "sB2 = [1,4]\n",
+ "sB2 = [0, 0]\n",
"\n",
"ch4_11ex3B2(sB2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"[Passez au notebook du chapitre 4.12. Trouver une base à partir d'un système générateur](./4.12.%20Trouver%20une%20base%20%C3%A0%20partir%20d'un%20syst%C3%A8me%20g%C3%A9n%C3%A9rateur.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 e7f31eb..789a587 100644
--- a/Chapitre 4 - Bases et dimension/Ch4Functions.py
+++ b/Chapitre 4 - Bases et dimension/Ch4Functions.py
@@ -1,1257 +1,1404 @@
import sys
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])))
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)
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$."))
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']):
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)
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]
out.clear_output()
with out:
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 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]
out.clear_output()
with out:
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."))
elif len(answer) > 3:
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 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."))
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'):
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
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())
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())
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())
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())
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())
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.']
buttons = []
for i in range(5):
b = widgets.ToggleButton(
value=False,
description=r[i],
disabled=False,
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:
if (buttons[0].value or buttons[2].value):
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)
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]]
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):
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[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)
+
+ 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]
+ w = [0.5, 1.5]
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:
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:
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))