A3PAL - Algèbre linéaire - TP2 : Vecteur en dimension arbitraire

Objectif

- Programmer une classe Vecteur pour représenter et manipuler les vecteurs dans l'espace euclidien de dimension n, quel que soit l'entier naturel n.

Liste des compétences à acquérir pendant le TP:

Ce programme sera ré-utilisé tout au long de l'unité A3PAL.

0 - Travail préliminaire

a. Téléchargez le fichier TP2.jar et enregistrez le dans le répertoire 'AlgèbreLinéaire' créé lors du premier TP.

b. Sous BlueJ, ouvrez le fichier TP2.jar : Menu "Projet" -> "Open Project" et sélectionnez le fichier "TP2.jar".

Après avoir répondu à une question, cliquez sur le bouton "Run Tests" et vérifiez que l'indicateur de la question passe au vert. Si BlueJ indique une croix rouge pour la question que vous venez de résoudre cela veut dire que votre solution n'est pas correcte ! Si l'indicateur passe au vert cela veut dire que votre solution est peut-être correcte !

1 - Création de la classe Vecteur

a. Créez dans votre projet une nouvelle classe Vecteur (bouton 'New Class' sous Bluej). Cette classe devra permettre d'instancier un vecteur en dimension arbitraire, c'est-à-dire, un vecteur défini dans espace euclidien dont la dimension est choisi au moment de la création du vecteur. En termes de programmation, cela signifie que l'on passera au constructeur (dont la programmation sera abordée à la question 1.c) de la classe un paramètre indiquant la dimension n de l'espace de définition du vecteur ; ce vecteur comprendra donc n coordonnées. Inspectez le code de la classe Vecteur créé par BlueJ ? Que contient-il ? Cela correspond-il à un vecteur en dimension arbitraire ? Supprimez les attributs et méthodes qui ne sont pas nécessaires. En utilisant uniquement les types de données vus en cours jusqu'à présent, est-il possible de déclarer les attributs correspondant à un vecteur en dimension arbitraire ? Pourquoi ?

b. Afin de pouvoir définir les attributs d'une classe pour représenter un vecteur en dimension arbitraire, il est possible d'utiliser un tableau. Par exemple, le vecteur dont les coordonnées sont (0 ; 1.5 ; 2) sera représenté grâce un attribut tableau à 3 cases et l'on retrouvera à l'indice 0 de ce tableau la valeur 0, à l'indice 1 la valeur 1.5 et à l'indice 2 la valeur 2. Après avoir lu cette ressource sur les tableaux, déclarez dans la classe Vecteur un attribut pour représenter un vecteur en dimension arbitraire. Nous rappelons que les coordonnées des vecteurs sont des nombres réels et que le type double est utilisé pour représenter ces nombres réels.

c. Ajoutez à la classe Vecteur un constructeur à un paramètre de type int spécifiant la dimension de l'espace de définition du vecteur et créant une instance du vecteur nul dans cet espace. La signature de ce constructeur est donc :

public Vecteur(final int pn)

d. Ajoutez à la classe Vecteur un accesseur à un paramètre de type int spécifiant l'indice i de la coordonnée à retourner. La signature de cet accesseur est donc :

public double getCoordonnee(final int pi)

e. Ajoutez à la classe Vecteur un accesseur sans paramètre retournant la dimension de l'espace de définition du vecteur. La signature de cet accesseur est donc :

public int getDimension()

f. Ajoutez à la classe Vecteur un modificateur à deux paramètres permettant d'affecter une valeur à l'une des coordonnées de l'instance courante de la classe Vecteur. Le premier paramètre, de type int, spécifie l'indice de la coordonnée à modifier et le second, de type double, spécifie la valeur à affecter à cette coordonnée. La signature de ce modificateur est donc :

public void setCoordonnee(final int pi, final double pCoordonnee)

g. Afin de tester votre classe, créez un vecteur en dimension 3 et un vecteur en dimension 4. Invoquez la méthode getDimension sur ces deux vecteurs et vérifiez qu'elle retourne une valeur conforme à la définition. Modifiez ensuite ces deux vecteurs afin de leur affecter les coordonnées (0 ; 1.5 ; 2) et (0 ; 0 ; 3 ; 1) respectivement. Enfin, vérifiez grâce à la méthode getCoordonnee que les modifications effectuées sont conformes à ce qui est souhaité. Que se passe-t-il lorsque vous invoquez getCoordonnee(4) sur les deux vecteurs que vous avez créés ? Expliquez ?

2 - Dessiner

a. Comme vous l'avez vu lors du TP précédent la classe Plan permet de représenter des vecteurs de l'espace euclidien de dimension 2. Pour visualiser simplement un vecteur en dimension arbitraire n, nous allons visualiser le vecteur en dimension 2 formé des deux premières coordonnées du vecteur en dimension n. Cela revient en quelque sorte à se placer dans le plan défini par les vecteurs (1; 0 ;...; 0) et (0 ;1 ; 0 ... 0) et à diriger le regard selon une direction orthogonale à ce plan. Afin de pouvoir réaliser une telle visualisation avec la classe Plan, ajoutez à la classe Vecteur deux accesseurs :

- nommés getX et getY ;

- sans paramètre ; et

- retournant respectivement la première et la deuxième coordonnée de l'instance courante de la classe vecteur.

b. Créez un Vecteur en dimension 3 et un Vecteur en dimension 4 et affectez à ces vecteurs les coordonnées (0 ; 1.5 ; 2) et (1 ; 2 ; 3 ; 1). Créez un Plan et représentez les deux vecteurs dans ce plan à l'aide de la méthode dessinerVecteurEn2d de ce Plan. Que constatez-vous si vous souhaitez dessiner dans ce plan le vecteur (0 ; 1.5 ; 0 ) ? Est-ce normal ?

Remarque : Dans la suite de l'unité, on s'intéressera à des méthodes de visualisation permettant de simuler l'image obtenu en positionnant arbitrairement l'observateur dans l'espace euclidien à trois dimensions.

3 - Multiplication par un scalaire

a. Après avoir consulté les éléments d'aide présentés ci-après, ajoutez à la classe Vecteur une procédure publique multiplicationScalaire à un paramètre qui multiplie l'instance courante du Vecteur par le paramètre scalaire.

Aide 1. Pour pouvoir répéter un bloc d'instructions donné pour chaque coordonnée d'un vecteur, il est possible d'utiliser une structure de contrôle 'boucle for'. Avant de commencer la programmation de la méthode norme, lisez cette ressource sur la boucle for.

b. Testez votre méthode sur quelques exemples en vérifiant qu'elle retourne bien une valeur conforme à la définition.

4 - Norme

a. Ajoutez à la classe Vecteur une méthode publique norme sans paramètre qui retourne la norme du Vecteur courant.

Aide 2. Pour calculer la racine carrée d'un nombre réel (représenté par un double en Java) Java fournie la méthode sqrt de la classe Math. Par exemple, la ligne de code suivante a pour effet d'affecter à a la racine carré de b :

a = Math.sqrt(b);

b. Testez votre méthode sur les vecteurs (1 ; 1 ; 1 ; 1 ; 1), (2; 0) et (0 ; 0 ; 0) et vérifiez que son action est conforme à la définition.

5 - Normalisation

a. Ajoutez à la classe Vecteur une procédure publique normaliser sans paramètre qui normalise l'instance courante de la classe Vecteur.

b. Testez votre méthode sur les vecteurs (1 ; 1 ; 1 ; 1 ; 1), (2; 0) et (0 ; 0 ; 0) et vérifiez que son action est conforme à la définition.

6 - Somme vectorielle

a. Ajoutez à la classe Vecteur une procédure publique sommeVectorielle à un paramètre qui somme le Vecteur passé en paramètre à l'instance courante du Vecteur.

b. Testez votre procédure sur quelques exemples et vérifiez que son action est conforme à la définition. Que se passe-t-il lorsque que vous essayez de sommer deux vecteurs définis dans des espaces de dimension différente ?

7 - Produit scalaire

a. Ajoutez à la classe Vecteur une fonction publique produitScalaire à un paramètre qui retourne le produit scalaire de l'instance courante du Vecteur avec le Vecteur passé en paramètre.

b. Testez votre méthode sur quelques exemples en vérifiant qu'elle retourne bien une valeur conforme à la définition. Que se passe-t-il lorsque vous essayez de calculer le produit scalaire de deux vecteurs définis dans des espaces de dimension différente ?

8 - Produit vectoriel en 3 dimensions

a. Ajoutez à la classe Vecteur une fonction publique produitVectoriel3d à un paramètre de type Vecteur. Cette méthode agit de la manière suivante :

