FixVec.h 17.8 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/******************************************************************************
 *
 * AMDiS - Adaptive multidimensional simulations
 *
 * Copyright (C) 2013 Dresden University of Technology. All Rights Reserved.
 * Web: https://fusionforge.zih.tu-dresden.de/projects/amdis
 *
 * Authors: 
 * Simon Vey, Thomas Witkowski, Andreas Naumann, Simon Praetorius, et al.
 *
 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 *
 * This file is part of AMDiS
 *
 * See also license.opensource.txt in the distribution.
 * 
 ******************************************************************************/
20
21


22
23
24
25
26
27
28

/** \file FixVec.h */

#ifndef AMDIS_FIXVEC_H
#define AMDIS_FIXVEC_H

#include <iostream>
Thomas Witkowski's avatar
Thomas Witkowski committed
29
#include "Global.h"
30
#include "MatrixVector.h"
Thomas Witkowski's avatar
Thomas Witkowski committed
31
#include "AMDiS_fwd.h"
32
33
34

namespace AMDiS {

Thomas Witkowski's avatar
Thomas Witkowski committed
35
36
37
38
39
40
41
42
  /// determines how to initialize a FixVec when constructed.
  enum InitType {
    NO_INIT = 0,       /**< no initialisation */
    VALUE_LIST = 1,    /**< a complete value list is given */
    DEFAULT_VALUE = 2, /**< all values ar set to a given default value */
    UNIT_VECTOR = 3,   /**< the i-th value is 1, all other values are 0 */
    UNIT_MATRIX = 4    /**< values at the diagonal of a matrix are set to one */
  };
43
44
45
46
47
48
49
50
51
52
53
54
55
56

  /** \ingroup Common
   * \brief
   * A FixVec is a template vector of a fixed size. 
   *
   * The size is determined at construction time and depends on the dimension
   * and the template parameter d. So a FixVec<int, VERTEX> is a integer vector
   * with 3 entries in 2d and with 4 entries in 3d. The dimension and the way
   * the vector should be initialized are specified by the constructor call.
   */
  template<typename T,GeoIndex d>
  class FixVec : public Vector<T>
  {
  public:
57
    
Thomas Witkowski's avatar
Thomas Witkowski committed
58
59
    /// Constructor without initialisation. initType must be NO_INIT. If dim is
    /// not spezified, a FixVec for DIM_OF_WORLD is created.
60
61
62
    FixVec(int dim = -1, InitType initType = NO_INIT)
      : Vector<T>(calcSize(dim))
    { 
63
      TEST_EXIT_DBG(initType == NO_INIT)("wrong initType or missing initializer\n");
64
65
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
66
67
    /// constructor with value list initialisation. initType must be VALUE_LIST.
    /// ini is an array which contains the initialisation values.
68
69
70
    FixVec(int dim, InitType initType, const T* ini)
      : Vector<T>(calcSize(dim))
    {
71
      TEST_EXIT_DBG(initType == VALUE_LIST)("wrong initType or wrong initializer\n");
72
      this->setValues(ini);
73
    }
74

Thomas Witkowski's avatar
Thomas Witkowski committed
75
76
    /// constructor with default value initialisation. initType must be
    /// DEFAULT_VALUE. All vector entries are set to ini.
77
78
79
    FixVec(int dim, InitType initType, const T& ini)
      : Vector<T>(calcSize(dim))
    {
80
      TEST_EXIT_DBG(initType == DEFAULT_VALUE)("wrong initType or wrong initializer\n");
81
82
83
      this->set(ini);
    }

84
    /// Initialisation for dim.
85
86
    inline void init(int dim) 
    {
87
      this->resize(calcSize(dim));
88
    }
89

90
    /// Initialisation for size
91
92
    inline void initSize(int size) 
    {
93
      this->resize(size);
94
    }
95

96
    /// Returns the \ref size_ of the FixVec.
97
98
    inline int size() const 
    { 
99
      return this->getSize(); 
100
    } 
101
102

  protected:
103
    /// Determines needed vector size.
104
105
106
    static int calcSize(int dim) 
    {
      if (dim < 0)
107
	return Global::getGeo(WORLD);
108
      else
109
	return Global::getGeo(d, dim);
110
    }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

  public:
    friend class GLWindow;
  };


  /** \ingroup Common
   * \brief
   * Contains an vector of FixVecs of same type. To simply allocate an array of 
   * FixVecs
   * isn't possible, because the FixVec constructor normally needs at least
   * the corresponding dimension. So you must create an array of FixVec pointers
   * and call the constructor of each FixVec manually. When you use 
   * VectorOfFixVecs, this work is done by VectorOfFixVecs's constructor.
   */
  template<typename FixVecType>
  class VectorOfFixVecs
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
130
131
132
    /// constructs a VectorOfFixVecs without initialisation. dim is passed to 
    /// FixVec's constructors. size_ is the number of contained FixVecs. initType
    /// must be NO_INIT.
133
134
135
    VectorOfFixVecs(int d, int s, InitType initType) 
      : size(s),
	dim(d)
136
    {
137
      TEST_EXIT_DBG(initType == NO_INIT)("wrong initType or wrong initializer\n");
138

139
140
      vec.resize(size);
      for (int i = 0; i < size; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
141
	vec[i] = new FixVecType(dim, NO_INIT);
142
143
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
144
145
146
    /// constructs a VectorOfFixVecs via an value list.  dim is passed to 
    /// FixVec's constructors. size_ is the number of contained FixVecs. initType
    /// must be VALUE_LIST. ini contains the initialisation values.
147
    VectorOfFixVecs(int d, int s, InitType initType, FixVecType const* ini)
148
149
      : size(s),
	dim(d)
150
    {
151
      TEST_EXIT_DBG(initType == VALUE_LIST)("wrong initType or wrong initializer\n");
152

153
154
      vec.resize(size);
      for (int i = 0; i < size; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
155
	vec[i] = new FixVecType(ini[i]);
156
157
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
158
159
160
    /// constructs a VectorOfFixVecs with an default value.  dim is passed to 
    /// FixVec's constructors. size_ is the number of contained FixVecs. initType
    /// must be DEFAULT_VALUE. All entries are set to ini.
161
162
163
    VectorOfFixVecs(int d, int s, InitType initType, const FixVecType& ini)
      : size(s),
	dim(d)
164
    {
165
166
167
168
      TEST_EXIT_DBG(initType == DEFAULT_VALUE)("wrong initType or wrong initializer\n");

      vec.resize(size);
      for (int i = 0; i < size; i++) 
Thomas Witkowski's avatar
Thomas Witkowski committed
169
	vec[i] = new FixVecType(ini);
170
171
    }

172
    /// Copy constructor
173
174
    VectorOfFixVecs(const VectorOfFixVecs<FixVecType>& rhs)
    {
175
176
      size = rhs.getSize();
      dim = rhs.getDim();
177

178
179
      vec.resize(size);
      for (int i = 0; i < size; i++) 
Thomas Witkowski's avatar
Thomas Witkowski committed
180
	vec[i] = new FixVecType(*(rhs.vec[i]));
181
    }
182

183
    /// Destructor
184
185
    virtual ~VectorOfFixVecs()
    {
186
      for (int i = 0; i < size; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
187
	delete vec[i];
188

189
190
191
192
      vec.clear();
    }

    /// Allows the access like in a normal array via []. Used for const objects.
193
194
    inline const FixVecType& operator[](int index) const
    {
195
      TEST_EXIT_DBG(index >= 0 && index < size)("invalid index\n");
196
      return *(vec[index]);
197
    }
198

199
    /// Allows the access like in a normal array via []. 
200
201
    inline FixVecType& operator[](int index)
    {
202
      TEST_EXIT_DBG(index >= 0 && index < size)("invalid index\n");
203
      return *(vec[index]);
204
    }
205

206
    /// Assignment operator
207
208
209
    VectorOfFixVecs<FixVecType>& 
    operator=(const VectorOfFixVecs<FixVecType>& rhs)
    {
210
211
212
213
      TEST_EXIT_DBG(size == rhs.size)("vectors of different size\n");
      if (this != &rhs) {
	for (int i = 0; i < size; i++)
	  *(vec[i]) = *(rhs.vec[i]);
214
215
      }
      return *this;
216
    }
217

218
219
220
221
222
    /// Resize the vector
    inline void resize(int newsize)
    {
      vec.resize(newsize);
      for (int i = size; i < newsize; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
223
	vec[i] = new FixVecType(dim, NO_INIT);
224
225
226
227
      size = newsize;
    }

    /// Returns the \ref size of this VectorOfFixVecs
Thomas Witkowski's avatar
Thomas Witkowski committed
228
229
    inline int getSize() const 
    { 
230
231
      return size;
    }
232

233
    /// Returns \ref dim
Thomas Witkowski's avatar
Thomas Witkowski committed
234
235
    inline int getDim() const 
    {
236
237
238
239
      return dim;
    }

    /// Returns the size of the contained FixVecs
Thomas Witkowski's avatar
Thomas Witkowski committed
240
241
    inline int getSizeOfFixVec() const 
    { 
242
243
      return vec[0]->getSize(); 
    }
244
245

  protected:
246
247
    /// number of contained FixVecs
    int size;
248

249
250
251
252
253
    /// dimension of world
    int dim;

    /// array of pointers to FixVecs
    std::vector<FixVecType*> vec;
254
255
256
257
258
259
260
261
262
263
264
265
  };


  /** \ingroup Common
   * \brief
   * Like the class VectorOfFixVecs contains a vector of FixVecs, this class
   * contains a matrix of FixVecs of same type.
   */
  template<typename FixVecType>
  class MatrixOfFixVecs
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
266
267
268
    /// Constructs the matrix without initialisation. r is the number of rows,
    /// c is the number of columns. The other parameters are analog to the
    /// VectorOfFixVecs constructors.
269
    MatrixOfFixVecs(int dim, int r, int c, InitType initType)
270
271
      : rows(r), 
	columns(c)
272
    {
273
      TEST_EXIT_DBG(initType == NO_INIT)("wrong initType or wrong initializer\n");
Thomas Witkowski's avatar
Thomas Witkowski committed
274
275
      vec = new VectorOfFixVecs<FixVecType>*[rows];
      for (VectorOfFixVecs<FixVecType>** i = &vec[0]; i < &vec[rows]; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
276
	*i = new VectorOfFixVecs<FixVecType>(dim, columns, NO_INIT);
277
    }
278

279
    /// destructor
280
281
    virtual ~MatrixOfFixVecs()
    {
Thomas Witkowski's avatar
Thomas Witkowski committed
282
      for (VectorOfFixVecs<FixVecType>** i = &vec[0]; i < &vec[rows]; i++)
Thomas Witkowski's avatar
Thomas Witkowski committed
283
	delete *i;
Thomas Witkowski's avatar
Thomas Witkowski committed
284
285

      delete [] vec;
286
    }
287

288
    /// assignment operator
289
290
    inline VectorOfFixVecs<FixVecType >& operator[](int index)
    {
291
      TEST_EXIT_DBG(index >= 0 && index < rows)("invalid index\n");
292
      return *(vec[index]);
293
    }
294

295
    /// assignment operator
296
297
    inline const VectorOfFixVecs<FixVecType >& operator[](int index) const
    {
298
      TEST_EXIT_DBG(index >= 0 && index < rows)("invalid index\n");
299
      return *(vec[index]);
300
    }
301

302
    /// Returns \ref rows
303
304
    inline int getNumberOfRows() const 
    { 
305
      return rows; 
306
    }
307

308
    /// Returns \ref columns
309
310
    inline int getNumberOfColumns() const 
    { 
311
      return columns; 
312
    }
313
314

  private:
315
    /// number of rows of the matrix
316
317
    int rows;

318
    /// number of columns of the matrix
319
320
    int columns;

321
    /// array of pointers to VectorOfFixVecs
322
323
324
325
326
327
328
329
330
331
332
    VectorOfFixVecs<FixVecType> **vec;
  };


  /** \ingroup Common
   * \brief
   * A DimVec is a FixVec with dim + 1 entries. It can be used for storing
   * barycentric coordinates or information associated to vertices or
   * parts of an element.
   */
  template<typename T>
333
334
  class DimVec : public FixVec<T,PARTS> 
  {
335
  public:
336
    DimVec() {}
337

338
339
    /// Calls the corresponding constructor of FixVec
    DimVec(int dim, InitType initType = NO_INIT)
340
      : FixVec<T,PARTS>(dim, initType)
341
    {}
342

343
    /// Calls the corresponding constructor of FixVec
344
    DimVec(int dim, InitType initType, T const* ini)
345
      : FixVec<T,PARTS>(dim, initType, ini)
346
    {}
347

348
    /// Calls the corresponding constructor of FixVec
349
350
    DimVec(int dim, InitType initType, const T& ini)
      : FixVec<T,PARTS>(dim, initType, ini)
351
352
    {}

353
    /// Multplication of a matrix with a vector.
354
    void multMatrixVec(DimMat<T> &m, DimVec<T> &v);
355
356
357
358
359
360
361
362
363
364
365
  };


  /** \ingroup Common
   * \brief
   * A DimMat is a VectorOfFixVecs of dim+1 DimVecs. 
   */
  template<typename T>
  class DimMat : public Matrix<T>
  {
  public:
Thomas Witkowski's avatar
Thomas Witkowski committed
366
    /// Calls the corresponding constructor of VectorOfFixVecs
367
368
    DimMat(int dim, InitType initType = NO_INIT)
      : Matrix<T>(dim + 1, dim + 1)
369
    {}
370

Thomas Witkowski's avatar
Thomas Witkowski committed
371
    /// Calls the corresponding constructor of VectorOfFixVecs
372
    DimMat(int dim, InitType initType, const T& ini)
373
      : Matrix<T>(dim + 1, dim + 1)
374
    {
375
      TEST_EXIT_DBG(initType == DEFAULT_VALUE)
376
377
	("wrong initType or wrong initializer\n");    
      this->set(ini);
378
    }
379

Thomas Witkowski's avatar
Thomas Witkowski committed
380
    /// Calls the corresponding constructor of VectorOfFixVecs
381
    DimMat(int dim, InitType initType, T const* ini)
382
      : Matrix<T>(dim + 1, dim + 1)
383
    {
384
      TEST_EXIT_DBG(initType == VALUE_LIST)("wrong initType or wrong initializer\n");
385
      setValues(ini);
386
    }
387
388
389
390
391
392
393
394
395
396
397
398
  };


  /** \ingroup Common
   * \brief
   * A WorldVector is an AlgoVec with DIM_OF_WORLD entries of type double.
   * Can be used for storing world coordinates.
   */
  template<typename T>
  class WorldVector : public FixVec<T, WORLD>
  {
  public:
399
400
401
    typedef WorldVector       self;
    typedef FixVec<T, WORLD>  super;
  
Thomas Witkowski's avatar
Thomas Witkowski committed
402
    /// Calls the corresponding constructor of AlgoVec
403
    WorldVector() 
404
      : super(Global::getGeo(WORLD), NO_INIT) 
405
    {}
406

Thomas Witkowski's avatar
Thomas Witkowski committed
407
    /// Calls the corresponding constructor of AlgoVec
408
409
    WorldVector(InitType initType, T const* ini) 
      : super(Global::getGeo(WORLD), initType, ini)
410
    {}
411

Thomas Witkowski's avatar
Thomas Witkowski committed
412
    /// Calls the corresponding constructor of AlgoVec
413
    WorldVector(InitType initType, const T& ini)
414
415
416
417
418
419
      : super(Global::getGeo(WORLD), initType, ini)
    {}
//     
    /// Copy constructor for other of same value_type
    WorldVector(self const& other)
      : super(other) 
420
    {}
421
    
422
423
    /// Copy assignement operator
    self& operator=(self other) 
424
    {
425
      swap(*this, other);
426
427
      return *this;
    }
428
      
429
430
    
    /// Assignement operator
431
432
    template <typename S>
    self& operator=(const Vector<S>& other) 
433
    {
434
435
436
      TEST_EXIT_DBG( other.getSize() == Global::getGeo(WORLD) )
		   ("Wrong dimensions in assignment.\n");
      this->setValues(other.getValArray());
437
438
      return *this;
    }
439

440
    /// Sets all entries to scal
441
    template <typename S>
442
    typename enable_if<boost::is_convertible<S, T>, self>::type &
443
    operator=(S scal)
444
    {
445
446
      this->set(scal);
      return *this;
447
    }
448

Thomas Witkowski's avatar
Thomas Witkowski committed
449
    /// Sets the arrays value to the geometric midpoint of the points  p1 and p2.
450
451
452
453
    inline void setMidpoint(const WorldVector<T> &p1, const WorldVector<T> &p2)
    {
      int dow = Global::getGeo(WORLD);

Thomas Witkowski's avatar
Thomas Witkowski committed
454
      for (int i = 0; i < dow; i++)
455
456
457
	this->valArray[i] = 0.5 * (p1[i] + p2[i]);
    }

Thomas Witkowski's avatar
Thomas Witkowski committed
458
    /// Multplication of a matrix with a vector.
459
    void multMatrixVec(const WorldMatrix<T> &m, const WorldVector<T> &v);
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
  };


  /** \ingroup Common
   * \brief
   * A WorldMatrix is a FixVec with DIM_OF_WORLD WorldVector entries.
   * So it can be seen as matrix with DIM_OF_WORLD x DIM_OF_WORLD double 
   * entries.
   * Here it's not necessary to use the VectorOfFixVecs class, because the 
   * FixVec constructor assumes dim = DIM_OF_WORLD, if no dim is spezified, 
   * what is the right assumption in this case.
   */
  template<typename T>
  class WorldMatrix : public Matrix<T>
  {
  public:
476
477
478
    typedef WorldMatrix   self;
    typedef Matrix<T>     super;
    
479
    /// Calls the corresponding constructor of FixVec
480
    WorldMatrix()
481
      : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
482
    {}
483

484
    /// Calls the corresponding constructor of FixVec
485
    WorldMatrix(InitType initType, T* ini)
486
      : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
487
    {
488
      TEST_EXIT_DBG(initType == VALUE_LIST)("???\n");
489
      this->setValues(ini);
490
    }
491
492
493
494
495
496

    /** \brief
     * Calls the corresponding constructor of FixVec and sets all matrix entries
     * to ini
     */
    WorldMatrix(InitType initType, const T& ini)
497
      : super(Global::getGeo(WORLD), Global::getGeo(WORLD))
498
    {
499
      TEST_EXIT_DBG(initType == DEFAULT_VALUE)("wrong initType or wrong initializer\n");
500
      this->set(ini);
501
    }
502
    
503
    /// Copy constructor 
504
505
506
507
    WorldMatrix(self const& other)
      : super(other) 
    { }
    
508
509
    /// Copy assignment operator
    self& operator=(self other) 
510
    {
511
      swap(*this, other);
512
513
514
      return *this;
    }
    
515
516
517
    /// Assignment operator
    template <typename S>
    self& operator=(const Matrix<S>& other) 
518
    {
519
520
521
522
      TEST_EXIT_DBG( other.getNumOfRows() == Global::getGeo(WORLD) &&
		     other.getNumOfCols() == Global::getGeo(WORLD) )
		    ("Wrong dimensions in assignment.\n");
      this->setValues(other.getValArray());
523
524
525
      return *this;
    }
    
526
    /// Assignment operator for scalars
527
528
    template <typename S>
    typename enable_if<boost::is_convertible<S, T>, WorldMatrix<T> >::type &
529
    operator=(S value) 
530
    {
531
      this->set(value);
532
533
      return *this;
    }
534
  
535
    /// Returns true if the matrix is a diagonal matrix, returns false otherwise.
536
537
    bool isDiagMatrix() const;

538
    /// Returns true if the matrix is symmetric, returns false otherwise.
539
540
    bool isSymmetric() const;

541
    /// Sets the diagonal entries to the given value.
542
543
544
545
546
547
548
549
550
551
552
553
554
555
    void setDiag(T value);

    /** \brief
     * Creates a matrix from the "multiplication" of two vectors.
     *
     * 2d-Example:
     *
     * /a\   /c\   /ac ad\
     * | | * | | = |     |
     * \b/   \d/   \bc bd/
     */
    void vecProduct(const WorldVector<T>& v1, const WorldVector<T>& v2);
  };

556
  /// FixVec operator for stream output
557
  template<typename T, GeoIndex d>
558
  std::ostream& operator <<(std::ostream& out, const FixVec<T,d>& fixvec)
559
  {
Thomas Witkowski's avatar
Thomas Witkowski committed
560
    for (int i = 0; i < fixvec.getSize() - 1; i++)
561
562
563
564
565
      out << fixvec[i] << " ";
    out << fixvec[fixvec.getSize()-1];
    return out;
  }

566
  /// creates and inits a VectorOfFixVecs<DimVec<double> >
567
568
  VectorOfFixVecs<DimVec<double> > *createAndInit(int dim, int size, ...);

569
  /// creates and inits and double array
570
571
  double *createAndInitArray(int size, ...); 

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
  template<typename T>
  struct GradientType
  {
    typedef WorldVector<T> type;
    
    static mtl::dense_vector<double> getValues(type &t) {
      mtl::dense_vector<double> result(t.getSize());
      for (size_t i = 0; i < t.getSize(); i++)
	result[i] = static_cast<T>(t[i]);
      return result;
    }
  };

  template<typename T>
  struct GradientType<WorldVector<T> >
  {
    typedef WorldVector<WorldVector<T> > type;

    static mtl::dense_vector<double> getValues(type &t) {
      mtl::dense_vector<double> result(sqr(t.getSize()));
      for (size_t i = 0; i < t.getSize(); i++)
	for (size_t j = 0; j < t.getSize(); j++)
	  result[i*(t.getSize()) + j] = static_cast<T>(t[i][j]);
      return result;
    }
  };

  template<typename T>
  struct D2Type
  {
    typedef WorldMatrix<T> type;
    
    static mtl::dense_vector<double> getValues(type &t) {
      mtl::dense_vector<double> result(t.numRows() * t.numCols());
      for (size_t i = 0; i < t.numRows(); i++)
	for (size_t j = 0; j < t.numCols(); j++)
	  result[i*(t.numCols()) + j] = static_cast<T>(t[i][j]);
      return result;
    }
  };
612
613
614
615
  
  template<typename T,GeoIndex d>
  inline void resize(FixVec<T,d>& vec, size_t newSize)
  { }
616
617
}

618

619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
#include <boost/numeric/mtl/concept/collection.hpp>
#include <boost/numeric/mtl/utility/ashape.hpp>
#include <boost/numeric/mtl/utility/category.hpp>
#include <boost/numeric/mtl/utility/is_row_major.hpp>

namespace mtl 
{
  template <typename T>
  struct Collection<AMDiS::WorldVector<AMDiS::WorldVector<T> > >
  {
    typedef T      value_type;
    typedef int    size_type;
  };

  namespace ashape 
  {
    template <typename T> 
    struct ashape_aux<AMDiS::WorldVector<AMDiS::WorldVector<T> > > 
    { 
      typedef mat<typename ashape<T>::type> type;  // nonscal
    };
  } // end namespace ashape  
  
  namespace traits
  {
    template <typename T>
    struct category<AMDiS::WorldVector<AMDiS::WorldVector<T> > > 
    {
	typedef tag::dense2D type;
    };
    
    template <typename T>
    struct is_row_major<AMDiS::WorldVector<AMDiS::WorldVector<T> > >
      : boost::mpl::true_ {};
  } // end namespace traits
} // end namespace mtl

656
657
658
#include "FixVec.hh"

#endif // AMDIS_FIXVEC_H