vectorsMatrices.hh

Go to the documentation of this file.
1 
6 #ifndef vectMatr_hh
7 #define vectMatr_hh
8 
9 #include <iostream>
10 #include <cmath>
11 #include <cstring>
12 #include <type_traits>
13 
14 #include "functionCompiler.hh"
15 #include "exceptions.hh"
16 #include "typedefs.hh"
18 #include "debug.hh"
19 #include <type_traits>
20 
21 // debugging Mapping
22 #define MappingAppll_D 0
23 #define MappingAppl_D 0
24 
25 #define MappingConstructorHack 1
26 
27 namespace concepts {
28 
30  template<typename F, typename G>
31  void memorycpy(F *dest, const G *src, size_t n) {
32  for (size_t i = 0; i < n; ++i) *dest++ = *src++;
33  }
34 
35  // ***************************************************************** Point **
36 
45  template<class F, uint dim>
46  class Point {
47  public:
51  Point() { F* d = data_; for(uint i = dim; i--;) *d++ = 0; }
53  template<class G>
54  Point(const Point<G, dim>& p) {
55  memorycpy(data_, (const G*)p, dim);
56  }
58  template<uint dim2>
59  Point(const Point<F, dim2>& p) {
60  if (dim2<dim) {
61  F* d = data_+dim2; for(uint i = dim-dim2; i--;) *d++ = 0;
62  }
63  memorycpy(data_, (const F*)p, ((dim < dim2) ? dim : dim2));
64  }
68  Point(F x) { F* d = data_; for(uint i = dim; i--;) *d++ = x; }
70  Point(const F e0, const F e1, const F e2 = 0) {
71  uint i = 0;
72  data_[i++] = e0;
73  if (dim > 1)
74  data_[i++] = e1;
75  if (dim > 2)
76  data_[i] = e2;
77  }
79  Point(const uchar *pgm, const Real x, const Real y, const Real z = 0.0);
80 
82  template<uint dim2>
84  if (this != &b)
85  memorycpy(data_, b.data_, ((dim < dim2) ? dim : dim2));
86  return *this;
87  }
88 
90  const F& operator[](const uint i) const {
92  return data_[i]; }
94  F& operator[](const uint i) {
96  return data_[i]; }
97 
99  operator F*() { return data_; }
101  operator const F*() const { return data_; }
102 
105  F* d = data_; const F* dp = p.data_;
106  for(uint i = dim; i--;) *d++ += *dp++;
107  return *this;
108  }
111  Point<F, dim> res(*this);
112  return res += p;
113  }
116  F* d = data_; const F* dp = p.data_;
117  for(uint i = dim; i--;) *d++ -= *dp++;
118  return *this;
119  }
122  Point<F, dim> res(*this);
123  return res -= p;
124  }
125 
127  F operator*(const Point<F, dim>& b) const;
128  F operator*(const UnitNd<dim>& b) const;
130  F dot(const Point<F, dim>& b) const;
131 
133  template<class G>
134  Point<F, dim>& operator*=(const G n) {
135  F* d = data_;
136  for(uint i = dim; i--;) *d++ *= n;
137  return *this;
138  }
139 
141  template<class G>
142  Point<F, dim>& operator/=(const G n) {
143  F* d = data_; for(uint i = dim; i--;) *d++ /= n;
144  return *this;
145  }
146 
149  Point<Cmplx, dim> res(*this);
150  return res *= n;
151  }
153  Point<F, dim> operator*(const Real n) const {
154  Point<F, dim> res(*this);
155  return res *= n;
156  }
157 
160  Point<Cmplx, dim> res(*this);
161  return res /= n;
162  }
164  Point<F, dim> operator/(const Real n) const {
165  Point<F, dim> res(*this);
166  return res /= n;
167  }
168 
171  F* d = data_; const F* e = n.data_;
172  for(uint i = dim; i--;) *d++ *= *e++;
173  return *this;
174  }
175 
179  F operator^(const Point<F, 2>& b) const;
180 
182  Real l2() const { return std::sqrt(l2_2()); }
184  Real l2_2() const;
186  Real linfty() const;
187 
189  void lincomb(const Point<F, dim>& a, const Point<F, dim>& b,
190  const F ca = 1.0, const F cb = 1.0);
191 
193  void max(const Point<F, dim>& a, const Point<F, dim>& b);
194 
196  void min(const Point<F, dim>& a, const Point<F, dim>& b);
197 
206 
207  std::ostream& info(std::ostream& os) const;
208  private:
209  F data_[dim];
210  };
211 
212  template<class F, uint dim>
213  std::ostream& operator<<(std::ostream& os, const Point<F, dim>& p) {
214  return p.info(os);
215  }
216 
217  // set the real type of a vector to the real type of the components
218  template<typename F, uint dim>
219  struct Realtype<Point<F,dim> > {
220  typedef typename Realtype<F>::type type;
221  };
222 
223  // set the data type of a vector to the data type of the components
224  template<typename F, uint dim>
225  struct Datatype<Point<F,dim> > {
226  //typedef typename Datatype<F>::type type;
227  typedef F type;
228  };
229 
230  template <class F, uint dim>
231  inline bool operator==(const Point<F,dim>& x, const Point<F,dim>& y)
232  {
233  const F* d = (const F*)x; const F* e = (const F*)y;
234  for (uint i = dim; i--;)
235  if (*d++ != *e++) return false;
236  return true;
237  }
238 
239  template <class F, uint dim>
241  {
242  return y * x;
243  }
244 
245  template <class F, uint dim>
247  {
248  return y * x;
249  }
250 
251  template<uint dim>
253  Cmplx res = 0.0;
254  const Cmplx* d = (const Cmplx*)a; const Real* db = (const Real*)b;
255  for(uint i = 2; i--;)
256  res += (*d++) * (*db++);
257  return res;
258  }
259 
260  template<uint dim>
262  Cmplx res = 0.0;
263  const Real* d = (const Real*)a; const Cmplx* db = (const Cmplx*)b;
264  for(uint i = dim; i--;)
265  res += (*d++) * (*db++);
266  return res;
267  }
268 
269  // **************************************************************** UnitNd **
270 
275  template <uint dim>
276  class UnitNd : public Point<Real, dim> {
278 
279  public:
281  UnitNd() : Point<Real, dim>() {len_ = 0.0;}
283  inline UnitNd(const Point<Real, dim>& u);
285  inline UnitNd(Real x, Real y, Real z);
286 
288  Real length() const {return len_;}
289  };
290 
291  template <uint dim>
293  : Point<Real, dim>(u) {
294  len_ = this->l2(); *this *= (1.0 / len_);
295  }
296 
297  template <uint dim>
299  : Point<Real, dim>(x, y, z) {
300  len_ = this->l2(); *this *= (1.0 / len_);
301  }
302 
303  // ************************************************ Mapping<F, DimY, DimX> **
304 
312  template<class F, uint DimY, uint DimX=DimY>
313  class Mapping {
314  public:
318  Mapping() {}
319 
322  memorycpy(data_, m.data_, DimX*DimY);
323  }
324 
330  template <class H>
332  for (uint i=0; i < DimY; ++i) {
333  for (uint j=0; j < DimX; ++j) {
334  data_[lin_(i,j)] = m(i,j);
335  }
336  }
337  }
338 
342 #if MappingConstructorHack
343  template <class G>
344  Mapping(G x) { F* d = data_; for(uint i = DimX*DimY; i--;) *d++ = x; }
345 #else
346  Mapping(F x) { F* d = data_; for(uint i = DimX*DimY; i--;) *d++ = x; }
347 #endif
348 
357 #if MappingConstructorHack
358  template<class... FieldTs>
359  Mapping(FieldTs... data) : data_{data...} {};
360 #else
361  template<class... FieldTs>
362  Mapping(std::enable_if<std::is_floating_point<FieldTs>::value, FieldTs>::type... data) : data_{data...} {
363  static_assert(sizeof...(FieldTs)==DimX*DimY,"Wrong number of arguments.");
364  }
365 #endif
366 
367  // /// Constructor for a 2D mapping
368  // Mapping(const F e0, const F e1,
369  // const F e2, const F e3);
370 
371  // /// Constructor for a 3D mapping
372  // Mapping(const F e0, const F e1, const F e2,
373  // const F e3, const F e4, const F e5,
374  // const F e6, const F e7, const F e8);
375 
376  // /// Constructor for a 6D mapping
377  // Mapping(const F e0, const F e1, const F e2,
378  // const F e3, const F e4, const F e5,
379  // const F e6, const F e7, const F e8,
380  // const F e9, const F e10, const F e11,
381  // const F e12, const F e13, const F e14,
382  // const F e15, const F e16, const F e17,
383  // const F e18, const F e19, const F e20,
384  // const F e21, const F e22, const F e23,
385  // const F e24, const F e25, const F e26,
386  // const F e27, const F e28, const F e29,
387  // const F e30, const F e31, const F e32,
388  // const F e33, const F e34, const F e35);
389 
393  Mapping(const Point<F, DimY> first);
394 
399  Mapping(const Point<F, DimY> first,
400  const Point<F, DimY> second);
401 
407  Mapping(const Point<F, DimY> first,
408  const Point<F, DimY> second,
409  const Point<F, DimY> third);
410 
415 
416 
418  F determinant() const;
419 
424 
428  Mapping<F, DimY-1, DimX-1> subMatrix(uint i, uint j) const;
429 
431  F trace() const;
432 
435 
437  const F& operator()(uint i, uint j) const {
438  conceptsAssert(i < DimY, Assertion());
439  conceptsAssert(j < DimX, Assertion());
440  DEBUGL(MappingAppll_D, '(' << i << ", " << j << ") is " << data_[i*DimY+j]
441  << " at " << &(data_[i*DimX+j]));
442  return data_[i*DimX+j];
443  }
444 
446  F& operator()(uint i, uint j) {
447  conceptsAssert(i < DimY, Assertion());
448  conceptsAssert(j < DimX, Assertion());
449  DEBUGL(MappingAppll_D, '(' << i << ", " << j << ") is " << data_[i*DimY+j]
450  << " at " << &(data_[i*DimX+j]));
451  return data_[i*DimX+j];
452  }
453 
455  template<class H>
457 
458  template<class H>
460  return this->operator*(b);
461  }
462 
464  template<class G, uint DimZ>
466 
469 
472 
474  template<class G>
476  const G n) const;
477 
480 
483 
486 
489 
492 
494  Point<F, DimY> column(const uint i) const;
495 
497  void zeros() { F* d = data_;
498  for (uint i = 0; i < DimX*DimY; ++i) *d++ = 0; }
499 
503  template <class H>
504  void mapTranspose(const Point<H, DimY>& y, Point<H, DimX>& x) const;
505 
508  const Point<F, DimY> y);
509 
514  template<class H, class J, uint dimy, uint dimx>
515  void operator()(const Point<H, dimy>& y, Point<J, dimx>& x) const;
516 
517  std::ostream& info(std::ostream& os) const;
518 
519  private:
521  F data_[DimX*DimY];
522 
524  const uint lin_(uint i, uint j) const { return i*DimX+j; }
525  };
526 
527  // Move to cc file?
528 
529  template<class F, uint DimY, uint DimX>
530  template<class H>
532  {
534  this->operator()(p, res);
535  return res;
536  }
537 
538  template<class F, uint DimY, uint DimX>
539  template<class H>
541  Point<H, DimX>& x) const
542  {
543  H* dr = (H*)x;
544  for(uint i = 0; i < DimX; i++, dr++) {
545  const H* dp = (const H*)y;
546  const F* dm = data_ + i;
547  *dr = 0;
548  for(uint j = DimY; j--; ++dp) {
549  *dr += (*dm) * (*dp);
550  dm += DimX;
551  }
552  }
553  }
554 
555  template<class F, uint DimY, uint DimX>
556  template<class H, class J, uint dimy, uint dimx>
558  {
559  DEBUGL(MappingAppl_D, *this << " * " << y << " -> " << x);
560  if (dimx == dimy && (void*)&x == (void*)&y) {
561 
562  J* dx = (J*)x;
563  const F* d = this->data_;
564  const H* yp = (const H*)y;
565  H yy[dimy];
566  for (uint k = 0; k < dimy; k++) yy[k] = yp[k];
567  const H* dy = yy;
568  for(uint i = 0; i < (DimY < dimx ? DimY : dimx); ++dx, ++i) {
569  dy = yy;
570  *dx = 0;
571  for(uint j = 0; j < (DimX < dimy ? DimX : dimy); ++j) {
572  *dx += d[j] * (*dy++);
573  }
574  d += DimX;
575  }
576  if (DimY < dimx) {
577  for(uint j = DimY; j < (dimx < dimy ? dimx : dimy); ++j)
578  *dx++ = *dy++;
579  for(uint k = 0; k < dimx - (DimX < dimy ? dimy : DimX); ++k)
580  *dx++ = 0;
581  }
582 
583  } // if (dimx == dimy && &x == &y)
584  else {
585  DEBUGL(MappingAppl_D, "x != y");
586  J* dx = (J*)x;
587  const F* d = this->data_;
588  const H* dy = (const H*)y;
589  for(uint i = 0; i < (DimY < dimx ? DimY : dimx); ++dx, ++i) {
590  dy = (const H*)y;
591  *dx = 0;
592  for(uint j = 0; j < (DimX < dimy ? DimX : dimy); ++j) {
593  *dx += d[j] * (*dy++);
594  }
595  DEBUGL(MappingAppl_D, "x = " << x);
596  d += DimX;
597  }
598  if (DimY < dimx) {
599  for(uint j = DimY; j < (dimx < dimy ? dimx : dimy); ++j)
600  *dx++ = *dy++;
601  for(uint k = 0; k < dimx - (DimX < dimy ? dimy : DimX); ++k)
602  *dx++ = 0;
603  }
604 
605  } // else (dimx == dimy && &x == &y)
606  }
607 
608  template<class F, uint DimY, uint DimX>
609  std::ostream& operator<<(std::ostream& os, const Mapping<F, DimY, DimX>& m) {
610  return m.info(os);
611  }
612 
613  // set the real type of a matrix to the real type of the components
614  template<typename F, uint DimX, uint DimY>
615  struct Realtype<Mapping<F, DimY, DimX> > {
616  typedef typename Realtype<F>::type type;
617  };
618 
619  // set the data type of a matrix to the data type of the components
620  template<typename F, uint DimX, uint DimY>
621  struct Datatype<Mapping<F, DimY, DimX> > {
622  typedef typename Datatype<F>::type type;
623  };
624 
629 
630 
631  // ******************************************************** GeneralMapping **
632 
641  template<class F, uint dim>
642  struct GeneralMapping {
643  typedef typename concepts::Mapping<F,dim> Type;
644  };
645 
646  template<class F>
647  struct GeneralMapping<F,1> {
648  typedef F Type;
649  };
650 
651 
652  // **************************************************************** number **
653 
654  template<class F, uint dim>
655  struct number<Point<F,dim> > {
656  static inline std::string name() {
657  return number<F>::name() + char('0'+dim) + 'd';
658  }
659  };
660 
661  template<class F, uint dim>
662  struct number<Mapping<F,dim> > {
663  static inline std::string name() {
664  return "Map" + number<F>::name() + char('0'+dim) + 'd';
665  }
666  };
667 
668  // ********************************************************** GeneralPoint **
669 
681  template<class F, uint CoordDim>
682  struct GeneralPoint : std::conditional<CoordDim==1,
683  F,
684  concepts::Point<F,CoordDim>> {};
685 
686  // ************************************************************ Coordinate **
687  template<uint CoordDim>
688  struct Coordinate : GeneralPoint<Real, CoordDim> {};
689 
690  // ******************************************************* CoordinateParam **
691  template<int CoordDim>
692  struct CoordinateParam : std::conditional<CoordDim==1,
693  const typename Coordinate<1>::type,
694  const typename Coordinate<CoordDim>::type &> {};
695 
696 
697 } // namespace concepts
698 
699 namespace std {
700 
708  template<class F, uint dim>
711  F* d = (F*)res; const F* e = (const F*)v;
712  for(uint i = dim; i--;) *d++ += conj(*e++);
713  return res;
714  }
715 
721  template<class F, uint dim>
722  inline const concepts::Real norm(const concepts::Point<F,dim>& v) {
723  return v.l2_2();
724  }
725 
726  // ******************************************************************** arg **
727 
734 
735 } // namespace std
736 
737 #endif // vectMatr_hh
Basic class for a 2D or 3D map.
Point< Cmplx, dim > operator*(const Cmplx n) const
Scaling operator with a complex number.
Mapping(const Mapping< F, DimY, DimX > &m)
Copy constructor.
Mapping< F, DimX, DimY > inverse() const
Returns the inverse of the matrix.
void rank1Product(const Point< F, DimX > x, const Point< F, DimY > y)
Computes x yT and adds the result to the matrix.
#define MappingAppll_D
UnitNd()
Constructor. Initializes all elements to 0.
Point(const Point< F, dim2 > &p)
Copy constructor.
Point< H, DimY > mapPoint(const Point< H, DimX > &b) const
Mapping< F, DimY, DimX > & operator*=(const Mapping< F, DimY, DimX > &m)
Multiplication operator ( *this = operator()(*this, m); )
Point< Cmplx, dim > operator/(const Cmplx n) const
Unscaling operator with a complex number.
F determinant() const
Returns the determinant of the matrix (only valid for square matrices)
Type of the data inside a container.
Definition: typedefs.hh:169
Mapping< F, DimY, DimX > & operator*=(const F n)
Scaling operator.
Basic class for a Point or a vector.
Introduction of a point type which is Real or Cmplx for dimension 1 and Point<Real,...
Mapping< F, DimY, DimX > & scaleCols(const Point< F, DimX > &s)
Scales the columns with the respective entries in s.
Point< F, dim > & operator/=(const G n)
Unscaling operator.
Introduction of a mapping type which is Real or Cmplx for dimension 1 and Mapping<Real,...
Point< F, dim > & operator*=(const G n)
Scaling operator.
Point< typename Combtype< F, H >::type, DimY > operator*(const Point< H, DimX > &p) const
Returns a mapped Point.
const concepts::Real conj(const concepts::Real &v)
Returns the conjugate complex of a real value.
Definition: operations.hh:83
Mapping(const Point< F, DimY > first, const Point< F, DimY > second, const Point< F, DimY > third)
Constructor for a 3D mapping.
Mapping< F, DimY-1, DimX-1 > subMatrix(uint i, uint j) const
Returns the submatrix where the ith and jth column are erased.
Point< F, dim > operator-(const Point< F, dim > &p) const
Subtraction operator.
concepts::Mapping< F, dim > Type
concepts::Real arg(const concepts::Point< concepts::Real, 2 > &p)
Returns the phase angle of a real 2D vector.
Point(const Point< G, dim > &p)
Copy constructor.
F data_[DimX *DimY]
entries of the matrix
Point< F, dim > operator/(const Real n) const
Unscaling operator with a real number.
Point()
Constructor.
const concepts::Real norm(const concepts::Real &v)
Returns the square of a real value.
Definition: operations.hh:90
Point< typename Combtype< F, Real >::type, dim > operator*(const Real x, const Point< F, dim > &y)
const F & operator()(uint i, uint j) const
Returns an entry of the matrix.
F operator*(const UnitNd< dim > &b) const
Point(const uchar *pgm, const Real x, const Real y, const Real z=0.0)
Constructor with a processed map.
unsigned char uchar
Abbreviation for unsigned char.
Definition: typedefs.hh:45
Mapping(const UnitNd< DimY > &n)
Constructor for rotation.
F trace() const
Returns the trace (only valid for square matrices)
#define conceptsAssert(cond, exc)
Assert that a certain condition is fulfilled.
Definition: exceptions.hh:394
F operator^(const Point< F, 2 > &b) const
Outer product (for 2D)
UnitNd(Real x, Real y, Real z)
Constructor for at most 3D.
#define MappingAppl_D
void operator()(const Point< H, dimy > &y, Point< J, dimx > &x) const
Application operator.
#define DEBUGL(doit, msg)
Mapping< F, DimY, DimY > prodTranspose() const
Returns the product with the transpose of the matrix.
Mapping< typename Combtype< G, F >::type, DimY, DimZ > operator*(const Mapping< G, DimX, DimZ > &m) const
Multiplication operator.
Point< F, dim > operator*(const Real n) const
Scaling operator with a real number.
Mapping< F, DimY, DimX > & operator+=(const Mapping< F, DimY, DimX > &M)
Addition operator.
Real l2_2() const
Returns the square of the Euclidian norm of the vector.
Mapping< F, DimX, DimY > transpose() const
Returns the transpose of the matrix.
F operator*(const Point< F, dim > &b) const
Inner product.
Exception class for assertions.
Definition: exceptions.hh:258
Point< F, dim > & operator+=(const Point< F, dim > &p)
Addition operator.
Point< F, dim > & scale(const Point< F, dim > &n)
Scaling.
Real l2() const
Returns the Euclidian norm of the vector.
Point< F, dim > & operator=(const Point< F, dim2 > &b)
Assignment operator.
Mapping(G x)
Constructor.
std::ostream & operator<<(std::ostream &os, const Level< dim > &c)
Name traits for number types.
Definition: typedefs.hh:68
std::ostream & info(std::ostream &os) const
F dot(const Point< F, dim > &b) const
Inner product, i.e. for complex arguments: this * conjugate(b)
Mapping(const Point< F, DimY > first, const Point< F, DimY > second)
Constructor for a 2D mapping.
A vector of dimension dim and length 1.
std::complex< Real > Cmplx
Type for a complex number. It also depends on the setting of Real.
Definition: typedefs.hh:39
Mapping()
Default constructor.
Mapping< F, DimY, DimX > adjugate() const
Returns the adjugate of the matrix (only valid for square matrices) [f \mbox{adj}(M) = M^{-1}\det(M) ...
Mapping< Real, 2 > MapReal2d
Point< F, 3 > operator^(const Point< F, 3 > &b) const
Outer product (for 3D)
Mapping< Real, 3 > MapReal3d
Point< F, dim > & ortho(const Point< F, dim > &a)
Change vector to the by 90 degrees (clockwise) rotated vector a (only 2D)
Point< F, dim > ortho() const
Returns a by 90 degrees (clockwise) rotated vector (only 2D)
F & operator()(uint i, uint j)
Returns an entry of the matrix (for read / write access)
Point< F, dim > operator+(const Point< F, dim > &p) const
Addition operator.
std::ostream & info(std::ostream &os) const
void mapTranspose(const Point< H, DimY > &y, Point< H, DimX > &x) const
Computes x = AT y.
Taking for a complex type the appropiate real type and for a real type itself.
Definition: typedefs.hh:100
Mapping< Cmplx, 2 > MapCmplx2d
void memorycpy(F *dest, const G *src, size_t n)
Copies n entries from src to dest (faster than std::memcpy)
Point< F, dim > & ortho()
Rotates the vector by 90 degrees (clockwise) (only 2D)
Mapping(FieldTs... data)
Constructor with variadic templates.
Point< F, dim > & operator-=(const Point< F, dim > &p)
Subtraction operator.
bool operator==(const Point< F, dim > &x, const Point< F, dim > &y)
F & operator[](const uint i)
Index operator.
void max(const Point< F, dim > &a, const Point< F, dim > &b)
Sets the vector to the elementwise maximum of a and b.
Point< F, DimY > column(const uint i) const
Returns a column of the matrix.
Mapping< Cmplx, 3 > MapCmplx3d
Point(F x)
Constructor.
const F & operator[](const uint i) const
Index operator.
Real length() const
Length of the initially given vector.
Mapping(const Mapping< H, DimY, DimX > &m)
Constructor.
Mapping(const Point< F, DimY > first)
Constructor for a 1D.
Point(const F e0, const F e1, const F e2=0)
Constructor for a 2D or a 3D Point.
void lincomb(const Point< F, dim > &a, const Point< F, dim > &b, const F ca=1.0, const F cb=1.0)
Assign the vector the linear combination of a and b.
void zeros()
Fills the matrix with zeros.
UnitNd(const Point< Real, dim > &u)
Constructor for a point.
Mapping< F, DimY, DimX > & scaleRows(const Point< F, DimY > &s)
Scales the rows with the respective entries in s.
const uint lin_(uint i, uint j) const
index in stack array of entry (i,j) of row-based matrix
double Real
Type normally used for a floating point number.
Definition: typedefs.hh:36
Mapping< typename Combtype< G, F >::type, DimY, DimX > operator*(const G n) const
Scaling operator.
void min(const Point< F, dim > &a, const Point< F, dim > &b)
Sets the vector to the elementwise minimum of a and b.
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Real linfty() const
Returns the Maximum norm of the vector.
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich