diff --git a/Chapitre 9 - Produits scalaires et espaces euclidens/Corrections/corrections.py b/Chapitre 9 - Produits scalaires et espaces euclidens/Corrections/corrections.py index 682aeb7..cd8ec45 100644 --- a/Chapitre 9 - Produits scalaires et espaces euclidens/Corrections/corrections.py +++ b/Chapitre 9 - Produits scalaires et espaces euclidens/Corrections/corrections.py @@ -1,979 +1,1040 @@ import sys sys.path.insert(0, './../') import numpy as np import matplotlib.pyplot as plt import ipywidgets as widgets from ipywidgets import interact_manual, Layout, widgets, HBox from IPython.display import display, Latex from Librairie.AL_Fct import get_couple_vectors_info_2D, get_couple_matrices_info, get_couple_functions_info -from Librairie.AL_Fct import couple_functions_plotter +from Librairie.AL_Fct import couple_functions_plotter, compute_expansion_coefficients def Ex1Chapitre9_1(): """Provides the correction of exercise 1 of notebook 9_1 """ a = widgets.Checkbox( value=False, description=r'$$\qquad u_1 \cdot u_2 \cdot [\dots] \cdot u_n = u_n \cdot [\dots] \cdot u_2 \cdot u_1$$', disabled=False, layout=Layout(width='90%', height='50px') ) b = widgets.Checkbox( value=False, description=r'$$\qquad (u_1 + u_2) \cdot (u_1 + u_2) = ||u_1|| + ||u_2|| + 2 (u_1 \cdot u_2)$$', disabled=False, layout=Layout(width='90%', height='50px') ) c = widgets.Checkbox( value=False, description=r"$$ \qquad \left(\sum\limits_{i=1}^nu_i\right) \cdot \left(\sum\limits_{i=1}^nu_i\right) = " r"\sum\limits_{i=1}^n ||u_i||^2 + 2\sum\limits_{i=1}^n\sum\limits_{j=1}^{i-1}u_i \cdot u_j$$", disabled=False, layout=Layout(width='100%', height='80px') ) d = widgets.Checkbox( value=False, description=r'\begin{align*}' r'\qquad (\lambda_1u_1 + \lambda_2u_2) \cdot (\lambda_3u_3 + \lambda_4u_4) =&' r'\lambda_1\lambda_3(u_1 \cdot u_3) + \lambda_1\lambda_4(u_1 \cdot u_4) \ + \\' r' \qquad \quad & \lambda_2\lambda_3(u_2 \cdot u_3) + \lambda_2\lambda_4(u_2 \cdot u_4)' r'\end{align*}', disabled=False, layout=Layout(width='90%', height='80px') ) e = widgets.Checkbox( value=False, description=r'$$\qquad u_1 \cdot u_2 = 0 \implies u_1 \perp u_2 \ \forall \ u_1, u_2 \in \mathbb{R}^2$$', disabled=False, layout=Layout(width='80%', height='50px') ) def correction(a, b, c, d, e): if a and not b and c and d and not e: display(Latex(r"C'est correct! En particulier: " "1. Vrai, en raison de la symétrie du produit scalaire. " "2. Faux, car les normes du côté gauche doivent être au carré. " "3. Vrai, en raison de l'additivité (la formule peut être prouvée par induction. Essaie! " "4. Vrai, en raison de la bilinéarité du produit scalaire. " "5. Faux, car il faut préciser que $u_1$ et $u_2$ ne peuvent pas être des vecteurs nuls.")) else: display(Latex("C'est faux.")) interact_manual(correction, a=a, b=b, c=c, d=d, e=e) return def Ex2Chapitre9_1(vec1, vec2): """Provides the correction of exercise 2 of notebook 9_1 """ display(Latex("Insérez les valeurs des quantités listées ci-dessous. " "Entrez les valeurs avec 4 chiffres après la virgule! Si l'angle n'est pas défini, entrez -999!")) norm_u = widgets.FloatText( value=0.0, step=0.0001, description='||u||:', disabled=False ) norm_v = widgets.FloatText( value=0.0, step=0.0001, description='||v||:', disabled=False ) u_dot_v = widgets.FloatText( value=0.0, step=0.0001, description=r'$u \cdot v$:', disabled=False ) theta_u_v = widgets.FloatText( value=0.0, step=0.0001, description=r'$\Delta\theta$', disabled=False ) solution_button = widgets.Button(description='Solution', disabled=True) box = HBox(children=[solution_button]) out = widgets.Output() @out.capture() def solution(e): out.clear_output() get_couple_vectors_info_2D(vec1, vec2, show=True, return_results=False) display(norm_u) display(norm_v) display(u_dot_v) display(theta_u_v) norm_u_true, norm_v_true, u_dot_v_true, theta_u_v_true = get_couple_vectors_info_2D(vec1, vec2, show=False, return_results=True) def f(): threshold = 1e-4 u_correct, v_correct, u_dot_v_correct, theta_correct = tuple(np.zeros((4, 1)).astype(bool)) if np.abs(norm_u.value - norm_u_true) < threshold: display(Latex(r"La norme de $u$ est correcte!")) u_correct = True else: display(Latex(f"La norme de $u$ n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if np.abs(norm_v.value - norm_v_true) < threshold: display(Latex(r"La norme de $v$ est correcte!")) v_correct = True else: display(Latex(f"La norme de $v$ n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if np.abs(u_dot_v.value - u_dot_v_true) < threshold: display(Latex(r"Le produit scalaire est correct!")) u_dot_v_correct = True else: display(Latex(f"Le produit scalaire n'est pas correct! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if not np.isnan(theta_u_v_true) and np.abs(theta_u_v.value - theta_u_v_true) < threshold: display(Latex(r"L'angle est correct!")) theta_correct = True elif np.isnan(theta_u_v_true) and theta_u_v.value == -999: display(Latex(r"Correct! L'angle n'est pas defini!")) theta_correct = True else: display(Latex(f"L'angle n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if u_correct and v_correct and u_dot_v_correct and theta_correct: display(Latex(r"RÉSULTATS")) get_couple_vectors_info_2D(vec1, vec2, show=True, return_results=False) else: solution_button.disabled = False interact_manual(f) solution_button.on_click(solution) display(box) display(out) return def Ex3Chapitre9_1(case=1): """Provides the correction of exercise 3 of notebook 9_1 :param case: number of the case. Available: {1,2,3}. Defaults to 1 :type case: int """ fig = plt.figure(figsize=(5, 5)) ax = fig.gca() origin = [0], [0] if case == 1: theta = np.hstack((np.linspace(0, np.pi / 4, 100), np.linspace(5 * np.pi / 4, 3 * np.pi / 2, 100))) x1 = 2 * np.cos(theta) x2 = 2 * np.sin(theta) limit = 2.5 for i in range(2): plt.plot(x1[i * 100: (i + 1) * 100], x2[i * 100: (i + 1) * 100], '-', color='r', linewidth=2) elif case == 2: theta_ref = np.linspace(0, 2 * np.pi, 13) theta = np.hstack( [np.linspace(theta_ref[i], theta_ref[i + 1], 50) if not i % 2 else np.array([]) for i in range(12)]) vals = [1, 3, 5, 7, 9, 11] x1 = np.hstack([vals[i] * np.cos(theta[i * 50:(i + 1) * 50]) for i in range(6)]) x2 = np.hstack([vals[i] * np.sin(theta[i * 50:(i + 1) * 50]) for i in range(6)]) limit = 12 for i in range(6): plt.plot(x1[i * 50:(i + 1) * 50], x2[i * 50:(i + 1) * 50], '-', color='r', linewidth=2) elif case == 3: theta = np.linspace(0, 8 * np.pi, 800) vals = np.logspace(-2, 0, 800) x1 = vals * np.cos(theta) x2 = vals * np.sin(theta) limit = 1.2 plt.plot(x1, x2, '-', color='r', linewidth=2) else: raise ValueError(f"Le cas {case} n'est pas défini. Cas disponibles: {1, 2, 3}") ax.plot(*origin, marker='o', color='b') ax.set_xlim(-limit, limit) ax.set_ylim(-limit, limit) ax.grid() # Move left y-axis and bottom x-axis to centre, passing through (0,0) ax.spines['left'].set_position('center') ax.spines['bottom'].set_position('center') # Eliminate upper and right axes ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') # Show ticks in the left and lower axes only ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') plt.show() if case == 1: a = widgets.Checkbox( value=False, description=r"L'ensemble peut être exprimé comme: " r" $$\qquad S=\Bigl\{v \in \mathbb{R}^2: ||v||=2 \land \theta \ \% \ \pi \in " r"\Bigl[0; \dfrac{\pi}{4}\Bigr]\Bigr\}$$", disabled=False, layout=Layout(width='80%', height='60px') ) b = widgets.Checkbox( value=False, description=r"L'ensemble peut être exprimé comme: " r" $$\qquad S=\Bigl\{v \in \mathbb{R}^2: ||v||=2 \land \Bigl\lfloor\dfrac{\theta}{\pi}\Bigr\rfloor " r"in [0; 1]\Bigr\}$$", disabled=False, layout=Layout(width='80%', height='60px') ) c = widgets.Checkbox( value=False, description=r"$v = \Bigl[\dfrac{\sqrt{2}}{2}; \dfrac{\sqrt{2}}{2}\Bigr]$ appartient à l'ensemble", disabled=False, layout=Layout(width='80%', height='50px') ) d = widgets.Checkbox( value=False, description=r"$v = -\dfrac{1}{2}\Bigl[\sqrt{2}; \sqrt{6}\Bigr]$ appartient à l'ensemble", disabled=False, layout=Layout(width='80%', height='50px') ) def correction(a, b, c, d): if a and not b and not c and d: display( (Latex(r"C'est correct! En effet l'ensemble S est fait d'éléments de norme égale à 2 $ et d'angles " r"dans $\Bigl[0; \dfrac{\pi}{4}\Bigr]$ ou dans " r"$\Bigl[\dfrac{5\pi}{4}; \dfrac{3\pi}{2}\Bigr]$, ce qui est indiqué par la réponse 1. " r"La réponse 2 est erronée car le calcul de $\Bigl\lceil\dfrac{\theta}{\pi}\Bigr\rceil$" r"n'a aucun sens dans ce contexte. Enfin, " r"$v_1 = \Bigl[\dfrac{\sqrt{2}}{2}; \dfrac{\sqrt{2}}{2}\Bigr]$ n'appartient pas à l'ensemble " r"puisque sa norme est égale à $1$ et non à $2$ (réponse 3); inversement " r"$v_2 = -\dfrac{1}{2}\Bigl[\sqrt{2}; \sqrt{6}\Bigr]$ fait partie à l'ensemble,appartenant " r" à l'arc dans le troisième quadrant (réponse 4)."))) else: display(Latex("C'est faux.")) elif case == 2: a = widgets.Checkbox( value=False, description=r"L'ensemble peut être exprimé comme: " r"$$\qquad S= \Bigl\{v \in \mathbb{R}^2: \Bigl\lceil \dfrac{\theta}{\pi / 6} \Bigr\rceil \ is \ odd \ \land ||v|| = \Bigl\lfloor \dfrac{\theta}{\pi / 6} \Bigr\rfloor \Bigr\}$$", disabled=False, layout=Layout(width='90%', height='60px') ) b = widgets.Checkbox( value=False, description=r"L'ensemble peut être exprimé comme: " r"$$\qquad S= \Bigl\{v \in \mathbb{R}^2: \Bigl\lfloor \dfrac{\theta}{\pi / 6} \Bigr\rfloor \ is \ even \ \land ||v|| = \Bigl\lceil \dfrac{\theta}{\pi / 6} \Bigr\rceil \Bigr\}$$", disabled=False, layout=Layout(width='90%', height='60px') ) c = widgets.Checkbox( value=False, description=r"$v = \dfrac{1}{2}\Bigl[\sqrt{3}; 3\Bigr]$ appartient à l'ensemble", disabled=False, layout=Layout(width='100%', height='60px') ) d = widgets.Checkbox( value=False, description=r"$v = \Bigl[-\sqrt{3}; \sqrt{3}\Bigr]$ appartient à l'ensemble", disabled=False, layout=Layout(width='100%', height='60px') ) def correction(a, b, c, d): if not a and b and c and not d: display((Latex( r"C'est correct! En effet l'ensemble est fait par tous les éléments tels que la partie entière de " r"a division de leur angle (supposée être en radians et en $[0;2\pi]$ par " r"$\dfrac{\pi}{6}$ est pair et avec norme égale à" r"$\Bigl\lceil\dfrac{\theta}{\pi / 6}\Bigr\rceil$ (réponse 2). La réponse 1 est erronée car" r"la norme des éléments de l'ensemble est égale à $\Bigl\lceil\dfrac{\theta}{\pi / 6}\Bigr\rceil$" r"et non à $\Bigl\lfloor\dfrac{\theta}{\pi / 6}\Bigr\rfloor$; la condition '" r"$\Bigl\lceil\dfrac{\theta}{\pi / 6}\Bigr\rceil \ is \ odd$' est plutôt vrai. Enfin, " r"$v_1 = \dfrac{1}{2}\bigl[\sqrt{3}; 3\bigr]$ appartient à S (c'est l'élément le plus à droite " r"du deuxième arc du premier quadrant) (réponse 3), tandis que" r" $v_2 = \bigl[-\sqrt{3}; \sqrt{3}\bigr]$ ne fait pas partie de S puisque sa norme est égale à $3$, " r"et il devrait être égal à $5$ pour faire partie de l'arc dans le deuxième quadrant (réponse 4)."))) else: display(Latex("C'est faux.")) elif case == 3: a = widgets.Checkbox( value=False, description=r"L'élément de l'ensemble $S$ avec la norme maximale a une norme égale à $1$", disabled=False, layout=Layout(width='90%', height='50px') ) b = widgets.Checkbox( value=False, description=r'Ce qui suit est valable: ' r'$$ \qquad \nexists \ v_1, v_2 \in S: v_1 \cdot v_2 = 0 \land ||v_1|| = ||v_2||$$', disabled=False, layout=Layout(width='90%', height='50px') ) c = widgets.Checkbox( value=False, description=r"Ce qui suit est valable: " r"$$ \qquad \forall \alpha \in [0;2\pi] \ \exists v \in S: \theta = \alpha$$", disabled=False, layout=Layout(width='100%', height='50px') ) d = widgets.Checkbox( value=False, description=r"Tous les couples d'élémets de S sont une base de $\mathbb{R}^2$", disabled=False, layout=Layout(width='100%', height='50px') ) def correction(a, b, c, d): if a and b and c and not d: display((Latex( r"C'est correct! En effet, cet ensemble est en fait constitué de vecteurs dont les angles s'étendent sur " r"$[0;8\pi]$ et dont les normes augmentent logarithmiquement de $10^{-2}$ (if $\theta = 0$) à " r"$10$ if $\theta = 8\pi$. Pour cette raison, l'élément avec la norme maximale a une norme égale à " r"$1$ (answer 1) et tous les angles dans $[0; 2\pi]$ sont représentés par un vecteur dans l'ensemble " r"(answer 3). (réponse 3). De plus, l'ensemble ne contient aucun couple d'éléments orthogonaux " r"et qui ont la même norme (en fait, il ne contient pas deux éléments avec le même " r"norme du tout!) (réponse 2). Au lieu de cela, tout couple d'éléments ayant le même angle est " r"dépend linéairement et ne peut donc pas être une base de $\mathbb{R}^2$ (réponse 4)."))) else: display(Latex("C'est faux.")) else: raise ValueError(f"Le cas {case} n'est pas défini. Cas disponibles: {1, 2, 3}") interact_manual(correction, a=a, b=b, c=c, d=d) return def Ex1Chapitre9_2(): """Provides the correction to exercise 1 of notebook 9_2 """ print("Cliquer sur CTRL pour sélectionner plusieurs réponses") style = {'description_width': 'initial'} ans1 = widgets.SelectMultiple( options=['1', '2', '3', '4', '5', '6'], description="L'opérateur est un produit scalaire dans les cas:", style=style, layout=Layout(width='70%', height='120px'), disabled=False, ) ans2 = widgets.SelectMultiple( options=['1', '2', '3', '4', '5', '6'], description=r"L' $\mathbb{R}$-espace vectoriel, équipé avec l'operateur donné, " r"est un espace Euclidien dans le cas", style=style, layout=Layout(width='70%', height='120px'), disabled=False, ) def correction(ans1, ans2): res_ans = np.zeros(2).astype(bool) res_ans[0] = '1' not in ans1 and '2' in ans1 and '3' in ans1 and \ '4' not in ans1 and '5' in ans1 and '6' not in ans1 res_ans[1] = '1' not in ans2 and '2' in ans2 and '3' in ans2 and \ '4' not in ans2 and '5' not in ans2 and '6' not in ans2 if res_ans.all(): display(Latex(r"C'est correct! En effet: CAS 1: l'opérateur n'est pas un produit scalaire " r"parce qu'il n'est pas défini positif; donc l'espace vectoriel ne peut pas être " r"un espace Euclidien. CAS 2: l'opérateur est en fait un produit scalaire (" r"il s'avère respecter toutes les propriétés requises); en plus l'espace vectoriel " r"à une dimension finie (3), et c'est donc un espace Euclidien une fois équipé " r"avec l'opérateur donné. CAS 3: l'opérateur est un produit scalaire; l'espace vectoriel " r"à une dimension finie (3, égal au nombre de coefficients caractérisants) " r"et c'est donc un espace Euclidien s'il est équipé de l'opérateur donné. CAS 4: l'opérateur " r"est le même que dans le cas 2, mais dans ce cas ce n'est PAS un produit scalaire car " r"il n'est pas défini positif (notez, en effet, que chaque polynôme de degré égal à 3 " r"à un produit scalaire nul avec lui-même, bien qu'il n'est pas le polynôme nul); " r"donc l'espace vectoriel ne peut alors pas être un espace Eucliden. " r"CAS 5: l'opérateur donné définit un produit scalaire. En particulier, definiè " r"positivitè vient du fait que, si $\langle a, a \rangle = 0$, alors $a(x_0) = 0$ " r"et $a'(x)^2=0 \ \forall x \in [x_0; x_1]$; en conséquence $a$ doit être constant dans $[x_0; x_1]$ " r"et égal à $0$ en $x_0$. En raison de la continuité, cela implique qu'en fait $a \equiv 0$, comme " r"souhaité. Cependant, la dimensionnalité de l'espace vectoriel est infinie; il ne peut donc pas " r"être un espace Euclidien. CAS 6: l'opérateur ne définit pas un produit scalaire car il n'est pas " r"défini positif; en effet, si $\langle a, a \rangle=0$ alors $a$ doit être $0$ à $x_0$ et il doit avoir " r"dérivée seconde nulle dans $[x_0; x_1]$. Ainsi, toute fonction linéaire égale à $0$ à $x_0$ " r"conduirait à avoir $ \langle a, a \rangle=0$, ce qui prouve que l'opérateur n'est pas " r"défini positif. Facilement, l'espace vectoriel ne peut pas être un espace Euclidien, aussi parce que " r"sa dimension est infinie.")) else: display(Latex("C'est faux.")) if not res_ans[0]: display((Latex("La réponse à la première question est fausse"))) if not res_ans[1]: display((Latex("La réponse à la deuxième question est fausse"))) interact_manual(correction, ans1=ans1, ans2=ans2) return def Ex2Chapitre9_2(): """Provides the correction to exercise 2 of notebook 9_2 """ print("Cliquer sur CTRL pour sélectionner plusieurs réponses") style = {'description_width': 'initial'} ans = widgets.SelectMultiple( options=['1', '2', '3', '4'], description='Les matrices sont orthogonales dans les cas:', style=style, layout=Layout(width='40%', height='80px'), disabled=False, ) def correction(ans): res_ans = '1' in ans and '2' not in ans and \ '3' in ans and '4' not in ans if res_ans: display(Latex(r"C'est correct!")) else: display(Latex("C'est faux.")) interact_manual(correction, ans=ans) return def Ex3Chapitre9_2(): """Provides the correction to exercise 3 of notebook 9_2 """ print("Cliquer sur CTRL pour sélectionner plusieurs réponses") style = {'description_width': 'initial'} ans = widgets.SelectMultiple( options=['1', '2', '3', '4', '5', '6'], description='Les fonctions sont orthogonales dans les cas:', style=style, layout=Layout(width='60%', height='110px'), disabled=False, ) def correction(ans): res_ans = '1' in ans and '2' not in ans and '3' not in ans and \ '4' in ans and '5' in ans and '6' not in ans if res_ans: display(Latex(r"C'est correct!")) else: display(Latex("C'est faux.")) interact_manual(correction, ans=ans) return def Ex3Chapitre9_2_plotter(case_nb=1): """Helper function that allows to plot the functions involved in Ex 3 of notebook 9_2 :param case_nb: test case number. Defaults to 1 :type case_nb: int """ if case_nb in {1, 2}: f = lambda x: 1 - x ** 2 g = lambda x: -(x - 1) ** 2 x0 = -1 x1 = 1 elif case_nb in {3, 4}: f = lambda x: x - 1 / 2 g = lambda x: x ** 2 - x - 1 / 6 x0 = 0 x1 = 1 elif case_nb in {5, 6}: f = lambda x: np.sin(x) g = lambda x: np.cos(x) x0 = -np.pi if case_nb == 5 else 0 x1 = np.pi if case_nb == 5 else np.pi / 2 else: raise ValueError(f"Cas test nombre {case_nb} n'est pas disponible. " f"Cas disponibles: [1,2,3,4,5,6]") couple_functions_plotter(f, g, [x0, x1], pi_formatting=case_nb in {5,6}) return def Ex1Chapitre9_3_4(): """Provides the correction to exercise 1 of notebook 9_3_4 """ print("Cliquer sur CTRL pour sélectionner plusieurs réponses") style = {'description_width': 'initial'} ans = widgets.SelectMultiple( options=['1', '2', '3', '4', '5', '6'], description='La déclaration est vraie dans les cas:', style=style, layout=Layout(width='40%', height='110px'), disabled=False, ) def correction(ans): res_ans = '1' in ans and '2' not in ans and '3' not in ans and \ '4' in ans and '5' not in ans and '6' in ans if res_ans: display(Latex(r"C'est correct! En effet, l'énoncé 1 correspond au lemme de Titu et c'est un " r"corollaire classique de l'inégalité Cauchy-Schwarz, qui peut être prouvé par l'exécution de les " r"substitutions $\tilde{u_i} = \dfrac{u_i}{\sqrt{u_i}}$ et $\tilde{v_i} = \sqrt{v_i}$, pour " r"$i \in \{1,\dots, n\}$. " r"L'énoncé 2 est faux, car l'inégalité traingulaire se maintient avec un " r"signe d'égalité si les vecteurs sont orthogonaux (théorème de Pythagore), mais l' inegalité de " r"Cauchy-Schwarz l'inégalité le fait si les vecteurs sont soit parallèles soit antiparallèles, " r"c'est-à-dire si le cosinus de l'angle entre les vecteurs est égal à 1 ou -1. " r"L'énoncé 3 est faux puisque, dans ce cas, il peut être prouvé par de simples calculs que le " r" cosinus de l'angle entre les deux vecteurs est egal a $0$, de sorte que l'angle est égal à " r"$\pi/2$ et les vecteurs sont orthogonaux." r"L'énoncé 4 est vrai, puisque toutes les fonctions appartenant à la famille $\mathcal{F}_1$ " r"sont mutuellement orthogonal par rapport au produit scalaire donné." r"L'énoncé 5, au contraire, est faux, puisque les monômes pairs et impairs sont toujours " r"orthogonaux sur un intervalle symétrique à 0$, mais deux monomiaux impairs et deux monomiaux " r"pairs ne le sont pas. " r"FEnfin, l'énoncé 6 est vraie, puisque on peut facilement vérifier que les quatre matrices " r"sont mutuellement orthogonales, par rapport au produit scalaire défini via l'opérateur de trace.")) else: display(Latex("C'est faux.")) interact_manual(correction, ans=ans) return def Ex2Chapitre9_3_4(case_nb=1): """Provides the correction to exercise 2 of notebook 9_3_4 :param case_nb: test case number. Defaults to 1 :type case_nb: int """ if case_nb == 1: A = np.array([[-1, 2, 1], [0, 1, -1], [-2, 3, 0]]) B = np.array([[0, -1, 2], [1, 3, -2], [1, 1, 1]]) elif case_nb == 2: A = np.array([[1, -1], [0, 3]]) B = np.array([[0, 2], [1, -1]]) elif case_nb == 3: A = np.array([[0, 1, 3, 0], [1, 0, 1, 0], [-1, -2, 2, 1], [3, 4, 1, 2]]) B = np.array([[3, 1, -1, 2], [2, 2, 0, 1], [-1, 1, -1, 3], [-1, 1, 1, -1]]) elif case_nb == 4: A = np.array([[1, 0], [-1, 3]]) B = np.array([[-1, -5], [2, -3]]) else: raise ValueError(f"Cas test nombre {case_nb} n'est pas disponible. " f"Cas disponibles: [1,2,3,4]") res = get_couple_matrices_info(A, B) display(Latex("Insérez les valeurs des quantités listées ci-dessous. " "Entrez les valeurs avec 4 chiffres après la virgule! Si l'angle n'est pas défini, entrez -999!")) style = {'description_width': 'initial'} angle = widgets.FloatText( value=0.0, step=0.0001, style=style, description=r'$\theta$:', disabled=False ) LHS = widgets.FloatText( value=0.0, step=0.0001, style=style, description='$||A+B||^2$', disabled=False ) RHS = widgets.FloatText( value=0.0, step=0.0001, style=style, description=r'$||A||^2 + ||B||^2$', disabled=False ) solution_button = widgets.Button(description='Solution', disabled=True) box = HBox(children=[solution_button]) out = widgets.Output() @out.capture() def solution(e): out.clear_output() get_couple_matrices_info(A, B, show=True) display(angle) display(LHS) display(RHS) def f(): threshold = 1e-4 if (np.isnan(res['angle']) and angle.value == -999.0) or \ (np.abs(angle.value - res['angle'] * 180.0 / np.pi) <= threshold): display(Latex(r"L'angle est correcte!")) theta_correct = True else: theta_correct = False display(Latex(f"La'angle n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if np.abs(LHS.value - res['norm_sum'] ** 2) <= threshold: display(Latex(r"$||A+B||^2$ est correcte!")) LHS_correct = True else: LHS_correct = False display(Latex(f"$||A+B||^2$ n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if np.abs(RHS.value - res['norm_1'] ** 2 - res['norm_2'] ** 2) <= threshold: display(Latex(r"$||A||^2 + ||B||^2$ est correcte!")) RHS_correct = True else: RHS_correct = False display(Latex(f"$||A||^2 + ||B||^2$ n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if theta_correct and LHS_correct and RHS_correct: display(Latex("C'est tout correct!")) else: solution_button.disabled = False display(Latex("Il y a quelques erreurs. " "N'oubliez pas d'insérer tous les résultats avec 4 chiffres après la virgule")) return interact_manual(f) solution_button.on_click(solution) display(box) display(out) return def Ex3Chapitre9_3_4(case_nb=1): """Provides the correction to exercise 3 of notebook 9_3_4 :param case_nb: test case number. Defaults to 1 :type case_nb: int """ if case_nb == 1: f = lambda x: x g = lambda x: np.exp(-np.abs(x)) x0 = -1 x1 = 1 elif case_nb == 2: f = lambda x: x ** 3 + 0.5 g = lambda x: x ** 2 - x x0 = 0 x1 = 1 elif case_nb == 3: f = lambda x: np.sin(np.abs(2 * x)) g = lambda x: np.cos(np.abs(x + np.pi / 2)) x0 = -np.pi / 2 x1 = np.pi / 2 elif case_nb == 4: f = lambda x: np.sin(np.abs(2 * x)) g = lambda x: np.cos(np.abs(x + np.pi / 2)) x0 = 0 x1 = np.pi / 2 else: raise ValueError(f"Cas test nombre {case_nb} n'est pas disponible. " f"Cas disponibles: [1,2,3,4]") res = get_couple_functions_info(f, g, [x0, x1]) display(Latex("Insérez les valeurs des quantités listées ci-dessous. " "Entrez les valeurs avec 4 chiffres après la virgule! Si l'angle n'est pas défini, entrez -999!")) style = {'description_width': 'initial'} angle = widgets.FloatText( value=0.0, step=0.0001, style=style, description=r'$\theta$:', disabled=False ) LHS = widgets.FloatText( value=0.0, step=0.0001, style=style, description='$||f+g||^2$', disabled=False ) RHS = widgets.FloatText( value=0.0, step=0.0001, style=style, description=r'$||f||^2 + ||g||^2$', disabled=False ) solution_button = widgets.Button(description='Solution', disabled=True) box = HBox(children=[solution_button]) out = widgets.Output() @out.capture() def solution(e): out.clear_output() if case_nb == 1: f = lambda x: x g = lambda x: np.exp(-np.abs(x)) x0 = -1 x1 = 1 elif case_nb == 2: f = lambda x: x ** 3 + 0.5 g = lambda x: x ** 2 - x x0 = 0 x1 = 1 elif case_nb == 3: f = lambda x: np.sin(np.abs(2 * x)) g = lambda x: np.cos(np.abs(x + np.pi / 2)) x0 = -np.pi / 2 x1 = np.pi / 2 elif case_nb == 4: f = lambda x: np.sin(np.abs(2 * x)) g = lambda x: np.cos(np.abs(x + np.pi / 2)) x0 = 0 x1 = np.pi / 2 get_couple_functions_info(f, g, [x0, x1], show=True) couple_functions_plotter(f, g, [x0, x1], pi_formatting=case_nb in {3,4}) display(angle) display(LHS) display(RHS) def f(): threshold = 1e-4 if (np.isnan(res['angle']) and angle.value == -999.0) or \ (np.abs(angle.value - res['angle'] * 180.0 / np.pi) <= threshold): display(Latex(r"L'angle est correcte!")) theta_correct = True else: theta_correct = False display(Latex(f"La'angle n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if np.abs(LHS.value - res['norm_sum'] ** 2) <= threshold: display(Latex(r"$||f+g||^2$ est correcte!")) LHS_correct = True else: LHS_correct = False display(Latex(f"$||f+g||^2$ n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if np.abs(RHS.value - res['norm_1'] ** 2 - res['norm_2'] ** 2) <= threshold: display(Latex(r"$||f||^2 + ||g||^2$ est correcte!")) RHS_correct = True else: RHS_correct = False display(Latex(f"$||f||^2 + ||g||^2$ n'est pas correcte! L'erreur est supérieure au seuil de {threshold}. " f"Entrez les valeurs avec 4 chiffres après la virgule!")) if theta_correct and LHS_correct and RHS_correct: display(Latex("C'est tout correct!")) else: solution_button.disabled = False display(Latex("Il y a quelques erreurs. " "N'oubliez pas d'insérer tous les résultats avec 4 chiffres après la virgule")) return interact_manual(f) solution_button.on_click(solution) display(box) display(out) return def Ex1Chapitre9_5(): """Provides the correction to exercise 1 of notebook 9_5 """ print("Cliquer sur CTRL pour sélectionner plusieurs réponses") style = {'description_width': 'initial'} ans1 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 1:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) ans2 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 2:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) ans3 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 3:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) ans4 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 4:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) def correction(ans1, ans2, ans3, ans4): res_ans = np.zeros(4).astype(bool) res_ans[0] = 'Famille Orthogonale' not in ans1 and 'Famille Orthonormale' not in ans1 and \ 'Base Orthogonale' not in ans1 and 'Base Orthonormale' not in ans1 res_ans[1] = 'Famille Orthogonale' in ans2 and 'Famille Orthonormale' in ans2 and \ 'Base Orthogonale' in ans2 and 'Base Orthonormale' in ans2 res_ans[2] = 'Famille Orthogonale' in ans3 and 'Famille Orthonormale' not in ans3 and \ 'Base Orthogonale' in ans3 and 'Base Orthonormale' not in ans3 res_ans[3] = 'Famille Orthogonale' in ans4 and 'Famille Orthonormale' not in ans4 and \ 'Base Orthogonale' in ans4 and 'Base Orthonormale' not in ans4 if res_ans.all(): display(Latex(r"C'est correct! " r"CAS 1: une famille de trois vecteurs dans un espace de dimension $2$ ne peut pas être " r"orthonormal et donc elle ne peut pas être une base; toutes les options sont fausses. " r"CAS 2: par rapport au produit scalaire non-usuel défini via la matrice $A$ symétrique et " r"défini positive, cette famille de vecteurs est en fait une base orthonormée; " r"en effet tous les produits scalaires entre les différents éléments de la famille sont égaux " r"à $0$ et les normes de tous les vecteurs (toujours calculés par rapport au produit scalaire " r"non-usuel donnèe) sont égaux à $1$. " r"CAS 3: c'est une famille de $4$ vecteurs orthogonaux (et donc linéairement indépendants!) " r"dans $\mathbb{R}^4$, donc c'est à la fois une famille orthogonale et une base orthogonale; " r"de​toute façon aucune des vecteurs a la norme unitaire et il n'y a donc pas d'orthonormalité. " r"CAS 4: il s'agit d'une famille de $3$ vecteurs orthogonaux (et donc linéairement " r"indépendants!) dans un sous-espace de dimension $5$; donc, c'est une famille orthogonale " r"(et aussi orthonormal), mais elle ne peut pas être une base.")) else: display(Latex("C'est faux.")) wrong_indices = np.where(res_ans == False)[0] right_indices = np.setdiff1d(np.arange(4), wrong_indices) display(Latex(f"Cas correctes: {right_indices+1}")) display(Latex(f"Cas mauvais: {wrong_indices+1}")) interact_manual(correction, ans1=ans1, ans2=ans2, ans3=ans3, ans4=ans4) return def Ex2Chapitre9_5(): """Provides the correction to exercise 2 of notebook 9_5 """ print("Cliquer sur CTRL pour sélectionner plusieurs réponses") style = {'description_width': 'initial'} ans1 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 1:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) ans2 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 2:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) ans3 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 3:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) ans4 = widgets.SelectMultiple( options=['Famille Orthogonale', 'Famille Orthonormale', 'Base Orthogonale', 'Base Orthonormale'], description='Cas 4:', style=style, layout=Layout(width='60%', height='80px'), disabled=False, ) def correction(ans1, ans2, ans3, ans4): res_ans = np.zeros(4).astype(bool) res_ans[0] = 'Famille Orthogonale' not in ans1 and 'Famille Orthonormale' not in ans1 and \ 'Base Orthogonale' not in ans1 and 'Base Orthonormale' not in ans1 res_ans[1] = 'Famille Orthogonale' in ans2 and 'Famille Orthonormale' not in ans2 and \ 'Base Orthogonale' not in ans2 and 'Base Orthonormale' not in ans2 res_ans[2] = 'Famille Orthogonale' in ans3 and 'Famille Orthonormale' in ans3 and \ 'Base Orthogonale' in ans3 and 'Base Orthonormale' in ans3 res_ans[3] = 'Famille Orthogonale' in ans4 and 'Famille Orthonormale' not in ans4 and \ 'Base Orthogonale' in ans4 and 'Base Orthonormale' not in ans4 if res_ans.all(): display(Latex(r"C'est correct! CASE 1: CAS 1: c'est la base du monôme standard de $\mathbb{P}^4(\mathbb{R})$; " r"de toute façon, il n'est ni orthogonal ni orthonormé par rapport au produit scalaire usuel. " r"CAS 2: c'est une famille de $4$ vecteurs dans un sous-espace de dimension $5$, donc il ne " r"peut pas être une base; de toute façon ses éléments sont orthogonaux entre eux, donc c'est " r"une famille orthogonale (non orthonormé, car aucune des normes des vecteurs est ègale à $1$)" r"CAS 3: c'est une famille de $3$ vecteurs orthogonaux, tous avec norme unitaire, dans un " r"sous-espace de dimension $3$; il s'agit donc d'une famille et d'une base orthogonales et " r"orthonormées. Remarque que tous les calculs doivent être effectués par rapport au produit" r"scalaire non-usuel donnèe, caractérisé par la fonction de pondération $w(x)=1-x^2$." r"CAS 4: c'est la base dite de Fourier et elle est constituée d'un nombre infini de modes, " r"dont la fréquence augmente jusqu'à l'infini (étant infinie la dimension du espace vectoriel " r"$V = \mathcal{C}\left([-\pi;\pi]; \mathbb{R}\right)$); de plus, tous les éléments " r"sont orthogonales entre elles, mais leurs normes sont égales à $\sqrt{2\pi}$ (pour la " r"fonction constante) et à $\sqrt{\ pi}$ (pour toutes les autres fonctions trigonométriques), " r"donc la base est orthogonale mais non orthonormal.")) else: display(Latex("C'est faux.")) wrong_indices = np.where(res_ans == False)[0] right_indices = np.setdiff1d(np.arange(4), wrong_indices) display(Latex(f"Cas correctes: {right_indices+1}")) display(Latex(f"Cas mauvais: {wrong_indices+1}")) interact_manual(correction, ans1=ans1, ans2=ans2, ans3=ans3, ans4=ans4) return + + +def Ex3Chapitre9_5(ans, case_nb=1): + """Provides the correction to exercise 2 of notebook 9_5 + + :param ans: answer of the user + :type ans: numpy.ndarray or list + :param case_nb: number of the test case. It defaults to 1 + :type case_nb: int + """ + + int_limits = None + weight_function = None + W = None + + if case_nb == 1: + B = [[2,0,1], [0,1,-1], [1,1,0]] + v = [1,1,1] + elif case_nb == 2: + B = [[2,0,1,1], [0,1,-1,1], [1,0,-1,-1], [0,2,1,-1]] + v = [-1,0,2,-2] + elif case_nb == 3: + B = [lambda x: 1.0, lambda x: x-1/2, lambda x: x**2-x+1/6, lambda x: x**3 - 3/2*x**2 + 3/5*x -1/20] + v = lambda x: x**3 - x**2 + x - 1 + int_limits = [0,1] + elif case_nb == 4: + B = [lambda x: np.sqrt(3)/2, lambda x: np.sqrt(15/2)*x, lambda x: np.sqrt(7)*5/7*x**2 - np.sqrt(7)/14] + v = lambda x: x**2 + x + 1 + int_limits = [-1,1] + weight_function = lambda x: 1 - x**2 + else: + raise ValueError(f"Case Number {case_nb} does not exist!") + + v_B = compute_expansion_coefficients(B, v, int_limits=int_limits, weight_function=weight_function, W=W) + + solution_button = widgets.Button(description='Solution', disabled=True) + box = HBox(children=[solution_button]) + out = widgets.Output() + + @out.capture() + def solution(e): + out.clear_output() + display(Latex(f"Solution: {v_B}")) + if case_nb == 4: + display(Latex(r"C'est le cas dans lequel la norme de $v$ peut être calculée rapidement. En effet, " + r"base donnée est orthonormée, donc la norme de $v$ est égale à celle du vecteur exprimant " + r"ses coordonnées par rapport à $\mathcal{B}$ et il peut être dérivé sans effectuer aucune " + r"intégration numérique!")) + + threshold = 1e-4 + if np.linalg.norm(ans-v_B) <= threshold: + display(Latex("C'est correct!")) + else: + solution_button.disabled = False + display(Latex("C'est faux! N'oubliez pas d'insérer tous les résultats avec 4 chiffres après la virgule")) + + solution_button.on_click(solution) + display(box) + display(out) + + return