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 431f968..b30a878 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,1313 +1,1447 @@ #!/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) 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 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() def solution(e): out.clear_output() 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): 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.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 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() def solution(e): out.clear_output() Sarrus_3x3(matrix) button.on_click(solution) display(box) display(out) def Sarrus_3x3(A): """ 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]) 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] # # 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(sp.det(A))) + '$')) ## 7.2 def ch_7_2_ex1(M): ch7_1_ex1(M) def question7_2a(): a = sp.Matrix([[4, -1, 4], [6, 2, -5], [-3, 3, 1]]) 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]]) 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]]) 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' 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 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) display(box) 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.")) 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) 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) ## 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]) 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 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) 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("Pour determiner si la matrice $" + latexp(A) + "$ est inversible, on calcule son déterminant.")) Determinant_3x3(A) if sp.det(A) == 0: display(Latex("Le déterminant est égal à zéro, donc la matrice est singulière." )) else: 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 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)) + A = sp.Matrix([[-1, -2, 1, 0, 1], [0, 1, -2, 4, 9], [-2, -4, 5, 3, 3], [2, 4, -2, 0, -2], [1, 2, 6, -3, 3]]) 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( "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 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() def solution(e): out.clear_output() 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) ## 7.4 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("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_4_2(): + A = sp.Matrix([[1, -2, 0], [2, 0, -1], [1, 1, -1]]) + B = A.inv() + + det_answer = widgets.Text(value='0.0', description="$\det C = $ ", disabled=False) + display(det_answer) + + def check_det(): + if np.abs(float(eval(det_answer.value)) - 1.0) > 1e-6: + display(Latex("Incorrect.")) + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + out = widgets.Output() + + @out.capture() + def solution(e): + display(Latex("On trouve d'abord $C$ en multipliant $A$ et $B$.")) + display(Latex("$C = A B = " + latexp(A) + latexp(B) + " = " + latexp(sp.simplify(A * B)) + "$")) + display(Latex("On voit que $C$ est la matrice identité. Son déterminant est donc 1.")) + + button.on_click(solution) + + display(box) + display(out) + else: + display(Latex("Correct! Le déterminant de $C$ est 1 car $C$ est la matrice identité. " \ + "Il était plus simple dans ce cas de d'abord multiplier $A$ et $B$ pour obtenir " \ + "$C$ et calculer ensuite directement son déterminant.")) + + im = interact_manual(check_det) + im.widget.children[0].description = 'Vérifier réponse' + + +def question7_4_3(): 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 = 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) + question7_4_3_sol(A, B, C) -def question7_4_2_sol(A,B,C): +def question7_4_3_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) ## 7.5 -def plotDeterminant3D(A): +def ex_7_5_1(A, orig=[0, 0]): + A_sp = sp.Matrix(A) + area = sp.Abs(A_sp.det()) + A = np.array(A) + + def sol_mat(e): + display(Latex("On voit sur la figure que des vecteurs qui définissent le parallélogramme sont: $" + latexp(A_sp[:, 0]) + "$ et $" + latexp(A_sp[:, 1]) + "$.")) + display(Latex("Une matrice definissant le parallélogramme est donc: $" + latexp(A_sp) + "$.")) + display(Latex("Completez votre réponse pour continuer l'exercice.")) + + def sol_area(e): + display(Latex("Pour trouver l'aire du parallélogramme, on prend simplement la valeur absolue du déterminant de la matrice trouvée plus haut.")) + display(Latex('Area $= |\det ' + latexp(A_sp) + '| = |' + latexp(A_sp.det()) + "| = " + latexp(sp.Abs(A_sp.det())) + "$")) + + if A.shape != (2, 2): + raise ValueError("La matrice doit être 2x2.") + + plotPara(A, orig=orig) + + style = {'description_width': 'initial'} + matrix_answer = widgets.Text(value='[[0, 0], [0, 0]]', description="Réponse:", style=style, disabled=False) + + display(Latex('Donnez une matrice définissant le parallélogramme réprensenté.')) + display(matrix_answer) + button_sol_mat = widgets.Button(description='Solution matrice', disabled=False) + button_sol_mat.on_click(sol_mat) + + def check_matrix(): + A_answer = np.array(eval(matrix_answer.value)) + + # To check vectors: check if det of answer is diff from 0 and check that both vectors belongs to the list + # of positive and negative columns + correct_list = [A[:, 0], -A[:, 0], A[:, 1], -A[:, 1]] + + bool_list_1 = [np.sum(np.abs(A_answer[:, 0] - x)) < 1e-4 for x in correct_list] + bool_list_2 = [np.sum(np.abs(A_answer[:, 1] - x)) < 1e-4 for x in correct_list] + + if not (any(bool_list_1) and any(bool_list_2) and np.abs(np.linalg.det(A_answer)) > 1e-4): + display(Latex("Incorrect, les colonnes de cette matrice ne définissent pas le parallélogramme représenté.")) + else: + display(Latex("Correct !")) + area_answer = widgets.FloatText(value='0', description="Aire:", style=style, disabled=False) + display(Latex("Donnez maintenant l'aire du paralélogramme.")) + display(area_answer) + + button_sol_area = widgets.Button(description='Solution aire', disabled=False) + button_sol_area.on_click(sol_area) + + def check_area(): + if abs(float(area)-area_answer.value)>1e-3: + display(Latex("Incorrect.")) + else: + display(Latex("Correct !")) + + im_area = interact_manual(check_area) + im_area.widget.children[0].description = 'Vérifier aire' + + display(button_sol_area) + + + im_matrix = interact_manual(check_matrix) + im_matrix.widget.children[0].description = 'Vérifier matrice' + display(button_sol_mat) + + +def ex_7_5_1_a(): + A1 = [[0.5, -2], [-2, 1]] + ex_7_5_1(A1, orig=[0, 0]) + + +def ex_7_5_1_b(): + A2 = [[-3, -4], [-1, 2]] + ex_7_5_1(A2, orig=[1, -1]) + + +def ex_7_5_1_c(): + A3 = [[1, 1], [3, 4]] + ex_7_5_1(A3, orig=[0, 1]) + + +def plotPara(A, orig=[0, 0]): + A = np.array(A) + if A.shape != (2, 2): + raise ValueError('Input matrix should be 2x2') + + x = np.array([0, A[0, 0], A[0, 0] + A[0, 1], A[0, 1], 0]) + orig[0] + y = np.array([0, A[1, 0], A[1, 0] + A[1, 1], A[1, 1], 0]) + orig[1] + + fig = go.Figure() + fig.add_trace(go.Scatter(x=x, y=y, + fill='toself', fillcolor='darkviolet', + hoveron='points+fills', # select where hover is active + line_color='black', + text="Points + Fills", + hoverinfo='text+x+y')) + fig.show() + + return + + +def ex_7_5_2_a(): + A1 = [[-3, 1, 5], + [2, -1, 3], + [1, -5, -1]] + + ex_7_5_2(A1, orig=[0, 0, 0], plot_vectors=True) + + +def ex_7_5_2_b(): + A2 = [[1, 1, 0], + [3, 0, -1], + [-2, 0, -1]] + + ex_7_5_2(A2, orig=[1, -1, 0], plot_vectors=True) + + +def ex_7_5_2_c(): + A3 = [[2, -2, 5], + [3, 4, 0], + [-2, 0, 3]] + + ex_7_5_2(A3, orig=[1, 1, 2], plot_vectors=False) + + +def ex_7_5_2(A, orig=[0, 0, 0], plot_vectors=False): + A_sp = sp.Matrix(A) + vol = sp.Abs(A_sp.det()) + A = np.array(A) + orig = np.array(orig) + + if A.shape != (3, 3): + raise ValueError("La matrice doit être 3x3.") + + def sol_mat(e): + display(Latex("Pour trouver des vecteurs définissant le parallélépipède, prenez un sommet quelquonque et " + "exprimez sous forme de vecteur chaque arrète touchant ce sommet. Ces 3 vecteurs forment " + "les colonnes de la matrice.")) + display(Latex("On voit sur la figure que des vecteurs qui peuvent définir le parallélépipède sont: $" + latexp( + A_sp[:, 0]) + "$, $" + latexp(A_sp[:, 1]) + "$ et $ " + latexp(A_sp[:, 2]) + "$.")) + display(Latex("Une matrice definissant le parallélépipède est donc: $" + latexp(A_sp) + "$.")) + display(Latex("Completez votre réponse pour continuer l'exercice.")) + + def sol_vol(e): + display(Latex( + "Pour trouver l'aire du parallélépipède, on prend simplement la valeur absolue du déterminant de la matrice trouvée plus haut.")) + display(Latex( + 'Area $= |\det ' + latexp(A_sp) + '| = |' + latexp(A_sp.det()) + "| = " + latexp(sp.Abs(A_sp.det())) + "$")) + + plotDeterminant3D(A, orig=orig, plot_vectors=plot_vectors) + + style = {'description_width': 'initial'} + matrix_answer = widgets.Text(value='[[0, 0, 0], [0, 0, 0], [0, 0, 0]]', description="Réponse:", style=style, disabled=False) + + display(Latex('Donnez une matrice définissant le parallélépipède réprensenté.')) + display(matrix_answer) + button_sol_mat = widgets.Button(description='Solution matrice', disabled=False) + button_sol_mat.on_click(sol_mat) + + def check_matrix(): + A_answer = np.array(eval(matrix_answer.value)) + + # To check vectors: check if det of answer is diff from 0 and check that both vectors belongs to the list + # of positive and negative columns + correct_list = [A[:, 0], -A[:, 0], A[:, 1], -A[:, 1], A[:, 2], -A[:, 2]] + + bool_list_1 = [np.sum(np.abs(A_answer[:, 0] - x)) < 1e-4 for x in correct_list] + bool_list_2 = [np.sum(np.abs(A_answer[:, 1] - x)) < 1e-4 for x in correct_list] + bool_list_3 = [np.sum(np.abs(A_answer[:, 2] - x)) < 1e-4 for x in correct_list] + + if not (any(bool_list_1) and any(bool_list_2) and any(bool_list_3) and np.abs(np.linalg.det(A_answer)) > 1e-4): + display(Latex("Incorrect, les colonnes de cette matrice ne définissent pas le parallélépipède représenté.")) + else: + display(Latex("Correct !")) + vol_answer = widgets.FloatText(value='0', description="Volume:", style=style, disabled=False) + display(Latex("Donnez maintenant le volume du parallélépipède.")) + display(vol_answer) + + button_sol_vol = widgets.Button(description='Solution volume', disabled=False) + button_sol_vol.on_click(sol_vol) + + def check_vol(): + if abs(float(vol) - vol_answer.value) > 1e-3: + display(Latex("Incorrect.")) + else: + display(Latex("Correct !")) + + im_area = interact_manual(check_vol) + im_area.widget.children[0].description = 'Vérifier volume' + + display(button_sol_vol) + + im_matrix = interact_manual(check_matrix) + im_matrix.widget.children[0].description = 'Vérifier matrice' + display(button_sol_mat) + + +def plotDeterminant3D(A, orig=np.array([0, 0, 0]), plot_vectors=False): """ 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. """ + A = np.array(A) + orig = np.array(orig) + # Will only execute if it is 3x3 - if (np.shape(A) != (3,3)): + 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)) + 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]]) + np.array([1, 1, 1]))/2.0 + 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): + vertices[i, :] = np.dot(A, cube[i, :]) + + # Displace parallelepiped + vertices = vertices + orig + + # Get each coodinate separately + data_x = vertices[:, 0] + data_y = vertices[:, 1] + data_z = vertices[:, 2] + + plot3d(A, data_x, data_y, data_z, orig=orig, plot_vectors=plot_vectors) + + +def plot3d(A, data_x, data_y, data_z, orig=[0, 0, 0], plot_vectors=False): """ - This function plots an interactive 3D plot of the determinant as a volume of a + 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 - ) - ) + orig = np.array(orig) + + x_line = np.array([np.zeros(3), A[0, :]]) + orig[0] + y_line = np.array([np.zeros(3), A[1, :]]) + orig[1] + z_line = np.array([np.zeros(3), A[2, :]]) + orig[2] + + 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), + go.Scatter3d(x=data_x, y=data_y, z=data_z, mode='markers', showlegend=False, + marker=dict(size=6, + color=data_z, # set color to an array/list of desired values + colorscale=[[0, 'darkblue'], + [1, 'darkblue']], # choose a colorscale + opacity=0.6 + ))] + + if plot_vectors: + data.append(go.Scatter3d(x=x_line[:, 0], y=y_line[:, 0], z=z_line[:, 0], line=dict(color='red', width=4), + marker=dict(size=6), + mode='lines+markers', + name='col1') + ) + + data.append(go.Scatter3d(x=x_line[:, 1], y=y_line[:, 1], z=z_line[:, 1], line=dict(color='blue', width=4), + marker=dict(size=6), + mode='lines+markers', + name='col2') + ) + + data.append(go.Scatter3d(x=x_line[:, 2], y=y_line[:, 2], z=z_line[:, 2], line=dict(color='green', width=4), + marker=dict(size=6), + mode='lines+markers', + name='col3') + ) + + data.append(go.Scatter3d(x=[orig[0]], y=[orig[1]], z=[orig[2]], mode='markers', showlegend=False, + marker=dict(size=7, + color='black', # set color to an array/list of desired values + opacity=1) + ) + ) + + fig = go.Figure(data=data, layout=go.Layout(autosize=True)) # This prints it - pyo.iplot(fig, filename='Determinant-Volume') + pyo.iplot(fig, filename='') -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(']','|') +## 7.7 - detA2_s = sp.latex(A2).replace('[','|').replace(']','|') - detA3_s = sp.latex(A3).replace('[','|').replace(']','|') +def ex_7_7_1(matrix): + A_sp = sp.Matrix(matrix) + A = np.array(matrix) - 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 + '$' + if np.abs(np.linalg.det(A)) < 1e-6: + display(Latex("$\det A=0.$" + " La matrice $A$ est singulière, l'inverse de $A$ n'existe pas.")) + return - 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))) + '$' + sol = np.linalg.inv(A) + inv_answer = widgets.Textarea(value='[[0, 0, 0],\n [0, 0, 0],\n [0, 0, 0]]', description="$A^{-1} = $ ", disabled=False) - # If we compute the determinant with col n + display(Latex("Entrez l'inverse de la matrice suivante $ A=" + latexp(A_sp) + "$.")) + display(Latex("Pour le calcul, utilisez la méthode des cofacteurs.")) + display(inv_answer) + + def check_inv(): + display(Latex("La matrice rentrée est: $" + latexp(sp.Matrix(sp.sympify(inv_answer.value))) + "$")) + answer = np.array(eval(inv_answer.value)) + if np.sum(np.abs(sol-answer)) < 1e-2: + display(Latex("Correct!")) 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(']','|') + display(Latex("Incorrect.")) + + im = interact_manual(check_inv) + im.widget.children[0].description = 'Vérifier réponse' - 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 + '$' + button = widgets.Button(description='Solution', disabled=False) + box = HBox(children=[button]) + out = widgets.Output() - 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)) + ')$' + def solution(e): + out.clear_output() + find_inverse_3x3(A_sp) - line3 = '$' + detA_s + ' = ' + sp.latex(sp.simplify(sp.Abs(sp.det(A)))) + '$' + button.on_click(solution) + display(box) + display(out) - # 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.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." )) + 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(']','|') + sub_matrix = [] + pl = [] + cofactor = [] + cofactor_o = [] + sub_matrix_latex = [] + cof_matrix = sp.Matrix([[1, 1, 1], [1, 1, 1], [1, 1, 1]]) + + # Construct 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)) + 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(']','|')) + 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 + 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) + '$' - + + 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 matrice des cofacteurs de $A$ est donc: " + # "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{cof } A" + ' = ' + latexp(cof_matrix) + '$' + + line6 = "On calcule le déterminant de $A$:" + + line7 = "$ \det A=" + detA_s + "=" + latexp(sp.simplify(sp.det(A))) + '$' + + line8 = "On peut trouver l'inverse de $A$ en utilisant le théorème donné plus haut." + + line9 = '$' + "A^{-1}" + ' = ' + "\dfrac{{1}}{{\det A}}" + "\cdot " + " (\mbox{cof }A)^T" + ' = ' \ + + "\dfrac{1}" + "{{{}}}".format(sp.simplify(sp.det(A))) + "\cdot " + latexp( + cof_matrix_t) + "=" + latexp(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() + + def solution(): 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) - - + solution() + + 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] + 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): + 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." )) + 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]]) + 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(']','|') + 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)) + 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(']','|')) + 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 + 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" +'$' - + + 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() + + line6 = '$' + "(\mbox{cof } B)" + ' = ' + latexp(cof_matrix) + '$' + + line7 = "On calcule le déterminant de $B$: $det\ B$" + + line8 = "$ \det B=" + detA_s + "=" + latexp(sp.simplify(sp.det(A))) + '$' + + line9 = "On peut trouver la matrice inverse en utilisant le théorème donné plus haut." + + line10 = '$' + "B^{-1}" + ' = ' + "\dfrac{{1}}{{\det B}}" + "\cdot " + " (\mbox{cof } B)^T" + ' = ' \ + + "\dfrac{1}" + "{{{}}}".format(sp.simplify(sp.det(A))) + "\cdot " + latexp( + cof_matrix_t) + "=" + latexp(sp.simplify(sp.det(A)) ** (-1) * cof_matrix_t) + '$' + + + def solution(): 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 + + solution() 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 f6bb426..31f970c 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,189 +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", "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", "\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", "En effet, si $A$ est singulière, alors $A^T$ l'est aussi." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 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", "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}$$ \n", "\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": [ "### 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" ] }, { "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_invertible(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 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_invertible(B)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 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", "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": [ "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)" + "[Passez au notebook du Chapitre 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.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 0e32630..66f5f66 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,138 +1,170 @@ { "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" ] }, { "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é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$ inversible, alors:\n", "$$\\det A^{-1} = \\frac{1}{\\det A} $$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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": [ "### Exercice 1\n", "\n", "Déterminez le déterminant de la matrice $C$\n", "\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": null, "metadata": {}, "outputs": [], "source": [ "question7_4_1()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Exercice 2\n", + "Déterminez le déterminant de la matrice $C$.\n", + "$$C = A B $$\n", "\n", - "En utilisant ces régles ci en haut, vérifiez sur papier que $$\\det(A+B) \\neq \\det(A) + \\det(B) $$\n", + "$$ A = \\left(\\begin{matrix}1 & -2 & 0\\\\2 & 0 & -1\\\\1 & 1 & -1\\end{matrix}\\right)$$\n", + "$$ B = \\left(\\begin{matrix}-1 & 2 & -2\\\\-1 & 1 & -1\\\\-2 & 3 & -4\\end{matrix}\\right)$$\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "question7_4_2()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Exercice 3\n", + "\n", + "En utilisant les régles données plus haut, vérifiez 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": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ - "question7_4_2()" + "question7_4_3()" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "### Complexité du calcul d'un déterminant (suite)\n", + "On a vu dans le notebook 7.2 que le calcul d'un déterminant en utilisant la définition donnée dans le cours 7.1 nécessitait **énormément** de calculs de sous-déterminants quand la taille de la matrice devenait importante ($n>10$). Dans certains domaines, il est nécessaire de calculer des determinant de matrices $(n \\times n)$ avec $n>1000$. Utiliser la première définition du cours pour effectuer un tel calcul est impossible en pratique.\n", + "\n", + "On peut utiliser la propiété donnée plus haut pour grandement reduire la complexité de cette operation. En effet, on peut factoriser $A$ comme $A = LU$ avec $L$ et $U$ des matrices triangulaire. On a donc que $\\det A = \\det L \\cdot \\det U$. Les determinants de $L$ et $U$ sont simplement les produits de leurs éléments diagonaux respectifs. \n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Passez au notebook du Chapitre 7.5 - Le déterminant, interprétation géométrique](./Chapitre%207.5%20-%20Le%20d%C3%A9terminant%2C%20interpr%C3%A9tation%20g%C3%A9om%C3%A9trique.ipynb)" + ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 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 b41c323..4190da6 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,1247 +1,137 @@ { "cells": [ { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - " \n", - " " - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "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", + "## THÉORÈME 1:\n", + "Soit $A \\in M_{2 \\times 2}(\\mathbb{R})$ une matrice de taille $2 \\times 2$ à coefficients réels. Alors l'aire du parallélogramme défini par les colonnes de $A$ est égale à $\\mid \\operatorname{det} A \\mid$.\n", "\n", - "Dans la prochaine partie, vous pouvez changer les paramètres de $A$ et voir comment le parallélogramme va changer. " + "## THÉORÈME 2 : \n", + "Soit $A \\in M_{3 \\times 3}(\\mathbb{R})$ une matrice de taille $3 \\times 3$ à coefficients réels. Alors le volume du parallélépipède défini par les colonnes de $A$ est égale à $\\mid \\operatorname{det} A \\mid$." ] }, { - "cell_type": "code", - "execution_count": 8, + "cell_type": "markdown", "metadata": {}, - "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", + "### Exercice 1:\n", + "A partir de la figure, donnez une matrice dont les colonnes définissent le parallélogramme représenté. Calculer ensuite l'aire du parallélogramme. \n", "\n", - "plotDeterminant2D(A)" + "*Vous pouvez afficher les coordonnées des sommets en passant votre souris dessus.*" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": {}, + "outputs": [], "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$." + "ex_7_5_1_a()" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "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" - } - ], + "outputs": [], "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)" + "ex_7_5_1_b()" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "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" - } - ], + "outputs": [], "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)" + "ex_7_5_1_c()" ] }, { "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}$$" + "### Exercice 2:\n", + "A partir de la figure, donnez une matrice dont les colonnes définissent le parallélépipède représenté. Calculer ensuite le volume du parallélépipède.\n", + "\n", + "- *Pour vous aider à trouver la matrice, les vecteurs définissant le parallélépipède sont représentés en couleur pour les deux premières questions (N.B. l'ordre des colonnes n'importe pas).*\n", + "\n", + "- *Passez votre souris sur les sommets pour obtenir leurs coordonnées, vous pouvez également changer l'angle de vue en maintenant le click tout en bougeant votre souris.*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "ex_7_5_2_a()" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "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" - } - ], + "outputs": [], "source": [ - "problem7_5()" + "ex_7_5_2_b()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], - "source": [] + "source": [ + "ex_7_5_2_c()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[Passez au notebook du Chapitre 7.7 - La matrice des cofacteurs et une formule pour l'inverse d'une matrice](./Chapitre%207.7%20-%20La%20matrice%20des%20cofacteurs%20et%20une%20formule%20pour%20l'inverse%20d'une%20matrice.ipynb)" + ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 } diff --git "a/Chapitre 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 66b8ed8..1270a6f 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,215 +1,111 @@ { "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", "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", + "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 \\times n$ 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": [ + "### Exercice 1\n", + "En utilisant la méthode des cofacteurs, calculez l'inverse de la matrice donnée.\n", "\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" + "*Rentrez si possible les valeurs exactes pour que votre solution soit traitée correctement. Vous pouvez utiliser des fractions avec `/`.*" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "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": "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": "090d4e7e42e04d028522bc46eb600734", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ - "A = sp.Matrix([[2,1,1],[1,-1,1],[-1,1,-2]])\n", - "find_inverse_3x3(A)" + "A = [[2,1,1],[1,-1,1],[-1,1,-2]]\n", + "\n", + "ex_7_7_1(A)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exercise \n", - "Trouver sur papier la matrice inverse de $ B_{4 \\times 4} $. \n", + "### Exemple: \n", + "On cherche à trouver l'inverse de la matrice $B$ de taille $(4 \\times 4)$ avec la méthode des cofacteurs. Executez la cellule suivante pour observer le developpement nécessaire pour obtenir la matrice inverse.\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, + "execution_count": null, "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": "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": "b3e5a9eccf314c05b8b5d434aca7002c", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "Output()" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "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, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "#### Remarque\n", + "On voit qu'un grand nombre d'étapes sont nécessaires car il faut calculer 16 déterminants de matrices $3 \\times 3$ et 1 déterminant d'une matrice $4 \\times 4$. De manières générale pour une matrice $n \\times n$, les calculs de $n^2$ déterminants de matrices $(n-1) \\times (n-1)$ sont nécessaires. \n", + "\n", + "C'est pour cette raison que la méthode des cofacteurs n'est pas du tout utilisée en pratique pour calculer l'inverse d'une matrice. Il existe des méthodes bien plus rapide comme la factorisation $LU$, très utilisée dans les programmes d'analyse numérique." + ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.2" } }, "nbformat": 4, "nbformat_minor": 4 }