IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Mathématiques et Python - Initiation au calcul vectoriel avec NumPy,
Un tutoriel de Denis Hulo

Le , par User

8PARTAGES

10  0 
Bonjour à tous,

Je vous propose dans ce nouvel article de découvrir le calcul vectoriel à l’aide de la bibliothèque NumPy :



Après avoir donné une rapide présentation des vecteurs et des opérations qui leur sont associées, nous allons montrer comment les définir avec NumPy et les représenter graphiquement à l'aide de Matplotlib.

Ensuite, nous allons réaliser différentes opérations dans l'environnement Python, comme l'addition de deux vecteurs NumPy, la multiplication par un scalaire, ou encore la transformation d'un vecteur via une fonction mathématique.

L'objectif est surtout de découvrir le calcul vectoriel avec NumPy à travers des exemples concrets : addition vectorielle, calcul du barycentre de trois points, détermination du centre de masse d'un demi-disque.

Bonne lecture à tous !
Vous avez lu gratuitement 14 305 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Mirmillon
Membre habitué https://www.developpez.com
Le 23/08/2025 à 10:51
Merci beaucoup pour ce tutoriel !
Pensez vous à l'étendre jusqu'à l’utilisation des calculs vectoriels dans le machine learning ?
1  0 
Avatar de fred1599
Expert éminent https://www.developpez.com
Le 27/08/2025 à 20:30
Hello,

Désolé pour le temps de réponse, voici quelques suggestions et questionnement, je n'ai pas tout lu !

