Page MenuHomec4science

Ch4Functions.py
No OneTemporary

File Metadata

Created
Fri, May 3, 21:48

Ch4Functions.py

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!<br />%s" % reason))
else:
display(Markdown("C'est incorrect!<br />%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!<br />La solution entrée ne permet pas d'engendrer $\mathbb{R}^3$."))
elif len(answer) > 3:
display(Markdown("C'est incorrect!<br />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!<br />La solution entrée contient des vecteurs qui sont dépendants."))
else: # Correct
display(Markdown("C'est correct!<br />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!<br />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!<br />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!<br />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!<br />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!<br />"
incorrect_text = "C'est incorrect.<br />"
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!<br />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!<br />"
incorrect_text = "C'est incorrect.<br />"
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 = "<br>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 = "<br />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 = "<br />" + 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]
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!<br />"
incorrect_text = "C'est incorrect.<br />"
display(Markdown((correct_text if is_correct else incorrect_text) + feedback))

Event Timeline