CLASS MATRICE EFFICACE

Signaler
Messages postés
492
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
12 janvier 2012
-
Menuki
Messages postés
13
Date d'inscription
lundi 10 octobre 2005
Statut
Membre
Dernière intervention
11 août 2008
-
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/47364-class-matrice-efficace

Menuki
Messages postés
13
Date d'inscription
lundi 10 octobre 2005
Statut
Membre
Dernière intervention
11 août 2008

Bonjour,

Juste une petite question :
Pourquoi tu ajoutes 1 au nombre d'entrées allouées dans le tableau?

exemple : ligne 240 => mat = new double[column * line + 1];

J'ai regardé en vitesse mais je n'ai pas trouvé où cette dernière valeur était utilisée.


Une deuxième remarque qui se rapporte un peu à la première :

Le test pour savoir si l'indice dans le tableau (opérateur []) est dans les limites est celui-ci :
if (i < 0 || i > (m_m * m_n)) throw ERROR_INVALID_PARAM;

Hors les indices valides sont entre 0 et m_m*m_n-1.
Si on admet que la valeur supplémentaire allouée ne sert à rien (et donc qu'on la supprime), il faut mettre un >= à la place du >

Me goure-je?



Sinon, j'aime bien ta classe. Ca semble rapide.
J'aurais préféré que l'aspect linéaire du stockage soit caché à l'utilisateur ( cf. l'opérateur []).
Cet opérateur pourrait plutôt renvoyer un pointeur sur le premier élément de la colonne (const double *).
Mais là, c'est une affaire de goût. ^_^
NairodDorian
Messages postés
130
Date d'inscription
lundi 26 juin 2006
Statut
Membre
Dernière intervention
18 août 2008

"Ton operator = ne permet pas le standard c++ qui autorise la forme :
mat1 mat2 mat3;"

Intérêt de faire mat1 mat2 mat3; ?

"Pour parler de l'"efficacité", il reste le C et aucune classe." Ce que j'ai voulu faire à la base mais je parle d'efficacité car les algos sont en O(n^3) pas en O(n!) comme la pluparts des sources.
yann_lo_san
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
17
...
yann_lo_san
Messages postés
1137
Date d'inscription
lundi 17 novembre 2003
Statut
Membre
Dernière intervention
23 janvier 2016
17
Salut,

Ton operator = ne permet pas le standard c++ qui autorise la forme :
mat1 mat2 mat3;

Pour cela il te faut un constructeur par recopie conforme et un prototype de cette forme :
const Matrice& oparator = (const Matrice&);

De plus ton operator + en friend est inutile et pour la même raison il doit renvoyer une Matrice non constante par valeur :

Matrice operator + (const Matrice&);

De mon point de vue il est beaucoup plus lisible de declarer un pointeur vers un tableau à 2 dimentions :

double** m_pMat;

car les differents calculs seront plus lisibles avec le double operateur d'extraction
(m_pMat[0][1]) et le compilateur ne verra pas la difference (linéaire en mémoire...)

Pour parler de l'"efficacité", il reste le C et aucune classe. Beaucoup moins générique mais certainement plus efficace :

typedef float MAT4x4[4][4];

Les fonctions ou MACROs pour toutes les primitives, ex :

inline void copie_matrice(MAT4x4 source, MAT4x4 dest)
{
memcpy(dest, source, sizeof(MAT4x4));
}

Sinon je te mets 6 pour le partage.
NairodDorian
Messages postés
130
Date d'inscription
lundi 26 juin 2006
Statut
Membre
Dernière intervention
18 août 2008

On ne parle pas de division puisque une matrice n'est pas commutative.
On parle de multiplication à gauche ou à droite par un inverse.

Utilisé le bon vocabulaire est important :).
turnerom
Messages postés
492
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
12 janvier 2012
1
la division de deux matrices est possible si la deuxième est inversible (donc carrée) et que la première est carrée.
Si A et B sont deux matrices répondant aux critères ci-dessus, alors A / B A x (1 / B) A x B-1.
NairodDorian
Messages postés
130
Date d'inscription
lundi 26 juin 2006
Statut
Membre
Dernière intervention
18 août 2008