Pour visualiser l'isobarycentre de trois points, dans le script global,

  1. Les deux lignes plt.plot(0, 0, "None" et plt.plot(7, 7, "None" servent à délimiter les axes. Ne serait-il pas plus explicite d'utiliser les fonctions dédiées plt.xlim() et plt.ylim() pour définir les limites des axes ?
  2. Je vois que plt.axis('scaled') et plt.axis('equal') sont appelés successivement. As-tu vérifié si l'appel à plt.axis('scaled') est réellement nécessaire ? D'après la documentation officielle de Matplotlib, l'option 'equal' est souvent suffisante pour garantir un repère orthonormé.
  3. Le triangle est tracé en trois appels distincts à plt.plot pour chaque segment (AB, BC, AC). Pourrait-on simplifier ce tracé en un seul appel ?
1  0 
Avatar de fred1599
Expert éminent https://www.developpez.com
Le 28/08/2025 à 11:32
Hello,

C'est tout de même un excellent travail, je pinaille

L'idée est de regrouper les informations des points dans une structure de données et d'itérer dessus pour éviter la répétition du code print, scatter et annotate.

Ne pourrait-on pas remplacer

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
plt.scatter(A[0], A[1], s=20, color = 'b')
plt.annotate('A', xy=(A[0], A[1]))# Trace le point B en vert
plt.scatter(B[0], B[1], s=20, color = 'g')
plt.annotate('B', xy=(B[0], B[1]))# Trace le point C en orange
plt.scatter(C[0], C[1], s=20, color = 'orange')
plt.annotate('C', xy=(C[0], C[1]))
print('Point A{0}'.format(A))
print('Point B{0}'.format(B))
print('Point C{0}'.format(C))
par

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
# Stocke les informations des points et les affiche via une boucle
points_info = {'A': (A, 'b'), 'B': (B, 'g'), 'C': (C, 'orange')}


for name, (coords, color) in points_info.items():
    print('Point {0}{1}'.format(name, coords))
    plt.scatter(coords[0], coords[1], s=20, color=color)
    plt.annotate(name, xy=coords)
Le code est plus court et plus facile à maintenir, qu'en penses-tu ?

Pour la simplification du triangle je parlais de l'appel à plot, donc cette ligne

Code : Sélectionner tout
1
2
plt.plot(x1, y1, x2, y2, x3, y3, color="black")
J'avais pensé à préférer remplacer ces lignes

Code : Sélectionner tout
1
2
3
4
5
6
7
8
# Trace le triangle ABC
x1, y1 = [A[0], B[0]], [A[1], B[1]]
x2, y2 = [B[0], C[0]], [B[1], C[1]]
x3, y3 = [A[0], C[0]], [A[1], C[1]]


plt.plot(x1, y1, x2, y2, x3, y3, color="black")
par

Code : Sélectionner tout
1
2
3
4
5
# Trace le triangle ABC en reliant les sommets dans l'ordre (A -> B -> C -> A)
triangle_coords_x = [A[0], B[0], C[0], A[0]]
triangle_coords_y = [A[1], B[1], C[1], A[1]]
plt.plot(triangle_coords_x, triangle_coords_y, color="black")
Cette approche est plus idiomatique avec Matplotlib pour tracer des polygones et son intention est immédiatement compréhensible : tracer une forme fermée passant par les points A, B, et C.
Qu'en penses-tu ?

Et je suis d'accord avec toi sur le fait de privilégier la clarté et la décomposition des étapes, c'est une excellente approche pédagogique.
1  0 
Avatar de User
Rédacteur/Modérateur https://www.developpez.com
Le 28/08/2025 à 18:16
Oui la logique Matplotlib : on passe les x et les y en arguments et après on génère les points à partir de leurs coordonnées et on les relie..

Merci mais je pense que je vais laisser comme ça, tu m'as déjà bien aidé, même si c'est un peu répétitif c'est juste 3 points. Après libre à chacun de choisir
1  0 
Avatar de User
Rédacteur/Modérateur https://www.developpez.com
Le 30/08/2025 à 20:31
Je me suis peut-être mal exprimé.

Si tu prends un disque homogène le centre de masse correspond au centre du disque qui est aussi le centre de symétrie.

Dans le cas du disque homogène si chaque point M généré dans le disque a son symétrique M' par rapport à O, alors tu gardes la symétrie. Mais tu peux aussi la perdre, en fonction des valeurs données par np.linspace(-r,r,k), mais aussi en fonction du test sur les points avec if ux*ux + uy*uy <= r*r (dans le disque ou pas).

Il peut aussi y avoir des erreurs dans les résultats des opérations portant sur des float notamment quand tu fais la somme ou la moyenne d'un grand nombre de valeurs.
1  0 
Avatar de User
Rédacteur/Modérateur https://www.developpez.com
Le 23/08/2025 à 17:25
Bonjour,

Citation Envoyé par Mirmillon Voir le message
Merci beaucoup pour ce tutoriel !
Pensez vous à l'étendre jusqu'à l’utilisation des calculs vectoriels dans le machine learning ?
Oui, c'est une idée que je retiens, merci à vous.
0  0 
Avatar de User
Rédacteur/Modérateur https://www.developpez.com
Le 28/08/2025 à 10:18
Bonjour,

Citation Envoyé par fred1599
Pour visualiser l'isobarycentre de trois points, dans le script global,

Les deux lignes plt.plot(0, 0, "None" et plt.plot(7, 7, "None" servent à délimiter les axes. Ne serait-il pas plus explicite d'utiliser les fonctions dédiées plt.xlim() et plt.ylim() pour définir les limites des axes ?
Oui merci, j'avais repris cet méthode sur un site, mais j'utilise bien plt.xlim() et plt.ylim() dans d'autres exemples et en effet c'est plus explicite, comme quoi..

Je vois que plt.axis('scaled') et plt.axis('equal') sont appelés successivement. As-tu vérifié si l'appel à plt.axis('scaled') est réellement nécessaire ? D'après la documentation officielle de Matplotlib, l'option 'equal' est souvent suffisante pour garantir un repère orthonormé.
Oui c'est exact, c'est un oubli de ma part, d'ailleurs pour les autres exemples je n'ai pas mis d'appel à plt.axis('scaled').

Le triangle est tracé en trois appels distincts à plt.plot pour chaque segment (AB, BC, AC). Pourrait-on simplifier ce tracé en un seul appel ?
C'est un des avantages de pyplot.quiver() sur pyplot.arrow() que de pouvoir tracer plusieurs vecteurs en un seul appel, on est d'accord.

J'ai fait ce choix pour le lecteur débutant : trouvant plus clair de faire trois appels avec un tracé de vecteur par appel, plutôt que de constituer des listes pour les origines (X,Y), pour les composantes (U,V), pour les couleurs, etc.

En gros j'ai trouvé plus lisible :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
# Trace le vecteur OA
plt.quiver(0, 0, OA[0], OA[1], color='b', angles='xy', scale_units = 'xy', scale = 1)

# Trace le vecteur OB 
plt.quiver(0, 0, OB[0], OB[1], color='g', angles='xy', scale_units = 'xy', scale = 1)

# Trace le vecteur OC 
plt.quiver(0, 0, OC[0], OC[1], color='orange', angles='xy', scale_units = 'xy', scale = 1)
Que :

Code : Sélectionner tout
plt.quiver([0, 0, 0], [0, 0, 0], [OA[0], OB[0], OC[0]], [OA[1], OB[1], OC[1]], color=['b','g','orange'], angles='xy', scale_units = 'xy', scale = 1)
Même si un appel c'est plus concis et plus rapide comme tu le suggères.

Encore merci
0  0 
Avatar de fred1599
Expert éminent https://www.developpez.com
Le 29/08/2025 à 12:41
Hello,

Ça marche ! Je lis au fur et à mesure... Je vois deux boucles imbriquées dans le code suivant

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def generer_vecteurs(ox=0, oy=0, r=1, k=100):
    # ox, oy : coordonnées du centre du disque
    # r : rayon du disque
    # k : nombre de valeurs en x et en y

    # initialisation de la liste des vecteurs
    OA=[]
        
    # parcours des valeurs de ux entre -r et +r
    for ux in np.linspace(-r,r,k):
        # parcours des valeurs de uy entre -r et +r
        for uy in np.linspace(-r,r,k):
            # test si le point de coordonnées (ux,uy) est dans le cercle
            if ux*ux + uy*uy <= r*r:
                # si oui, ajout du vecteur (ux+ox,uy+oy) à la liste
                OA.append(np.array([ux+ox,uy+oy]))

    # renvoie la liste des vecteurs : OA[0], OA[1], ...
    return OA
On est pas top, et niveau efficacité il y a sans doute mieux avec NumPy (que tu utilises dans tes autres codes).
Pour une résolution de k=500, la différence de performance n'est plus théorique, elle devient très perceptible.
Avec k=500, ta list comprehension effectue 500x500=250 000 itérations en Python. C'est précisément le cas de figure où l'approche vectorisée de NumPy montre toute sa puissance.

Dis moi si je tape à côté...
0  0 
Avatar de User
Rédacteur/Modérateur https://www.developpez.com
Le 29/08/2025 à 16:32
Salut,

Dans un sens tu as raison, mais c'est moins intuitif pour un débutant. Là je construis une liste de couples (liste de points) petit-à-petit dans une double boucle. Comme je le mentionne, tu peux aussi utiliser la vectorisation avec numpy.meshgrid() (beaucoup plus rapide, mais moins intuitif).

Voilà ce que ça donnerai (ce n'est pas de moi) :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import numpy as np

def generer_vecteurs(ox=0, oy=0, r=1, k=100):
    # Génération de la grille
    ux = np.linspace(-r, r, k)
    uy = np.linspace(-r, r, k)

    # transforme deux vecteurs 1D (ux et uy) en deux grilles 2D
    X, Y = np.meshgrid(ux, uy, indexing="xy")

    # Test de l'appartenance au disque
    mask = X**2 + Y**2 <= r**2

    # Sélection des points valides et translation (ox, oy)
    Xv = X[mask] + ox
    Yv = Y[mask] + oy

    # Empilement sous forme de vecteurs [x,y]
    OA = np.stack([Xv, Yv], axis=1)

    return OA
X contient toutes les coordonnées x répétées en colonnes.
Y contient toutes les coordonnées y répétées en lignes.
0  0 
Avatar de fred1599
Expert éminent https://www.developpez.com
Le 29/08/2025 à 16:56
Yes,

C'est ce que j'attendais, du coup faut faire le test fonctionnel, comparer les performances, et voir si l'intérêt en vaut la peine comme je l'ai prédis dans mon précédent message.

Citation Envoyé par User
Dans un sens tu as raison, mais c'est moins intuitif pour un débutant.
Bah tu peux pas l'utiliser dans ton tuto et me dire que dans ce cas de figure, NumPy est moins intuitif

Dans ce cas soit on ne fait que pro NumPy, soit on le retire sur l'ensemble du tuto... Perso, débutant ou pas, sur ce genre de travail, on ne peut pas éviter NumPy, ils devront s'y mettre à un moment donné.

EDIT : J'ajoute que les boucles avec NumPy sont une très mauvaise pratique, ce qui n'est pas ce qu'on veut dans un tuto digne de ce nom.
0  0