- si le Vecteur courant et celui passé en paramètre sont définis en dimension 3, alors la méthode retourne un nouveau Vecteur qui est le produit vectorielle de l'instance courante par le Vecteur passé en paramètre.

- sinon, la méthode retourne la référence null (grâce à l'instruction return null;) pour indiquer que l'opération ne peut pas être effectuée.

b. Testez votre méthode sur quelques exemples en vérifiant qu'elle retourne bien une valeur conforme à la définition. Testez en particulier le vecteur nul.

c. Après avoir lu les éléments d'aide présentés ci-dessous, visualisez graphiquement le résultat du produit vectoriel de u par v, où u = (1 ; 1; 1) et v= (-1; 1; -1).

Aide 3. Le code-pad de Bluej pourra vous être utile. Pour cela, l'option 'show code-pad' du menu 'view' doit être sélectionnée. Le code-pad est un petit terminal grace auquel il est possible d'exécuter pas-à-pas des instructions en Java. Essayez par exemple d'entrer dans le code pad l'instruction 'u = new Vecteur(3);' puis l'instruction 'p = new Plan()', et enfin l'instruction 'p.dessinerVecteurEn2d(u);'.

9 - Orthogonalité

a. Ajoutez à la classe Vecteur une fonction publique estOrthogonal à un paramètre qui retourne une valeur booléenne indiquant si l'instance courante du Vecteur est orthogonale au Vecteur passé en paramètre.

b. Testez votre méthode sur quelques exemples en vérifiant (par exemple avec les vecteurs u et v de la question 8.c) qu'elle retourne bien une valeur conforme à la définition. Testez en particulier le vecteur nul.

10 - Colinéarite

a. Ajoutez à la classe Vecteur une fonction publique estColineaire à un paramètre qui retourne un booléen indiquant si l'instance courante du Vecteur est colinéaire au Vecteur passé en paramètre.

b. Testez votre méthode sur les exemples suivants :

Si le résultat est conforme pour tous les tests sauf le dernier, ne vous inquiétez pas, nous allons résoudre le problème dans la question suivante.

c. Dans ce TP, nous ne nous sommes pas souciés des erreurs d'arrondi (le type double n'est qu'une approximation des nombres réels car il faudrait une quantité infinie de mémoire et de puissance de calcul pour pouvoir représenter et manipuler les réels de façon exacte). Ajoutez à la classe Vecteur une fonction approche prenant trois paramètres de type double a, b et epsilon et retournant true si l'écart entre a et b est inférieur à epsilon. Si vous aviez déjà codé cette fonction lors du TP précédent, vous pouvez réutiliser ce que vous aviez déjà fait.

Aide 4 : Pour calculer la valeur absolue d'un double, Java fournie la méthode abs de la classe Math. Par exemple, la ligne de code suivante a pour effet d'affecter à a la valeur absolue de b :

a = Math.abs(b);

d. Dans les fonctions estOrthogonal et estColineaire, remplacez chaque test d'égalité entre deux variables de type double par un appel à la méthode approche avec une valeur d'epsilon suffisamment petite (0,00001).

e. Vérifiez que la méthode estColineaire fonctionne correctement en reprenant les tests de la question 10.b.

11 - Coplanarité en 3 dimensions

a. Ajoutez à la classe Vecteur une fonction publique estCoplanaire3d à deux paramètres qui retourne un booléen indiquant si l'instance courante de la classe Vecteur est coplanaire aux deux instances de la classe Vecteur passées en paramètre. On supposera que les vecteurs mis en jeu lors d'appels à cette méthode sont toujours définis en dimension 3.

b. Testez votre méthode sur quelques exemples en vérifiant qu'elle retourne bien une valeur conforme à la définition. Testez en particulier le vecteur nul.

12 - TP1

Terminez le TP 1, si ce n'est pas déjà fait

13 - Orthogonalité : pour aller plus loin

a. Ajoutez à la classe Vecteur une fonction obtenirVect3dOrthogonal sans paramètre. Cette méthode doit retourner un vecteur orthogonal (non nul) à l'instance courante du Vecteur si celui-ci est défini en dimension 3 ou à la référence null sinon.

b. Testez votre méthode sur quelques exemples en vérifiant qu'elle retourne bien une valeur conforme à la définition. Testez en particulier le vecteur nul.

Sujet rédigé par Jean Cousty, Benjamin Perret et Leïla Reille pour l'unité A3PAL à ESIEE Paris.