Matrice : opérations et affichage

Description

Cette source permet de définir une matrice, il est possible d'effectuer les opérations suivantes :
- Accéder à la valeur i, j
- Modifier la valeur i, j</li>
- Effectuer un produit matriciel avec une autre matrice
- Multiplier la matrice par un scalaire réel
- Additionner des matrices
- Déterminer si la matrice est carrée
- Calculer le déterminant de la matrice
- Calculer la trace de la matrice
- Inverser une matrice
- Transposer une matrice
- Récupérer l'endomorphisme associé à la matrice
- Normaliser les sorties d'une matrice pour l'affichage
- Afficher une matrice dans une chaîne de caractères
- Récupérer la sous matrice en supprimant certaines lignes et colonnes

De plus, une classe MatriceView permet d'afficher la matrice dans un JEditoPane

Source / Exemple :


package fr.julien.matrice.model;

import java.util.Arrays;

import fr.julien.matrice.exception.TechnicalException;

/**

  • <b>Matrice est la classe qui définir une matrice à valeurs réelles</b>
  • <p>
  • Cette classe est caractérisée par les informations suivantes :
  • <ul>
  • <li>Le nombre de lignes de la matrice</li>
  • <li>Le nombre de colonnes de la matrice</li>
  • <li>Les valeurs de la matrice</li>
  • </ul>
  • </p>
  • <p>
  • Ce plus, cette classe permet d'effectuer les opérations suivantes :
  • <ul>
  • <li>Accéder à la valeur i, j</li>
  • <li>Modifier la valeur i, j</li>
  • <li>Effectuer un produit matriciel avec une autre matrice</li>
  • <li>Multiplier la matrice par un scalaire réel</li>
  • <li>Additionner des matrices</li>
  • <li>Déterminer si la matrice est carrée</li>
  • <li>Calculer le déterminant de la matrice</li>
  • <li>Calculer la trace de la matrice</li>
  • <li>Inverser une matrice</li>
  • <li>Transposer une matrice</li>
  • <li>Récupérer l'endomorphisme associé à la matrice</li>
  • <li>Normaliser les sorties d'une matrice pour l'affichage</li>
  • <li>Afficher une matrice dans une chaine de caractères</li>
  • <li>Récupérer la sous matrice en supprimant certaines lignes et colonnes</li>
  • </ul>
  • </p>
  • <p>
  • Cette classe contient deux paramètres statiques qui pourront être surchargés :
  • <ul>
  • <li>
  • DEBUT_COMPTAGE désigne l'indice par lequel on commence à numéroter les
  • enregistrements de la matrice, par défaut, cette valeur est 1
  • </li>
  • <li>
  • VARIABLES désigne la liste des variables utilisées pour créer l'expression de
  • l'endomorphisme associé à la matrice. Cette chaine contient par défaut 10 lettres,
  • il faudra ajouter des lettres pour les matrices de dimension supérieures à 10.
  • Les variables sont séparées par des espaces.
  • </li>
  • </ul>
  • </p>
  • @author Julien
  • @version 1.0
  • /
public class Matrice { /**
  • Les valeurs de la matrice enregistrées dans un tableau
  • /
private double[] valeurs; /**
  • Le nombre de lignes de la matrice
  • /
private int nLignes; /**
  • Le nombre de colonnes de la matrice
  • /
private int nColonnes; /**
  • L'indice du premier coefficient de la matrice.
  • Si DEBUT_COMPTAGE=1 alors la première valeur de la matrice est m1,1
  • Si DEBUT_COMPTAGE=0 alors la première valeur de la matrice est m0,0
  • /
public static final int DEBUT_COMPTAGE=1; /**
  • Les noms des variables utilisées pour la génération de
  • l'endomorphisme associé.
  • Les noms des variables sont séparés par des espaces
  • /
public static String VARIABLES = "x y z t m n p k s r"; /**
  • <b>Constructeur de la matrice</b>
  • @param nLignes
  • Le nombre de lignes de la matrice
  • @param nColonnes
  • Le nombre de colonnes de la matrice
  • @param valeurs
  • Les valeurs de la matrice renseignées ligne par ligne
  • <p>
  • Ce constructeur lèvera une TechniclaException (classe fille de RuntimeException)
  • si le nombre de valeurs entrées ne correspond pas aux dimensions de la matrice.
  • </p>
  • <p>
  • Remarque : on peut appeler ce constructeur en utilisant un tableau ou en lui donnant
  • toutes les valeurs en paramètre (ellipse de java 1.6) ce qui revient au même.
  • </p>
  • /
public Matrice(final int nLignes, final int nColonnes, final double... valeurs) { if(nLignes*nColonnes!=valeurs.length){ throw new TechnicalException("Le nombre de valeurs entrées ne correspond pas au nombre de ligne ou de colonnes"); } this.nLignes = nLignes; this.nColonnes = nColonnes; this.valeurs = Arrays.copyOf(valeurs, valeurs.length);; } /**
  • <b>Constructeur de la matrice</b>
  • @param nLignes
  • Le nombre de lignes de la matrice
  • @param nColonnes
  • Le nombre de colonnes de la matrice
  • /
public Matrice(final int nLignes, final int nColonnes) { this(nLignes, nColonnes, new double[nLignes*nColonnes]); } /**
  • <b>Constructeur de matrice</b>
  • @param valeurs
  • Les valeurs à affecter aux coefficients diagonaux
  • <p>
  • Si on ne précise pas la taille de la matrice à construire, alors, la
  • matrice créée est une matrice diagonale dont les coefficients diagonaux sont
  • les valeurs passées en paramètre.
  • </p>
  • /
public Matrice(final double... valeurs){ this.nLignes=valeurs.length; this.nColonnes=valeurs.length; this.valeurs = new double[valeurs.length*valeurs.length]; for(int k=0; k<getnLignes()*getnColonnes(); k++){ this.valeurs[k]=0; } for(int k=DEBUT_COMPTAGE; k<valeurs.length+DEBUT_COMPTAGE; k++){ set(k, k, valeurs[k-DEBUT_COMPTAGE]); } } /**
  • Méthode permettant d'accéder aux valeurs de la matrice
  • @param i
  • indice de la ligne à récupérer
  • @param j
  • indice de la colonne à récupérer
  • @return
  • la valeur à l'indice i, j
  • <p>
  • Cette méthode a des résultats différents selon la valeur du paramètre
  • DEBUT_COMPTAGE. Par défaut le premier coefficient est celui d'indice 1,1
  • </p>
  • /
public final double get(final int i, final int j){ testerIndices(i, j); return valeurs[(i-DEBUT_COMPTAGE)*nColonnes+(j-DEBUT_COMPTAGE)]; } /**
  • Méthode permettant de modifier les valeurs de la matrice
  • @param i
  • indice de la ligne à modifier
  • @param j
  • indice de la colonne à modifier
  • @param value
  • la nouvelle valeur à affecter
  • <p>
  • Cette méthode a des résultats différents selon la valeur du paramètre
  • DEBUT_COMPTAGE. Par défaut le premier coefficient est celui d'indice 1,1
  • </p>
  • /
public final void set(final int i, final int j, final double value){ testerIndices(i, j); valeurs[(i-DEBUT_COMPTAGE)*nColonnes+(j-DEBUT_COMPTAGE)]=value; } /**
  • Fonction qui permet de vérifier que i et j sont bien des éléments de la matrice.
  • Si ce n'est pas le cas, une exception est levée.
  • @param i
  • indice de ligne
  • @param j
  • indice de colonne
  • @throws TechnicalException
  • /
private void testerIndices(int i, int j){ if(i<DEBUT_COMPTAGE || i > nLignes+DEBUT_COMPTAGE){ throw new TechnicalException("Le nombre de lignes de la matrice est insuffisant pour accéder à la ligne "+i); } if(j<DEBUT_COMPTAGE || j > nColonnes+DEBUT_COMPTAGE){ throw new TechnicalException("Le nombre de colonnes de la matrice est insuffisant pour accéder à la colonne "+j); } } /**
  • Méthode permettant de faire un produit matriciel avec une autre matrice.
  • L'ordre du produit est this*m
  • @param m
  • La matrice à droite du produit matriciel
  • @return la matrice résultante
  • @throws TechnicalException si le produit est impossible c'est à dire si
  • tailles des matrices sont incompatibles
  • /
public final Matrice multiplier(final Matrice m) { Matrice res = new Matrice(getnLignes(), m.getnColonnes()); if(getnColonnes()!=m.getnLignes()){ throw new TechnicalException("Le produit des deux matrices est impossible : leurs dimensions sont incompatibles pour le produit"); } for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++){ for(int j=DEBUT_COMPTAGE; j<m.getnColonnes()+DEBUT_COMPTAGE; j++){ double c = 0; for(int k=DEBUT_COMPTAGE; k<getnColonnes()+DEBUT_COMPTAGE; k++){ c+=get(i, k)*m.get(k, j); } res.set(i, j, c); } } return res; } /**
  • Méthode permettant de multiplier une matrice par un scalaire
  • @param valeur
  • La valeur qui multiplie la matrice
  • @return une nouvelle matrice résultat de l'opération de multiplication
  • /
public final Matrice multiplier(final double valeur){ double[] vals = new double[valeurs.length]; for(int i=0; i<valeurs.length; i++) { vals[i]=valeurs[i]*valeur; } return new Matrice(getnLignes(), getnColonnes(), vals); } /**
  • Fonction permettant de calculer la somme de deux matrices
  • @param m
  • La matrice à ajouter
  • @return la somme de m et de la matrice courante
  • @throws TechnicalException si les tailles des deux matrices sont
  • différentes.
  • /
public final Matrice ajouter(final Matrice m) { if(getnColonnes()!=m.getnColonnes() || getnLignes()!=m.getnLignes()){ throw new TechnicalException("L'addition est impossible pour ces deux matrices qui ne sont pas de mêmes tailles"); } Matrice res = new Matrice(getnLignes(), getnColonnes()); for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++) { for(int j=DEBUT_COMPTAGE; j<getnColonnes()+DEBUT_COMPTAGE; j++) { res.set(i, j, get(i, j)+m.get(i, j)); } } return res; } /**
  • Fonction permettant de savoir si la matrice est carrée
  • @return vrai si la matrice est carrée
  • <p>
  • Une matrice carrée est une matrice pour laquelle le nombre
  • de ligne est égal au nombre de colonnes.
  • </p>
  • /
public final boolean isCarree(){ return getnLignes()==getnColonnes(); } /**
  • Fonction permettant de calculer la trace de la matrice
  • @return la trace de la matrice
  • @throws TechnicalException si la matrice n'est pas carrée. Dans ce cas
  • la trace n'est pas définie
  • <p>
  • La trace d'une matrice est la somme de ses coefficients diagonaux
  • </p>
  • /
public final double trace() { if(getnColonnes()!=getnLignes()){ throw new TechnicalException("La matrice n'est pas carrée, la trace n'est pas définie"); } double trace=0; for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++) { trace+=get(i, i); } return trace; } /**
  • Fonction permettant de calculer le déterminant de la matrice
  • @return le déterminant de la matrice
  • @throws TechnicalException si la matrice n'est pas carrée, dans ce cas, le
  • déterminant n'est pas définit
  • <p>
  • Le calcul du déterminant d'une matrice est un outil nécessaire tant en algèbre
  • linéaire pour vérifier une inversibilité ou calculer l'inverse d'une matrice qu'en
  • analyse vectorielle avec, par exemple, le calcul d'un jacobien.
  • </p>
  • /
public final double determinant() throws TechnicalException { if(getnColonnes()!=getnLignes()){ throw new TechnicalException("Matrice non carée, le déterminant n'est pas définit"); } double det=0; if(getnLignes()==1){ det=-get(DEBUT_COMPTAGE, DEBUT_COMPTAGE); } else { for(int k=DEBUT_COMPTAGE; k<getnLignes()+DEBUT_COMPTAGE; k++){ det+=Math.pow(-1, k)*get(k, DEBUT_COMPTAGE)*getSousMatrice(k, 1).determinant(); } } return det; } /**
  • Méthode permettant de récupérer une matrice en supprimant la ligne d'indice
  • indexI et la colonne d'indice indiceJ
  • @param indexI
  • l'indice de la ligne à supprimer
  • @param indexJ
  • l'indice de la colonne à supprimer
  • @return la sous matrice
  • <p>
  • Cette méthode est utilisée notamment dans le calcul du déterminant
  • </p>
  • /
public final Matrice getSousMatrice(final int indexI, final int indexJ) { if(indexI<DEBUT_COMPTAGE || indexJ < DEBUT_COMPTAGE || indexI>getnLignes()+DEBUT_COMPTAGE || indexJ>getnColonnes()+DEBUT_COMPTAGE){ throw new TechnicalException("La ligne ou la colonne a à supprimer n'existe pas"); } double[] vals = new double[(getnLignes()-1)*(getnLignes()-1)]; int k=0; for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++) { if(i!=indexI){ for(int j=DEBUT_COMPTAGE; j<getnColonnes()+DEBUT_COMPTAGE; j++) { if(j!=indexJ){ vals[k]=get(i, j); k++; } } } } return new Matrice(getnLignes()-1, getnColonnes()-1, vals); } /**
  • Cette méthode calcul la transposée de la matrice courante
  • @return la transposée
  • <p>
  • La transposée est la matrice de coef aji si la matrice courante
  • et de coef aij
  • </p>
  • /
public final Matrice transposee(){ double[] vals = new double[getnColonnes()*getnLignes()]; for(int j=DEBUT_COMPTAGE; j<getnColonnes()+DEBUT_COMPTAGE; j++) { for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++) { vals[(j-DEBUT_COMPTAGE)*nLignes+(i-DEBUT_COMPTAGE)]=get(i, j); } } return new Matrice(getnColonnes(), getnLignes(), vals); } /**
  • Cette méthode permet de savoir si la matrice est inversible ou non
  • @return vrai si la matrice est inversible
  • @throws TechnicalException si la matrice n'est pas care
  • <p>
  • Une matrice carrée est inversible si son déterminant est différent de 0
  • </p>
  • /
public final boolean isInversible() { return determinant()!=0; } /**
  • Cette fonction calcul l'inverse de la matrice courante
  • @return l'inverse de la matrice courante
  • @throws MatriceException si la matrice n'est pas inversible
  • <p>
  • Le calcul est effectué en calculant la transposée de la
  • commatrice de la matrice courante.
  • </p>
  • /
public final Matrice inverse() { if(!isInversible()){ throw new TechnicalException("La matrice n'est pas inversible"); } double[] vals = new double[getnColonnes()*getnLignes()]; Matrice res = null; if(getnLignes()==2){ vals[0]=get(2, 2); vals[1]=-get(1, 2); vals[2]=-get(2, 1); vals[3]=get(1, 1); res=new Matrice(getnLignes(), getnColonnes(), vals).multiplier(1/determinant()); } else { Matrice tmp = null; double det = determinant(); for (int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++){ for (int j=DEBUT_COMPTAGE; j<getnColonnes()+DEBUT_COMPTAGE; j++){ tmp = getSousMatrice(i,j); vals[(i-DEBUT_COMPTAGE)*nColonnes+(j-DEBUT_COMPTAGE)]=Math.pow(-1,i+j+1)*(tmp.determinant()/det); } } res=new Matrice(getnLignes(), getnColonnes(), vals).transposee(); } return res; } /**
  • Cette fonction permet de déterminer l'endomorphisme associé à la matrice
  • @return l'endomorphisme associé à la matrice
  • <p>
  • Cette fonction utilise la variable VARIABLES pour les noms des variables
  • de l'endomorphisme.
  • </p>
  • /
public final String getEndomorphisme(){ String[] vars = VARIABLES.split("\\p{Space}"); if(getnColonnes()>vars.length){ throw new TechnicalException("Le nombre de variable disponible est insuffisant. Modifier MAtrice.VARIABLES"); } StringBuilder sb = new StringBuilder(); for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++){ boolean p=true; for(int j=DEBUT_COMPTAGE; j<getnColonnes()+DEBUT_COMPTAGE-1; j++){ sb.append(nomaliserEndomorphisme(get(i, j), vars[j-DEBUT_COMPTAGE], p, false, j)); p = p && get(i, j)==0; } sb.append(nomaliserEndomorphisme(get(i, getnColonnes()+DEBUT_COMPTAGE-1), vars[getnColonnes()-1], p, true, getnColonnes()+DEBUT_COMPTAGE-1)); } return sb.toString(); } @Override public final String toString(){ StringBuilder sb=new StringBuilder(); for(int i=DEBUT_COMPTAGE; i<nLignes+DEBUT_COMPTAGE; i++){ for(int j=DEBUT_COMPTAGE; j<nColonnes+DEBUT_COMPTAGE; j++){ sb.append(normaliser(get(i, j))).append("\t"); } sb.append("\n"); } return sb.toString(); } /**
  • Fonction permettant de supprimer les .0 à l'affichage
  • @param valeur
  • La valeur à afficher
  • @return la valeur normalisée
  • /
public final String normaliser(final double valeur){ return (""+valeur).replaceAll("\\.0+$", ""); } /**
  • Fonction permettant de formater les lignes de l'endomorphisme pour
  • que les noms des variables et les opérateurs soient alignés.
  • @param val
  • la valeur du coef
  • @param var
  • le nom de la variable
  • @param premier
  • booléen vrai si la variable est la première non nulle de la ligne
  • @param dernier
  • booléen vrai si la variable est la dernière de la ligne
  • @param j
  • l'indice de la colonne
  • @return la ligne formatée
  • /
private final String nomaliserEndomorphisme(final double val, final String var, final boolean premier, final boolean dernier, final int j){ int max=0; for(int i=DEBUT_COMPTAGE; i<getnLignes()+DEBUT_COMPTAGE; i++){ double d=get(i, j); if((normaliser(d)).length()>max){ max=(normaliser(d)).length(); } } StringBuilder sb = new StringBuilder(); if(val==0){ sb.append(espaces(max+4)); } else { if(!premier){ if(val<0){ sb.append(" - "); } else{ sb.append(" + "); } } else if(val<0){ sb.append("-"); } if(Math.abs(val)==1){ sb.append(espaces(max)); } else { sb.append(espaces(max-normaliser(val).length())); sb.append(normaliser(Math.abs(val))); } sb.append(var); } if(dernier){ sb.append(" = 0\n"); } return sb.toString(); } /**
  • Fonction permettant de retourner une chaine constitué d'espaces
  • @param nombre
  • Le nombre d'espaces e la chaine
  • @return la chaine d'espaces
  • /
private final String espaces(final int nombre){ StringBuilder sb = new StringBuilder(); for(int k=0; k<nombre; k++){ sb.append(" "); } return sb.toString(); } /**
  • Accesseur au nombre de lignes de la matrice
  • @return le nombre de lignes de la matrice
  • /
public final int getnLignes() { return nLignes; } /**
  • Accesseur au nombre de colonnes de la matrice
  • @return le nombre de colonnes de la matrice
  • /
public final int getnColonnes() { return nColonnes; } }

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.