"ça manque un peu de documentation quand même: quelques commentaires dans le header serait pas de refus et améliorerait la compréhension. En plus ça coûte rien, pourquoi s'en priver ? :)"

Ce sera fait.

"Sinon c'est pas trop mal" merci.
"bon oui il manque les const, il manque aussi les commentaires." Sera rajouté.

"2. Diviser par une matrice ? Gné ?"
Je me disais aussi :). Merci de confirmer que ce n'est pas possible.

Je prends note de vos commentaires à tout les deux et je vais mettre à jour prochainement cette classe.
Sam_Loack
Messages postés
1
Date d'inscription
vendredi 6 juillet 2007
Statut
Membre
Dernière intervention
21 juillet 2008

Bonjour,

ça manque un peu de documentation quand même: quelques commentaires dans le header serait pas de refus et améliorerait la compréhension. En plus ça coûte rien, pourquoi s'en priver ? :)

Sinon c'est pas trop mal, bon oui il manque les const, il manque aussi les commentaires. En retravaillant un peu ces points je pense que ça serait mieux: surtout lorsque tu distribues ta classe. ;)

Bon par contre:
"A moins que j'ai loupé aussi qqchose tu peux tres bien divisé une matrice par un réél ou par une autre matrice."
1. Oui tu peux diviser par un réel. Car si tu divises pas 5 ça revient à mulitplier par 1/5
2. Diviser par une matrice ? Gné ? Autant tu peux multiplier par la matrice inverse, nous sommes d'accord. Mais alors diviser par une matrice, j'aimerai que tu me dises comment tu fais là. "Les matrices c'est beau, c'est la pureté, c'est l'or des mathématiques ! Vous allez pas rabaisser les matrices à un vulgaire denominateur !" (mon prof de maths)

Bon voilà, en tout cas tu as comprit ce qui m'a le plus gêné dans l'histoire: abscence de documentation =/
NairodDorian
Messages postés
130
Date d'inscription
lundi 26 juin 2006
Statut
Membre
Dernière intervention
18 août 2008

"double Matrix::_getvalue(int line, int column) {
return m_mat[line * m_n + column];
}

devrait etre :

const double Matrix::_getvalue(const int & line, const int & column) const {
return m_mat[line * m_n + column];
}
"

Non. Pourquoi passer line et column par référence? Pour perdre du temps? Ajouter un const ne change pas grand chose le compilo génère le même code car il voit que je ne fais pas de modif sur line et column.

"D'ailleurs que se passe-t-il a ton avis si je fais un _getvalue(-1,-1) ou meme avec une valeur or limite ?"
Pour passer des valeurs négatives faut vraiment le faire exprès et pour le reste il n'y a pas de vérifs sur les paramètres passé pour gagner en vitesse. Celui qui appel doit vérifié qu'il ne fait pas n'importe quoi. Pour celà il peut utilisé _column() et _line().

Effectivement c'est += que j'ai mis pas +.

"A moins que j'ai loupé aussi qqchose tu peux tres bien divisé une matrice par un réél ou par une autre matrice."
Je ne savais pas. Mais si tu veux divisé par un réel tu fais m*=1.0/valeur; m type Matrix.

"Ben oui justement voir meme de bool."
La class est faites pour travailler avec des doubles point barre. Programme scientifique donc on travail avec des réels.
"Si tu veux stocker une image RGB par exemple tu seras content d'avoir 3 dimensions."
Programme scientifique donc matrice (m,n).

"waouhh si tu a une matrice A et que tu veuille acceder à l'element (2,3) c'est quand meme vachement plus intuitif de faire A(2,3) que A[3*A._line()+2] ou encore A._getvalue(2,3)"
Oui bon... Utilisé A(2,3) plutôt que A._getvalue(2,3) c'est vraiment pour la flemme :)

