9
votes

Comment puis-je utiliser un STD :: Valarray pour stocker / manipuler un tableau 2D contigu?

Comment puis-je utiliser un std :: valarray pour stocker / manipuler un tableau 2D?

J'aimerais voir un exemple de tableau 2D avec des éléments accessibles par des indices de rangée / colonne . Quelque chose comme ce pseudo code: xxx

Un exemple de comment initialiser un tel tableau serait aussi agréable.

Je suis déjà au courant de Boost. Mularray, Boost.ublas et Blitz ++.

N'hésitez pas à répondre à la raison pour laquelle je ne devrais pas utiliser Valarray pour mon cas d'utilisation. Cependant, je veux que la mémoire de la matrice multidimensionnelle soit un bloc contigu (colonnes x lignes). Pas de tableaux imbriqués de style Java.


3 commentaires

Pourquoi voudriez-vous utiliser Valarray? Je ne l'ai pas vu utiliser n'importe où et ne connaissez que des arguments contre son utilisation.


@GF: Je suis assez content de booster pour des tableaux multidimensionnels "dynamiques". Mais je suis tombé sur le Valarraille quelque part d'autre, et était curieux de savoir comment il pourrait être utilisé pour des tableaux multidimensionnels. Des exemples en ligne sur l'utilisation du valarray (en particulier pour mon étui d'utilisation) semblent rares.


@Georgfritzsche Quels sont les arguments contre l'utilisation?


4 Réponses :


-1
votes

Voici un exemple qui inclut Un peu de manipulation matricielle


3 commentaires

Pourriez-vous au moins inclure un court exemple qui répond à la question? Les sites externes pourraient être en panne à un moment donné.


Je ne semble pas pouvoir trouver un rôle 2D VALARRAY dans cet exemple mais une matrice 2D aplatit. Je pense que l'OP veut un Valarray > trucsy.


@Dircrange: Je veux que la mémoire de la matrice soit contiguë, donc aucun Valarray >. Question modifiée.



5
votes
#include <iostream>
#include <valarray>

using namespace std;

typedef valarray<valarray<int> > va2d;

int main()
{
    int data[][3] = { {1, 2, 3}, {4, 5, 6} };
    va2d mat(valarray<int>(3), 2);
    for (int i = 0; i < 2; ++i)
    {
        for (int j = 0; j < 3; ++j)
           mat[ i ][ j ] = data[ i ][ j ];
    }
    for (int i = 0; i < 2; ++i)
        for (int j = 0; j < 3; ++j)
           cout << mat[ i ][ j ] << endl;
}
More on valarray:
It is optimized for numeric computation.
It is a vector like container with special member functions for slicing and dicing.
No iterators
Designed for vector machines and perform poorly on current ones: vector access may be faster
Was not supported by all compilers (check the documentation)  / poorly implemented
See 26.1 for the types that can be used as a parameter to valarray<T>: E.g:

  3 In addition, many member and related
  functions of valarray can be
  successfully instantiated and will
  exhibit well-defined behavior if and
  only if T satisfies additional
  requirements specified for each such
  member or related function. 
  
  4 [
  Example: It is valid to instantiate
  valarray, but operator>()
  will not be successfully instantiated
  for valarray operands, since
  complex does not have any ordering
  operators. —end example ]
Edit#2: The standard gurantees that vector, like arrays, always use contiguous memory. Also, we have:
  26.5.2 Class template valarray
  
  1 The class template valarray is a
  one-dimensional smart array, with
  elements numbered sequentially from
  zero. It is a representation of the
  mathematical concept of an ordered set
  of values. The illusion of higher
  dimensionality may be produced by the
  familiar idiom of computed indices,
  together with the powerful
  subsetting capabilities provided by
  the generalized subscript operators.
and further:
  26.5.2.3 valarray element access
  
  4 Likewise, the expression &a[i] !=
  &b[j] evaluates as true for any two
  arrays a and b and for any size_t i
  and size_t j such that i is less than
  the length of a and j is less than the
  length of b. This property indicates
  an absence of aliasing and may be used
  to advantage by optimizing compilers.

5 commentaires

Oups. Désolé. N'a pas clarifié ma question assez vite. +1 de toute façon.


Valarray est destiné à contenir des tableaux multidimensionnels sans niché. Valarray >> ne doit être nécessaire que pour un tableau de matrices / tableaux de tailles différentes.


Dirkgement répondit avant que je précise que je voulais la mémoire contiguë. Pas besoin de bowevote.


Depuis les citations que vous avez postées, ce n'est pas clair pour moi si les données du Valarray sont garanties pour être contiguës. Peux-tu élaborer?


Dans Valarray , le type T a certaines contraintes (non appliquées par le compilateur). T ne peut pas être un valarray, selon ce gcc.gnu.org/ml /LibstDC++/2000-Q1/MSG00123.HTML



12
votes

éteint le dessus de ma tête: xxx

std :: valarray offre de nombreuses façons intéressantes d'accéder aux éléments, via des tranches, des masques, des tranches multidimentées ou une Table d'indirection. Voir std :: slice_array , std :: gslice_array , std :: mask_array , et std :: indirect_array pour Plus de détails.


8 commentaires

Ah oui, merci. C'est ce que je cherchais. J'aime particulièrement que vous avez montré un accès majeur de ligne / colonne.


Les données du valorray sont-elles garanties pour être contiguës, comme vecteur?


De MSDN: La classe de modèle décrit un objet qui contrôle une séquence d'éléments de type de type enregistré en tant que tableau, conçu pour effectuer des opérations mathématiques à grande vitesse et optimisée pour des performances de calcul. Donc, je suppose que oui.


@MSN Il y a une erreur dans votre CTOR, vous avez deux m_stride. m_stride (largeur), m_stride (hauteur)


@MSN: quel compilateur / stdlib utilisiez-vous de telle que matrice :: opérateur () compilé? Sur ma copie de GCC 4.4.5 SLICE_ARRAY (comme retourné par valarray :: opérateur [SLICE SLC] ) ne semble pas avoir un < code> opérateur [] . Voici ce que j'essayais . Le clang site de démonstration est également étouffé dessus.


@genpfault, je ne l'ai jamais compilée. Qui en regardant la documentation de SLICE_ARRAY signifie que cela ne fonctionnera tout simplement pas, bien que le retour de GSLICE_ARRAY.


@Msn La réponse n'est pas correcte - SLICE_ARRAY / GSLICE_ARRAY NE PAS Impression d'un accès par élément (autant que je sache ces classes visaient à l'opération SIMD). De l'autre côté, on peut affecter "efficacement" une ligne (à une foulée spécifiée) de valeurs d'un autre Valarray.


Oui, comme @GenPfault mentionné, je suis capable d'utiliser une tranche comme un accesseur de colonne, mais pas comme un accesseur de ligne. Toute solution de contournement pour cela?



0
votes

Si vous souhaitez tester la matrice multidimensionnelle pour être un bloc contigu (colonnes x lignes). Vous pouvez voir cet exemple avec Valarray strong>.

template<class T>
class Array: public std::valarray<T> {
  size_t row,col; 
public:
  Array(){}
  Array(size_t nx) : std::valarray<T>(nx){row=nx,col=1;}
  Array(size_t nx, size_t ny) : std::valarray<T>(nx*ny){row=nx,col=ny;}
  virtual ~Array(){}
  T& operator()(size_t i,size_t j) { return (*this)[i*col+j];}
  size_t Size(size_t n) const { return (n<2) ? col: row;}
};


0 commentaires