Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F63115940
Ch10_lib.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, May 17, 21:19
Size
17 KB
Mime Type
text/x-python
Expires
Sun, May 19, 21:19 (2 d)
Engine
blob
Format
Raw Data
Handle
17733816
Attached To
rJNAL Jupyter notebooks for Linear Algebra
Ch10_lib.py
View Options
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
def
points_on_circle
(
n
,
center
=
np
.
array
([
0
,
0
])):
theta
=
2
*
np
.
pi
/
n
s_pts
=
np
.
zeros
((
n
,
2
))
e_pts
=
np
.
zeros
((
n
,
2
))
for
i
in
range
(
n
):
s_pts
[
i
]
=
[
np
.
cos
(
i
*
theta
)
+
center
[
0
],
np
.
sin
(
i
*
theta
)
+
center
[
1
]]
e_pts
[
i
]
=
[
np
.
cos
((
i
+
1
)
*
theta
)
+
center
[
0
],
np
.
sin
((
i
+
1
)
*
theta
)
+
center
[
1
]]
return
np
.
array
(
s_pts
),
np
.
array
(
e_pts
)
def
plot_geom_2D
(
s_pts
,
e_pts
,
A
):
n
=
len
(
s_pts
)
if
n
!=
len
(
e_pts
):
raise
ValueError
(
"start_points and end_points must have same length."
)
layout
=
go
.
Layout
(
yaxis
=
dict
(
scaleanchor
=
"x"
,
scaleratio
=
1
))
display
(
Latex
(
"On montre la transformation provoquée par la multiplication par la matrice $A = "
+
al
.
texMatrix
(
A
)
+
"$ sur une figure géométrique."
))
fig
=
go
.
Figure
(
layout
=
layout
)
color
=
[
'black'
,
'red'
,
'blue'
,
'green'
,
'yellow'
,
'brown'
,
'grey'
,
'cyan'
,
'orange'
,
'violet'
]
n_col
=
len
(
color
)
if
n
>
n_col
:
color
=
[
'blue'
]
n_col
=
1
for
i
in
range
(
n
):
a
=
np
.
array
(
s_pts
[
i
])
b
=
np
.
array
(
e_pts
[
i
])
a2
=
A
@
a
b2
=
A
@
b
if
i
==
0
:
show_legend
=
True
else
:
show_legend
=
False
fig
.
add_trace
(
go
.
Scatter
(
x
=
[
a
[
0
],
b
[
0
]],
y
=
[
a
[
1
],
b
[
1
]],
line
=
dict
(
color
=
color
[
i
%
n_col
],
width
=
2
),
mode
=
'lines+markers'
,
showlegend
=
show_legend
,
name
=
'Original Figure'
))
fig
.
add_trace
(
go
.
Scatter
(
x
=
[
a2
[
0
],
b2
[
0
]],
y
=
[
a2
[
1
],
b2
[
1
]],
line
=
dict
(
color
=
color
[
i
%
n_col
],
width
=
2
,
dash
=
'dot'
),
mode
=
'lines+markers'
,
showlegend
=
show_legend
,
name
=
'Modified Figure'
))
fig
.
show
()
def
is_orthogonal
(
A
):
A
=
sp
.
Matrix
(
A
)
n
=
A
.
shape
[
0
]
if
n
!=
A
.
shape
[
1
]:
raise
ValueError
(
"A should be a square matrix"
)
display
(
Latex
(
"On cherche à savoir si la matrice $A = "
+
latexp
(
A
)
+
"$ est orthogonale en utilisant la "
+
"définition 1."
))
if
A
.
is_lower
or
A
.
is_upper
:
for
i
in
range
(
n
):
if
A
[
i
,
i
]
!=
1
and
A
[
i
,
i
]
!=
-
1
:
display
(
Latex
(
"Les valeurs propres de $A$ sont ses éléments diagonaux. Une des valeurs propres de "
+
"$A$ est différente de 1 ou -1. Il existe donc un vecteur propres $v$ de $A$ tel "
+
" que $A v = \lambda v$ avec $\lambda
\\
neq \pm 1$. Donc dans ce cas on a $\|A v\| "
+
"
\\
neq \|v\| $."
))
return
v
=
sp
.
zeros
(
n
,
1
)
for
i
in
range
(
n
):
symb_name
=
"x_"
+
str
(
i
+
1
)
v
[
i
]
=
sp
.
symbols
(
symb_name
,
real
=
True
)
b
=
A
*
v
b_norm
=
b
.
norm
()
**
2
v_norm
=
v
.
norm
()
**
2
display
(
Latex
(
"Il faut vérifier si $\|A v\| = \|v\|$ pour tout $v \in \mathbb{R}^"
+
str
(
n
)
+
"$."
+
" On utilise le carré des normes pour s'affranchir des racines carrées."
))
display
(
Latex
(
"On calcule d'abord la norme au carré de $v$ et on obtient: $\|v\|^2 = "
+
sp
.
latex
(
v_norm
)
+
"$."
))
display
(
Latex
(
"On calcule ensuite le produit $Av = "
+
latexp
(
b
)
+
"$"
))
if
sp
.
simplify
(
b_norm
)
!=
b_norm
:
display
(
Latex
(
"On calcule la norme au carré de $Av$ et on obtient: $\|Av\|^2 = "
+
sp
.
latex
(
b_norm
)
+
"="
+
sp
.
latex
(
sp
.
simplify
(
b_norm
))
+
"$"
))
else
:
display
(
Latex
(
"On calcule la norme au carré de $Av$ et on obtient: $\|Av\|^2 = "
+
sp
.
latex
(
b_norm
)
+
"$"
))
if
sp
.
simplify
(
b_norm
-
v_norm
)
==
0
:
display
(
Latex
(
"Les normes sont toujours égales. La matrice est donc orthogonale."
))
else
:
display
(
Latex
(
"Les normes sont différente. La matrice n'est donc pas orthogonale."
))
def
interactive_is_orthogonal
(
A
):
A
=
sp
.
Matrix
(
A
)
n
=
A
.
shape
[
0
]
if
n
!=
A
.
shape
[
1
]:
raise
ValueError
(
"A should be a square matrix"
)
display
(
Latex
(
"La matrice suivante est-elle orthogonale ? $A = "
+
latexp
(
A
)
+
"$"
))
answer
=
widgets
.
RadioButtons
(
options
=
[
"Oui"
,
"Non"
],
description
=
"Réponse: "
,
disabled
=
False
)
sol
=
A
.
transpose
()
*
A
-
sp
.
eye
(
n
)
==
sp
.
zeros
(
n
)
display
(
answer
)
def
f
():
if
answer
.
value
==
"Oui"
:
answer_bool
=
True
else
:
answer_bool
=
False
if
answer_bool
==
sol
:
display
(
Latex
(
"Correct !"
))
else
:
display
(
Latex
(
"Incorrect"
))
interact_manual
(
f
)
display
(
Latex
(
"Si vous n'arrivez pas à trouver la solution, vous pouvez afficher la solution détaillée en"
" cliquant ici"
))
def
f_sol
():
is_orthogonal
(
A
)
im
=
interact_manual
(
f_sol
)
im
.
widget
.
children
[
0
]
.
description
=
'Solution'
def
ortho_diag
(
A
):
A
=
sp
.
Matrix
(
A
)
n
=
A
.
shape
[
0
]
if
A
-
A
.
transpose
()
!=
sp
.
zeros
(
n
):
display
(
Latex
(
"La matrice $A = "
+
latexp
(
A
)
+
"$ n'est pas orthogonalement diagonalisable car elle n'est pas "
"symétrique."
))
return
eig
=
A
.
eigenvals
()
eig_list
=
list
(
eig
.
keys
())
eig_list
.
sort
()
display
(
Latex
(
"On cherche à diagonaliser orthogonalement la matrice $ A = "
+
latexp
(
A
)
+
"$."
))
default_value_P
=
str
(
np
.
ones
(
A
.
shape
,
dtype
=
np
.
int16
)
.
tolist
())
default_value_P
=
default_value_P
.
replace
(
"],"
,
"],
\n
"
)
default_value_D
=
str
(
np
.
ones
(
A
.
shape
[
0
],
dtype
=
np
.
int16
)
.
tolist
())
answer_P
=
widgets
.
Text
(
value
=
default_value_P
,
description
=
'P: '
,
disabled
=
False
)
answer_D
=
widgets
.
Text
(
value
=
default_value_D
,
description
=
'D: '
,
disabled
=
False
)
display
(
Latex
(
"Pour les réponses aux questions suivantes, ne faites pas d'approximation numériques, "
"toutes les valeurs doivent être exactes. Pour les racines carrées "
"(utiles pour normaliser les vecteurs), utilisez 'sqrt('votre valeur')'."
))
display
(
Latex
(
"Donnez les éléments diagonaux de la matrice $D$"
))
display
(
answer_D
)
display
(
Latex
(
"Donnez la matrice P permettant de diagonaliser orthogonalement la matrice $A$ de sorte que "
"$ A = PDP^T = PDP^{-1} $"
))
display
(
answer_P
)
def
f
():
P_user
=
eval
(
answer_P
.
value
)
P_user
=
sp
.
Matrix
(
P_user
)
D_diag
=
eval
(
answer_D
.
value
)
D_diag_order
=
set
(
D_diag
.
copy
())
D_diag_order
=
list
(
D_diag_order
)
D_diag_order
.
sort
()
D_user
=
sp
.
zeros
(
n
)
for
i
in
range
(
n
):
D_user
[
i
,
i
]
=
D_diag
[
i
]
D_user
=
sp
.
Matrix
(
D_user
)
if
np
.
allclose
(
np
.
array
(
D_diag_order
,
dtype
=
np
.
float64
),
np
.
array
(
eig_list
,
dtype
=
np
.
float64
)):
if
P_user
*
P_user
.
transpose
()
-
sp
.
eye
(
n
)
==
sp
.
zeros
(
n
):
if
P_user
*
D_user
*
P_user
.
transpose
()
-
A
==
sp
.
zeros
(
n
):
display
(
Latex
(
"Correct !"
))
else
:
display
(
Latex
(
"Incorrect. On a $PDP^{T}
\\
neq A$ avec $P = "
+
latexp
(
P_user
)
+
"$ et $D ="
+
latexp
(
D_user
)
+
"$."
))
else
:
display
(
Latex
(
"La matrice $P = "
+
latexp
(
P_user
)
+
"$ n'est pas orthogonale, i.e. $P P^{T}
\\
neq I$."
))
else
:
display
(
Latex
(
"Incorrect. "
"Les éléments diagonaux de $D$ ne correspondent pas aux valeurs propres de la matrice $A$."
))
return
interact_manual
(
f
)
def
correction_ortho_diag
():
display
(
Latex
(
"Pour diagonaliser orthogonalement une matrice, on a applique la méthode donnée dans le cours:"
))
display
(
Markdown
(
"**Méthode**. Soit $A \in M_{n
\\
times n}(\mathbb{R})$ symétrique. Soit $\mathcal{C}$ la base canonique de $\mathbb{R}^{n}$ "
+
nl
()
+
"(1) Cherchons le polynôme caractéristique $c_{A}(t)$"
+
nl
()
+
"(2) Trouver toutes les racines distinctes $\lambda_{1}, \ldots, \lambda_{r} \in \mathbb{R}$ de $c_{A}(t)$ t.q. $c_{A}(t)=\pm\left(t-\lambda_{1}
\\
right)^{m_{1}} \cdots\left(t-\lambda_{r}
\\
right)^{m_{r}}$"
+
nl
()
+
"(3) Pour chaque $i,$ trouver une base $\mathcal{B}_{i}$ de $E_{\lambda_{i}}$"
+
nl
()
+
"(4) On sait que pour $v \in \mathcal{B}_{i}, w \in \mathcal{B}_{j}, i
\\
neq j, v \cdot w=0$"
+
nl
()
+
"(5) Pour chaque $i$, utiliser Gram-Schmidt pour trouver une base orthonormée $\mathcal{B}_{i}^{\prime}$ de $E_{\lambda_{i}}$"
+
nl
()
+
"(6) $\mathcal{B}^{\prime}=\mathcal{B}_{1}^{\prime} \cup \cdots \cup \mathcal{B}_{r}^{\prime}$ est une base orthonormée de $V$"
+
nl
()
+
"(7) $P=[
\\
text { id }]_{C \mathcal{B}^{\prime}}$ est orthogonale et $P^{T} A P=P^{-1} A P$ est diagonale."
))
lamda
=
sp
.
symbols
(
'lamda'
)
poly_char_exp
=
sp
.
expand
(
A
.
charpoly
(
lamda
)
.
as_expr
())
poly_char_fac
=
sp
.
factor
(
A
.
charpoly
(
lamda
)
.
as_expr
())
poly_char_exp_str
=
sp
.
latex
(
poly_char_exp
)
poly_char_fac_str
=
sp
.
latex
(
poly_char_fac
)
display
(
Latex
(
"Le polynôme caractéristique de $A$ s'exprime comme: $c_A (t) = "
+
poly_char_exp_str
+
"$."
))
display
(
Latex
(
"On trouve les racines du polynôme caractéristique et on factorise. On obtient $c_A (t) = "
+
poly_char_fac_str
+
"$."
))
eig_list_
=
list
(
eig
.
keys
())
mult_list_
=
list
(
eig
.
values
())
display
(
Latex
(
"On obtient donc les valeurs propres $\lambda$ et leur multiplicité respective $m$: "
" $ \lambda = "
+
sp
.
latex
(
eig_list_
)
+
" \hspace{10mm} m = "
+
sp
.
latex
(
mult_list_
)
+
"$."
))
display
(
Markdown
(
"**On trouve une base orthonormée pour tous les espaces propres.**"
))
final_basis
=
[]
P
=
sp
.
Matrix
([])
k
=
0
for
l
in
eig_list_
:
basis_orthonorm
=
[]
basis
,
basic_idx
,
free_idx
=
eigen_basis
(
A
,
l
,
prop_basis
=
None
,
disp
=
True
,
return_
=
True
,
dispA
=
False
)
for
v
in
basis
:
if
np
.
all
(
v
==
np
.
round
(
v
)):
v
=
v
.
astype
(
np
.
int16
)
basis_orthonorm
.
append
(
sp
.
Matrix
(
v
))
basis_orthonorm
=
sp
.
GramSchmidt
(
basis_orthonorm
,
True
)
for
v
in
basis_orthonorm
:
final_basis
.
append
(
v
)
P
=
P
.
col_insert
(
k
,
v
)
k
+=
1
display
(
Latex
(
"On applique le procédé de Gram-Schmidt pour obtenir des vecteurs de norme 1 et orthogonaux. "
"On obtient $"
+
sp
.
latex
(
basis_orthonorm
)
+
"$"
))
display
(
Latex
(
"Finalement, on construit la matrice $P$ en utilisant chaque vecteur de base "
"trouvé précedemment comme colonne de cette matrice. Cette dernière est bien orthogonale car "
"les vecteurs de base sont orthogonaux entre eux et tous de norme unitaire."
"On construit la matrice $D$ en plaçant les valeurs propres de $A$ sur la diagonale. "
"Le placement des valeurs propres sur la diagonale de $D$"
"doit correspondre avec celui des vecteurs propres dans $P$."
))
D
=
sp
.
zeros
(
n
)
i
=
0
for
idx
in
range
(
len
(
eig_list_
)):
for
_
in
range
(
mult_list_
[
idx
]):
D
[
i
,
i
]
=
eig_list_
[
idx
]
i
+=
1
display
(
Latex
(
"On obtient $P = "
+
latexp
(
P
)
+
"\hspace{5mm} \mbox{et} \hspace{5mm} D = "
+
latexp
(
D
)
+
"$"
))
display
(
Latex
(
"On vérifie le résultat par un calcul:"
))
display
(
Latex
(
"$P D P^T = "
+
latexp
(
P
)
+
latexp
(
D
)
+
latexp
(
P
.
transpose
())
+
" = "
+
latexp
(
P
*
D
*
P
.
transpose
())
+
"=A$"
))
display
(
Latex
(
"Si vous n'arrivez pas à résoudre l'exercice, vous pouvez afficher la solution étape "
"par étape en cliquant ici."
))
interact_manual
(
correction_ortho_diag
)
def
nl
():
return
"$$ $$"
def
sol_is_ortho
(
A
):
A
=
sp
.
Matrix
(
A
)
n
=
A
.
shape
[
0
]
if
n
!=
A
.
shape
[
1
]:
display
(
Latex
(
"La matrice $A = "
+
latexp
(
A
)
+
"$ n'est pas carrée !"
))
return
display
(
Latex
(
"Pour vérifier si la matrice $A$ est orthogonale, on effectue dans cette correction "
"le produit de $A$ et de sa transposée $A^T$."
" On vérifie ensuite si l'on obtient la matrice identité."
))
if
sp
.
simplify
(
A
*
A
.
transpose
()
-
sp
.
eye
(
n
))
==
sp
.
zeros
(
n
):
display
(
Latex
(
"On a que: $A A^T = "
+
latexp
(
A
)
+
latexp
(
A
.
transpose
())
+
"= "
+
latexp
(
sp
.
eye
(
n
))
+
"= I_n $"
))
display
(
Latex
(
"La matrice $A$ est donc orthogonale."
))
else
:
display
(
Latex
(
"On a que: $A A^T = "
+
latexp
(
A
)
+
latexp
(
A
.
transpose
())
+
"
\\
neq I_n $"
))
display
(
Latex
(
"Par consequent, la matrice $A$ n'est pas orthogonale."
))
return
def
is_ortho_10_2
(
A
):
A
=
sp
.
Matrix
(
A
)
n
=
A
.
shape
[
0
]
display
(
Latex
(
"La matrice $A ="
+
latexp
(
A
)
+
"$ est-elle orthogonale ?"
))
answer
=
widgets
.
RadioButtons
(
options
=
[
"Oui"
,
"Non"
],
description
=
"Réponse: "
,
disabled
=
False
)
display
(
answer
)
sol
=
sp
.
simplify
(
A
*
A
.
transpose
()
-
sp
.
eye
(
n
))
==
sp
.
zeros
(
n
)
if
n
!=
A
.
shape
[
1
]:
sol
=
False
def
f
():
if
answer
.
value
==
"Oui"
:
answer_bool
=
True
else
:
answer_bool
=
False
if
answer_bool
==
sol
:
display
(
Latex
(
"Correct !"
))
else
:
display
(
Latex
(
"Incorrect"
))
if
sol
:
display
(
Latex
(
"La matrice $A$ est orthogonale."
))
else
:
display
(
Latex
(
"La matrice $A$ n'est pas orthogonale."
))
interact_manual
(
f
)
def
f_sol
():
sol_is_ortho
(
A
)
display
(
Latex
(
"Pour afficher la solution, cliquez-ici."
))
im
=
interact_manual
(
f_sol
)
im
.
widget
.
children
[
0
]
.
description
=
'Solution'
# Vrai faux
def
vf
(
sol
):
"""
:param sol: (bool) solution au vrai faux
:return: bool si réponse juste (vrai) ou non (faux)
"""
answer
=
widgets
.
RadioButtons
(
options
=
[
"Vrai"
,
"Faux"
],
description
=
"Réponse: "
,
disabled
=
False
)
def
vf_10_2_2
():
display
(
Latex
(
"Soit $A \in M_{n
\\
times n}(\mathbb{R})$ une matrice orthogonale. On construit la matrice"
" $B \in M_{n
\\
times n}(\mathbb{R})$ en réarrangeant les colonnes de $A$ dans un ordre quelquonque. "
"La matrice $B$ est aussi orthogonale."
))
answer
=
widgets
.
RadioButtons
(
options
=
[
"Vrai"
,
"Faux"
],
description
=
"Réponse: "
,
disabled
=
False
)
display
(
answer
)
def
f
():
if
answer
.
value
==
"Vrai"
:
display
(
Latex
(
"Correct ! En effet, si l'ordre des colonnes est modifié, l'ensemble de ces dernières reste "
"toujours une base orthonormée de l'espace $V$. "
"La proposition (5) est donc vérifiée pour la matrice $B$."
))
else
:
display
(
Latex
(
"Incorrect, changez votre réponse !"
))
interact_manual
(
f
)
def
vf_10_2_3
():
display
(
Latex
(
"Soit $A \in M_{n
\\
times n}(\mathbb{R})$ une matrice orthogonale. On construit la matrice"
" $B \in M_{n
\\
times n}(\mathbb{R})$ en réarrangeant les lignes de $A$ dans un ordre quelquonque. "
"La matrice $B$ est aussi orthogonale."
))
answer
=
widgets
.
RadioButtons
(
options
=
[
"Vrai"
,
"Faux"
],
description
=
"Réponse: "
,
disabled
=
False
)
display
(
answer
)
def
f
():
if
answer
.
value
==
"Vrai"
:
display
(
Latex
(
"Correct ! En effet, si l'ordre des lignes est modifié, l'ensemble de ces dernières reste "
"toujours une base orthonormée de l'espace $V$. "
"La proposition (4) est donc vérifiée pour la matrice $B$."
))
else
:
display
(
Latex
(
"Incorrect, changez votre réponse !"
))
interact_manual
(
f
)
def
vf_10_2_1
():
display
(
Latex
(
"Soit $A \in M_{n
\\
times n}(\mathbb{R})$ une matrice orthogonale. $A^T$ est aussi orthogonale."
))
answer
=
widgets
.
RadioButtons
(
options
=
[
"Vrai"
,
"Faux"
],
description
=
"Réponse: "
,
disabled
=
False
)
display
(
answer
)
def
f
():
if
answer
.
value
==
"Vrai"
:
display
(
Latex
(
"Correct ! En effet, comme $A$ est orthogonale, on sait que ses colonnes forment "
"une base orthonormée de l'espace $V$. Comme les lignes de $A^T$ sont les colonnes de $A$, "
"alors la proposition (4) est vérifiée pour $A^T$, i.e. les lignes de $A^T$ forment une base "
"orthonormée de $V$. $A^T$ est donc une matrice orthogonale."
))
else
:
display
(
Latex
(
"Incorrect, changez votre réponse !"
))
interact_manual
(
f
)
def
vf_10_2_4
():
display
(
Latex
(
"Soit $A \in M_{n
\\
times n}(\mathbb{R})$ une matrice ayant une valeur propre $\lambda = 2$. "
"Il est possible que $A$ soit orthogonale."
))
answer
=
widgets
.
RadioButtons
(
options
=
[
"Vrai"
,
"Faux"
],
description
=
"Réponse: "
,
disabled
=
False
)
display
(
answer
)
def
f
():
if
answer
.
value
==
"Faux"
:
display
(
Latex
(
"Correct ! Etant donné que $A$ a pour valeur propre $\lambda=2$, cela signifique qu'il existe "
"un vecteur $v$ tel que $A v = 2 v$. Donc la matrice $A$ ne conserve pas toujours les longeurs lors "
"d'une multiplication avec un vecteur. La proposition (1) n'est pas vérifiée."
" $A$ ne peut donc pas être orthogonale."
))
else
:
display
(
Latex
(
"Incorrect, changez votre réponse !"
))
interact_manual
(
f
)
Event Timeline
Log In to Comment