Skip to content

Instantly share code, notes, and snippets.

@khinsen
Created December 5, 2018 08:44
Show Gist options
  • Save khinsen/e892765281641087b16e2fc69bab67c4 to your computer and use it in GitHub Desktop.
Save khinsen/e892765281641087b16e2fc69bab67c4 to your computer and use it in GitHub Desktop.
NumPy - Applications
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# NumPy : applications"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"%matplotlib inline\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Dérivées numériques"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pour un traitement numérique, une fonction $f(x)$ est souvent représentée par ses valeurs sur une grille $x_i$, $i = 1\\ldots N$. Nous en avons vu en exemple la semaine dernière, en plottant les fonctions $\\sin$ et $\\cos$:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"x = np.linspace(0, 2.*np.pi, 50)\n",
"sin_x = np.sin(x)\n",
"cos_x = np.cos(x)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercice : dérivée numérique"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Étant donné $x_i$ et $f(x_i)$ pour $i=1\\ldots N$, l'approximation la plus simple pour la dérivée $f'$ est\n",
"\n",
"$$x'_j = \\frac{1}{2}(x_j + x_{j+1})$$\n",
"\n",
"$$f'(x'_j) = \\frac{f(x_{j+1})-f(x_j)}{x_{j+1}-x_{j}}$$\n",
"\n",
"pour $j = 1 \\ldots N-1$.\n",
"\n",
"Calculez cette dérivée numérique pour la fonction $\\sin$ et faites un plot comparatif avec la fonction $\\cos$.\n",
"\n",
"**Pour bien profiter des avantages en performance de NumPy, il est important de ne pas utiliser des boucles explicites dans votre code. Le `for` est donc interdit dans cet exercice !**"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"hide_input": false
},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x11366bba8>"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\ngkFERGr5/8oa2oLoftJlAAAAAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x11340c160>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"xx = 0.5*(x[1:]+x[:-1])\n",
"ff = (sin_x[1:]-sin_x[:-1]) / (x[1:]-x[:-1])\n",
"plt.plot(xx, ff, '*', label=\"dérivée de sin\")\n",
"plt.plot(x, cos_x, '+', label=\"cos\")\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Matrices"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Les matrices sont des tableaux avec deux dimensions. Elles sont fréquemment utilisées en calcul scientifique, souvent dans les applications de l'algèbre linéaire (systèmes d'équations linéaires, équations différentielles, opérateurs linéaires, ...), mais aussi pour des applications très différentes comme la représentation d'un graphe (matrices d'adjacence).\n",
"\n",
"Deux opérations fréquentes sont la multiplication de deux matrices :\n",
"\n",
" $$A_{ij} = \\sum_{k} B_{ik} \\cdot C_{kj}$$\n",
"\n",
"et la multiplication d'un vecteur (tableau 1D) avec une matrice :\n",
"\n",
" $$y_{i} = \\sum_{k} M_{ik} \\cdot x_{k}$$\n",
"\n",
"Les deux sont écrites de la même façon en NumPy :"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"vecteur = np.array([1, 2])\n",
"matrice1 = np.array([[10, 20], [30, 40]])\n",
"matrice2 = matrice1.T"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Le suffix `.T` produit la transposée de la matrice d'origine."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 500, 1100],\n",
" [1100, 2500]])"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"matrice1 @ matrice2"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([ 50, 110])"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"matrice1 @ vecteur"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il ne faut surtout pas confondre la multiplication de matrices avec la multiplication élément par élément de deux tableaux :"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 100, 600],\n",
" [ 600, 1600]])"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"matrice1 * matrice2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exercice : géométrie 2D"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Un point dans un plan (papier, écran, ...) peut être représenté par un vecteur avec deux éléments $r = [x, y]$. Les deux transformations les plus basiques dans un plan sont la translation,\n",
"\n",
" $$r' = r + [\\Delta_x, \\Delta_y]$$\n",
"\n",
"et la rotation autour de l'origine par un angle $\\phi$,\n",
"\n",
" $$r'' = D(\\phi) \\cdot r$$\n",
"\n",
"avec la matrice de rotation\n",
"\n",
"$$\n",
" D(\\phi) =\n",
" \\left( \\begin{matrix}\n",
" \\cos\\phi & -\\sin\\phi \\\\\n",
" \\sin\\phi & \\cos\\phi \\\\\n",
" \\end{matrix} \\right)\n",
"$$\n",
"\n",
"En rajoutant un troisième élément $1$ aux vecteurs $r = [x, y, 1]$, on peut écrire une rotation suivie par une translation comme\n",
"\n",
" $$ r''' = T(\\phi, \\Delta) \\cdot r$$\n",
"\n",
"avec\n",
"\n",
"$$\n",
" T(\\phi, \\Delta) =\n",
" \\left( \\begin{matrix}\n",
" \\cos\\phi & -\\sin\\phi & \\Delta_x \\\\\n",
" \\sin\\phi & \\cos\\phi & \\Delta_y \\\\\n",
" 0 & 0 & 1 \\\\\n",
"\\end{matrix} \\right)\n",
"$$\n",
"\n",
"L'intérêt de cette représentation est que toute transformation devient une multiplication par une matrice. On peut ainsi facilement définir des transformations plus compliquées."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Votre mission, si toutefois vous l'acceptez, consiste des tâches suivantes :\n",
"\n",
" 1. Définissez une fonction `point(x, y)` qui rend un tableau avec 3 éléments représentant un point.\n",
" 2. Définissez une fonction `translation(dx, dy)` qui rend un tableau 3x3 représentant une translation définie par les deux déplacements `dx` et `dy`.\n",
" 3. Définissez une fonction `rotation(phi)` qui rend un tableau 3x3 représentant une rotation autour de l'origine par un angle `phi`.\n",
" 4. Utilisez ces fonctions pour construire une rotation par $\\phi=45°$ autour du point $[1, 1]$. La façon la plus simple est d'enchaîner trois transformations :\n",
" 1. Une translation qui déplace le point $[1, 1]$ à l'origine.\n",
" 2. Une rotation autour de l'origine.\n",
" 3. Une translation qui déplace l'origine vers $[1, 1]$.\n",
"\n",
"Vérifiez votre code de façon graphique comme montré ci-dessous:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": true,
"hide_input": false
},
"outputs": [],
"source": [
"def point(x, y):\n",
" return np.array([x, y, 1.])"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": true,
"hide_input": false
},
"outputs": [],
"source": [
"def translation(dx, dy):\n",
" return np.array([[1., 0., dx],\n",
" [0., 1., dy],\n",
" [0., 0., 1.]])"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true,
"hide_input": false
},
"outputs": [],
"source": [
"def rotation(phi):\n",
" return np.array([[np.cos(phi), -np.sin(phi), 0.],\n",
" [np.sin(phi), np.cos(phi), 0.],\n",
" [0., 0., 1.]])"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": true,
"hide_input": false
},
"outputs": [],
"source": [
"rotation_autour_1_1 = translation(1, 1) @ rotation(45.*np.pi/180.) @ translation(-1, -1)"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"hide_input": false
},
"outputs": [
{
"data": {
"image/png": "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\nn1Dhi4j4xP8HSDC4i5IGlQ4AAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x108cc8be0>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(6,6))\n",
"plt.xlim(0, 4)\n",
"plt.ylim(0, 4)\n",
"\n",
"centre_de_rotation = point(1,1)\n",
"for p in [point(2, 1), point(1, 2), point(3, 2)]:\n",
" p_tr = rotation_autour_1_1 @ p\n",
" points_a_connecter = [p, centre_de_rotation, p_tr]\n",
" plt.plot([r[0] for r in points_a_connecter],\n",
" [r[1] for r in points_a_connecter])"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment