diff --git a/.gitignore b/.gitignore index 2bde8ed..1a6e77c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ */.ipynb_checkpoints/*.ipynb */.ipynb_checkpoints/*.py *.pyc *.iml *.xml - +.DS_Store diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Ch7Functions.py" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Ch7Functions.py" index a909cc0..431f968 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Ch7Functions.py" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Ch7Functions.py" @@ -1,1187 +1,1313 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ """ # Import the necessaries libraries # Set notebook mode to work in offline from __future__ import division import numpy as np from IPython.display import display, Latex, display_latex, Markdown import plotly import plotly.graph_objs as go import matplotlib.pylab as plt from matplotlib.patches import Polygon from matplotlib.collections import PolyCollection import plotly.offline as pyo import plotly.graph_objs as go import ipywidgets as widgets from ipywidgets import interact, interactive, fixed, interact_manual, Layout, HBox, VBox from sympy import S plotly.offline.init_notebook_mode(connected=True) from IPython.core.magic import register_cell_magic from IPython.display import HTML import ipywidgets as widgets import random from ipywidgets import interact_manual, Layout import sympy as sp @register_cell_magic def bgc(color): script = ( "var cell = this.closest('.jp-CodeCell');" "var editor = cell.querySelector('.jp-Editor');" "editor.style.background='{}';" "this.parentNode.removeChild(this)" ).format(color) display(HTML(''.format(script))) ############################################################################### + +def latexp(A): + """ + Function to output latex expression of a sympy matrix but with round parenthesis + @param A: sympy matrix + @return: latex string + """ + return sp.latex(A, mat_delim='(', mat_str='matrix') + + ## Chapter 7.1 def red_matrix(A, i, j): """ Return reduced matrix (without row i and col j)""" row = [0, 1, 2] col = [0, 1, 2] - row.remove(i-1) - col.remove(j-1) + row.remove(i - 1) + col.remove(j - 1) return A[row, col] -def pl_mi(i,j, first=False): +def pl_mi(i, j, first=False): """ Return '+', '-' depending on row and col index""" - if (-1)**(i+j)>0: + if (-1) ** (i + j) > 0: if first: return "" else: return "+" else: return "-" def brackets(expr): """Takes a sympy expression, determine if it needs parenthesis and returns a string containing latex of expr with or without the parenthesis.""" expr_latex = sp.latex(expr) if '+' in expr_latex or '-' in expr_latex: return "(" + expr_latex + ")" else: return expr_latex -def ch7ex(matrix): +def ch7_1_ex1(matrix): + if len(matrix.free_symbols) == 1: + x = list(matrix.free_symbols)[0] + + det_answer = widgets.Text(value='0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante $" + latexp(matrix) + "$.")) + display(det_answer) + + def check_det(): + det = matrix.det() + + answer = sp.sympify(det_answer.value) + if sp.simplify(answer-det).is_zero: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + button = widgets.Button(description='Solution', disabled=False) box = HBox(children=[button]) out = widgets.Output() - @out.capture() - + def solution(e): out.clear_output() - Determinant_3x3(matrix, step_by_step=True) - + Determinant_3x3(matrix, step_by_step=True) + button.on_click(solution) - + display(box) display(out) - - + + def Determinant_3x3(A, step_by_step=True, row=True, n=1): """ Step by step computation of the determinant of a 3x3 sympy matrix starting with given row/col number :param A: 3 by 3 sympy matrix :param step_by_step: Boolean, True: print step by step derivation of det, False: print only determinant :param row: True to compute determinant from row n, False to compute determinant from col n :param n: row or col number to compute the determinant from (int between 1 and 3) :return: display step by step solution for """ - if A.shape!=(3,3): + if A.shape != (3, 3): raise ValueError('Dimension of matrix A should be 3x3. The input A must be a sp.Matrix of shape (3,3).') - if n<1 or n>3 or not isinstance(n, int): + if n < 1 or n > 3 or not isinstance(n, int): raise ValueError('n should be an integer between 1 and 3.') - + # Construct string for determinant of matrix A - detA_s = sp.latex(A).replace('[','|').replace(']','|') - + detA_s = sp.latex(A).replace('[', '|').replace(']', '|') + # To print all the steps if step_by_step: # If we compute the determinant with row n if row: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, n, 1) A2 = red_matrix(A, n, 2) A3 = red_matrix(A, n, 3) - detA1_s = sp.latex(A1).replace('[','|').replace(']','|') - detA2_s = sp.latex(A2).replace('[','|').replace(']','|') - detA3_s = sp.latex(A3).replace('[','|').replace(']','|') + detA1_s = sp.latex(A1).replace('[', '|').replace(']', '|') + detA2_s = sp.latex(A2).replace('[', '|').replace(']', '|') + detA3_s = sp.latex(A3).replace('[', '|').replace(']', '|') - line1 = "$" + detA_s + ' = ' + pl_mi(n,1, True) + sp.latex(A[n-1, 0]) + detA1_s + pl_mi(n,2) + \ - sp.latex(A[n-1, 1]) + detA2_s + pl_mi(n,3) + sp.latex(A[n-1, 2]) + detA3_s + '$' + line1 = "$" + detA_s + ' = ' + pl_mi(n, 1, True) + sp.latex(A[n - 1, 0]) + detA1_s + pl_mi(n, 2) + \ + sp.latex(A[n - 1, 1]) + detA2_s + pl_mi(n, 3) + sp.latex(A[n - 1, 2]) + detA3_s + '$' - line2 = '$' + detA_s + ' = ' + pl_mi(n,1, True) + sp.latex(A[n-1, 0]) + "\cdot (" + sp.latex(sp.det(A1)) \ - +")" + pl_mi(n,2) + sp.latex(A[n-1, 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")"+ \ - pl_mi(n,3) + sp.latex(A[n-1, 2]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' + line2 = '$' + detA_s + ' = ' + pl_mi(n, 1, True) + sp.latex(A[n - 1, 0]) + "\cdot (" + sp.latex(sp.det(A1)) \ + + ")" + pl_mi(n, 2) + sp.latex(A[n - 1, 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")" + \ + pl_mi(n, 3) + sp.latex(A[n - 1, 2]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # If we compute the determinant with col n else: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, 1, n) A2 = red_matrix(A, 2, n) A3 = red_matrix(A, 3, n) - detA1_s = sp.latex(A1).replace('[','|').replace(']','|') - detA2_s = sp.latex(A2).replace('[','|').replace(']','|') - detA3_s = sp.latex(A3).replace('[','|').replace(']','|') + detA1_s = sp.latex(A1).replace('[', '|').replace(']', '|') + detA2_s = sp.latex(A2).replace('[', '|').replace(']', '|') + detA3_s = sp.latex(A3).replace('[', '|').replace(']', '|') - line1 = "$" + detA_s + ' = ' + pl_mi(n,1, True) + brackets(A[0, n-1]) + detA1_s + pl_mi(n,2) + \ - brackets(A[1, n-1]) + detA2_s + pl_mi(n,3) + brackets(A[2, n-1]) + detA3_s + '$' + line1 = "$" + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[0, n - 1]) + detA1_s + pl_mi(n, 2) + \ + brackets(A[1, n - 1]) + detA2_s + pl_mi(n, 3) + brackets(A[2, n - 1]) + detA3_s + '$' - line2 = '$' + detA_s + ' = ' + pl_mi(n,1, True) + brackets(A[0, n-1]) + "\cdot (" + sp.latex(sp.det(A1))\ - +")" + pl_mi(n,2) + brackets(A[1, n-1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")"+ \ - pl_mi(n,3) + brackets(A[2, n-1]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' + line2 = '$' + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[0, n - 1]) + "\cdot (" + sp.latex(sp.det(A1)) \ + + ")" + pl_mi(n, 2) + brackets(A[1, n - 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")" + \ + pl_mi(n, 3) + brackets(A[2, n - 1]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # Display step by step computation of determinant display(Latex(line1)) display(Latex(line2)) display(Latex(line3)) # Only print the determinant without any step else: display(Latex("$" + detA_s + "=" + sp.latex(sp.det(A)) + "$")) -def ch7ex3(matrix): - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) + +def ch7_1_ex2(matrix): + if len(matrix.free_symbols) == 1: + x = list(matrix.free_symbols)[0] + + det_answer = widgets.Text(value='0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante $" + latexp(matrix) + "$.")) + display(det_answer) + + def check_det(): + det = matrix.det() + + answer = sp.sympify(det_answer.value) + if sp.simplify(answer-det).is_zero: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) out = widgets.Output() - @out.capture() - + def solution(e): out.clear_output() - Sarrus_3x3(matrix) - + Sarrus_3x3(matrix) + button.on_click(solution) - + display(box) - display(out) - - - - + display(out) + + def Sarrus_3x3(A): - if A.shape!=(3,3): + """ + Function that develop the determinant of a 3x3 matrix with the Sarrus Rule + CAREFUL, THE FUNCTION WILL RETURN A INCORRECT EXPRESSION IF USED WITH A MATRIX WITH A COEFFICIENT WITH MULTIPLE TERMS + SUCH AS 1 + x, THE FUNCTION WILL NOT ADD PARENTHESIS + :param A: 3 by 3 sympy matrix + :return: + """ + if A.shape != (3, 3): raise ValueError('Dimension of matrix A should be 3x3. The input A must be a sp.Matrix of shape (3,3).') - + x = sp.symbols('x') + if len(A.free_symbols) == 1: + x = list(A.free_symbols)[0] + # Construct string for determinant of matrix A - detA_s = sp.latex(A).replace('[','|').replace(']','|') - - A11 = sp.latex(A[0,0]); A12 = sp.latex(A[0,1]); A13 = sp.latex(A[0,2]) - A21 = sp.latex(A[1,0]); A22 = sp.latex(A[1,1]); A23 = sp.latex(A[1,2]) - A31 = sp.latex(A[2,0]); A32 = sp.latex(A[2,1]); A33 = sp.latex(A[2,2]) - + detA_s = sp.latex(A).replace('[', '|').replace(']', '|') + + A11 = sp.latex(A[0, 0]) + A12 = sp.latex(A[0, 1]) + A13 = sp.latex(A[0, 2]) + A21 = sp.latex(A[1, 0]) + A22 = sp.latex(A[1, 1]) + A23 = sp.latex(A[1, 2]) + A31 = sp.latex(A[2, 0]) + A32 = sp.latex(A[2, 1]) + A33 = sp.latex(A[2, 2]) + x1 = '(' + A11 + '\cdot ' + A22 + '\cdot ' + A33 + ')' x2 = '(' + A12 + '\cdot ' + A23 + '\cdot ' + A31 + ')' x3 = '(' + A13 + '\cdot ' + A21 + '\cdot ' + A32 + ')' - + y1 = '(' + A13 + '\cdot ' + A22 + '\cdot ' + A31 + ')' y2 = '(' + A11 + '\cdot ' + A23 + '\cdot ' + A32 + ')' y3 = '(' + A12 + '\cdot ' + A21 + '\cdot ' + A33 + ')' - - prod1 = A[0,0] * A[1,1] * A[2,2] - prod2 = A[0,1] * A[1,2] * A[2,0] - prod3 = A[0,2] * A[1,0] * A[2,1] - - prod4 = A[0,2] * A[1,1] * A[2,0] - prod5 = A[0,0] * A[1,2] * A[2,1] - prod6 = A[0,1] * A[1,0] * A[2,2] - - def cplus(ex): - # Function to return the correct sign to print after a plus - if sp.simplify(ex) < 0: - string = " " - else: - string = "+" - return string - - def cminus(ex): - # Function to return the correct sing to print after a plus - if sp.simplify(ex) < 0: - string = " " - else: - string = "-" - return string - display(Latex('$' + detA_s + ' = ' + x1 + "+" + x2 + "+" + x3 + "-" + y1 + "-" + y2 + "-" + y3 + '$' )) + # prod1 = A[0, 0] * A[1, 1] * A[2, 2] + # prod2 = A[0, 1] * A[1, 2] * A[2, 0] + # prod3 = A[0, 2] * A[1, 0] * A[2, 1] + # + # prod4 = A[0, 2] * A[1, 1] * A[2, 0] + # prod5 = A[0, 0] * A[1, 2] * A[2, 1] + # prod6 = A[0, 1] * A[1, 0] * A[2, 2] + # + # y = sp.symbols('y', positive=True) + + # def cplus(ex): + # # Function to return the correct sign to print after a plus + # if sp.simplify(ex.replace(x, y)) < 0: + # string = " " + # else: + # string = "+" + # return string + # + # def cminus(ex): + # # Function to return the correct sing to print after a plus + # if sp.simplify(ex.replace(x, y)) < 0: + # string = " " + # else: + # string = "-" + # return string + + display(Latex('$' + detA_s + ' = ' + x1 + "+" + x2 + "+" + x3 + "-" + y1 + "-" + y2 + "-" + y3 + '$')) + + # Commenting those line because there not very useful to understand everything + # I'm not 100% sure the printed developments are correct in all case + # display(Latex('$' + detA_s + ' = ' + sp.latex(sp.simplify(prod1)) + cplus(prod2) + sp.latex(sp.simplify(prod2)) + cplus(prod3) + sp.latex(sp.simplify(prod3)) + " - [" + sp.latex(sp.simplify(prod4)) + cplus(prod5) + sp.latex(sp.simplify(prod5)) + cplus(prod6) + sp.latex(sp.simplify(prod6)) + '] $')) + # display(Latex('$' + detA_s + ' = ' + sp.latex(sp.simplify(prod1 + prod2 + prod3)) + cminus(prod4 + prod5 + prod6) + sp.latex(sp.simplify(prod4 + prod5 + prod6)) + '$')) - display(Latex('$' + detA_s + ' = ' + sp.latex(sp.simplify(prod1)) + cplus(prod2) + sp.latex(sp.simplify(prod2)) + cplus(prod3) \ - + sp.latex(sp.simplify(prod3)) + " - [" + sp.latex(sp.simplify(prod4)) + cplus(prod5) + \ - sp.latex(sp.simplify(prod5)) + cplus(prod6) + sp.latex(sp.simplify(prod6)) + '] $')) - display(Latex('$' + detA_s + ' = ' + sp.latex(sp.simplify(prod1+prod2+prod3)) + cminus(prod4+prod5 +prod6) \ - + sp.latex(sp.simplify(prod4+prod5+prod6)) + '$')) - display(Latex('$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$')) - + + ## 7.2 +def ch_7_2_ex1(M): + ch7_1_ex1(M) -def question7_2(reponse): - A = sp.Matrix([[4,6,-3], [-1,2,3], [4, -5, 1]]) - - if np.abs(reponse - sp.det(A)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - out.clear_output() - Determinant_3x3(A, step_by_step = True) - - button.on_click(solution) - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse. Utilisez cette réponse pour les prochaines questions.")) -def question7_2a(reponse): +def question7_2a(): a = sp.Matrix([[4, -1, 4], [6, 2, -5], [-3, 3, 1]]) - - if np.abs(reponse - sp.det(a)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - display(Markdown("Dans ce cas, cette matrice est la transposée de A. Les déterminants sont égaux.")) - out.clear_output() - Determinant_3x3(a, step_by_step = True) - - button.on_click(solution) - - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse")) - -def question7_2b(reponse): + + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante: $ " + latexp(a) + " $. ")) + display(Markdown("*Aidez-vous du déterminant de la matrice $M$ et des propositions données plus haut.*")) + display(det_answer) + + def check_det(): + det = a.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(e): + display(Markdown("Dans ce cas, cette matrice est la transposée de $M$. Les déterminants sont donc égaux.")) + display(Markdown(" $\det A = \det M = 155$")) + + button.on_click(solution) + + display(box) + + +def question7_2b(): b = sp.Matrix([[4, 6, -3], [7, 14, -3], [4, -5, 1]]) - - if np.abs(reponse - sp.det(b)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - display(Markdown("Dans ce cas, la première rangée a été multiplié par deux et elle a été ajouté à la deuxième rangée")) - display(Latex("$ Soit: 2 \\times R_1 + R_2 \\rightarrow R_2 $")) - display(Markdown("Le déterminant est le même")) - out.clear_output() - Determinant_3x3(b, step_by_step = True) - - button.on_click(solution) - - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse")) - -def question7_2c(reponse): - c = sp.Matrix([[4,6,-3], [-4,8,12], [-4, 5, -1]]) - - if np.abs(reponse - sp.det(c)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - display(Markdown("Dans ce cas, la deuxième rangée a été multiplié par 4 et la troisième par -1")) - display(Latex("$ Soit: 4 \\times R_2 \\rightarrow R_2, -1 \\times R_3 \\rightarrow R_3 $")) - display(Markdown("Le déterminant est donc:")) - display(Latex('$ det|c| = (-1) \cdot (4) \cdot det|A| = -4 \cdot 155 = - 620 $')) - out.clear_output() - Determinant_3x3(c, step_by_step = True) - - button.on_click(solution) - - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse")) -def question7_2d(reponse): - d = sp.Matrix([[4, 6, -3], [-1,2,3], [-8,10,-2]]) - - if np.abs(reponse - sp.det(d)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description='Solution', disabled=False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - display(Markdown("Dans ce cas, la troisième rangée est multipliée par -2 ")) - display(Latex("$ Soit: -2 \\times R_3 \\rightarrow R_3 $")) - display(Markdown("Le déterminant est donc:")) - display(Latex("$ det|d| = (-2) \cdot det|A| = -2 \cdot 155 = - 310 $")) - out.clear_output() - Determinant_3x3(d, step_by_step = True) - - button.on_click(solution) - - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse.")) - -def question7_2e(reponse): - e = sp.Matrix([[-1, 2, 3], [4,6,-3], [0,-11,4]]) - - if np.abs(reponse - sp.det(e)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(k): - display(Markdown("Dans ce cas, deux fois la première rangée a été ajouté à la troisième rangée.")) - display(Markdown("Aussi les premières deux rangées sont échangées.")) - display(Latex("$ Soit: 2 \\times R_1 + R_3 \\rightarrow R_3, R_1 \\leftrightarrow R_2 $")) - display(Markdown("Le déterminant est donc:")) - display(Latex("$ det|e| = (-1) \cdot det|A| = (-1) \cdot 155 = - 155 $")) - out.clear_output() - Determinant_3x3(e, step_by_step = True) - - button.on_click(solution) - - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse.")) - -def question7_2f(reponse): + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante: $ " + latexp(b) + " $. ")) + display(Markdown("*Aidez-vous du déterminant de la matrice $M$ et des propositions données plus haut.*")) + display(det_answer) + + def check_det(): + det = b.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(e): + display(Markdown( + "Dans ce cas, la première ligne de $M$ a été multiplié par 2 et elle a été ajouté à la deuxième ligne")) + display(Latex("Soit: $2 \\times L_1 + L_2 \\rightarrow L_2 $")) + display(Markdown("Le déterminant est égal au determinant de $M$.")) + display(Markdown(" $\det B = \det M = 155$")) + + button.on_click(solution) + display(box) + + +def question7_2c(): + c = sp.Matrix([[4, 6, -3], [-4, 8, 12], [-4, 5, -1]]) + + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante: $ " + latexp(c) + " $. ")) + display(Markdown("*Aidez-vous du déterminant de la matrice $M$ et des propositions données plus haut.*")) + display(det_answer) + + def check_det(): + det = c.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(e): + display(Markdown("Dans ce cas, la deuxième ligne de $M$ a été multiplié par 4 et la troisième par -1.")) + display(Latex("Soit: $4 \\times L_2 \\rightarrow L_2, -1 \\times L_3 \\rightarrow L_3 $")) + display(Markdown("Le déterminant est donc:")) + display(Latex('$ \det C = (-1) \cdot (4) \cdot \det M = -4 \cdot 155 = - 620 $')) + + button.on_click(solution) + display(box) + + +def question7_2d(): + d = sp.Matrix([[4, 6, -3], [-1, 2, 3], [-8, 10, -2]]) + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante: $ " + latexp(d) + " $. ")) + display(Markdown("*Aidez-vous du déterminant de la matrice $M$ et des propositions données plus haut.*")) + display(det_answer) + + def check_det(): + det = d.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(e): + display(Markdown("Dans ce cas, la troisième ligne de $M$ est multipliée par -2.")) + display(Latex("Soit: $-2 \\times L_3 \\rightarrow L_3 $")) + display(Markdown("Le déterminant est donc:")) + display(Latex("$ \det D = (-2) \cdot \det M = -2 \cdot 155 = - 310 $")) + + button.on_click(solution) + display(box) + + +def question7_2e(): + e = sp.Matrix([[-1, 2, 3], [4, 6, -3], [0, -11, 4]]) + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice suivante: $ " + latexp(e) + " $. ")) + display(Markdown("*Aidez-vous du déterminant de la matrice $M$ et des propositions données plus haut.*")) + display(det_answer) + + def check_det(): + det = e.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(k): + display(Markdown("Dans ce cas, la première ligne a été soustraite à la troisième ligne.")) + display(Markdown("Ensuite les deux premières lignes sont échangées.")) + display(Latex("Soit: $- L_1 + L_3 \\rightarrow L_3, L_1 \\leftrightarrow L_2 $")) + display(Markdown("Le déterminant est donc:")) + display(Latex("$ \det E = (-1) \cdot \det M = (-1) \cdot 155 = - 155 $")) + + button.on_click(solution) + display(box) + + +def question7_2f(): f = sp.Matrix([[4, -5, 8], [6, 10, 1], [-3, 15, -2]]) - - if np.abs(reponse - sp.det(f)) != 0: - display(Markdown('Faux')) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - display(Markdown("Dans ce cas, la deuxième rangée a été multiplié par cinq.")) - display(Markdown("Après ça, c''est la transposée de la matrice.")) - display(Latex("$ Soit: 5 \\times R_2 \\rightarrow R_2, \: et \: transposée $")) - display(Markdown("Le déterminant est donc:")) - display(Latex("$ det|f| = 5 \cdot det|A|^T = 5 \cdot det|A| = 5 \cdot 155 = 755 $")) - out.clear_output() - Determinant_3x3(f, step_by_step = True) - - button.on_click(solution) - - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse.")) - -def question7_2g(reponse): - B = sp.Matrix([[1, -2, -3, 0 ,1], [-1, 8,3, 2, -3], [3, -5, 1, 4, 5], [-2, 4, 7, -2, 0], [1, 0, 9, -1, 3]]) - B1= sp.Matrix([[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 1, 10, 4, 2], [0, 0, 1,-2, 2], [0, 2, 12, -1, 2]]) - B2= sp.Matrix([[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 0, 10, S('11/3'),S('7/3')], [0, 0, 1,-2, 2], \ - [0, 0, 12, S('-5/3'), S('8/3')]]) - B3= sp.Matrix([[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 0, 10, S('11/3'),S('7/3')], [0, 0, 0,S('-71/30'), S('53/30')], \ - [0, 0, 0, S('-91/15'), S('-2/15')]]) - B4= sp.Matrix([[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 0, 10, S('11/3'),S('7/3')], [0, 0, 0,S('-71/30'), S('53/30')], \ - [0, 0, 0, 0, S('-331/71')]]) - - if np.abs(reponse - sp.det(B)) != 0: - display(Markdown('Faux')) - - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(k): - out.clear_output() - display(Markdown("Dans ce cas, on doit simplifier la matrice avec des opérations de lignes.")) - display(Markdown("On commence par simplifier la première colonne.")) - display(Latex("$ Soit: 1 \\times R_1 + R_2 \\rightarrow R_2, \: \: \ - -3 \\times R_1 + R_3 \\rightarrow R_3, \: \: \ - 2 \\times R_1 + R_4 \\rightarrow R_4, \: \: \ - -1 \\times R_1 + R_5 \\rightarrow R_5$")) - display(Markdown("Ce qui donne:")) - lineB1 = '$' + sp.latex(B1) + '$' - display(Latex(lineB1)) - - display(Markdown("On continue par simplifier la deuxième colonne.")) - display(Latex("$ Soit: -1/6 \\times R_2 + R_3 \\rightarrow R_3, \: \: \ - -1/3 \\times R_2 + R_5 \\rightarrow R_5$")) - display(Markdown("Ce qui donne:")) - lineB2 = '$' + sp.latex(B2) + '$' - display(Latex(lineB2)) - display(Markdown("On continue par simplifier la troisième colonne.")) - display(Latex("$ Soit: -1/10 \\times R_3 + R_4 \\rightarrow R_4, \: \: \ - -12/10 \\times R_3 + R_5 \\rightarrow R_5 $")) - display(Markdown("Ce qui donne:")) - lineB3 = '$' + sp.latex(B3) + '$' - display(Latex(lineB3)) + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + display(Latex("Entrez le determinant de la matrice suivante: $ " + latexp(f) + " $. ")) + display(Markdown("*Aidez-vous du déterminant de la matrice $M$ et des propositions données plus haut.*")) + display(det_answer) + def check_det(): + det = f.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' - display(Markdown("On continue par simplifier la quatrième colonne.")) - display(Latex("$ Soit: \\frac{-91/15}{-71/30} = \\frac{-91}{15} \\times \\frac{-30}{71} = \ - 91 \\times \\frac{2}{71} = \\frac{182}{71} \\times R_4 + R_5 \\rightarrow R_5 $")) - display(Markdown("Ce qui donne:")) - lineB4 = '$' + sp.latex(B4) + '$' - display(Latex(lineB4)) + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) - display(Markdown('On termine par multiplier les éléments sur la diagonale (principale) de $B$')) - display(Markdown('$ det B = 1 \\times 6 \\times 10 \\times \\frac{-71}{30} \\times \\frac{-331}{71} = 662 $')) + def solution(e): + display(Markdown("Dans ce cas, la deuxième ligne de $M$ a été multiplié par 5.")) + display(Markdown("Après ça, la transposée est prise." )) + display(Latex("Soit: $5 \\times L_2 \\rightarrow L_2, \: \mbox{ et } \: transposée $")) + display(Markdown("Le déterminant est donc:")) + display(Latex("$ \det F = 5 \cdot \det M^T = 5 \cdot \det M = 5 \cdot 155 = 775 $")) - button.on_click(solution) + button.on_click(solution) + display(box) - display(box) - display(out) - else: - display(Markdown("Bravo! Vous avez trouvé la réponse.")) - -## 7.3 -def whether_invertibleA(A): - """Judge whether the matrix C is invertible by calculating the determinant.""" - A_RREF = A.rref()[0] - A_det = sp.Float(A.det(), 4) - detA_s = sp.latex(A) - detAr_s = sp.latex(A_RREF) - Ar_det = sp.Float(A_RREF.det(), 4) - flag = None - - - select = widgets.SelectMultiple( - options = ['La matrice est inversible', "La matrice n'est pas inversible"], - description = 'Réponse: ', - disabled = False, - layout = Layout(width='auto', height = 'auto') - ) - button = widgets.Button(description = 'Vérifier', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - - def callback(e): - out.clear_output() - with out: - if len(select.value) <= 0: - pass - elif len(select.value) >1: - display(Markdown('Seulement une réponse est requise')) - elif sp.det(A) == 0: - if "La matrice n'est pas inversible" not in select.value: - display(Markdown("Faux")) - question3a(A) - else: - display(Markdown("Correct!")) - elif sp.det(A) != 0: - if 'La matrice est inversible' not in select.value: - display(Markdown("Faux")) - question3a(A) - else: - display(Markdown("Correct!")) +def question7_2_ex2(): + B = sp.Matrix([[1, -2, -3, 0, 1], [-1, 8, 3, 2, -3], [3, -5, 1, 4, 5], [-2, 4, 7, -2, 0], [1, 0, 9, -1, 3]]) + B1 = sp.Matrix([[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 1, 10, 4, 2], [0, 0, 1, -2, 2], [0, 2, 12, -1, 2]]) + B2 = sp.Matrix([[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 0, 10, S('11/3'), S('7/3')], [0, 0, 1, -2, 2], \ + [0, 0, 12, S('-5/3'), S('8/3')]]) + B3 = sp.Matrix( + [[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 0, 10, S('11/3'), S('7/3')], [0, 0, 0, S('-71/30'), S('53/30')], \ + [0, 0, 0, S('-91/15'), S('-2/15')]]) + B4 = sp.Matrix( + [[1, -2, -3, 0, 1], [0, 6, 0, 2, -2], [0, 0, 10, S('11/3'), S('7/3')], [0, 0, 0, S('-71/30'), S('53/30')], \ + [0, 0, 0, 0, S('-331/71')]]) + + det_answer = widgets.FloatText(value='0.0', description="det: ", disabled=False) + + display(Latex("Entrez le determinant de la matrice $ B = " + latexp(B) + " $. ")) + display(det_answer) + + def check_det(): + det = B.det() + answer = det_answer.value + if np.abs(answer - det) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) - button.on_click(callback) - display(select) + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(k): + display(Markdown("Dans ce cas, on doit simplifier la matrice avec des opérations de lignes.")) + display(Markdown("On commence par simplifier la première colonne.")) + display(Latex("$ Soit: 1 \\times R_1 + R_2 \\rightarrow R_2, \: \: \ + -3 \\times R_1 + R_3 \\rightarrow R_3, \: \: \ + 2 \\times R_1 + R_4 \\rightarrow R_4, \: \: \ + -1 \\times R_1 + R_5 \\rightarrow R_5$")) + display(Markdown("Ce qui donne:")) + lineB1 = '$' + latexp(B1) + '$' + display(Latex(lineB1)) + + display(Markdown("On continue par simplifier la deuxième colonne.")) + display(Latex("Soit: $-1/6 \\times R_2 + R_3 \\rightarrow R_3, \: \: \ + -1/3 \\times R_2 + R_5 \\rightarrow R_5$")) + display(Markdown("Ce qui donne:")) + lineB2 = '$' + latexp(B2) + '$' + display(Latex(lineB2)) + + display(Markdown("On continue par simplifier la troisième colonne.")) + display(Latex("Soit: $-1/10 \\times R_3 + R_4 \\rightarrow R_4, \: \: \ + -12/10 \\times R_3 + R_5 \\rightarrow R_5 $")) + display(Markdown("Ce qui donne:")) + lineB3 = '$' + latexp(B3) + '$' + display(Latex(lineB3)) + + display(Markdown("On continue par simplifier la quatrième colonne.")) + display(Latex("Soit: $\\frac{-91/15}{-71/30} = \\frac{-91}{15} \\times \\frac{-30}{71} = \ + 91 \\times \\frac{2}{71} = \\frac{182}{71} \\times R_4 + R_5 \\rightarrow R_5 $")) + display(Markdown("Ce qui donne:")) + lineB4 = '$' + latexp(B4) + '$' + display(Latex(lineB4)) + + display(Markdown('On termine par multiplier les éléments sur la diagonale (principale) de $B$')) + display( + Markdown('$ \det B = 1 \\times 6 \\times 10 \\times \\frac{-71}{30} \\times \\frac{-331}{71} = 662 $')) + + button.on_click(solution) display(box) - display(out) -def whether_invertibleB(A): - """Judge whether the matrix C is invertible by calculating the determinant.""" - A_RREF = A.rref()[0] - A_det = sp.Float(A.det(), 4) - detA_s = sp.latex(A) - detAr_s = sp.latex(A_RREF) - Ar_det = sp.Float(A_RREF.det(), 4) - flag = None - - - select = widgets.SelectMultiple( - options = ['La matrice est inversible', "La matrice n'est pas inversible"], - description = 'Réponse: ', - disabled = False, - layout = Layout(width='auto', height = 'auto') - ) - button = widgets.Button(description = 'Vérifier', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - - def callback(e): - out.clear_output() - with out: - if len(select.value) <= 0: - pass - elif len(select.value) >1: - display(Markdown('Seulement une réponse est requise')) - elif sp.det(A) == 0: - if "La matrice n'est pas inversible" not in select.value: - display(Markdown("Faux")) - question3b(A) - else: - display(Markdown("Correct!")) - elif sp.det(A) != 0: - if 'La matrice est inversible' not in select.value: - display(Markdown("Faux")) - question3b(A) - else: - display(Markdown("Correct!")) - - - button.on_click(callback) - display(select) +def question7_2_ex3(A): + A = sp.Matrix(A) + + def best_choice(A): + res = [] + for row in range(3): + n_0 = 0 + for i in range(3): + if np.abs(A[row, i]) < 1e-6: + n_0 += 1 + res.append(n_0) + for col in range(3): + n_0 = 0 + for i in range(3): + if np.abs(A[i, col]) < 1e-6: + n_0 += 1 + res.append(n_0) + + res = np.array(res, dtype=np.int16) + out = np.argwhere(res == np.max(res)) + out = out.flatten() + values = np.array(['L1', 'L2', 'L3', 'C1', 'C2', 'C3']) + return values[out] + + + + display(Latex("Vous devez calculer le déterminant de la matrice suivante: $" + latexp(A) + "$")) + display(Latex("A partir de quelle ligne ou colonne vous semble-t-il judicieux de commencer le calcul du déterminant " + "afin de simplifier les calculs ?")) + + choice_row_col = widgets.RadioButtons(options=['L1', 'L2', 'L3', 'C1', 'C2', 'C3'], value='L1', description='Réponse', + disabled=False) + + display(choice_row_col) + + def check_choice(): + correct_choice = best_choice(A) + user_choice = choice_row_col.value + + if user_choice in correct_choice: + display(Latex("Correct, " + user_choice + " est une des lignes/colonnes ayant le plus de zeros, " + "il est donc judicieux de commencer le calcul du déterminant avec " + user_choice + ".")) + else: + display(Latex("Il existe une ligne/colonne contenant plus de 0 que " + user_choice + ". Il est evidemment " + "possible de calculer le déterminant à partir de " + user_choice + ", mais un choix plus " + "judicieux pour simplifier le developpement existe.")) + + im = interact_manual(check_choice) + im.widget.children[0].description = 'Vérifier réponse' + + + display(Latex("A partir de la ligne/colonne selectrionnée ci-dessus, calculez le determinant de la matrice.")) + + det_answer = widgets.Text(value='0', description="det: ", disabled=False) + + display(det_answer) + + def check_det(): + det = A.det() + + answer = sp.sympify(det_answer.value) + if sp.simplify(answer - det).is_zero: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + + def solution(e): + if choice_row_col.value[0] == 'L': + row = True + else: + row = False + + n_row_col = eval(choice_row_col.value[1]) + Determinant_3x3(A, row=row, n=n_row_col) + + button.on_click(solution) + display(box) - display(out) -def whether_invertibleC(A): - """Judge whether the matrix C is invertible by calculating the determinant.""" - A_RREF = A.rref()[0] - A_det = sp.Float(A.det(), 4) - detA_s = sp.latex(A) - detAr_s = sp.latex(A_RREF) - Ar_det = sp.Float(A_RREF.det(), 4) - flag = None - - - select = widgets.SelectMultiple( - options = ['La matrice est inversible', "La matrice n'est pas inversible"], - description = 'Réponse: ', - disabled = False, - layout = Layout(width='auto', height = 'auto') + +## 7.3 +def whether_invertible(A): + yes = "La matrice est inversible" + no = "La matrice n'est pas inversible" + + select = widgets.RadioButtons( + options=[yes, no], + description='Réponse: ', + disabled=False, + layout=Layout(width='auto', height='auto') ) - button = widgets.Button(description = 'Vérifier', disabled = False) - box = HBox(children = [button]) + button = widgets.Button(description='Vérifier', disabled=False) + box = HBox(children=[button]) out = widgets.Output() + + correct_answer = (sp.det(A) != 0) * yes + (sp.det(A) == 0) * no + @out.capture() - - def callback(e): out.clear_output() with out: - if len(select.value) <= 0: - pass - elif len(select.value) >1: - display(Markdown('Seulement une réponse est requise')) - elif sp.det(A) == 0: - if "La matrice n'est pas inversible" not in select.value: - display(Markdown("Faux")) - question3c(A) - else: - display(Markdown("Correct!")) - elif sp.det(A) != 0: - if 'La matrice est inversible' not in select.value: - display(Markdown("Faux")) - question3c(A) - else: - display(Markdown("Correct!")) - + if select.value == correct_answer: + display(Markdown("Correct!")) + else: + display(Markdown("Incorrect!")) + solution_7_3_1(A) + button.on_click(callback) display(select) display(box) - display(out) + display(out) -def question3a(A): - A_RREF = A.rref()[0] - A_det = sp.Float(A.det(), 4) - detA_s = sp.latex(A) - detAr_s = sp.latex(A_RREF) - Ar_det = sp.Float(A_RREF.det(), 4) - - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) +def solution_7_3_1(A): + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) out = widgets.Output() + @out.capture() - def solution(e): out.clear_output() - display(Latex("$" + "\det A"+"="+ "\det" + detA_s + "=" + "k \cdot"+ "\det" + detAr_s+ "= k \cdot"+ "{}".format(Ar_det)+"=" + "{}".format(A_det)+"$" )) - display(Latex("Où $k$ est une constante qui n'est pas égale à zéro. ")) + display(Latex("Pour determiner si la matrice $" + latexp(A) + "$ est inversible, on calcule son déterminant.")) + Determinant_3x3(A) + if sp.det(A) == 0: - display(Latex("$\det A$ est égal à zéro, donc la matrice $A$ est singulière." )) + display(Latex("Le déterminant est égal à zéro, donc la matrice est singulière." )) else: - display(Latex("$\det A $ n'est pas égal à zéro, donc la matrice $A$ est inversible.")) + display(Latex("Le déterminant n'est pas égal à zéro, donc la matrice $A$ est inversible.")) button.on_click(solution) display(box) - display(out) - -def question3b(A): - A_RREF = A.rref()[0] - A_det = sp.Float(A.det(), 4) - detA_s = sp.latex(A) - detAr_s = sp.latex(A_RREF) - Ar_det = sp.Float(A_RREF.det(), 4) + display(out) - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) + +def exercice7_3_2_1(): + A = sp.Matrix([[-1, -2, 1, 0, 1], [0, 0, -2, 4, 9], [-2, -4, 5, 3, 3], [2, 4, -2, 0, -2], [1, 2, 6, -3, 3]]) + print(sp.det(A)) + + display(Latex("Entrez le déterminant de la matrice suivante: $" + latexp(A) + "$")) + + det_answer = widgets.FloatText(value='-1.0', description="det: ", disabled=False) + display(det_answer) + + def check_det(): + answer = det_answer.value + if np.abs(answer - 0.0) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) out = widgets.Output() + @out.capture() - def solution(e): out.clear_output() - display(Latex("$" + "\det B"+"="+ "\det" + detA_s + "=" + "k \cdot"+ "\det" + detAr_s+ "= k \cdot"+ "{}".format(Ar_det)+"=" + "{}".format(A_det)+"$" )) - display(Latex("Où $k$ est une constante qui n'est pas égale à zéro. ")) - if sp.det(A) == 0: - display(Latex("$\det B$ est égal à zéro, donc la matrice $B$ est singulière." )) - else: - display(Latex("$\det B $ n'est pas égal à zéro, donc la matrice $B$ est inversible.")) + display(Latex( + "On peut trouver le déterminant en évitant de long calculs. En effet, on peut observer que les lignes de le matrice sont linérairement dépendantes: $L4 = -2 \cdot L1$")) + + display(Latex("La matrice n'est donc pas inversible et par conséquent son déterminant est nul.")) button.on_click(solution) + display(box) - display(out) - -def question3c(A): - A_RREF = A.rref()[0] - A_det = sp.Float(A.det(), 4) - detA_s = sp.latex(A) - detAr_s = sp.latex(A_RREF) - Ar_det = sp.Float(A_RREF.det(), 4) - - - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) + display(out) + + +def exercice7_3_2_2(): + A = sp.Matrix([[4, 0, -4, 7], + [2, 1, -1, -3], + [-1, 1, 2, 5], + [-1, -2, -1, 5] + ]) + display(Latex("Entrez le déterminant de la matrice suivante: $" + latexp(A) + "$")) + + det_answer = widgets.FloatText(value='-1.0', description="det: ", disabled=False) + display(det_answer) + + def check_det(): + answer = det_answer.value + if np.abs(answer - 0.0) < 1e-6: + display(Latex("Correct!")) + else: + display(Latex("Incorrect.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) out = widgets.Output() - @out.capture() + @out.capture() def solution(e): out.clear_output() - display(Latex("$" + "\det C"+"="+ "\det" + detA_s + "=" + "k \cdot"+ "\det" + detAr_s+ "= k \cdot"+ "{}".format(Ar_det)+"=" + "{}".format(A_det)+"$" )) - display(Latex("Où $k$ est une constante qui n'est pas égale à zéro. ")) - if sp.det(A) == 0: - display(Latex("$\det C$ est égal à zéro, donc la matrice $C$ est singulière." )) - else: - display(Latex("$\det C $ n'est pas égal à zéro, donc la matrice $C$ est inversible.")) + display(Latex("On peut trouver le déterminant sans calculs. En effet, on peut observer que les colonnes de le matrice sont linérairement dépendantes: $C3 = C2 - C1$")) + + display(Latex("La matrice n'est donc pas inversible et par conséquent son déterminant est nul.")) button.on_click(solution) display(box) - display(out) + display(out) + - - - ## 7.4 -def question7_4a_solution(reponse): - if np.abs(reponse - 6/119) > 0.01: - - button = widgets.Button(description = 'Solution', disabled = False) - box = HBox(children = [button]) - out = widgets.Output() - @out.capture() - - def solution(e): - out.clear_output() - display(Markdown("Faux.")) - A = sp.Matrix([[-3,2,7], [1,-1,4], [2,5,-6]]) # det = 119 - B = sp.Matrix([[-4, 3, 0],[9, -4, -1],[-7, 1, 1]]) # det = 6 - Determinant_3x3(A, step_by_step = True) - Determinant_3x3(B, step_by_step = True) - display(Latex("$$ \det C = \det B \det A^{-1} = \det B \left( \\frac{1}{\det A} \\right) = \\frac{\det B}{\det A} = \\frac{6}{119}$$")) - - button.on_click(solution) - - display(box) - display(out) - - - - else: - display("Bravo! Vous avez trouvé la réponse") +def question7_4_1(): + det_answer = widgets.Text(value='0.0', description="$\det(BA^{-1})$ ", disabled=False) + display(det_answer) + + def check_det(): + reponse = eval(det_answer.value) + if np.abs(reponse - 6 / 119) > 0.01: + display(Latex("Incorrect.")) + + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + out = widgets.Output() + + @out.capture() + def solution(e): + out.clear_output() + display(Markdown("Faux.")) + A = sp.Matrix([[-3, 2, 7], [1, -1, 4], [2, 5, -6]]) # det = 119 + B = sp.Matrix([[-4, 3, 0], [9, -4, -1], [-7, 1, 1]]) # det = 6 + display(Latex("On calcule d'abord le determinant de $A$.")) + Determinant_3x3(A, step_by_step=True) + display(Latex("Puis celui de $B$.")) + Determinant_3x3(B, step_by_step=True) + display(Latex("On utilise ensuite les formules données plus haut pour trouver le determinant de $C = BA^-1$.")) + display(Latex( + "$$ \det C = \det B \det A^{-1} = \det B \left( \\frac{1}{\det A} \\right) = \\frac{\det B}{\det A} = \\frac{6}{119}$$")) + + button.on_click(solution) + + display(box) + display(out) + + else: + display(Latex("Correct! Le déterminant de $C$ est de $\\frac{6}{119}$.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' -def question7_4b_solution(detC, somme): +def question7_4_2(): A = sp.Matrix([[1, 3, -6], [5, 2, 2], [-2, -4, 9]]) B = sp.Matrix([[5, 0, -2], [10, -3, 7], [-1, 4, 1]]) - C = sp.Matrix([[6, 3, -8], [15, -1, 9],[-3, 0, 10]]) - flag1 = False - flag2 = False - - if detC != sp.det(C): - display(Markdown('Votre solution pour $\det(A+B) $ est fausse')) - flag1 = True - if somme != (sp.det(A) + sp.det(B)): - display(Markdown('Votre solution pour $\det A + \det B$ est fausse')) - flag1 = True - else: - display(Markdown("Correct! $\det(A+B)$ n'est pas égale à $\det A + \det B $")) - - if flag1: - question7_4b(A,B,C) - -def question7_4b(A,B,C): - display(Markdown('Cliquez en sous pour la solution pour $\det(A+B)$ et pour $\det A + \det B $ ')) - button1 = widgets.Button(description = 'Solution', disabled = False) + C = A + B + style = {'description_width': 'initial'} + + det_apb_answer = widgets.Text(value='0.0', description="$\det(A+B)$ ", style=style, disabled=False) + det_a_det_b_answer = widgets.Text(value='0.0', description="$\det(A) + \det(B)$ ", style=style, disabled=False) + display(det_apb_answer) + display(det_a_det_b_answer) + + def check_answers(): + det_a_det_b = eval(det_a_det_b_answer.value) + det_apb = eval(det_apb_answer.value) + + if np.abs(det_apb - sp.det(C)) < 1e-6: + correct_apb = True + else: + correct_apb = False + + if np.abs(det_a_det_b - sp.det(A) - sp.det(B)) < 1e-6: + correct_a_b = True + else: + correct_a_b = False + + if correct_apb and correct_a_b: + display(Latex("Les deux réponses sont correctes! On voit que $\det(A+B) \\neq \det(A) + \det(B)$")) + else: + if not correct_apb: + display(Latex("Votre solution pour $\det(A+B)$ est incorrecte.")) + if not correct_a_b: + display(Latex("Votre solution pour $\det(A) + \det(B)$ est incorrecte.")) + + im = interact_manual(check_answers) + im.widget.children[0].description = 'Vérifier réponses' + + question7_4_2_sol(A, B, C) + + +def question7_4_2_sol(A,B,C): + button1 = widgets.Button(description='Solution', disabled = False) box1 = HBox(children = [button1]) out1 = widgets.Output() @out1.capture() def solution(e): out1.clear_output() display(Markdown('La solution pour $\det(A+B)$')) Determinant_3x3(C, step_by_step = True) display(Markdown('La solution pour $\det A$')) Determinant_3x3(A, step_by_step = True) display(Markdown('La solution pour $\det B$')) Determinant_3x3(B, step_by_step = True) button1.on_click(solution) display(box1) - display(out1) - + display(out1) + + ## 7.5 def plotDeterminant3D(A): """ This function is used to plot a 3D representation of a determinant as the volume of a parallelopiped. This gets the vertices and sends it to another function below to plot. """ # Will only execute if it is 3x3 if (np.shape(A) != (3,3)): print('La matrice A doit être 3x3.') return # This creates the parallelopiped coordonates cube = np.array([[-1, -1, -1], [1, -1, -1 ], [1, 1, -1], [-1, 1, -1], [-1, -1, 1], [1, -1, 1 ], [1, 1, 1], [-1, 1, 1]]) vertices = np.zeros((8,3)) for i in range(8): vertices[i,:] = np.dot(cube[i,:], A) data_x = vertices[:,0] data_y = vertices[:,1] data_z = vertices[:,2] vol = np.abs(np.linalg.det(A)) vol = np.round(vol, decimals = 3) plot3d(data_x, data_y, data_z, vol) def plot3d(data_x, data_y, data_z, vol): """ This function plots an interactive 3D plot of the determinant as a volume of a parallelopiped """ fig = go.Figure( data = [ go.Mesh3d( x = data_x, y = data_y, z = data_z, i = [7, 0, 0, 0, 4, 4, 6, 6, 4, 0, 3, 2], # These are needed, numbers from documentation 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], colorscale=[[0, 'darkblue'], [0.5, 'lightskyblue'], [1, 'darkblue']], intensity = np.linspace(0, 1, 8, endpoint=True), showscale=False, opacity = 0.6 ) ], layout = go.Layout( title = "Le volume est: " + str(vol), autosize = True ) ) # This prints it pyo.iplot(fig, filename='Determinant-Volume') def plotDeterminant2D(A): # See; https://stackoverflow.com/questions/44881885/python-draw-parallelepiped """ This function creates a 2D plot of the area of a determinant for a 2x2 matrix. """ # Will only execute if it is 2x2 if (np.shape(A) != (2,2)): print('La matrice A doit être 2x2.') return # Define vertices for a cube to multiply with input matrix A to get parallelopiped rect = np.array([[1, -1], [1, 1], [-1, 1], [-1, -1]]) vertices = np.zeros((5,2)) for i in range(4): vertices[i,:] = np.dot(rect[i,:], A) vertices[4,0] = vertices[0,0] vertices[4,1] = vertices[0,1] # Create figure / grid to plot fig = plt.figure(figsize=(10,5)) ax = fig.add_subplot(111) # Plot vertices ax.plot(vertices[:,0], vertices[:,1]) vol = np.abs(np.linalg.det(A)) # absolute value of the determinant vol = np.round(vol, decimals = 3) print("L'aire est:", vol) coll = PolyCollection([vertices]) ax.add_collection(coll) ax.autoscale_view() plt.grid() plt.show() def problem7_5(): A = [[1, 3], [5,2]] display(Markdown('Cliquez en sous pour la solution pour votre dessin')) button = widgets.Button(description = 'Solution', disabled = False) box = HBox(children = [button]) out = widgets.Output() @out.capture() def solution(e): out.clear_output() plotDeterminant2D(A) button.on_click(solution) display(box) display(out) def Determinant_3x3_abs(A, step_by_step=True ,row=True, n=1): """ Step by step computation of the determinant of a 3x3 sympy matrix strating with given row/col number :param A: 3 by 3 sympy matrix :param step_by_step: Boolean, True: print step by step derivation of det, False: print only determinant :param row: True to compute determinant from row n, False to compute determinant from col n :param n: row or col number to compute the determinant from (int between 1 and 3) :return: display step by step solution for Same idea as for 7.1 but returns the absolute value of the result """ if A.shape!=(3,3): raise ValueError('Dimension of matrix A should be 3x3. The input A must be a sp.Matrix of shape (3,3).') if n<1 or n>3 or not isinstance(n, int): raise ValueError('n should be an integer between 1 and 3.') # Construct string for determinant of matrix A detA_s = sp.latex(A).replace('[','|').replace(']','|') # To print all the steps if step_by_step: # If we compute the determinant with row n if row: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, n, 1) A2 = red_matrix(A, n, 2) A3 = red_matrix(A, n, 3) detA1_s = sp.latex(A1).replace('[','|').replace(']','|') detA2_s = sp.latex(A2).replace('[','|').replace(']','|') detA3_s = sp.latex(A3).replace('[','|').replace(']','|') line1 = "$" + detA_s + ' = ' + pl_mi(n,1, True) + sp.latex(A[n-1, 0]) + detA1_s + pl_mi(n,2) + \ sp.latex(A[n-1, 1]) + detA2_s + pl_mi(n,3) + sp.latex(A[n-1, 2]) + detA3_s + '$' line2 = '$' + detA_s + ' = ' + pl_mi(n,1, True) + sp.latex(A[n-1, 0]) + "\cdot (" + sp.latex(sp.det(A1)) \ +")" + pl_mi(n,2) + sp.latex(A[n-1, 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")"+ \ pl_mi(n,3) + sp.latex(A[n-1, 2]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # If we compute the determinant with col n else: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, 1, n) A2 = red_matrix(A, 2, n) A3 = red_matrix(A, 3, n) detA1_s = sp.latex(A1).replace('[','|').replace(']','|') detA2_s = sp.latex(A2).replace('[','|').replace(']','|') detA3_s = sp.latex(A3).replace('[','|').replace(']','|') line1 = "$" + detA_s + ' = ' + pl_mi(n,1, True) + brackets(A[0, n-1]) + detA1_s + pl_mi(n,2) + \ brackets(A[1, n-1]) + detA2_s + pl_mi(n,3) + brackets(A[2, n-1]) + detA3_s + '$' line2 = '$' + detA_s + ' = ' + pl_mi(n,1, True) + brackets(A[0, n-1]) + "\cdot (" + sp.latex(sp.det(A1))\ +")" + pl_mi(n,2) + brackets(A[1, n-1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")"+ \ pl_mi(n,3) + brackets(A[2, n-1]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.Abs(sp.det(A)))) + '$' # Display step by step computation of determinant display(Latex(line1)) display(Latex(line2)) display(Latex(line3)) if sp.det(A) < 0: display(Latex('$' + ' Le \: déterminant \: est \: négatif \: alors \: on \: prend \: la \: valeur \: absolue \: $')) display(Latex("$ Le \: volume \: est \: = " + sp.latex(-1 * sp.det(A)) + "$")) # Only print the determinant without any step else: if sp.det(A) > 0: display(Latex("$" + detA_s + "=" + sp.latex(sp.det(A)) + "$")) else: display(Latex('$' + ' Le \: déterminant \: est \: négatif \: alors \: on \: prend \: la \: valeur \: absolue \: $')) display(Latex("$ Le \: volume \: est \: = " + sp.latex(-1 * sp.det(A)) + "$")) ## 7.7 def find_inverse_3x3(A): """ Step by step computation of the determinant of a 3x3 sympy matrix strating with given row/col number :param A: 3 by 3 sympy matrix :param step_by_step: Boolean, True: print step by step derivation of det, False: print only determinant :param row: True to compute determinant from row n, False to compute determinant from col n :param n: row or col number to compute the determinant from (int between 1 and 3) :return: display step by step solution for """ if A.shape!=(3,3): raise ValueError(' La Matrice A doit être 3x3.') if A.det() == 0: display(Latex("$\det A=0.$" +" La matrice $A$ est singulière alors l'inverse de $A$ n'existe pas." )) else: sub_matrix=[] pl=[] cofactor=[] cofactor_o=[] sub_matrix_latex=[] cof_matrix =sp.Matrix([[1,1,1],[1,1,1],[1,1,1]]) # Construc string for determinant of matrix A detA_s = sp.latex(A).replace('[','|').replace(']','|') for i in range(3): for j in range(3): sub_matrix.append(red_matrix(A, i+1, j+1)) pl.append( (-1)**(i+j+2)) for i in range(len(pl)): cofactor.append(sp.latex(pl[i]*sp.simplify(sp.det(sub_matrix[i])))) cofactor_o.append(pl[i]*sp.simplify(sp.det(sub_matrix[i]))) sub_matrix_latex.append(sp.latex(sub_matrix[i]).replace('[','|').replace(']','|')) for i in range(3): for j in range(3): cof_matrix[i,j]=cofactor_o[i*3+j] cof_matrix_t=cof_matrix.T A1 = red_matrix(A, 1, 1) A2 = red_matrix(A, 1, 2) A3 = red_matrix(A, 1, 3) detA1_s = sp.latex(A1).replace('[','|').replace(']','|') detA2_s = sp.latex(A2).replace('[','|').replace(']','|') detA3_s = sp.latex(A3).replace('[','|').replace(']','|') c12 = sp.simplify(sp.det(A2))*(-1) line0 = "$\mathbf{Solution:}$ Les neuf cofacteurs sont" line1 = "$" + "C_{11}" + ' = ' + pl_mi(1,1, True) + sub_matrix_latex[0] + ' = ' + cofactor[0] + "\qquad " +\ "C_{12}" + ' = ' + pl_mi(1,2) + sub_matrix_latex[1] + ' = ' + cofactor[1]+ "\qquad " +\ "C_{13}" + ' = ' + pl_mi(1,3) + sub_matrix_latex[2] + ' = ' + cofactor[2]+ '$' line2 = "$" + "C_{21}" + ' = ' + pl_mi(2,1, True) + sub_matrix_latex[3] + ' = ' + cofactor[3] + "\qquad " +\ "C_{22}" + ' = ' + pl_mi(2,2) + sub_matrix_latex[4] + ' = ' + cofactor[4]+ "\qquad " +\ "C_{23}" + ' = ' + pl_mi(2,3) + sub_matrix_latex[5] + ' = ' + cofactor[5]+ '$' line3 = "$" + "C_{31}" + ' = ' + pl_mi(3,1, True) + sub_matrix_latex[6] + ' = ' + cofactor[6] + "\qquad " +\ "C_{32}" + ' = ' + pl_mi(3,2) + sub_matrix_latex[7] + ' = ' + cofactor[7]+ "\qquad " +\ "C_{33}" + ' = ' + pl_mi(3,3) + sub_matrix_latex[8] + ' = ' + cofactor[8]+ '$' line4 = "La comatrice de $A$ est la transposée de la matrice de cofaceurs de $A$" #"Then we can get the adjugate matrix that is the transpose of the matrix of cofactors. For instance, $C_{13}$ goes \ # in the $(3,1)$ position of the adjugate matrix." line5 = '$'+"\mbox{adj} A" + ' = ' + "(\mbox{cof} A)^T" + ' = ' + sp.latex(cof_matrix_t) + '$' line6 = "On calcule le déterminant de $A$: $det\ A$" line7 = "$ \mbox{det} A=" + detA_s + "=" + sp.latex(sp.simplify(sp.det(A))) + '$' line8 = "On peut trouver la matrice inverse en utilisant le théorème en haut." line9 = '$'+"A^{-1}" + ' = ' + "\dfrac{{1}}{{\mbox{det} A}}"+"\cdot "+" \mbox{adj} A" + ' = ' \ +"\dfrac{1}"+"{{{}}}".format(sp.simplify(sp.det(A)))+"\cdot "+sp.latex(cof_matrix_t)+"="+ sp.latex(sp.simplify(sp.det(A))**(-1)*cof_matrix_t) + '$' # Display step by step computation of determinant display(Markdown('Cliquez en sous pour la solution')) button = widgets.Button(description = 'Solution', disabled = False) box = HBox(children = [button]) out = widgets.Output() @out.capture() def solution(e): out.clear_output() display(Latex(line0)) display(Latex(line1)) display(Latex(line2)) display(Latex(line3)) display(Latex(line4)) display(Latex(line5)) display(Latex(line6)) display(Latex(line7)) display(Latex(line8)) display(Latex(line9)) button.on_click(solution) display(box) display(out) def red_matrix4(A, i, j): """ Return reduced matrix (without row i and col j)""" row = [0, 1, 2, 3] col = [0, 1, 2, 3] row.remove(i-1) col.remove(j-1) return A[row, col] def find_inverse_4x4(A): """ Step by step computation of the determinant of a 4x4 sympy matrix strating with given row/col number :param A: 3 by 3 sympy matrix :param step_by_step: Boolean, True: print step by step derivation of det, False: print only determinant :param row: True to compute determinant from row n, False to compute determinant from col n :param n: row or col number to compute the determinant from (int between 1 and 3) :return: display step by step solution for """ if A.shape!=(4,4): raise ValueError(' La Matrice B doit être 4x4.') if A.det() == 0: display(Latex("$\det B=0.$" +" La matrice $B$ est singulière alors l'inverse de $B$ n'existe pas." )) else: sub_matrix=[] pl=[] cofactor=[] cofactor_o=[] sub_matrix_latex=[] cof_matrix =sp.Matrix([[1,1,1,1],[1,1,1,1],[1,1,1,1],[1,1,1,1]]) # Construc string for determinant of matrix A detA_s = sp.latex(A).replace('[','|').replace(']','|') for i in range(4): for j in range(4): sub_matrix.append(red_matrix4(A, i+1, j+1)) pl.append( (-1)**(i+j+2)) for i in range(len(pl)): cofactor.append(sp.latex(pl[i]*sp.simplify(sp.det(sub_matrix[i])))) cofactor_o.append(pl[i]*sp.simplify(sp.det(sub_matrix[i]))) sub_matrix_latex.append(sp.latex(sub_matrix[i]).replace('[','|').replace(']','|')) for i in range(4): for j in range(4): cof_matrix[i,j]=cofactor_o[i*4+j] cof_matrix_t=cof_matrix.T A1 = red_matrix4(A, 1, 1) A2 = red_matrix4(A, 1, 2) A3 = red_matrix4(A, 1, 3) detA1_s = sp.latex(A1).replace('[','|').replace(']','|') detA2_s = sp.latex(A2).replace('[','|').replace(']','|') detA3_s = sp.latex(A3).replace('[','|').replace(']','|') c12 = sp.simplify(sp.det(A2))*(-1) line0 = "$\mathbf{Solution:}$ Les 16 cofacteurs sont" line1 = "$" + "C_{11}" + ' = ' + pl_mi(1,1, True) + sub_matrix_latex[0] + ' = ' + cofactor[0] + "\qquad " +\ "C_{12}" + ' = ' + pl_mi(1,2) + sub_matrix_latex[1] + ' = ' + cofactor[1] + "\qquad " +\ "C_{13}" + ' = ' + pl_mi(1,3) + sub_matrix_latex[2] + ' = ' + cofactor[2] + "\qquad " +\ "C_{14}" + ' = ' + pl_mi(1,4) + sub_matrix_latex[3] + ' = ' + cofactor[3] + "\qquad " + '$' line2 = "$" + "C_{21}" + ' = ' + pl_mi(2,1, True) + sub_matrix_latex[4] + ' = ' + cofactor[4] + "\qquad " +\ "C_{22}" + ' = ' + pl_mi(2,2) + sub_matrix_latex[5] + ' = ' + cofactor[5]+ "\qquad " +\ "C_{23}" + ' = ' + pl_mi(2,3) + sub_matrix_latex[6] + ' = ' + cofactor[6]+ "\qquad " + \ "C_{24}" + ' = ' + pl_mi(2,4) + sub_matrix_latex[7] + ' = ' + cofactor[7]+ "\qquad" + '$' line3 = "$" + "C_{31}" + ' = ' + pl_mi(3,1, True) + sub_matrix_latex[8] + ' = ' + cofactor[8] + "\qquad " +\ "C_{32}" + ' = ' + pl_mi(3,2) + sub_matrix_latex[9] + ' = ' + cofactor[9] + "\qquad " + \ "C_{33}" + ' = ' + pl_mi(3,3) + sub_matrix_latex[10] + ' = ' + cofactor[10]+ "\qquad " + \ "C_{34}" + ' = ' + pl_mi(3,4) + sub_matrix_latex[11] + ' = ' + cofactor[11]+ "\qquad" +'$' line4 = "$" + "C_{41}" + ' = ' + pl_mi(4,1, True) + sub_matrix_latex[12] + ' = ' + cofactor[12] + "\qquad " +\ "C_{42}" + ' = ' + pl_mi(4,2) + sub_matrix_latex[13] + ' = ' + cofactor[13] + "\qquad " +\ "C_{43}" + ' = ' + pl_mi(4,3) + sub_matrix_latex[14] + ' = ' + cofactor[14]+ "\qquad " +\ "C_{44}" + ' = ' + pl_mi(4,4) + sub_matrix_latex[15] + ' = ' + cofactor[15]+ "\qquad" +'$' line5 = "Cela donne la matrice de cofacteurs de $B$." line6 = '$'+ "(\mbox{cof} B)" + ' = ' + sp.latex(cof_matrix) + '$' line7 = "La comatrice de $B$ est la transposée de la matrice de cofacteurs de $B$" #"Then we can get the adjugate matrix that is the transpose of the matrix of cofactors. For instance, $C_{13}$ goes \ # in the $(3,1)$ position of the adjugate matrix." line8 = '$'+"\mbox{adj} B" + ' = ' + "(\mbox{cof} B)^T" + ' = ' + sp.latex(cof_matrix_t) + '$' line9 = "On calcule le déterminant de $B$: $det\ B$" line10 = "$ \mbox{det} B=" + detA_s + "=" + sp.latex(sp.simplify(sp.det(A))) + '$' line11 = "On peut trouver la matrice inverse en utilisant le théorème en haut." line12 = '$'+"B^{-1}" + ' = ' + "\dfrac{{1}}{{\mbox{det} B}}"+"\cdot "+" \mbox{adj} B" + ' = ' \ +"\dfrac{1}"+"{{{}}}".format(sp.simplify(sp.det(A)))+"\cdot "+sp.latex(cof_matrix_t)+"="+ sp.latex(sp.simplify(sp.det(A))**(-1)*cof_matrix_t) + '$' # Display step by step computation of determinant display(Markdown('Cliquez en sous pour la solution')) button = widgets.Button(description = 'Solution', disabled = False) box = HBox(children = [button]) out = widgets.Output() @out.capture() def solution(e): out.clear_output() display(Latex(line0)) display(Latex(line1)) display(Latex(line2)) display(Latex(line3)) display(Latex(line4)) display(Latex(line5)) display(Latex(line6)) display(Latex(line7)) display(Latex(line8)) display(Latex(line9)) display(Latex(line10)) display(Latex(line11)) display(Latex(line12)) button.on_click(solution) display(box) display(out) \ No newline at end of file diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.1 - Le d\303\251terminant, d\303\251finition et exemples.ipynb" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.1 - Le d\303\251terminant, d\303\251finition et exemples.ipynb" index d8d21fe..fb0ceeb 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.1 - Le d\303\251terminant, d\303\251finition et exemples.ipynb" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.1 - Le d\303\251terminant, d\303\251finition et exemples.ipynb" @@ -1,202 +1,211 @@ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import sympy as sp\n", "import sys, os \n", "from Ch7Functions import *\n", "from IPython.display import display, Latex\n", "from sympy import S" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Définition du déterminant\n", "Soit $A=(a_{ij})\\in M_{n \\times n}(\\mathbb{R})$ une matrice de taille $n \\times n$ à coefficients réels. Pour $1\\leq i,j\\leq n,$ on définit $\\hat{A}_{ij}$ comme étant la matrice de taille $(n-1) \\times (n-1)$ obtenue en supprimant dans $A$ la $i$-ème ligne et la $j$-ème colonne. Le déterminant de $A$ est le nombre réel défini récursivement par \n", "$$\\det A = a_{11} \\det \\hat{A}_{11} - a_{12}\\det \\hat{A}_{12} + \\cdots + (-1)^{n+1} a_{1n}\\det \\hat{A}_{1n} $$\n", - "où $\\det (a)=a$ pour toute matrice $a$ un seul élément, i.e., $(a)\\in M_{1 \\times 1}(\\mathbb{R}).$\n" + "où $\\det (a)=a$ pour toute matrice $a$ un seul élément, i.e., $(a)\\in M_{1 \\times 1}(\\mathbb{R}).$\n", + "\n", + "\n", + "### Notation\n", + "En général, la notation suivante désigne le determinant de la matrice. \n", + "$$\\det \\left(\\begin{matrix} a & b \\\\ c & d \\end{matrix}\\right) = \\left|\\begin{matrix} a & b \\\\ c & d \\end{matrix}\\right|\n", + "$$\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exemple 1: Application de la définition à une matrice 2x2\n", "\n", "Soit $A= \\begin{pmatrix}a & b\\\\ c & d \\end{pmatrix}$\n", "\n", "On utilise la définition ci-dessus pour trouver le determinant:\n", "\n", "$$ \\det A = a_{11} \\det \\hat{A}_{11} - a_{12}\\det \\hat{A}_{12} =a \\cdot \\det \\begin{pmatrix} d \\end{pmatrix} - b \\cdot \\det \\begin{pmatrix} c \\end{pmatrix} = ad - bc$$ \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exemple 2: Application de la définition à une matrice 3x3\n", "\n", - "Soit $A$ est une matrice de taille $3 \\times 3$, le déterminant peut être calculer avec sa première colonne:\n", + "Soit $A$ est une matrice de taille $3 \\times 3$, le déterminant peut être calculé avec sa première colonne:\n", "$$ A = \\begin{pmatrix} a_{11} & a_{12} & a_{13} \\\\\n", " a_{21} & a_{22} & a_{23} \\\\\n", " a_{31} & a_{32} & a_{33} \\end{pmatrix}$$\n", "Alors\n", "$$ \\det A = a_{11} \\begin{pmatrix} a_{22} & a_{23} \\\\ a_{32} & a_{33} \\end{pmatrix} \n", "- a_{21} \\begin{pmatrix} a_{12} & a_{13} \\\\ a_{32} & a_{33} \\end{pmatrix}\n", "+ a_{31} \\begin{pmatrix} a_{12} & a_{13} \\\\ a_{22} & a_{23} \\end{pmatrix}$$\n", "\n", "Les déterminants des matrices de taille $2 \\times 2$ peuvent être calculer comme en haut." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice 1: Calcul de déterminant en utilisant la définition\n", - "Soient $A$ est une matrice de taille $3 \\times 3$ donnée ci-dessous et $x \\in \\mathbb{R}$\n", + "**a)** Soient $A$ est une matrice de taille $3 \\times 3$ donnée ci-dessous, calculez son déterminant.\n", "\n", "\n", - "$$ A = \\begin{pmatrix} 1 & 4 & 3\\\\-2 & 2 & 5\\\\-6 & 7 & -1\\end{pmatrix} $$" + "$$ A = \\begin{pmatrix} 1 & 4 & 3\\\\-2 & 2 & 3\\\\-6 & 2 & -1\\end{pmatrix} $$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "A = sp.Matrix([[1,4,3], [-2,2,5], [-6,7,-1]])\n", - "ch7ex(A)" + "A = sp.Matrix([[1, 4, 3], [-2, 2, 3], [-6, 2, -1]])\n", + "ch7_1_ex1(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercice 2: Calcul de déterminant en utilisant la définition\n", - "Soient $A$ est une matrice de taille $3 \\times 3$ donnée ci-dessous et $x \\in \\mathbb{R}$\n", + "**b)** Soient $A$ est une matrice de taille $3 \\times 3$ donnée ci-dessous et $x \\in \\mathbb{R}$, calculez son déterminant. \n", + "\n", + "*Votre résultat peut dépendre de $x$, rentrez simplement l'expression (attention une expression du type **`2x`** n'est pas acceptée, utilisez **`2 * x`** à la place). Les puissances se font avec le caractère **`^`**. Par exemple, pour répondre $2x^2 - 2x + 1$, rentrez* **`2*x^2 - 2*x + 1`**.\n", "\n", "\n", - "$$ A = \\begin{pmatrix} 1 & x & 3/4\\\\1/2 & 2 & 4\\\\1 & x & 43\\end{pmatrix} $$" + "$$ A = \\begin{pmatrix} 1 & x & -2\\\\4 & -1 & 5\\\\1 & x & -5\\end{pmatrix} $$" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ - "x = sp.symbols('x', positive=True)\n", - "A = sp.Matrix([[1,x,S('3/4')], [S('1/2'),2,4], [1,x**2/x,43]])\n", + "x = sp.symbols('x')\n", + "A = sp.Matrix([[1, x, -2], [4, -1, 5], [1, x, -5]])\n", "\n", - "ch7ex(A)" + "ch7_1_ex1(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Règle de Sarrus\n", "Soit $A=(a_{ij})\\in M_{3\\times 3}(\\mathbb{R})$. \n", "\n", "$$ A = \\begin{pmatrix} a_{11} & a_{12} & a_{13} \\\\\n", " a_{21} & a_{22} & a_{23} \\\\\n", " a_{31} & a_{32} & a_{33} \\end{pmatrix}$$\n", "\n", "\n", "Alors\n", "\n", - "$$\\det A=a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}-a_{13}a_{22}a_{31}-a_{11}a_{23}a_{32}-a_{12}a_{21}a_{33}$$\n", - "\n", - "Également\n", - "$$\\det A=a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}- (a_{13}a_{22}a_{31} + a_{11}a_{23}a_{32} + a_{12}a_{21}a_{33})$$\n", - "\n" + "$$\\det A=a_{11}a_{22}a_{33}+a_{12}a_{23}a_{31}+a_{13}a_{21}a_{32}-a_{13}a_{22}a_{31}-a_{11}a_{23}a_{32}-a_{12}a_{21}a_{33}$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Remarque: cette règle ne peut pas être généraliser aux matrices de tailles 4x4 ou plus grands. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Exercice 3: Calculs de déterminants en utilisant la règle de Sarrus\n", + "### Exercice 2: Calculs de déterminants en utilisant la règle de Sarrus\n", "Avec l'aide de la règle de Sarrus, calculez les determinants des matrices suivantes:\n", "\n", - "$$ \\mbox{a)} \\hspace{3mm} \\begin{pmatrix}1 & x & 3/4\\\\1/2 & 2 & 4\\\\1 & x & 43\\end{pmatrix} \\hspace{20mm} \\mbox{b)} \\hspace{3mm} \\begin{pmatrix}1 & -2 & x\\\\-1/2 & 8 & -4\\\\x & -23 & 6\\end{pmatrix} \\hspace{20mm} \\mbox{c)} \\hspace{3mm} \\begin{pmatrix}-x & 2 & x\\\\3 & -2 & -11\\\\x & -4 & -3\\end{pmatrix}$$\n", + "$$ \\mbox{a)} \\hspace{3mm} A = \\begin{pmatrix}1 & 2 & 3\\\\1 & 2 & -5\\\\1 & 5 & -2\\end{pmatrix} \\hspace{20mm} \\mbox{b)} \\hspace{3mm} B=\\begin{pmatrix}1 & -2 & x\\\\0 & 8 & -4\\\\x & -5 & 2\\end{pmatrix} \\hspace{20mm} \\mbox{c)} \\hspace{3mm} C=\\begin{pmatrix}-x & 2 & x\\\\3 & -2 & -11\\\\x & -4 & -3\\end{pmatrix}$$\n", "\n", "\n", - "Faites les exemples à la main et vérifiez avec les boutons de solution ci-dessous" + "Faites les exemples à la main et rentrez vos réponses.\n", + "\n", + "*Votre résultat peut dépendre de $x$, rentrez simplement l'expression (attention une expression du type **`2x`** n'est pas acceptée, utilisez **`2 * x`** à la place). Les puissances se font avec le caractère **`^`**. Par exemple, pour répondre $2x^2 - 2x + 1$, rentrez* **`2*x^2 - 2*x + 1`**.\n", + "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "A = sp.Matrix([[1,x,S('3/4')], [S('1/2'),2,4], [1,x,43]])\n", - "\n", - "\n", - "\n", - "ch7ex3(A)" + "x = sp.symbols('x')\n", + "A = sp.Matrix([[1, 2, 3], [1, 2, -5], [1,5,-2]])\n", + "ch7_1_ex2(A)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "B = sp.Matrix([[1,-2,x], [S('-1/2'),8,-4], [x,-23,6]])\n", - "\n", - "ch7ex3(B)" + "B = sp.Matrix([[1, -2, x], [0, 8, -4], [x, -5, 2]])\n", + "ch7_1_ex2(B)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "C = sp.Matrix([[-x,2,x], [3,-2,-11], [x,-4,-3]])\n", - "\n", - "ch7ex3(C)" + "ch7_1_ex2(C)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Passez au notebook du chapitre 7.2: Multiplication de matrices](./Chapitre%207.2%20-%20Propri%C3%A9t%C3%A9s%20du%20d%C3%A9terminant%2C%20astuces%20de%20calcul.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.6" + "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.2 - Propri\303\251t\303\251s du d\303\251terminant, astuces de calcul.ipynb" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.2 - Propri\303\251t\303\251s du d\303\251terminant, astuces de calcul.ipynb" index 253658a..d5a959e 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.2 - Propri\303\251t\303\251s du d\303\251terminant, astuces de calcul.ipynb" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.2 - Propri\303\251t\303\251s du d\303\251terminant, astuces de calcul.ipynb" @@ -1,302 +1,299 @@ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import sympy as sp\n", - "import sys, os \n", + "import sys, os\n", "from Ch7Functions import *\n", - "from IPython.display import display, Latex\n" + "from IPython.display import display, Latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Les charactéristiques des déterminants\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Notation\n", - "\n", - "En général, la notation de lignes droites autour des matrices veut dire qu'on considère le déterminant de la matrice. \n", - "\n", - "Par exemple,\n", - "$$\\det \\left(\\begin{matrix} a & b \\\\ c & d \\end{matrix}\\right) = \\left|\\begin{matrix} a & b \\\\ c & d \\end{matrix}\\right|\n", - "$$" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Matrices Triangulaire\n", + "# Les caractéristiques des déterminants\n", "\n", - "Si $A$ est une matrice triangulaire, le déterminant est le produit des éléments sur la diagonale (principale) de $A$.\n", "\n", - "Par exemple,\n", + "### PROPOSITION 1 :\n", + "Soient $A=\\left(a_{i j}\\right) \\in M_{n \\times n}(\\mathbb{R})$ et $1 \\leq p, r \\leq n$. Alors\n", + "$$\n", + "\\begin{aligned}\n", + "\\operatorname{det} A &=a_{p 1}(-1)^{p+1} \\operatorname{det} \\hat{A}_{p 1}+a_{p 2}(-1)^{p+2} \\operatorname{det} \\hat{A}_{p 2}+\\cdots+a_{p n}(-1)^{p+n} \\operatorname{det} \\hat{A}_{p n} \\\\\n", + "&=a_{1 r}(-1)^{r+1} \\operatorname{det} \\hat{A}_{1 r}+a_{2 r}(-1)^{r+2} \\operatorname{det} \\hat{A}_{2 r}+\\cdots+a_{n r}(-1)^{r+n} \\operatorname{det} \\hat{A}_{n r}\n", + "\\end{aligned}\n", + "$$\n", + "### PROPRIÉTÉS 2 :\n", + "Soient $A \\in M_{n \\times n}(\\mathbb{R}), \\lambda \\in \\mathbb{R}$ et $1 \\leq r, s \\leq n .$ Alors les affirmations suivantes sont vérifiées.\n", + "1. $\\operatorname{det} L_{r s}(\\lambda) A=\\operatorname{det} A$\n", + "2. $\\operatorname{det} T_{r s} A=-\\operatorname{det} A$\n", + "3. $\\operatorname{det} D_{r}(\\lambda) A=\\lambda \\operatorname{det} A$\n", + "4. $\\operatorname{det} A L_{r s}(\\lambda)=\\operatorname{det} A$\n", + "5. $\\operatorname{det} A T_{r s}=-\\operatorname{det} A$\n", + "6. $\\operatorname{det} A D_{r}(\\lambda)=\\lambda \\operatorname{det} A$.\n", "\n", - "$$ A = \\left| \\begin{matrix} \n", - " a_{11} & a_{12} & a_{13} & a_{14} \\\\\n", - " 0 & a_{22} & a_{23} & a_{24} \\\\\n", - " 0 & 0 & a_{33} & a_{34} \\\\\n", - " 0 & 0 & 0 & a_{44}\n", - " \\end{matrix} \\right| \n", - " = a_{11}a_{22}a_{33}a_{44}\n", - " $$\n", - " \n", + "### PROPOSITION 3 :\n", + "Si $A=\\left(a_{i j}\\right) \\in M_{n \\times n}$ ( $\\mathbb{R}$ ) est une matrice triangulaire (inférieure ou supérieure), alors son déterminant est égal au produit de ses coefficients diagonaux, i.e.\n", + "$$\n", + "\\operatorname{det} A=a_{11} a_{22} \\cdots a_{n n}\n", + "$$\n", "\n", - "---" + "### PROPOSITION 4 :\n", + "Soit $A=\\left(a_{i j}\\right) \\in M_{n \\times n}(\\mathbb{R})$. Alors\n", + "$$\n", + "\\operatorname{det} A^{T}=\\operatorname{det} A\n", + "$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Opérations des lignes\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Soit $A$ est une matrice carrée \n", + "Soit $A$ est une matrice carrée:\n", "\n", - "Si un multiple d'une ligne de $A$ est ajouté à une autre ligne pour faire la matrice $B$, le déterminant de $B$ est égal au déterminant de $A$\n", + "Si un multiple d'une ligne de $A$ est ajouté à une autre ligne pour faire la matrice $B$, alors \n", "$$ \\det B = \\det A $$\n", "\n", "\n", - "Si deux lignes de $A$ sont échangées pour faire $B$, le déterminant de $B$ est égal au négatif du déterminant de $A$\n", + "Si deux lignes de $A$ sont échangées pour faire $B$, alors\n", "$$ \\det B = -\\det A $$\n", "\n", "\n", - "Si une ligne de $A$ est multipliée par $\\textit{k}$ pour faire $B$, le déterminant de $B$ est le déterminant de $A$ multiplié par $\\textit{k}$.\n", + "Si une ligne de $A$ est multipliée par $\\textit{k}$ pour faire $B$, alors\n", "$$ \\det B = \\textit{k} \\cdot \\det A $$\n", "\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Inversibilité\n", - "\n", - "Si une matrice carrée $A$ est invertible, son déterminant ne peut pas être égal à zéro. \n", - "\n", - "\n", - "Si $A^{-1}$ existe, $\\det A \\neq 0 $\n", - "\n", - "---\n" + "### Exercice 1\n", + "Calculez le determinant de la matrice $M$.\n", + "$$ M = \\begin{pmatrix}4 & 6 & -3\\\\-1 & 2 & 3\\\\4 & -5 & 1\\end{pmatrix} $$" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "### Transposées\n", - "\n", - "Si $A$ est une $n \\times n$ matrice (carrée), alors $$ \\det A^T = \\det A $$\n", - "\n", - "---" + "M = sp.Matrix([[4, 6, -3], [-1, 2, 3], [4, -5, 1]])\n", + "ch_7_2_ex1(M)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Exemple 1\n", - "\n", - "En premier, calculez à la main le déterminant de A.\n", - "\n", - "$$ A = \\begin{pmatrix}4 & 6 & -3\\\\-1 & 2 & 3\\\\4 & -5 & 1\\end{pmatrix} $$\n", - "\n", "Avec ce résultat, que valent les déterminants suivants?\n", "\n", "$$ \\mbox{a)} \\hspace{3mm} A = \\left(\n", " \\begin{matrix} 4 & -1 & 4\\\\\n", " 6 & 2 & -5\\\\\n", " -3 & 3 & 1\\end{matrix}\\right) \\hspace{20mm} \n", " \\mbox{b)} \\hspace{3mm} B = \\left(\n", " \\begin{matrix} 4 & 6 & -3\\\\\n", " 7 & 14 & -3\\\\\n", " 4 & -5 & 1\\end{matrix}\\right) \\hspace{20mm} \n", "\\mbox{c)} \\hspace{3mm} C = \\left(\n", " \\begin{matrix}4 & 6 & -3\\\\\n", " -4 & 8 & 12\\\\\n", " -4 & 5 & -1\\end{matrix}\\right) $$\n", " \n", "$$ \\mbox{d)} \\hspace{3mm} D = \\left(\n", " \\begin{matrix} 4 & 6 & -3\\\\\n", " -1 & 2 & 3\\\\\n", " -8 & 10 & -2\\end{matrix}\\right) \\hspace{20mm} \n", " \\mbox{e)} \\hspace{3mm} E = \\left(\n", " \\begin{matrix} -1 & 2 & 3\\\\\n", " 4 & 6 & -3\\\\\n", " 0 & -11 & 4\\end{matrix}\\right) \\hspace{20mm} \n", "\\mbox{f)} \\hspace{3mm} F = \\left(\n", " \\begin{matrix}4 & -5 & 8\\\\\n", " 6 & 10 & 1\\\\\n", - " -3 & 15 & -2\\end{matrix}\\right) $$" + " -3 & 15 & -2\\end{matrix}\\right) $$\n", + " \n", + "Executez les cellules suivantes et rentrez vos résultats." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Écrivez votre réponse pour le déterminant de la matrice A ici: (C'est un nombre entier, e.g. -1,3, -382, 137, 282, etc)\n", - "# Remplacez le zéro\n", - "reponse_2 = 0 " + "question7_2a()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "question7_2(reponse_2)" + "question7_2b()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# Écrivez vos réponses pour les question a-f ci dessous. (Remplacez les zéros)\n", - "reponse_2a = 0\n", - "reponse_2b = 0\n", - "reponse_2c = 0\n", - "reponse_2d = 0\n", - "reponse_2e = 0\n", - "reponse_2f = 0" + "question7_2c()" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "Les fonctions ci-dessous peuvent être utilisées pour vérifier vos réponses" + "question7_2d()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "question7_2a(reponse_2a)" + "question7_2e()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "question7_2b(reponse_2b)" + "question7_2f()" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "question7_2c(reponse_2c)" + "### Exercice 2\n", + "A l'aide des propisitions données plus haut, échelonnez la matrice $B$ pour ensuite trouver le déterminant de $B$.\n", + "\n", + "$$ B = \\begin{pmatrix}1 & -2 & -3 & 0 & 1 \\\\\n", + " -1 & 8 & 3 & 2 & -3 \\\\\n", + " 3 & -5 & 1 & 4 & 5 \\\\\n", + " -2 & 4 & 7 & -2 & 0 \\\\\n", + " 1 & 0 & 9 & -1 & 3\n", + " \\end{pmatrix} $$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "question7_2d(reponse_2d)" + "# # Écrivez vos réponses pour l question ci dessous. (Remplacez le zéro)\n", + "question7_2_ex2() " ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "question7_2e(reponse_2e)" + "### Complexité du calcul d'un déterminant\n", + "Supposez que vous devez calculer le determinant d'une matrice de taille $n \\times n$ et que vous utilisiez pour cela la définition du déterminant donnée dans le cours 7.1. \n", + "\n", + "Pour vous aider, plusieurs personnes se proposent de calculer un déterminant d'une sous matrice de taille $3 \\times 3$ chacun.\n", + "\n", + "De combien de personne aurez-vous besoin pour différentes valeurs de $n$ ?\n", + "\n", + "- Si $n=3$, vous n'aurez besoin que d'une personne.\n", + "- Si $n=4$, vous aurez cettte fois besoin de 4 personnes.\n", + "- Si $n=5$, 20 personnes.\n", + "- Si $n=6$, 120 personnes.\n", + "- .....\n", + "- Si $n=10$, vous aurez besoin de 604 800 personnes.\n", + "- .....\n", + "- Si $n=14$, vous aurez besoin de plus de personnes qu'il n'y en a sur terre, 14 529 715 200 pour être exact !\n", + "\n", + "Un moyen simple pour limiter le nombre de sous determinants à calculer est de choisir (à chaque étape) la ligne/colonne avec le plus de 0 pour développer le prochain determinant. Grâce à cela, le calcul du déterminant d'une matrice creuse, i.e. une matrice avec un nombre d'éléments nuls important, est beaucoup plus rapide.\n", + "\n", + "\n", + "### Exercice 3\n", + "Exécutez les cellues suivantes, choissisez la ligne ou la colonnes à partir de laquelle il est judicieux de commencer le calcul du déterminant, puis faites ce calcul." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "question7_2f(reponse_2f)" + "A = sp.Matrix([[1, 2, 4], [0, 0, 2], [1, -1, 1]])\n", + "question7_2_ex3(A)" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "source": [ - "### Exemple 2\n", - "Calculez le déterminant de la matrice B.\n", - "\n", - "$$ B = \\begin{pmatrix}1 & -2 & -3 & 0 & 1 \\\\\n", - " -1 & 8 & 3 & 2 & -3 \\\\\n", - " 3 & -5 & 1 & 4 & 5 \\\\\n", - " -2 & 4 & 7 & -2 & 0 \\\\\n", - " 1 & 0 & 9 & -1 & 3\n", - " \\end{pmatrix} $$" + "A = sp.Matrix([[0, 2, 4], [0, -5, 0], [1, -1, 0]])\n", + "question7_2_ex3(A)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "# # Écrivez vos réponses pour l question ci dessous. (Remplacez le zéro)\n", - "\n", - "reponse_2g = 0\n", - "question7_2g(reponse_2g) " + "A = sp.Matrix([[-5, 2, 4], [0, 0, 0], [1, 12, -3]])\n", + "question7_2_ex3(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "\n" + "[Passez au notebook du chapitre 7.3 - Critère d'inversibilité](./Chapitre%207.3%20-%20Crit%C3%A8re%20d'inversibilit%C3%A9.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.6" + "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.3 - Crit\303\250re d'inversibilit\303\251.ipynb" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.3 - Crit\303\250re d'inversibilit\303\251.ipynb" index 78bdb38..f6bb426 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.3 - Crit\303\250re d'inversibilit\303\251.ipynb" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.3 - Crit\303\250re d'inversibilit\303\251.ipynb" @@ -1,167 +1,189 @@ { "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import sympy as sp\n", - "import sys, os \n", + "import sys, os\n", "from Ch7Functions import *\n", "from IPython.display import display, Latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### PROPOSITION :\n", + "Si $A=(a_{ij})\\in M_{n\\times n}(\\mathbb{R})$. Alors $A$ est inversible si et seulement si $\\det A \\neq 0$.\n", "\n", - "#### Si $A=(a_{ij})\\in M_{n\\times n}(\\mathbb{R})$. Alors $A$ est inversible si et seulement si $\\det A \\neq 0$.\n", "\n", - "Ce théorème ajoute à la déclaration “$\\det A \\neq 0$” au théorème de la matrice inversible. C'est aussi utile de savoir que si \n", - "$\\det A = 0$, ça veut dire que les colonnes de $A$ sont linéairement dépandantes . Ainsi que quand $\\det A = 0$, les rangées de $A$ sont linéairement dépandantes. (Les rangées de $A$ sont les colonnes de $A^T$, et des colonnes linéairement dépandantes cause $A^T$ d'être singulièreé\n", + "Il est aussi utile de noter que cela implique que si $\\det A = 0$, alors les colonnes de $A$ sont linéairement dépendantes. \n", + "C'est aussi le cas pour les lignes de $A$ car les lignes de $A$ sont les colonnes de $A^T$ et $\\det A^T = \\det A$.\n", "\n", - "On peut dire que quand $A^T$ est singulière, $A$ est singulière aussi grace au théorème de la matrice inversible.\n", - "\n", - "\n", - "\n", - " \n" + "En effet, si $A$ est singulière, alors $A^T$ l'est aussi." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exemple : \n", + "### Exemple : \n", "Calculez $ \\det A $, quand \n", "$$A = \\begin{pmatrix}\n", "3 & -1 & 2 & -5\\\\\n", "0 & 5 &-3 & -6\\\\\n", "-6 & 7 & -7 & 4\\\\\n", "-5 & -8 & 0 & 9\n", "\\end{pmatrix}$$\n", "\n", "\n", - "**SOLUTION** Ajoutez deux fois la rangée 1 à la rangée 3\n", + "On peut ajouter deux fois la ligne 1 à la ligne 3. \n", "\n", "\n", "\n", "$$ \\det A = \\det \\begin{pmatrix}\n", "3 & -1 & 2 & -5\\\\\n", "0 & 5 &-3 & -6\\\\\n", "0 & 5 &-3 & -6\\\\\n", "-5 & -8 & 0 & 9\n", - "\\end{pmatrix} = 0 $$ \n", + "\\end{pmatrix}$$ \n", "\n", - "$\\det A = 0$ alors la matrice $A$ est singulière, parce que la deuxième rangée et la troisième rangée sont égales.\n" + "La matrice obtenue a deux lignes identiques, on en déduit donc que $A$ n'est pas inversible et donc que son déterminant est nul.\n", + "$$ \\det A = 0 $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "#### Exercise : Déterminez si la matrice A est inversible en calculant son déterminant\n", - "Exécuter la cellule suivante après avoir faites les calculs sur papier.\n", + "### Exercice 1\n", + "Executez les cellules suivantes et déterminez si les matrices suivantes sont inversibles.\n", + "Déterminez si la matrice A est inversible.\n", "\n", "$$ A = \\begin{pmatrix}\n", "1 & 2 & 3/4 \\\\\n", "1/2 & 2 & 4 \\\\\n", "1 & 6 & 43 \\\\\n", - "\\end{pmatrix}$$ \n" + "\\end{pmatrix}$$\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "A = sp.Matrix([[1,2,3/4], [0.5,20/10,4], [1,6,43]])\n", "\n", - "reponseA = whether_invertibleA(A)" + "reponseA = whether_invertible(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exercise : Déterminez si la matrice B est inversible en calculant son déterminant\n", + "#### Exercice : Déterminez si la matrice B est inversible en calculant son déterminant\n", "Exécuter la cellule suivante après avoir faites les calculs sur papier.\n", "\n", "$$ B = \\begin{pmatrix}\n", "4 & -3 & -1 \\\\\n", "-7 & 5 &-3 \\\\\n", "8 & 1 & 2 \\\\\n", "\\end{pmatrix} $$ \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "B = sp.Matrix([[4,-3,-1], [-7,5,-3], [8,1,2]])\n", "\n", - "whether_invertibleB(B)" + "whether_invertible(B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exercise : Déterminez si la matrice C est inversible en calculant son déterminant\n", + "#### Exercice : Déterminez si la matrice C est inversible en calculant son déterminant\n", "Exécuter la cellule suivante après avoir faites les calculs sur papier.\n", "\n", "$$ C = \\begin{pmatrix}\n", "3 & 1 & -1 \\\\\n", "-6 & -2 & 2 \\\\\n", "4 & 10 & 7 \\\\\n", "\\end{pmatrix} $$ \n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "C = sp.Matrix([[3,1,-1], [-6,-2, 2], [4,10,7]])\n", - "\n", - "reponseC = whether_invertibleC(C)\n" + "reponseC = whether_invertible(C)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 2\n", + "Executez les cellules suivantes puis calculez le déterminant des matrices affichées. Pour cela servez-vous de la propositions et des remarques données plus haut." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exercice7_3_2_1()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "exercice7_3_2_2()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Passez au notebook du hapitre 7.4 - Le déterminant d'un produit](./Chapitre%207.4%20-%20Le%20d%C3%A9terminant%20d'un%20produit.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.6" + "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.4 - Le d\303\251terminant d'un produit.ipynb" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.4 - Le d\303\251terminant d'un produit.ipynb" index 67f993e..0e32630 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.4 - Le d\303\251terminant d'un produit.ipynb" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.4 - Le d\303\251terminant d'un produit.ipynb" @@ -1,223 +1,138 @@ { "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "import numpy as np\n", "import sympy as sp\n", "import sys, os \n", "from Ch7Functions import *\n", "from IPython.display import display, Latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Le déterminant d'un produit\n", "\n", "Soit $A$ et $B$ sont deux matrices carrées de taille $ n \\times n$, le déterminant de $AB$ est le produit des déterminants de $A$ et $B$.\n", "$$\\det AB = (\\det A)(\\det B) $$\n", "\n", - "Cependant, ceci n'est pas le cas pour l'addition ou la soustraction de matrices. En générale, $$ \\det (A \\pm B) \\neq \\det A \\pm \\det B $$\n", + "Cependant, ceci n'est pas le cas pour l'addition ou la soustraction de matrices. En général, $$ \\det (A \\pm B) \\neq \\det A \\pm \\det B $$\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Soit $A$ est une matrice de taille $n \\times n$ et $A$ est inversible, le déterminant de $A^-1$ est:\n", + "Soit $A$ est une matrice de taille $n \\times n$ et $A$ inversible, alors:\n", "$$\\det A^{-1} = \\frac{1}{\\det A} $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Soit $A$ et $B$ sont deux matrices semblables de taille $n \\times n$. Le déterminant de $A$ est égal au déterminant de $B$.\n", + "Soit $A$ et $B$ deux matrices semblables de taille $n \\times n$. Le déterminant de $A$ est égal au déterminant de $B$.\n", "$$\\det A = \\det B$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "---\n", - "## Exemple 1\n", + "### Exercice 1\n", + "\n", + "Déterminez le déterminant de la matrice $C$\n", "\n", - "En utilisant ces régles ci en haut, trouvez le déterminant de $C$.\n", "$$C = B A^{-1}$$\n", "\n", "$$ A = \\begin{pmatrix} \n", " -3 & 2 & 7 \\\\\n", " 1 & -1 & 4 \\\\\n", " 2 & 5 & -6 \\\\\n", " \\end{pmatrix}$$\n", " \n", "$$B = \\begin{pmatrix} \n", " -4 & 3 & 0 \\\\\n", " 9 & -4 & -1 \\\\\n", " -7 & 1 & 1 \\\\\n", " \\end{pmatrix}$$" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "3d05ca1bc9eb46d481809cac939ccc03", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(Button(description='Solution', style=ButtonStyle()),))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "e8f0ed88177d4d47a23bf1c2a26b5312", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "# Écrivez votre réponse ici avec 3 décimales;\n", - "reponse = 0\n", - "\n", - "\n", - "question7_4a_solution(reponse)" + "question7_4_1()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Exemple 2\n", + "### Exercice 2\n", "\n", "En utilisant ces régles ci en haut, vérifiez sur papier que $$\\det(A+B) \\neq \\det(A) + \\det(B) $$\n", "\n", "$$ A = \\begin{pmatrix} \n", " 1 & 3 & -6 \\\\\n", " 5 & 2 & 2 \\\\\n", " -2 & -4 & 9 \\\\\n", " \\end{pmatrix}$$\n", " \n", "$$B = \\begin{pmatrix} \n", " 5 & 0 & -2 \\\\\n", " 10 & -3 & 7 \\\\\n", " -1 & 4 & 1 \\\\\n", " \\end{pmatrix}$$" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/markdown": [ - "Correct! $\\det(A+B)$ n'est pas égale à $\\det A + \\det B $" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "# det(A+B):\n", - "detAB = 0\n", - "\n", - "# det(A) + det(B)\n", - "somme = 0\n", - "\n", - "\n", - "question7_4b_solution(detAB, somme)" + "question7_4_2()" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.6" + "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.5 - Le d\303\251terminant, interpr\303\251tation g\303\251om\303\251trique.ipynb" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.5 - Le d\303\251terminant, interpr\303\251tation g\303\251om\303\251trique.ipynb" index 6545ed5..b41c323 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.5 - Le d\303\251terminant, interpr\303\251tation g\303\251om\303\251trique.ipynb" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.5 - Le d\303\251terminant, interpr\303\251tation g\303\251om\303\251trique.ipynb" @@ -1,127 +1,1247 @@ { "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + " \n", + " " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "import numpy as np\n", "import matplotlib.pylab as plt\n", "from matplotlib.patches import Polygon\n", "from matplotlib.collections import PolyCollection\n", "import plotly.offline as pyo\n", "import plotly.graph_objs as go\n", "from Ch7Functions import *\n", "from IPython.display import display, Latex\n", "import sympy as sp\n", "pyo.init_notebook_mode(connected = True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Chapitre 7.5 – Représentations géométriques des déterminants\n", "\n", "Soit $A=(a_{ij})\\in M_{2 \\times 2}(\\mathbb{R})$, la valeur absolue du déterminant de $A$ est l'aire du parallélogramme crée par les deux vecteurs de $A$.\n", "\n", "Dans la prochaine partie, vous pouvez changer les paramètres de $A$ et voir comment le parallélogramme va changer. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "L'aire est: 33.75\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "# Vous pouvez changer les valeurs ci-dessous\n", "A = [[4.5, -1.5], \n", " [3.3, 6.4]]\n", "\n", "plotDeterminant2D(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Soit $A=(a_{ij})\\in M_{3 \\times 3}(\\mathbb{R})$, la valeur absolue du déterminant de $A$ est le volume du parallélépipède crée par les trois vecteurs de $A$." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "application/vnd.plotly.v1+json": { + "config": { + "linkText": "Export to plot.ly", + "plotlyServerURL": "https://plot.ly", + "showLink": false + }, + "data": [ + { + "colorscale": [ + [ + 0, + "darkblue" + ], + [ + 0.5, + "lightskyblue" + ], + [ + 1, + "darkblue" + ] + ], + "i": [ + 7, + 0, + 0, + 0, + 4, + 4, + 6, + 6, + 4, + 0, + 3, + 2 + ], + "intensity": [ + 0, + 0.14285714285714285, + 0.2857142857142857, + 0.42857142857142855, + 0.5714285714285714, + 0.7142857142857142, + 0.8571428571428571, + 1 + ], + "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 + ], + "opacity": 0.6, + "showscale": false, + "type": "mesh3d", + "x": [ + 0, + -6, + -2, + 4, + 2, + -4, + 0, + 6 + ], + "y": [ + 5, + 7, + 5, + 3, + -5, + -3, + -5, + -7 + ], + "z": [ + -7, + 3, + 9, + -1, + -9, + 1, + 7, + -3 + ] + } + ], + "layout": { + "autosize": true, + "template": { + "data": { + "bar": [ + { + "error_x": { + "color": "#2a3f5f" + }, + "error_y": { + "color": "#2a3f5f" + }, + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "bar" + } + ], + "barpolar": [ + { + "marker": { + "line": { + "color": "#E5ECF6", + "width": 0.5 + } + }, + "type": "barpolar" + } + ], + "carpet": [ + { + "aaxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "baxis": { + "endlinecolor": "#2a3f5f", + "gridcolor": "white", + "linecolor": "white", + "minorgridcolor": "white", + "startlinecolor": "#2a3f5f" + }, + "type": "carpet" + } + ], + "choropleth": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "choropleth" + } + ], + "contour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "contour" + } + ], + "contourcarpet": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "contourcarpet" + } + ], + "heatmap": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmap" + } + ], + "heatmapgl": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "heatmapgl" + } + ], + "histogram": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "histogram" + } + ], + "histogram2d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2d" + } + ], + "histogram2dcontour": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "histogram2dcontour" + } + ], + "mesh3d": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "type": "mesh3d" + } + ], + "parcoords": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "parcoords" + } + ], + "pie": [ + { + "automargin": true, + "type": "pie" + } + ], + "scatter": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter" + } + ], + "scatter3d": [ + { + "line": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatter3d" + } + ], + "scattercarpet": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattercarpet" + } + ], + "scattergeo": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergeo" + } + ], + "scattergl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattergl" + } + ], + "scattermapbox": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scattermapbox" + } + ], + "scatterpolar": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolar" + } + ], + "scatterpolargl": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterpolargl" + } + ], + "scatterternary": [ + { + "marker": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "type": "scatterternary" + } + ], + "surface": [ + { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + }, + "colorscale": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "type": "surface" + } + ], + "table": [ + { + "cells": { + "fill": { + "color": "#EBF0F8" + }, + "line": { + "color": "white" + } + }, + "header": { + "fill": { + "color": "#C8D4E3" + }, + "line": { + "color": "white" + } + }, + "type": "table" + } + ] + }, + "layout": { + "annotationdefaults": { + "arrowcolor": "#2a3f5f", + "arrowhead": 0, + "arrowwidth": 1 + }, + "coloraxis": { + "colorbar": { + "outlinewidth": 0, + "ticks": "" + } + }, + "colorscale": { + "diverging": [ + [ + 0, + "#8e0152" + ], + [ + 0.1, + "#c51b7d" + ], + [ + 0.2, + "#de77ae" + ], + [ + 0.3, + "#f1b6da" + ], + [ + 0.4, + "#fde0ef" + ], + [ + 0.5, + "#f7f7f7" + ], + [ + 0.6, + "#e6f5d0" + ], + [ + 0.7, + "#b8e186" + ], + [ + 0.8, + "#7fbc41" + ], + [ + 0.9, + "#4d9221" + ], + [ + 1, + "#276419" + ] + ], + "sequential": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ], + "sequentialminus": [ + [ + 0, + "#0d0887" + ], + [ + 0.1111111111111111, + "#46039f" + ], + [ + 0.2222222222222222, + "#7201a8" + ], + [ + 0.3333333333333333, + "#9c179e" + ], + [ + 0.4444444444444444, + "#bd3786" + ], + [ + 0.5555555555555556, + "#d8576b" + ], + [ + 0.6666666666666666, + "#ed7953" + ], + [ + 0.7777777777777778, + "#fb9f3a" + ], + [ + 0.8888888888888888, + "#fdca26" + ], + [ + 1, + "#f0f921" + ] + ] + }, + "colorway": [ + "#636efa", + "#EF553B", + "#00cc96", + "#ab63fa", + "#FFA15A", + "#19d3f3", + "#FF6692", + "#B6E880", + "#FF97FF", + "#FECB52" + ], + "font": { + "color": "#2a3f5f" + }, + "geo": { + "bgcolor": "white", + "lakecolor": "white", + "landcolor": "#E5ECF6", + "showlakes": true, + "showland": true, + "subunitcolor": "white" + }, + "hoverlabel": { + "align": "left" + }, + "hovermode": "closest", + "mapbox": { + "style": "light" + }, + "paper_bgcolor": "white", + "plot_bgcolor": "#E5ECF6", + "polar": { + "angularaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "radialaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "scene": { + "xaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "yaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + }, + "zaxis": { + "backgroundcolor": "#E5ECF6", + "gridcolor": "white", + "gridwidth": 2, + "linecolor": "white", + "showbackground": true, + "ticks": "", + "zerolinecolor": "white" + } + }, + "shapedefaults": { + "line": { + "color": "#2a3f5f" + } + }, + "ternary": { + "aaxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "baxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + }, + "bgcolor": "#E5ECF6", + "caxis": { + "gridcolor": "white", + "linecolor": "white", + "ticks": "" + } + }, + "title": { + "x": 0.05 + }, + "xaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + }, + "yaxis": { + "automargin": true, + "gridcolor": "white", + "linecolor": "white", + "ticks": "", + "title": { + "standoff": 15 + }, + "zerolinecolor": "white", + "zerolinewidth": 2 + } + } + }, + "title": { + "text": "Le volume est: 88.0" + } + } + }, + "text/html": [ + "
\n", + " \n", + " \n", + "
\n", + " \n", + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Vous pouvez changer les valeurs ci-dessous\n", "A = [[-3, 1, 5],\n", " [2, -1, 3],\n", " [1, -5, -1]]\n", "\n", "plotDeterminant3D(A)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/latex": [ + "$\\left|\\begin{matrix}-3 & 1 & 5\\\\2 & -1 & 3\\\\1 & -5 & -1\\end{matrix}\\right| = -3\\left|\\begin{matrix}-1 & 3\\\\-5 & -1\\end{matrix}\\right|-1\\left|\\begin{matrix}2 & 3\\\\1 & -1\\end{matrix}\\right|+5\\left|\\begin{matrix}2 & -1\\\\1 & -5\\end{matrix}\\right|$" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\left|\\begin{matrix}-3 & 1 & 5\\\\2 & -1 & 3\\\\1 & -5 & -1\\end{matrix}\\right| = -3\\cdot (16)-1\\cdot (-5)+5\\cdot (-9)$" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$\\left|\\begin{matrix}-3 & 1 & 5\\\\2 & -1 & 3\\\\1 & -5 & -1\\end{matrix}\\right| = -88$" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$ Le \\: déterminant \\: est \\: négatif \\: alors \\: on \\: prend \\: la \\: valeur \\: absolue \\: $" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/latex": [ + "$ Le \\: volume \\: est \\: = 88$" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# Pour comparer, le déterminant de la matrice A est aussi calculé ci-dessous\n", "a = sp.Matrix(A)\n", "Determinant_3x3_abs(a, step_by_step = True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exemple\n", "Dessine sur un papier le paraléllogramme qui correspond à la matrice \n", "$$ B = \\begin{pmatrix} \n", " 1 & 3 \\\\\n", " 5 & 2 \\\\\n", " \\end{pmatrix}$$" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/markdown": [ + "Cliquez en sous pour la solution pour votre dessin" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "60385fbb7b634f608d1d6c68365f28b5", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "HBox(children=(Button(description='Solution', style=ButtonStyle()),))" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "78d5a1724b104c55a7fccda21ccada14", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "problem7_5()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.9" + "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.7 - La matrice des cofacteurs et une formule pour l'inverse d'une matrice.ipynb" "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.7 - La matrice des cofacteurs et une formule pour l'inverse d'une matrice.ipynb" index e2ea043..66b8ed8 100644 --- "a/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.7 - La matrice des cofacteurs et une formule pour l'inverse d'une matrice.ipynb" +++ "b/Chapitre 7 - Le d\303\251terminant d'une matrice/Chapitre 7.7 - La matrice des cofacteurs et une formule pour l'inverse d'une matrice.ipynb" @@ -1,208 +1,215 @@ { "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import numpy as np\n", "import sympy as sp\n", "from IPython.display import display, Latex\n", "from Ch7Functions import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### RAPPEL:\n", "Soit $A=(a_{ij})\\in M_{n\\times n}(\\mathbb{R})$ une matrice de taille $n\\times n$ à coefficients réels. Pour $1\\leq i,j\\leq n,$ on définit $\\hat{A}_{ij}$ comme étant la matrice de taille $(n-1)\\times (n-1)$ obtenue en supprimant dans $A$ la $i$-ème ligne et la $j$-ème colonne. \n", "\n", "### DÉFINITION:\n", "Soit $A=(a_{ij})\\in M_{n\\times n}(\\mathbb{R})$ une matrice de taille $n\\times n$ à coefficients réels. La matrice des cofacteurs de $A$ est la matrice $\\mbox{cof} A\\in M_{n \\times n}(\\mathbb{R})$ de taille $(n-1)\\times (n-1)$ définie par\n", "$$(\\mbox{cof}A)_{ij}=(-1)^{i+j}\\mbox{det}\\hat{A}_{ij}=C_{ij}$$\n", "\n", "\n", "### THÉORÈME:\n", "Soit $A=(a_{ij})\\in M_{n\\times n}(\\mathbb{R})$ une matrice inversible. Alors\n", "$$A^{-1} = \\dfrac{1}{\\mbox{det}A}\\cdot (\\mbox{cof}A)^T$$\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### Exercise \n", "Trouver sur papier la matrice inverse de $ A_{3 \\times 3} $.\n", "\n", "$$ A = \\begin{pmatrix}2 & 1 & 1\\\\1 & -1 & 1\\\\ -1 & 1 & 2\\end{pmatrix} $$\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "Cliquez en sous pour la solution" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5cb0fe975db744fe8662f861d8c7fd10", + "model_id": "7efcc3c73f284ab58082b6c942132f65", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Button(description='Solution', style=ButtonStyle()),))" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "5a354679b0d94c8b9909b60d0b5aeaa7", + "model_id": "090d4e7e42e04d028522bc46eb600734", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "A = sp.Matrix([[2,1,1],[1,-1,1],[-1,1,-2]])\n", "find_inverse_3x3(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Exercise \n", "Trouver sur papier la matrice inverse de $ B_{4 \\times 4} $. \n", "\n", "$$ B = \\begin{pmatrix}\n", "3 & -1 & 0 & 2\\\\\n", "0 & 2 & -4 & 2\\\\ \n", "1 & -3 & 1 & 0\\\\\n", "-1 & 0 & 1 & 1 \n", "\\end{pmatrix}$$\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "Cliquez en sous pour la solution" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ffea93b636814640a6a63f868a871229", + "model_id": "35c46cd2401e429e8a9738e397eb0f0a", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(Button(description='Solution', style=ButtonStyle()),))" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "a85ef03c256743e1a411a74474934c89", + "model_id": "b3e5a9eccf314c05b8b5d434aca7002c", "version_major": 2, "version_minor": 0 }, "text/plain": [ "Output()" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "B = sp.Matrix([[3,-1,0,-2],[0,2,-4,2],[1,-3,1,0],[-1,0,1,1]])\n", "find_inverse_4x4(B)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.9" + "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py index db648be..fc0a71c 100644 --- a/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py +++ b/Chapitre 8 - Valeurs propres, vecteurs propres, diagonalisation/Ch8_lib.py @@ -1,1353 +1,1350 @@ import sys, os sys.path.append('../Librairie') import AL_Fct as al import numpy as np import sympy as sp from IPython.utils import io from IPython.display import display, Latex, Markdown import plotly import plotly.graph_objects as go from sympy import I as I_sym import ipywidgets as widgets from ipywidgets import interact_manual, Layout def vector_plot(A, v): """ Show plot of a two vector v and b to identify if a vector is an eigenvector. (b is equal to A*v with A a matrix) @param A: 2D list (square) @param v: 1D list """ A = np.array(A) v = np.array(v) b = A @ v if v.shape != b.shape or len(v.shape)>1: raise ValueError('Both vector should be of same shape (2,) or (3,)') if v.shape[0]==3: vector_plot_3D(v, b) elif v.shape[0] == 2: vector_plot_2D(v, b) else: raise ValueError('Vector should 2D or 3D') def vector_plot_3D(v, b): """ Show 3D plot of a vector (v) and of b = A * v @param v: numpy array of shape (3,) @param b: numpy array of shape (3,) @return: """ fig = go.Figure() fig.add_trace(go.Scatter3d(x=[0, v[0]], y=[0, v[1]], z=[0, v[2]], line=dict(color='red', width=4), mode='lines+markers', name='$v$')) fig.add_trace(go.Scatter3d(x=[0, b[0]], y=[0, b[1]], z=[0, b[2]], line=dict(color='royalblue', width=4, dash='dash'), mode='lines+markers', name='$A \ v$')) fig.show() def vector_plot_2D(v, b): """ Show 2D plot of a vector (v) and of b = A * v @param v: numpy array of shape (2,) @param b: numpy array of shape (2,) @return: """ fig = go.Figure() fig.add_trace(go.Scatter(x=[0, v[0]], y=[0, v[1]], line=dict(color='red', width=4), mode='lines+markers', name='$v$')) fig.add_trace(go.Scatter(x=[0, b[0]], y=[0, b[1]], line=dict(color='royalblue', width=4, dash='dash'), mode='lines+markers', name='$A \ v$')) fig.show() def interactiveEigenVector(A, v): if not isinstance(A, sp.Matrix) or not isinstance(v, sp.Matrix): raise ValueError('A and v should be of type sympy matrix') display(Latex("Le vecteur $v=" + latexp(v) +"$ est-il un vecteur propre de la matrice $A = "+ latexp(A) + "$")) answer = widgets.RadioButtons( options=["Oui", "Non"], description="Réponse: ", disabled=False) # Matrix Multiplication b = A * v # Check if there is a solution lambda of eq: A*v = lambda * v l = sp.symbols('\lambda', real=True) eq = sp.Eq(b, l * v) sol = sp.solve(eq, l) sol_bool = bool(sol) display(answer) answer_eig = widgets.FloatText( value='1', description='$\lambda: $', disabled=False) def f(): if answer.value == "Oui": answer_bool = True else: answer_bool = False if sol_bool == answer_bool: display(Latex("Correct !")) if sol_bool == True: display(Latex("Quelle est la valeur propre associée ?")) display(answer_eig) def f_eig(): if abs(float(answer_eig.value) - sol[l]) < 1e-6: display(Latex("Correct !")) else: display(Latex("Incorrect, entrez une nouvelle valeur.")) interact_manual(f_eig) else: display(Latex("Incorrect, changez votre réponse.")) interact_manual(f) def f_detailled_sol(): CheckEigenVector(A, v) display(Latex("Si vous n'arrivez pas à résoudre l'exercice, vous pouvez afficher la solution détaillée.")) im = interact_manual(f_detailled_sol) im.widget.children[0].description = 'Solution' return def CheckEigenVector(A, v): """ Check if v is an eigenvector of A, display step by step solution @param A: square sympy Matrix of shape (n,n) @param v: 1D sympy Matrix of shape (n,1) @return: """ if not isinstance(A, sp.Matrix) or not isinstance(v, sp.Matrix): raise ValueError('A and v should be of type sympy matrix') # Check Dimensions if A.shape[0] != A.shape[1] or v.shape[0] != A.shape[1]: raise ValueError('Dimension problem, A should be square (n x n) and v (n x 1)') if v == sp.zeros(v.shape[0], 1): display(Latex("$v$ est le vecteur nul, il ne peut pas être un vecteur propre par définition.")) else: # Matrix Multiplication b = A * v # Print some explanation about the method display(Latex("On voit que $ b = A v = " + latexp(b) + "$")) display(Latex("On cherche alors un nombre $\lambda \in \mathbb{R}$ tel que $b = \lambda v" \ + "\Leftrightarrow" + latexp(b) + " = \lambda" + latexp(v) + '$')) # Symbol for lambda l = sp.symbols('\lambda', real=True) # Check if there is a solution lambda of eq: A*v = lambda * v eq = sp.Eq(b, l * v) sol = sp.solve(eq, l) # If there is l st b = l*v if sol: display(Latex("Il existe bien une solution pour $\lambda$. Le vecteur $v$ est donc un vecteur \ propre de la matrice $A$.")) display(Latex("La valeur propre associée est $\lambda = " + sp.latex(sol[l]) + "$.")) # Otherwise else: display(Latex("L'equation $b = \lambda v$ n'a pas de solution.")) display(Latex("Le vecteur $v$ n'est donc pas un vecteur propre de la matrice $A$.")) def ch8_1_exo_2(A, l, vp, v): """ Display step by step @param A: Square sympy matrix @param l: eigenvalue (float or int) @param vp: Boolean, given answer to question is l an eigenvalue of A @param v: proposed eigenvector @return: """ if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy matrix") # Check Dimensions if A.shape[0] != A.shape[1] or v.shape[0] != A.shape[1]: raise ValueError('Dimension problem, A should be square (n x n) and v (n x 1)') n = A.shape[0] eig = list(A.eigenvals().keys()) for i, w in enumerate(eig): eig[i] = float(w) eig = np.array(eig) if np.any(abs(l-eig) < 10**-10): if vp: display(Latex("$\lambda = " + str(l) + "$ est bien une valeur propre de la matrice $A$.")) else: display(Latex("Non, $\lambda = " + str(l) + "$ est bien une valeur propre de la matrice $A$.")) if v != sp.zeros(n, 1): # Check the eigen vector v z = sp.simplify(A * v - l * v) if z == sp.zeros(n, 1): display(Latex("$v$ est bien un vecteur propre de $A$ associé à $\lambda = " + str(l) + "$ car on a:")) display(Latex("$$" + latexp(A) + latexp(v) + "= " + str(l) + "\cdot " + latexp(v) + "$$")) else: display(Latex("$v$ n'est pas un vecteur propre de $A$ associé à $\lambda = " + str(l) + "$ car on a:")) display(Latex("$$" + latexp(A) + latexp(v) + "\\neq \lambda" + latexp(v) + "$$")) else: display(Latex("$v$ est le vecteur nul et ne peut pas être par définition un vecteur propre.")) else: if not vp: display(Latex("En effet, $\lambda$ n'est pas une valeur propre de $A$.")) else: display(Latex("Non, $\lambda = " + str(l) + "$ n'est pas une valeur propre de $A$.")) def interactiveEigenVal(A, l): eig = list(A.eigenvals().keys()) for i, w in enumerate(eig): eig[i] = float(w) eig = np.array(eig) if np.any(abs(l - eig) < 10 ** -10): sol = True else: sol = False display(Latex("$\lambda = " + str(l) + "$ est-elle une valeur propre de la matrice $A =" + latexp(A) +" $ ? ")) answer = widgets.RadioButtons( options=["Oui", "Non"], description="Réponse: ", disabled=False) display(answer) eig_answer = widgets.Text(value='[1, 2, 3]', description='$v = $', disabled=False) def f(): if answer.value == "Oui": answer_bool = True else: answer_bool = False if answer_bool == sol: display(Latex("Correct !")) if sol: display(Latex("Entrez un vecteur propre de la matrice sous la forme d'une liste " "(exemples: 2D: [1, 2], 3D: [1 , 2, 3]).")) display(eig_answer) def f_vect(): v = eval(eig_answer.value) v = sp.Matrix(v) if (sp.simplify(A*v - l*v)).norm() < 1e-8: display(Latex("Correct, on a bien $A v = \lambda v$")) else: display(Latex("Incorrect, $A v \\neq \lambda v$")) interact_manual(f_vect) else: display(Latex("Incorrect, changez votre réponse.")) interact_manual(f) return def red_matrix(A, i, j): """ Return reduced matrix (without row i and col j)""" row = [0, 1, 2] col = [0, 1, 2] row.remove(i - 1) col.remove(j - 1) return A[row, col] def pl_mi(i, j, first=False): """ Return '+', '-' depending on row and col index""" if (-1) ** (i + j) > 0: if first: return "" else: return "+" else: return "-" def brackets(expr): """Takes a sympy expression, determine if it needs parenthesis and returns a string containing latex of expr with or without the parenthesis.""" expr_latex = sp.latex(expr) if '+' in expr_latex or '-' in expr_latex: return "(" + expr_latex + ")" else: return expr_latex def poly_char_3x3(A): A = sp.Matrix(A) if A.shape[0] != 3 or A.shape[1] != 3: raise ValueError('Matrix should be 3 by 3') l = sp.symbols('\lambda') I = sp.eye(3) Determinant_3x3(A - l * I, True, True) return def Determinant_3x3(A, step_by_step=True, row=True, n=1): """ Step by step computation of the determinant of a 3x3 sympy matrix strating with given row/col number @param A: 3 by 3 sympy matrix @param step_by_step: Boolean, True: print step by step derivation of det, False: print only determinant @param row: True to compute determinant from row n, False to compute determinant from col n @param n: row or col number to compute the determinant from (int between 1 and 3) @return: display step by step solution for """ if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy matrix") if A.shape != (3, 3): raise ValueError('Dimension of matrix A should be 3x3. The input A must be a sp.Matrix of shape (3,3).') if n < 1 or n > 3 or not isinstance(n, int): raise ValueError('n should be an integer between 1 and 3.') # Construc string for determinant of matrix A detA_s = sp.latex(A).replace('[', '|').replace(']', '|') # To print all the steps if step_by_step: # If we compute the determinant with row n if row: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, n, 1) A2 = red_matrix(A, n, 2) A3 = red_matrix(A, n, 3) detA1_s = sp.latex(A1).replace('[', '|').replace(']', '|') detA2_s = sp.latex(A2).replace('[', '|').replace(']', '|') detA3_s = sp.latex(A3).replace('[', '|').replace(']', '|') line1 = "$" + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[n - 1, 0]) + detA1_s + pl_mi(n, 2) + \ brackets(A[n - 1, 1]) + detA2_s + pl_mi(n, 3) + brackets(A[n - 1, 2]) + detA3_s + '$' line2 = '$' + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[n - 1, 0]) + "\cdot (" + sp.latex(sp.det(A1)) \ + ")" + pl_mi(n, 2) + brackets(A[n - 1, 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")" + \ pl_mi(n, 3) + brackets(A[n - 1, 2]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # If we compute the determinant with col n else: # Matrix with row i and col j removed (red_matrix(A, i, j)) A1 = red_matrix(A, 1, n) A2 = red_matrix(A, 2, n) A3 = red_matrix(A, 3, n) detA1_s = sp.latex(A1).replace('[', '|').replace(']', '|') detA2_s = sp.latex(A2).replace('[', '|').replace(']', '|') detA3_s = sp.latex(A3).replace('[', '|').replace(']', '|') line1 = "$" + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[0, n - 1]) + detA1_s + pl_mi(n, 2) + \ brackets(A[1, n - 1]) + detA2_s + pl_mi(n, 3) + brackets(A[2, n - 1]) + detA3_s + '$' line2 = '$' + detA_s + ' = ' + pl_mi(n, 1, True) + brackets(A[0, n - 1]) + "\cdot (" + sp.latex(sp.det(A1))\ + ")" + pl_mi(n, 2) + brackets(A[1, n - 1]) + "\cdot (" + sp.latex(sp.det(A2)) + ")" + \ pl_mi(n, 3) + brackets(A[2, n - 1]) + "\cdot (" + sp.latex(sp.det(A3)) + ')$' line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.det(A))) + '$' # Display step by step computation of determinant display(Latex(line1)) display(Latex(line2)) display(Latex(line3)) # Only print the determinant without any step else: display(Latex("$" + detA_s + "=" + sp.latex(sp.det(A)) + "$")) def solve_poly_char(A): A = sp.Matrix(A) l = sp.symbols('\lambda') I = sp.eye(3) if A.shape[0] != 3 or A.shape[1] != 3: raise ValueError('Matrix should be 3 by 3') # Resolution de l'équation avec sympy eq = sp.Eq(sp.det(A - l * I), 0) sol = sp.solve(eq, l) display(Latex("Les racines du polynôme caractéristiques (les valeurs propres de A) sont: $" + sp.latex(sol) + "$.")) return def interactive_valeur_propres(A): A = sp.Matrix(A) eig = list(A.eigenvals().keys()) for i, w in enumerate(eig): eig[i] = float(w) eig = np.array(eig) eig.sort() answer_eig = widgets.Text(value="[0, 0]", description="Valeur(s) propre(s)", disabled=False) display(Latex("Quelles sont les valeurs propres de la matrice $A= " + latexp(A) + "$ ? " "(Entrez les valeurs propres sous la forme d'une liste: [$\lambda_1$, $\lambda_2$, ...]" )) display(answer_eig) def f(): eig_prop = eval(answer_eig.value) eig_prop = np.array(eig_prop) eig_prop.sort() if eig_prop.shape != eig.shape: display(Latex("Le nombre de valeur propre n'est pas correct.")) elif np.allclose(eig, eig_prop): display(Latex("Correct !")) else: display(Latex("Incorrect, entrez de nouvelles valeurs.")) interact_manual(f) def f2(): valeurs_propres(A) display(Latex("Si vous n'arrivez pas à trouver les valeurs propres, vous pouvez afficher la solution détaillée.")) im = interact_manual(f2) im.widget.children[0].description = "Solution" def valeurs_propres(A): A = sp.Matrix(A) if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy matrix") if A.shape[0] != A.shape[1]: raise ValueError("A should be a square matrix") l = sp.symbols('\lambda') n = A.shape[0] poly = sp.det(A - l * sp.eye(n)) poly_exp = sp.expand(poly) poly_factor = sp.factor(poly) det_str = sp.latex(poly_exp) + "=" + sp.latex(poly_factor) display(Latex("On cherche les valeurs propres de la matrice $ A=" + latexp(A) + "$.")) display(Latex("Le polynome caractéristique de $A$ est: $$\det(A- \lambda I)= " + det_str + "$$")) eq = sp.Eq(poly, 0) sol = sp.solve(eq, l) if len(sol) > 1: display(Latex("Les racines du polynôme caractéristique sont $" + sp.latex(sol) + "$.")) display(Latex("Ces racines sont les valeurs propres de la matrice $A$.")) else: display(Latex("L'unique racine du polynôme caractéristique est" + str(sol[0]))) def texVector(v): """ Return latex string for vertical vector Input: v, 1D np.array() """ n = v.shape[0] return al.texMatrix(v.reshape(n, 1)) def interactive_basis(A): A = sp.Matrix(A) eig = list(A.eigenvals().keys()) for i, w in enumerate(eig): eig[i] = float(w) eig = np.array(eig) display(Latex("Trouvez une valeur propre de $A = " + latexp(A) + "$.")) eig_answer = widgets.FloatText(value='0', description="$\lambda: $", disabled=False) display(eig_answer) def f_eig(): if np.any(np.abs(eig_answer.value - eig) < 10**-3): display(Latex("Correct, $\lambda = "+ str(eig_answer.value) + "$ est bien une valeur propre de $A$")) basis, basic_idx, free_idx = eigen_basis(A, eig_answer.value, disp=False, dispA=False, return_=True) dim_sol = len(free_idx) display(Latex("Quelle est la dimension de l'espace propre associé à $\lambda = " + str(eig_answer.value) + "$")) dim_answer = widgets.IntText(value='0', description="Dim: ", disabled=False) display(dim_answer) def f_dim(): if (dim_answer.value == dim_sol): display(Latex("Correct, la dimension de l'espace propre associé à $\lambda = " + str(eig_answer.value)+ "$ est bien " + str(dim_sol) + ".")) basis_text = np.ones((dim_sol, A.shape[0])) basis_text = str(basis_text.tolist()) display(Latex("Entrez une base de vector propres. \nLes valeurs sont par défaut 1, " + "changez-les en gardant bien la même synthaxe. ")) basis_answer = widgets.Text(value=basis_text, description="Basis", disabled=False) display(basis_answer) def f_basis(): prop_basis = eval(basis_answer.value) if check_basis(basis, prop_basis): display(Latex("Correct, la base proposée est bien une base de l'espace propre associé à " "$\lambda = " + str(eig_answer.value) + "$.")) else: display(Latex("Incorrect, la base proposée n'est pas une base de l'espace propre associé à " "$\lambda = " + str(eig_answer.value) + "$. Entrez une autre base.")) interact_manual(f_basis) else: display(Latex("Incorrect, la dimension de l'espace propre associé à $\lambda = " + str(eig_answer.value) + "$ n'est pas " + str(dim_answer.value) + ".")) interact_manual(f_dim) def f_detailled_sol(): eigen_basis(A, eig_answer.value, dispA=False) display(Latex("Si vous n'arrivez pas à trouver une base de l'espace propre, vous pouvez afficher " "la solution détaillée en cliquant ici.")) im = interact_manual(f_detailled_sol) im.widget.children[0].description = 'Solution détaillée' else: display(Latex("Incorrect, $\lambda = "+ str(eig_answer.value) + "$ n'est pas une valeur propre de $A$. " + "Entrez une autre valeur.")) def show_eig(): display(Latex("Les valeurs propres de $A$ sont " + str(eig) + ".")) interact_manual(f_eig) display(Latex("Si vous n'arrivez pas à trouver les valeurs propres, vous pouvez les afficher en cliquant ici.")) im = interact_manual(show_eig) im.widget.children[0].description = 'Afficher valeurs propres' - - - 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 """ prop = np.array(prop, dtype=np.float64) # number of vector in basis n = len(sol) # Check dimension of proposed eigenspace if n != len(prop): display(Latex("Le nomber de vecteur(s) propre(s) donné(s) est incorrecte. " + "La dimension de l'espace propre est égale au nombre de variable(s) libre(s).")) 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 eigen_basis(A, l, prop_basis=None, disp=True, return_=False, dispA=True): """ Display step by step method for finding a basis of the eigenspace of A associated to eigenvalue l Eventually check if the proposed basis is correct. Display or not @param A: Square sympy Matrix with real coefficients @param l: real eigen value of A (float or int) @param prop_basis: Proposed basis: list of base vector (type list of list of floats) @param disp: boolean if display the solution. If false it displays nothing @param return_: boolean if return something or nothing @return: basis: a correct basis for the eigen space (2D numpy array) basic_idx: list with indices of basic variables of A - l*I free_idx: list with indices of free variables of A - l*I """ A = sp.Matrix(A) if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy Matrix.") # Check if A is square n = A.shape[0] if n != A.shape[1]: raise ValueError('A should be a square matrix.') # Compute eigenvals in symbolic eig = A.eigenvals() eig = list(eig.keys()) # Deal with complex number (removal) complex_to_rm = [] for idx, el in enumerate(eig): if not el.is_real: complex_to_rm.append(idx) for index in sorted(complex_to_rm, reverse=True): del eig[index] eig = np.array(eig) # evaluate symbolic expression eig_eval = np.array([float(el) for el in eig]) # Check that entered eigenvalue is indeed an eig of A if np.all(abs(l - eig_eval) > 1e-10) and len(eig) > 0: display(Latex("$\lambda$ n'est pas une valeur propre de $A$.")) return None, None, None # Change value of entered eig to symbolic expression (for nice print) l = eig[np.argmin(np.abs(l - eig))] I = sp.eye(n) Mat = A - l * I b = np.zeros(n) if disp: if dispA: display(Latex("On a $ A = " + latexp(A) + "$.")) display(Latex("On cherche une base de l'espace propre associé à $\lambda = " + str(l) + "$.")) # ER matrix e_Mat, basic_idx = Mat.rref() # Idx of basic and free varialbe basic_idx = list(basic_idx) basic_idx.sort() free_idx = [idx for idx in range(n) if idx not in basic_idx] free_idx.sort() n_free = len(free_idx) # String to print free vars free_str = "" for i in range(n): if i in free_idx: free_str += "x_" + str(i + 1) + " \ " # Display echelon matrix if disp: display(Latex("On échelonne la matrice du système $A -\lambda I = 0 \Rightarrow " + al.texMatrix(np.array(Mat), np.reshape(b, (n, 1))) + "$")) display(Latex("On obtient: $" + al.texMatrix(np.array(e_Mat[:, :n]), np.reshape(b, (n, 1))) + "$")) display(Latex("Variable(s) libre(s): $" + free_str + "$")) # Build a list of n_free basis vector: # first dim: which eigenvector (size of n_free) # second dim: which element of the eigenvector (size of n) basis = np.zeros((n_free, n)) for i in range(n_free): basis[i, free_idx[i]] = 1.0 for idx, j in enumerate(free_idx): for i in basic_idx: basis[idx, i] = - float(e_Mat[i, j]) # Show calculated basis basis_str = "" for idx, i in enumerate(free_idx): basis_str += "\\alpha_" + str(idx + 1) + " \cdot" + texVector(basis[idx]) if idx < n_free - 1: basis_str += " + " if disp: display(Latex("On peut donc exprimer les vecteurs de l'espace propre comme: $" + basis_str + "$")) if prop_basis is not None and disp: correct_answer = check_basis(basis, prop_basis) if correct_answer: display(Latex("La base donnée est correcte car on peut retrouver la base calculée ci-dessus" \ " avec une combinaison linéaire de la base donnée. " "Aussi les deux bases ont bien le même nombre de vecteurs.")) else: display(Latex("La base donnée est incorrecte.")) if return_: return basis, basic_idx, free_idx def generate_eigen_vector(basis, l, limit): """ Function to generate a random eigenvector associated to a eigenvalue given a basis of the eigenspace The returned eigenvector is such that itself and its multiplication with the matrix will stay in range of limit in order to have a nice plot @param basis: basis of eigenspace associated to eigenvalue lambda @param l: eigenvalue @param limit: limit of the plot: norm that the engenvector or its multiplication with the matrix will not exceed @return: eigen vector (numpy array) """ n = len(basis) basis_mat = np.array(basis).T basis_mat = basis_mat.astype(np.float64) coeff = 2 * np.random.rand(n) - 1 vect = basis_mat @ coeff if abs(l) <= 1: vect = vect / np.linalg.norm(vect) * (limit - 1) else: vect = vect / np.linalg.norm(vect) * (limit - 1) / l return vect def plot3x3_eigspace(A, xL=-10, xR=10, p=None, plot_vector=False): # To have integer numbers if p is None: p = xR - xL + 1 n = A.shape[0] # Check 3 by 3 if n != 3 or n != A.shape[1]: raise ValueError("A should be 3 by 3") w = A.eigenvals() w = list(w.keys()) # Deal with complex number (removal) complex_to_rm = [] for idx, el in enumerate(w): if not el.is_real: complex_to_rm.append(idx) for index in sorted(complex_to_rm, reverse=True): del w[index] display("Des valeurs propres sont complexes, on les ignore.") if len(w)==0: display("Toute les valeurs propres sont complexes.") return gr = 'rgb(102,255,102)' org = 'rgb(255,117,26)' # red = 'rgb(255,0,0)' blue = 'rgb(51, 214, 255)' colors = [blue, gr, org] s = np.linspace(xL, xR, p) t = np.linspace(xL, xR, p) tGrid, sGrid = np.meshgrid(s, t) data = [] A_np = np.array(A).astype(np.float64) for i, l in enumerate(w): l_eval = float(l) basis, basic_idx, free_idx = eigen_basis(A, l_eval, disp=False, return_=True) n_free = len(basis) if n_free != len(free_idx): raise ValueError("len(basis) and len(free_idx) should be equal.") gr = 'rgb(102,255,102)' colorscale = [[0.0, colors[i]], [0.1, colors[i]], [0.2, colors[i]], [0.3, colors[i]], [0.4, colors[i]], [0.5, colors[i]], [0.6, colors[i]], [0.7, colors[i]], [0.8, colors[i]], [0.9, colors[i]], [1.0, colors[i]]] X = [None] * 3 if n_free == 2: X[free_idx[0]] = tGrid X[free_idx[1]] = sGrid X[basic_idx[0]] = tGrid * basis[0][basic_idx[0]] + sGrid * basis[1][basic_idx[0]] plot_obj = go.Surface(x=X[0], y=X[1], z=X[2], showscale=False, showlegend=True, colorscale=colorscale, opacity=1, name="$ \lambda= " + sp.latex(l) + "$") elif n_free == 1: plot_obj = go.Scatter3d(x=t * basis[0][0], y=t * basis[0][1], z=t * basis[0][2], line=dict(colorscale=colorscale, width=4), mode='lines', name="$\lambda = " + sp.latex(l) + "$") elif n_free == 3: display(Latex("La dimension de l'espace propre de l'unique valeur propre est 3: tous les vecteurs" \ "$v \in \mathbb{R}^3 $ appartiennent à l'espace propre de la matrice $A$." \ "On ne peut donc pas reprensenter sous la forme d'un plan ou d'une droite.")) return else: print("error") return data.append(plot_obj) if (plot_vector): v1 = generate_eigen_vector(basis, l_eval, xR) v2 = A_np @ v1 data.append(go.Scatter3d(x=[0, v1[0]], y=[0, v1[1]], z=[0, v1[2]], line=dict(width=6), marker=dict(size=4), mode='lines+markers', name='$v_{' + sp.latex(l) + '}$')) data.append(go.Scatter3d(x=[0, v2[0]], y=[0, v2[1]], z=[0, v2[2]], line=dict(width=6, dash='dash'), marker=dict(size=4), mode='lines+markers', name="$A \ v_{" + sp.latex(l) + "}$")) layout = go.Layout( showlegend=True, # not there WHY???? --> LEGEND NOT YET IMPLEMENTED FOR SURFACE OBJECTS!! legend=dict(orientation="h"), autosize=True, width=800, height=800, scene=go.layout.Scene( xaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)', range=[xL, xR] ), yaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)', range=[xL, xR] ), zaxis=dict( gridcolor='rgb(255, 255, 255)', zerolinecolor='rgb(255, 255, 255)', showbackground=True, backgroundcolor='rgb(230, 230,230)', range=[xL, xR] ), aspectmode="cube", ) ) fig = go.Figure(data=data, layout=layout) plotly.offline.iplot(fig) return def plot2x2_eigspace(A, xL = -10, xR = 10, p=None): if p is None: p = xR - xL + 1 w = A.eigenvals() w = list(w.keys()) # Deal with complex number (removal) complex_to_rm = [] for idx, el in enumerate(w): if not el.is_real: complex_to_rm.append(idx) for index in sorted(complex_to_rm, reverse=True): del w[index] display("Une valeur propre est complexe, on l'ignore.") if len(w) == 0: display("Toute les valeurs propres sont complexes.") return data = [] for i, l in enumerate(w): l_eval = float(l) basis, basic_idx, free_idx = eigen_basis(A, l_eval, disp=False, return_=True) n_free = len(basis) if n_free != len(free_idx): raise ValueError("len(basis) and len(free_idx) should be equal.") if n_free == 2: display(Latex("Tous les vecteurs du plan appartiennent à l'espace propre de A associé à $\lambda = " \ + sp.latex(l) + "$. On ne peut donc pas le représenter.")) return else: t = np.linspace(xL, xR, p) trace = go.Scatter(x=t*basis[0][0], y=t*basis[0][1], marker=dict(size=6), mode='lines+markers', name="$\lambda = " + sp.latex(l) + "$") data.append(trace) layout = go.Layout(showlegend=True, yaxis=dict(scaleanchor="x", scaleratio=1)) fig = go.Figure(data=data, layout=layout) plotly.offline.iplot(fig) return def plot_eigspace(A, xL=-10, xR=10, p=None): """ Plot the eigenspaces associated to all eigenvalues of A @param A: Sympy matrix of shape (2,2) or (3,3) @param xL: Left limit of plot @param xR: Right limit of plot @param p: Number of points to use """ A = sp.Matrix(A) if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy Matrix.") n = A.shape[0] # Check 3 by 3 or 2 by 2 if (n != 2 and n != 3) or n != A.shape[1]: raise ValueError("A should be 2 by 2 or 3 by 3.") if n == 2: plot2x2_eigspace(A, xL, xR, p) else: plot3x3_eigspace(A, xL, xR, p) def latexp(A): """ Function to output latex expression of a sympy matrix but with round parenthesis @param A: sympy matrix @return: latex string """ return sp.latex(A, mat_delim='(', mat_str='matrix') def ch8_8_ex_1(A): """ Check if a matrix is diagonalisable. @param A: sympy square matrix @param prop_answer: boolean, answer given by the student @return: """ A = sp.Matrix(A) if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy Matrix.") n = A.shape[0] if n != A.shape[1]: raise ValueError('A should be a square matrix.') display(Latex("Dans ce graphique, les espaces propres de toutes les valeurs propres de $A$ sont représentés.")) plot_eigspace(A) eig = A.eigenvects() dim_geom = 0 for x in eig: dim_geom += len(x[2]) sol = dim_geom == n display(Latex("La matrice $A =" + latexp(A) + "$ est-elle diagonalisable ?")) answer = widgets.RadioButtons( options=["Oui", "Non"], description="Réponse: ", disabled=False) 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. Vous pouvez revoir la méthode donnée plus bas.")) if sol: display(Latex("La matrice est diagonalisable.")) else: display(Latex("La matrice n'est pas diagonalisable.")) interact_manual(f) def isDiagonalizable(A): """ Step by step method to determine if a given matrix is diagonalizable. This methods uses always (I think) the easiest way to determine it (as seen in the MOOC) @param A: sympy matrix @return: nothing """ if not isinstance(A, sp.Matrix): raise ValueError("A should be a sympy Matrix.") n = A.shape[0] if n != A.shape[1]: raise ValueError('A should be a square matrix.') display(Latex("On cherche à déterminer si la matrice $A=" + latexp(A) + "$ de taille $n \\times n$ avec $n = " + str(n) + "$ est diagonalisable.")) if A.is_lower or A.is_upper: display(Latex("Les valeurs propres sont simple à trouver, ce sont les éléments diagonaux.")) else: valeurs_propres(A) # Check if eigenvalue are all distincts eig = A.eigenvects() if len(eig) == n: display(Latex("On a $n$ valeurs propres distinctes. La matrice est donc diagonalisable.")) return else: display(Latex("Les valeurs propres ne sont pas toutes distinctes. On va donc vérifier la multiplicité " + "géométrique des valeurs propres ayant une multiplicité algébrique supérieur à 1.")) # Some list to have info about eigenvalues with algebraic mult > 1 idx = [] eigenvalues = [] mult_al = [] mult_geo = [] for i in range(len(eig)): if eig[i][1] > 1: idx.append(i) eigenvalues.append(eig[i][0]) mult_al.append(eig[i][1]) mult_geo.append(len(eig[i][2])) display(Latex("L'ensemble des valeurs propres ayant une multiplicité algébrique supérieur à 1 est " + str( eigenvalues) + ".")) for i, l in enumerate(eigenvalues): display(Markdown("**On calcule la multiplicité géométrique pour $\lambda= " + sp.latex(l) + "$ ayant une multiplicité algébrique de " + str(mult_al[i]) + ".**")) basis, basic, free = eigen_basis(A, l, prop_basis=None, disp=True, return_=True) display(Markdown("**La multiplicité géométrique pour $\lambda= " + sp.latex(l) + "$ est de " + str(len(free)) + ".**")) if (len(free) < mult_al[i]): display(Markdown("**La multiplicité géométrique est strictement inférieur à la multiplicité" + " algébrique pour cette valeur propre. La matrice n'est donc pas diagonalisable.**")) return else: display(Latex("On a bien multiplicité algébrique = multiplicité géométrique pour cette valeur propre.")) display(Markdown("**Toutes les valeurs propres ont une multiplicité algébrique et géométrique égales." + " La matrice $A$ est donc bien diagonalisable !**")) def interactive_is_diag(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 $A = " + latexp(A) + "$ est-elle diagonalisable ?")) answer = widgets.RadioButtons( options=["Oui", "Non"], description="Réponse: ", disabled=False) display(answer) sol = A.is_diagonalizable() 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 est diagonalisable.")) else: display(Latex("La matrice n'est pas diagonalisable.")) interact_manual(f) def f_sol(): isDiagonalizable(A) display(Latex("Si vous n'arrivez pas à trouver la solution, vous pouvez afficher la solution détaillée en cliquant " "ici !")) im = interact_manual(f_sol) im.widget.children[0].description = 'Solution' def find_P_D(A, P_user, D_user, step_by_step=True): """ :param A: sympy square matrix :param P_user: sympy square matrix :param D_user: sympa sqaure matrix :param step_by_step: Print step by step solution :return: """ A = sp.Matrix(A) P_user = sp.Matrix(P_user) D_user = sp.Matrix(D_user) n = A.shape[0] if n != A.shape[1] or P_user.shape[0] != n or P_user.shape[1] != n or D_user.shape[0] != n or D_user.shape[1] != n: raise ValueError('A, P and D should be a square matrix of the same size.') if not D_user.is_diagonal(): raise ValueError("D should be a diagonal matrix.") if not A.is_diagonalizable(): raise ValueError("A is not diagonalizable.") if (P_user.det()!=0): P_1_user = P_user ** -1 if ((A - P_user * D_user * P_1_user).norm() < 1e-10): display(Latex("Votre réponse est correcte, on a bien $A = PDP^{-1}$")) else: display(Latex("Votre réponse est incorrecte, $A \\neq PDP^{-1}$")) else: display(Latex("La matrice $P_{user} = " + latexp(P_user) + "$ n'est pas inversible.")) def step_by_step_sol(): display(Latex("On cherche à déterminer les matrices $P$ et $D$ telles que $A=" + latexp(A) + "= P D P^{-1}$.")) if A.is_lower or A.is_upper: display(Latex("Les valeurs propres sont simple à trouver, ce sont les éléments diagonaux.")) else: valeurs_propres(A) display( Latex("Pour chaque valeur propre $\lambda_i$, on cherche $n_i$ vecteurs propres linéairement indépendants" + " (avec $n_i = \dim E_{\lambda_i}$). On trouve ces vecteurs on calculant une base pour " + "chaque espace propre. On peut ensuite utiliser les vecteurs de base comme colonnes pour la " + "matrice $P$.")) eig = A.eigenvects() # Some list to have info about eigenvalues with algebraic mult > 1 idx = [] eigenvalues = [] mult_al = [] mult_geo = [] D = sp.zeros(n) for i in range(len(eig)): idx.append(i) eigenvalues.append(eig[i][0]) mult_al.append(eig[i][1]) mult_geo.append(len(eig[i][2])) P = [] k = 0 for i, l in enumerate(eigenvalues): basis, _, _ = eigen_basis(A, l, return_=True, disp=step_by_step, dispA=False) for j in range(len(basis)): D[k, k] = l k += 1 P.append(basis[j]) P = np.transpose(np.array(P)) if np.all(np.mod(P, 1) == 0): P = P.astype(int) P = sp.Matrix(P) display(Latex("En utilisant les vecteurs de base trouvés ci dessus pour les colonnes de la matrice $P$ et en " + "plaçant les valeurs propres de $A$ correspondantes sur la diagonal de $D$, on obtient " + "les matrices $P$ et $D$.")) display(Latex("$P = " + latexp(P) + "$, " + "$D = " + latexp(D) + "$")) display(Latex("Si vous n'arrivez pas à résoudre l'exercice, vous pouvez afficher la solution détaillée.")) im = interact_manual(step_by_step_sol) im.widget.children[0].description = 'Solution' def diagonalizeComplex(A): """ @param A: """ A = sp.Matrix(A) if not A.is_diagonalizable(): display(Latex("A n'est pas diagonalisable.")) return lamda = sp.symbols('lamda') poly = A.charpoly(lamda) poly = sp.factor(poly, extension=[I_sym]) eig = A.eigenvects() eigenval = [] mult = [] for el in eig: eigenval.append(sp.simplify(el[0])) mult.append(el[1]) display(Latex("Le polynome caractéristique de la matrice $A = " + latexp(A) + "$ est $ c_A (\lambda) = " + sp.latex( poly) + "$")) display(Latex("Les valeurs propres de A sont donc: " + listsp_to_str(eigenval))) display(Latex("Pour chaque valeur propre $\lambda$, on calcule une base de l'espace propre associé " "($\ker (A -\lambda I)$). On se sert ensuite des vecteurs propres (vecteur de base de l'espaces" + " propre) pour diagonaliser la matrice.")) k = 0 P = sp.zeros(A.shape[0], A.shape[0]) D = sp.zeros(A.shape[0], A.shape[0]) for i, l in enumerate(eigenval): display(Latex( "Pour la valeur propres $\lambda = " + sp.latex(l) + "$, on trouve une base de l'espace propre associé. " + "On obtient comme base: " + listsp_to_str(eig[i][2]))) for vec in eig[i][2]: P[:, k] = vec D[k, k] = l k += 1 P = sp.simplify(P) D = sp.simplify(D) display(Latex("Avec la matrice $D= " + latexp(D) + "$ on obtient la matrice $P = " + latexp(P) + "$.")) display(Latex("La matrice $A$ se diagonalise donc avec comme $A = P D P^{-1}$")) display(Latex("$P D P^{-1} = " + latexp(P) + latexp(D) + latexp(sp.simplify(P ** -1)) + " = " + latexp(sp.simplify(P * D * P ** -1)) + " = A$ ")) def listsp_to_str(splist): out = "$" + sp.latex(sp.simplify(splist[0]), mat_delim='(') + "$" if len(splist) == 1: return out for i in range(1, len(splist) - 1): out += ", $" + sp.latex(sp.simplify(splist[i]), mat_delim='(') + "$" out += " et $" + sp.latex(sp.simplify(splist[-1]), mat_delim='(') + "$" return out def showMatVect(A,v): display(Latex(" $A =" + latexp(A) + "\hspace{20mm} v= " + latexp(v) + "$")) def check_a_pdp(A, P, D): A = sp.Matrix(A) P = sp.Matrix(P) D = sp.Matrix(D) if P.det() == 0: display(Latex("La matrice P n'est pas inversible.")) else: PDP_1 = P * D * P ** -1 display(Latex("$A = " + latexp(A) + " \hspace{20mm} P = " + latexp(P) + "\hspace{20mm} D = " + latexp(D) + "$")) display(Latex("$ P D P^{-1} = " + latexp(PDP_1) + "$")) if (A - PDP_1).norm() < 1e-10: display(Latex("Votre réponse est correcte ! On a bien $A = P D P^{-1}$")) else: display(Latex("Votre réponse est incorrecte ! On a $A \\neq P D P^{-1}$")) def f(): diagonalizeComplex(A) display(Latex("Si vous n'arrivez pas à résoudre l'exercice, vous pouvez afficher la solution détaillée.")) im = interact_manual(f) im.widget.children[0].description = 'Solution'