Au fait ou sont les operateurs de copie et l'operator= ?
Matrix n'est pas destiner à être remplacer.
Si tu veux modifié ta matrice :
double *mat = (double*)m;
et tu travailles avec mat ou alors m._setvalue(...);
turnerom
Messages postés
492
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
12 janvier 2012
1
Au fait ou sont les operateurs de copie et l'operator= ?
turnerom
Messages postés
492
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
12 janvier 2012
1
"Il y a des paramètres à passer à mes méthodes... "
????
ce que je veux dire c que par exemple

double Matrix::_getvalue(int line, int column) {
return m_mat[line * m_n + column];
}

devrait etre :

const double Matrix::_getvalue(const int & line, const int & column) const {
return m_mat[line * m_n + column];
}

D'ailleurs que se passe-t-il a ton avis si je fais un _getvalue(-1,-1) ou meme avec une valeur or limite ?

"La surcharge de l'opérateur '+' existe. Quand à l'opérateur '/', peut-être que j'ai loupé qqch mais je ne crois pas qu'on puisse divisé une matrice par une autre ni même par un réel. "
A moins que j'ai raté qqchose les operateurs que j'ai cité ne sont pas présent soit il y'a += mais ce n'est pas la meme chose : a=b+c est impossible. A moins que j'ai loupé aussi qqchose tu peux tres bien divisé une matrice par un réél ou par une autre matrice.

""Je ne parle même pas de la templatisation inexistante qui aurait pourtant permit de faire des matrices d'autres choses que de double". Fort exact mais tu voulais mettre quoi d'autre des floats, des int peut-être lol. "
Ben oui justement voir meme de bool. Pourquoi alors reserver et faire des calculs en double avec seulement des 0 et des 1 ?

"Chez moi une matrice c'est m lignes, n colonnes. (m,n) Je sais pas où tu vas cherché des matrices à plus de deux dimensions. "
Si tu veux stocker une image RGB par exemple tu seras content d'avoir 3 dimensions.

""Enfin coté pratique un petit operator() aurait ete le bien venu" justement il y a []. "
waouhh si tu a une matrice A et que tu veuille acceder à l'element (2,3) c'est quand meme vachement plus intuitif de faire A(2,3) que A[3*A._line()+2] ou encore A._getvalue(2,3)
NairodDorian
Messages postés
130
Date d'inscription
lundi 26 juin 2006
Statut
Membre
Dernière intervention
18 août 2008

"Une classe matrice efficace sans un seul paramètre ni une seule méthode const"
Il y a des paramètres à passer à mes méthodes...
Elle est pas marqué "retour fonction(...) const" oh mon dieu c'est la catastrophe ! Sache que ça ne change pas grand chose.
"Des doubles boucles pour tout les opérateurs" Faux.
"On ne retrouve pourtant ni '+' , '-' ou '/'". La surcharge de l'opérateur '+' existe. Quand à l'opérateur '/', peut-être que j'ai loupé qqch mais je ne crois pas qu'on puisse divisé une matrice par une autre ni même par un réel.
"Je ne parle même pas de la templatisation inexistante qui aurait pourtant permit de faire des matrices d'autres choses que de double". Fort exact mais tu voulais mettre quoi d'autre des floats, des int peut-être lol.
"De plus matrices limitées a 2 dimensions" Chez moi une matrice c'est m lignes, n colonnes. (m,n) Je sais pas où tu vas cherché des matrices à plus de deux dimensions.
"Enfin coté pratique un petit operator() aurait ete le bien venu" justement il y a [].

Bref du grand nawak.
turnerom
Messages postés
492
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
12 janvier 2012
1
Une classe matrice efficace sans un seul paramètre ni une seule méthode const !!! Des doubles boucles pour tout les opérateurs, dans lesquels on ne retrouve pourtant ni '+' , '-' ou '/'. Je ne parle même pas de la templatisation inexistante qui aurait pourtant permit de faire des matrices d'autres choses que de double. De plus matrices limitées a 2 dimensions. Enfin coté pratique un petit operator() aurait ete le bien venu !