Bjarne Substroup dans son livre référence, suggère une implémentation d'une
classe Matrix qui utilise la classe slice. C'est donc ce que j'ai fait.
Seulement la fonction membre
Slice_iter Matrix::row(size_t i); // TRES
CONTRAIGNANT
qui mathématiquement retourne le ième vecteur rangée de la matrice, retourne
ici un objet Slice_iter, qui n'est qu'un itérateur sur un valarray. Il
serait souhaitable qu'une telle fonction retourne réellement un vecteur afin
de pouvoir manipuler la ième rangée de la matrice comme un vecteur, en
particulier, qu'il puisse bénéficier des opérations vectorielles (*, +,
;..). Or, je n'ai pas l'intention de développer ces opérateurs pour la
classe Slice_iter, car ce serait très maladroit.
Pourtant, il est nécessaire d'utiliser un tel artifice afin de ne pas
recopier inutilement les données (performance oblige) dans un valarray :
Alors, je réfléchis à une solution hybride : une classe Vector qui pourrait
contenir son itérateur :
class Vector {
public:
// Constructeur
Vector(uint size) { v = new valarray<double>(size); s = 0; }
Vector(valarray<double>* vv, slice ss) { v = vv; s = new
slice(ss); }
~Vector() { if(s == 0) delete v; }
// Acces aux éléments
double& operator[] (uint i) { return ref(i); }
private:
valarray<double>* v;
slice* s;
double& ref(uint i) const { if(s == 0) return (*v)[i]; return
(*v)[s->start()+i*s->stride()]; }
}
Je ne sais pas quoi penser de cette implémentation. Un Vector peut donc
avoir deux facettes, selon que son slice soit nul ou pas. C'est surtout le
destructeur qui pose un problème. Ce modèle me semble fragile et dangereux.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Gabriel Dos Reis
"Boris Sargos" writes:
| Salut à tous, | | Bjarne Substroup dans son livre référence, suggère une implémentation d'une ^^^^^^^^^
Je crois que tu voulais dire Stroustrup.
| classe Matrix qui utilise la classe slice. C'est donc ce que j'ai fait. | Seulement la fonction membre | | Slice_iter Matrix::row(size_t i); // TRES | CONTRAIGNANT | | qui mathématiquement retourne le ième vecteur rangée de la matrice, retourne | ici un objet Slice_iter, qui n'est qu'un itérateur sur un valarray. Il
La raison pour laquelle, il a choisi de retourner un Slice_iter est expliquée page 673:
The Slice_iters are used to circumvent the ban on copying slice_arrays. I couldn't return a slice_array:
Le comité, à l'époque, n'avait pas accordé grand intérêt à la chose. Il a fallu que Robert Klarer reprennent les mêmes arguments pour que l'erreur soit enfin corrigée :
[ Digression : si tu utilises GCC, tu auras noté qu'à cause d'un bug dans le compilateur qui ne vérifiait pas les contrôles d'accès comme il faut, on pouvait retourner les xxx_array par valeur. GCC-3.4.0 est plus stricte maintenant, et la restriction ci-haut a aussi été enlevée dans l'implémentation qui vient avec ce compilateur. ]
| serait souhaitable qu'une telle fonction retourne réellement un vecteur afin | de pouvoir manipuler la ième rangée de la matrice comme un vecteur, en | particulier, qu'il puisse bénéficier des opérations vectorielles (*, +, | ;..). Or, je n'ai pas l'intention de développer ces opérateurs pour la | classe Slice_iter, car ce serait très maladroit. | Pourtant, il est nécessaire d'utiliser un tel artifice afin de ne pas | recopier inutilement les données (performance oblige) dans un valarray : | | valarray<double> Matrix::row(size_t i); // MALADROIT | | Alors, je réfléchis à une solution hybride : une classe Vector qui pourrait | contenir son itérateur : | | class Vector { | public: | // Constructeur | Vector(uint size) { v = new valarray<double>(size); s = 0; }
Hmm, je ne comprends pas ceci.
| Vector(valarray<double>* vv, slice ss) { v = vv; s = new | slice(ss); } | ~Vector() { if(s == 0) delete v; } | // Acces aux éléments | double& operator[] (uint i) { return ref(i); } | private: | valarray<double>* v; | slice* s; | double& ref(uint i) const { if(s == 0) return (*v)[i]; return | (*v)[s->start()+i*s->stride()]; } | } | | | Je ne sais pas quoi penser de cette implémentation. Un Vector peut donc
Je ne comprends pas trop où tu veux en venir avec cette implémentation. Est-ce que tu peux essayer de remplacer Slice_iter par slice_array et voir les problèmes de conception/implémentation que tu as ?
-- Gaby
"Boris Sargos" <bsargos@wanadoo.fr> writes:
| Salut à tous,
|
| Bjarne Substroup dans son livre référence, suggère une implémentation d'une
^^^^^^^^^
Je crois que tu voulais dire Stroustrup.
| classe Matrix qui utilise la classe slice. C'est donc ce que j'ai fait.
| Seulement la fonction membre
|
| Slice_iter Matrix::row(size_t i); // TRES
| CONTRAIGNANT
|
| qui mathématiquement retourne le ième vecteur rangée de la matrice, retourne
| ici un objet Slice_iter, qui n'est qu'un itérateur sur un valarray. Il
La raison pour laquelle, il a choisi de retourner un Slice_iter est
expliquée page 673:
The Slice_iters are used to circumvent the ban on copying
slice_arrays. I couldn't return a slice_array:
Le comité, à l'époque, n'avait pas accordé grand intérêt à la chose. Il
a fallu que Robert Klarer reprennent les mêmes arguments pour que l'erreur
soit enfin corrigée :
[ Digression : si tu utilises GCC, tu auras noté qu'à cause d'un bug
dans le compilateur qui ne vérifiait pas les contrôles d'accès
comme il faut, on pouvait retourner les xxx_array par valeur.
GCC-3.4.0 est plus stricte maintenant, et la restriction ci-haut a
aussi été enlevée dans l'implémentation qui vient avec ce
compilateur. ]
| serait souhaitable qu'une telle fonction retourne réellement un vecteur afin
| de pouvoir manipuler la ième rangée de la matrice comme un vecteur, en
| particulier, qu'il puisse bénéficier des opérations vectorielles (*, +,
| ;..). Or, je n'ai pas l'intention de développer ces opérateurs pour la
| classe Slice_iter, car ce serait très maladroit.
| Pourtant, il est nécessaire d'utiliser un tel artifice afin de ne pas
| recopier inutilement les données (performance oblige) dans un valarray :
|
| valarray<double> Matrix::row(size_t i); // MALADROIT
|
| Alors, je réfléchis à une solution hybride : une classe Vector qui pourrait
| contenir son itérateur :
|
| class Vector {
| public:
| // Constructeur
| Vector(uint size) { v = new valarray<double>(size); s = 0; }
Hmm, je ne comprends pas ceci.
| Vector(valarray<double>* vv, slice ss) { v = vv; s = new
| slice(ss); }
| ~Vector() { if(s == 0) delete v; }
| // Acces aux éléments
| double& operator[] (uint i) { return ref(i); }
| private:
| valarray<double>* v;
| slice* s;
| double& ref(uint i) const { if(s == 0) return (*v)[i]; return
| (*v)[s->start()+i*s->stride()]; }
| }
|
|
| Je ne sais pas quoi penser de cette implémentation. Un Vector peut donc
Je ne comprends pas trop où tu veux en venir avec cette
implémentation. Est-ce que tu peux essayer de remplacer Slice_iter par
slice_array et voir les problèmes de conception/implémentation que tu as ?
| Salut à tous, | | Bjarne Substroup dans son livre référence, suggère une implémentation d'une ^^^^^^^^^
Je crois que tu voulais dire Stroustrup.
| classe Matrix qui utilise la classe slice. C'est donc ce que j'ai fait. | Seulement la fonction membre | | Slice_iter Matrix::row(size_t i); // TRES | CONTRAIGNANT | | qui mathématiquement retourne le ième vecteur rangée de la matrice, retourne | ici un objet Slice_iter, qui n'est qu'un itérateur sur un valarray. Il
La raison pour laquelle, il a choisi de retourner un Slice_iter est expliquée page 673:
The Slice_iters are used to circumvent the ban on copying slice_arrays. I couldn't return a slice_array:
Le comité, à l'époque, n'avait pas accordé grand intérêt à la chose. Il a fallu que Robert Klarer reprennent les mêmes arguments pour que l'erreur soit enfin corrigée :
[ Digression : si tu utilises GCC, tu auras noté qu'à cause d'un bug dans le compilateur qui ne vérifiait pas les contrôles d'accès comme il faut, on pouvait retourner les xxx_array par valeur. GCC-3.4.0 est plus stricte maintenant, et la restriction ci-haut a aussi été enlevée dans l'implémentation qui vient avec ce compilateur. ]
| serait souhaitable qu'une telle fonction retourne réellement un vecteur afin | de pouvoir manipuler la ième rangée de la matrice comme un vecteur, en | particulier, qu'il puisse bénéficier des opérations vectorielles (*, +, | ;..). Or, je n'ai pas l'intention de développer ces opérateurs pour la | classe Slice_iter, car ce serait très maladroit. | Pourtant, il est nécessaire d'utiliser un tel artifice afin de ne pas | recopier inutilement les données (performance oblige) dans un valarray : | | valarray<double> Matrix::row(size_t i); // MALADROIT | | Alors, je réfléchis à une solution hybride : une classe Vector qui pourrait | contenir son itérateur : | | class Vector { | public: | // Constructeur | Vector(uint size) { v = new valarray<double>(size); s = 0; }
Hmm, je ne comprends pas ceci.
| Vector(valarray<double>* vv, slice ss) { v = vv; s = new | slice(ss); } | ~Vector() { if(s == 0) delete v; } | // Acces aux éléments | double& operator[] (uint i) { return ref(i); } | private: | valarray<double>* v; | slice* s; | double& ref(uint i) const { if(s == 0) return (*v)[i]; return | (*v)[s->start()+i*s->stride()]; } | } | | | Je ne sais pas quoi penser de cette implémentation. Un Vector peut donc
Je ne comprends pas trop où tu veux en venir avec cette implémentation. Est-ce que tu peux essayer de remplacer Slice_iter par slice_array et voir les problèmes de conception/implémentation que tu as ?