C++ Classe Matrix
En C, si je voulais créer une matrice de struct, je voudrais utiliser:
struct matrix {
int col, row;
double data[1]; //I want the matrix entries stored
//right after this struct
}
Alors je peux allouer à
matrix* allocate_matrix(int row, int col) {
matrix* m = malloc(sizeof(matrix) + sizeof(double) * (row * col - 1));
m->row = row; m->col = col;
return m;
}
Maintenant dois-je faire l'équivalent en C++?
EDIT:
Je veux savoir le cannonical façon de mettre en œuvre une matrice de classe en C++.
- Vous devez remplir le
...
pour effacer la confusion de certaines réponses sont avoir. - bon appel; cela suffit-il?
Vous devez vous connecter pour publier un commentaire.
nota bene.
Cette réponse a 20 upvotes maintenant, mais il est pas prévu comme une approbation de
std::valarray
.Dans mon expérience, le temps est mieux dépensé de l'installation et de l'apprentissage d'une part entière de la bibliothèque math comme Eigen. Valarray a moins de fonctionnalités que la concurrence, mais il n'est pas plus efficace et surtout plus facile à utiliser.
Si vous avez seulement besoin d'un peu d'algèbre linéaire, et vous êtes morts-ensemble contre le fait d'ajouter quelque chose à votre chaîne d'outils, puis peut-être
valarray
adaptée. Mais, d'être coincé dans l'impossibilité d'exprimer mathématiquement bonne solution à votre problème est une très mauvaise position. Math est implacable et impitoyable. Utiliser le bon outil pour le travail.De la bibliothèque standard fournit
std::valarray<double>
.std::vector<>
, suggéré par quelques autres ici, est conçu comme un conteneur pour objets.valarray
, moins connus, car il est plus spécialisé (ne pas utiliser "spécialisés" comme le C++ terme), a plusieurs avantages:vector
tours jusqu'à la prise électrique la plus proche des deux lors de l'attribution, de sorte que vous pouvez la redimensionner sans la réaffectation de tous les temps. (Vous pouvez toujours redimensionner unevalarray
, c'est juste encore plus cher querealloc()
.)Bien sûr, l'avantage de l'utilisation de C est que vous n'avez pas besoin de gérer la mémoire. Les dimensions peuvent résider sur la pile, ou dans une tranche de l'objet.
valarray
... les quelques fois où j'ai essayé, la tranche des classes ont été une douleur. C'est peut-être cela vaut le coup, et mieux que rouler votre propre que les autres réponses suggèrent ici, mais il ya de meilleures bibliothèques. (Eh bien, il semblerait donc, au moins, je n'ai pas vraiment l'habitude de tout. Boost BLAS devrait être bon, cependant).std::valarray
est plutôt difficile à utiliser, prend en charge uniquement la base memberwise de l'algèbre, et il n'est pas très populaire. Essayez de le Eigen Bibliothèque qui est très facile à utiliser, puissant et populaire.C++ est surtout un sur-ensemble de C. Vous pouvez continuer à faire ce que vous faisiez.
Cela dit, en C++, ce que vous devez faire est de définir la Matrice de la classe qui gère sa propre mémoire. Il pourrait, par exemple, être soutenu par un interne de
std::vector
, et vous pourriez remplaceroperator[]
ouoperator()
à l'index dans le vecteur de manière appropriée (par exemple, voir: Comment puis-je créer un indice de l'opérateur pour une Matrice de classe?) à partir du C++ FAQ.Pour vous aider à démarrer:
(À noter que ce qui précède ne pas faire une vérification de limites, et je laisse comme un exercice de modèle en sorte que cela fonctionne pour d'autres choses que de
double
.)Il y a beaucoup de subtilités dans la mise en place un système efficace et de haute qualité de la matrice de classe. Heureusement qu'il y a plusieurs bonnes implémentations flottant sur.
Réfléchir si vous voulez une taille fixe de la matrice de classe ou une variable de la taille d'une.
c'est à dire pouvez-vous faire cela:
ou avez-vous besoin pour être en mesure de faire ce
Il y a de bonnes bibliothèques qui prennent en charge le style, et certains qui soutiennent à la fois.
Ils ont différents schémas de répartition et des différentes prestations.
Si vous voulez coder vous-même, puis la version du modèle nécessite quelques connaissances de modèles (duh). Et de la dynamique que l'on doit certains des hacks pour obtenir autour de beaucoup de petites allocations si utilisé à l'intérieur des boucles serrées.
Vous pourrait le faire de cette façon. La seule différence est que vous devez jeter le résultat de
malloc
.Plutôt, vous devez utiliser une
vector
, soit comme un tableau 1D avec calculée d'indexation ou un intégré à l'vecteur. (L'ancien correspond à votre code mieux.)Par exemple:
Ou:
Mais ce ne sont que des exemples. Vous souhaitez faire une classe à part entière; si vous voulez plus de conseils sur cela, éditez votre question et de préciser que vous souhaitez connaître la manière canonique de la mise en œuvre de la matrice des classes.
Il y a des pré-existante de la matrice des classes. Mon préféré est qu'à partir de boost, UBLAS.
data[1][1]
, pasdata[1, 1]
. (Et techniquement,m.data[1][1]
.)vector
devector
va être un moyen très efficace de mise en œuvre.Vous pouvez utiliser un modèle comme :
*édition, correction d'une faute de frappe.
vous pourriez le faire avec un modèle, si la matrice de taille est connue à la compilation :
Matrix<3, 3> matrix;
Pour une matrice de classe, vous voulez rester à l'écart de la surcharge de la
[]
opérateur.Voir C++ FAQ 13.10
Aussi, la recherche sur le web pour certains freeware Matrice de classes. Pire des cas, ils peuvent vous donner des conseils. Dans le meilleur des cas, moins de logiciels que vous avez à écrire et de débogage.
J'ai écrit un Bibliothèque de matrice qui prend en charge de nombreuses fonctionnalités.
De sa documentation:
Utilisation
son utilisation est similaire à c++ tableaux.
Résultat:
Ici est la la documentation
Github Lien
Il n'y a pas de "canonique" façon de faire de la matrice en C++, STL ne fournit pas de classes comme "matrice". Cependant, il ya certaines 3ème partie les bibliothèques. Vous êtes encouragés à les utiliser ou écrire votre propre mise en œuvre.
En C++, vous pouvez utiliser comme ceci:
Après,
struct
à une variable ou de durée indéterminée tableau de taille, donc tout simplement à l'aide denew
au lieu demalloc
ne fonctionne pas.