Honeycomb  0.1
Component-Model Framework
Base.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Misc/Optional.h"
8 #include "Honey/Math/Alge/Trig.h"
9 
10 namespace honey
11 {
12 
13 template<class Real> class Svd;
14 
16 template<class Subclass>
17 class MatrixBase : public matrix::priv::Traits<Subclass>::Storage
18 {
19 protected:
21 public:
22  typedef Subclass MatrixS;
23  using typename Storage::Real;
24 protected:
25  typedef typename Numeral<Real>::Real_ Real_;
26  typedef typename Real_::DoubleType Double_;
27  typedef typename Double_::Real Double;
28  typedef Alge_<Real> Alge;
30  typedef Trig_<Real> Trig;
31  typedef Svd<Real> Svd;
32  using Storage::assertSize;
33  using Storage::assertIndex;
34 
35 public:
36  using Storage::s_rows;
37  using Storage::s_cols;
38  using Storage::s_size;
39  using Storage::options;
40  using typename Storage::Alloc;
41  using Storage::subc;
42  using Storage::operator[];
43  using Storage::operator();
44  using Storage::rows;
45  using Storage::cols;
46  using Storage::size;
47 
50 
52  template<class Num>
53  MatrixS& fromArray(const Num* a, bool rowMajor = true)
54  {
55  assert(a, "Array null");
56  if (!rowMajor) return subc().fromColMajor(a);
57  for (sdt i = 0, end = size(); i < end; ++i) m(i) = (Real)a[i];
58  return subc();
59  }
60 
61  MatrixS& fromArray(const Real* a, bool rowMajor = true)
62  {
63  assert(a, "Array null");
64  if (!rowMajor) return subc().fromColMajor(a);
65  matrix::priv::storageCopy(a, subc());
66  return subc();
67  }
68 
70  MatrixS& fromZero() { matrix::priv::storageFillZero(subc()); return subc(); }
72  MatrixS& fromScalar(Real f) { matrix::priv::storageFill(subc(), f); return subc(); }
73 
75  MatrixS& fromIdentity()
76  {
77  fromZero();
78  sdt n = Alge::min(rows(), cols());
79  for (sdt i = 0; i < n; ++i) m(i,i) = 1;
80  return subc();
81  }
82 
84 
92  template<class T>
93  matrix::Builder<MatrixS> operator<<(T&& val) { return move(matrix::Builder<MatrixS>(subc()).operator,(forward<T>(val))); }
94 
96  template<class T>
98  {
99  typedef MatrixBase<T> Rhs;
100  static_assert( (s_rows == matrix::dynamic || Rhs::s_rows == matrix::dynamic || s_rows == Rhs::s_rows) &&
101  (s_cols == matrix::dynamic || Rhs::s_cols == matrix::dynamic || s_cols == Rhs::s_cols),
102  "Can only assign to matrix of the same size");
103 
104  resize(rhs.rows(), rhs.cols());
105  matrix::priv::storageCopy(rhs.subc(), subc());
106  return *this;
107  }
108 
110  template<class Matrix>
112  {
113  auto ret = Matrix().resize(rows(), cols());
114  matrix::priv::storageTransform(subc(), ret, [](Real e) { return typename Matrix::Real(e); });
115  return ret;
116  }
117 
118  template<class T>
119  bool operator==(const MatrixBase<T>& rhs) const
120  {
121  typedef MatrixBase<T> Rhs;
122  static_assert(s_size == matrix::dynamic || Rhs::s_size == matrix::dynamic || s_size == Rhs::s_size, "can't compare different sized matrices");
123  assert(size() == rhs.size(), "Can't compare different sized matrices");
124 
125  return matrix::priv::storageEqual(subc(), rhs.subc());
126  }
127 
128  template<class T>
129  bool operator!=(const MatrixBase<T>& rhs) const { return !operator==(rhs.subc()); }
130  template<class T>
131  bool operator< (const MatrixBase<T>& rhs) const { return find(subc(), rhs.subc(), [](Real e, Real rhs) { return e >= rhs; }) == end(); }
132  template<class T>
133  bool operator> (const MatrixBase<T>& rhs) const { return find(subc(), rhs.subc(), [](Real e, Real rhs) { return e <= rhs; }) == end(); }
134  template<class T>
135  bool operator<=(const MatrixBase<T>& rhs) const { return find(subc(), rhs.subc(), [](Real e, Real rhs) { return e > rhs; }) == end(); }
136  template<class T>
137  bool operator>=(const MatrixBase<T>& rhs) const { return find(subc(), rhs.subc(), [](Real e, Real rhs) { return e < rhs; }) == end(); }
138 
140  template<class T, class Res>
141  Res&& add(const T& rhs, Res&& res) const { return map(subc(), rhs.subc(), forward<Res>(res.resize(rows(),cols())), [](Real e, Real rhs) { return e + rhs; }); }
142 
143  MatrixS operator+ () const { return subc(); }
144  template<class T>
145  MatrixS operator+ (const MatrixBase<T>& rhs) const { return add(rhs.subc(), MatrixS()); }
146  template<class T>
147  MatrixS& operator+=(const MatrixBase<T>& rhs) { return add(rhs.subc(), subc()); }
148 
150  template<class T, class Res>
151  Res&& sub(const T& rhs, Res&& res) const { return map(subc(), rhs.subc(), forward<Res>(res.resize(rows(),cols())), [](Real e, Real rhs) { return e - rhs; }); }
152 
153  MatrixS operator- () const { return map(subc(), MatrixS().resize(rows(),cols()), [](Real e) { return -e; }); }
154  template<class T>
155  MatrixS operator- (const MatrixBase<T>& rhs) const { return sub(rhs.subc(), MatrixS()); }
156  template<class T>
157  MatrixS& operator-=(const MatrixBase<T>& rhs) { return sub(rhs.subc(), subc()); }
158 
160  template<class T, class Res>
161  Res&& mul(const T& rhs, Res&& res) const
162  {
163  static_assert( s_cols == matrix::dynamic || T::s_rows == matrix::dynamic ||
164  s_cols == T::s_rows, "Concatenation invalid with rhs dimensions");
165  assert(cols() == rhs.rows(), "Concatenation invalid with rhs dimensions");
166 
167  res.resize(rows(), rhs.cols()).fromZero();
168  const sdt rows = this->rows(), cols = this->cols(), cols2 = rhs.cols();
169  for (sdt i = 0; i < rows; ++i)
170  for (sdt j = 0; j < cols2; ++j)
171  for (sdt k = 0; k < cols; ++k)
172  res(i,j) += m(i,k) * rhs(k,j);
173  return forward<Res>(res);
174  }
175 
177  template<class T>
178  Matrix<s_rows, T::s_cols, Real> operator*(const T& rhs) const { return subc().mul(rhs, Matrix<s_rows, T::s_cols, Real>()); }
179  MatrixS operator* (Real rhs) const { return map(subc(), MatrixS().resize(rows(),cols()), [&](Real e) { return e * rhs; }); }
180  template<class T>
181  MatrixS& operator*=(const MatrixBase<T>& rhs) { return subc().operator=(subc().operator*(rhs.subc())); }
182  MatrixS& operator*=(Real rhs) { return map(subc(), subc(), [&](Real e) { return e * rhs; }); }
183 
184  MatrixS operator/ (Real rhs) const { return operator*(1 / rhs); }
185  MatrixS& operator/=(Real rhs) { return operator*=(1 / rhs); }
186 
187  friend MatrixS operator*(Real lhs, const MatrixBase& rhs) { return rhs.subc().operator*(lhs); }
188 
190  MatrixS elemAdd(Real rhs) const { return map(subc(), MatrixS().resize(rows(),cols()), [&](Real e) { return e + rhs; }); }
192  MatrixS& elemAddEq(Real rhs) { return map(subc(), subc(), [&](Real e) { return e + rhs; }); }
194  MatrixS elemSub(Real rhs) const { return map(subc(), MatrixS().resize(rows(),cols()), [&](Real e) { return e - rhs; }); }
196  MatrixS& elemSubEq(Real rhs) { return map(subc(), subc(), [&](Real e) { return e - rhs; }); }
198  template<class T>
199  MatrixS elemMul(const MatrixBase<T>& rhs) const { return map(subc(), rhs.subc(), MatrixS().resize(rows(),cols()), [](Real e, Real rhs) { return e * rhs; }); }
201  template<class T>
202  MatrixS& elemMulEq(const MatrixBase<T>& rhs) { return map(subc(), rhs.subc(), subc(), [](Real e, Real rhs) { return e * rhs; }); }
204  template<class T>
205  MatrixS elemDiv(const MatrixBase<T>& rhs) const { return map(subc(), rhs.subc(), MatrixS().resize(rows(),cols()), [](Real e, Real rhs) { return e / rhs; }); }
207  template<class T>
208  MatrixS& elemDivEq(const MatrixBase<T>& rhs) { return map(subc(), rhs.subc(), subc(), [](Real e, Real rhs) { return e / rhs; }); }
210  MatrixS elemAbs() const { return map(subc(), MatrixS().resize(rows(),cols()), [](Real e) { return Alge::abs(e); }); }
212  MatrixS elemSqr() const { return map(subc(), MatrixS().resize(rows(),cols()), [](Real e) { return e * e; }); }
214  MatrixS elemInverse() const { return map(subc(), MatrixS().resize(rows(),cols()), [](Real e) { return 1 / e; }); }
216  template<class T>
217  MatrixS elemMin(const MatrixBase<T>& rhs) const { return map(subc(), rhs.subc(), MatrixS().resize(rows(),cols()), [](Real e, Real rhs) { return Alge::min(e,rhs); }); }
219  template<class T>
220  MatrixS elemMax(const MatrixBase<T>& rhs) const { return map(subc(), rhs.subc(), MatrixS().resize(rows(),cols()), [](Real e, Real rhs) { return Alge::max(e,rhs); }); }
221 
223  bool isZero() const { return find(subc(), [](Real e) { return e != 0; }) == end(); }
225  bool isNearZero(Real tol = Real_::zeroTol) const { return find(subc(), [&](Real e) { return !Alge::isNearZero(e, tol); }) == end(); }
227  template<class T>
228  MatrixS clamp(const MatrixBase<T>& min, const MatrixBase<T>& max) const
229  { return map(subc(), min.subc(), max.subc(), MatrixS().resize(rows(),cols()), [](Real e, Real min, Real max) { return Alge::clamp(e, min, max); }); }
230 
232  Real sum() const { return reduce(subc(), Real(0), [](Real a, Real e) { return a + e; }); }
234  Real prod() const { return reduce(subc(), Real(1), [](Real a, Real e) { return a * e; }); }
236  Real mean() const { return sum() / size(); }
238  Real min() const { return reduce(subc(), Real_::inf, [](Real a, Real e) { return Alge::min(a,e); }); }
240  Real max() const { return reduce(subc(), -Real_::inf, [](Real a, Real e) { return Alge::max(a,e); }); }
241 
243 
250  template<sdt Rows, sdt Cols>
252  block(sdt row, sdt col, sdt rows = -1, sdt cols = -1) { return matrix::Block<MatrixS,Rows,Cols>(subc(), row, col, rows, cols); }
253 
254  template<sdt Rows, sdt Cols>
256  block(sdt row, sdt col, sdt rows = -1, sdt cols = -1) const { return matrix::Block<const MatrixS,Rows,Cols>(subc(), row, col, rows, cols); }
257 
260  block(sdt row, sdt col, sdt rows, sdt cols) { return matrix::Block<MatrixS>(subc(), row, col, rows, cols); }
261 
263  block(sdt row, sdt col, sdt rows, sdt cols) const { return matrix::Block<const MatrixS>(subc(), row, col, rows, cols); }
264 
266  matrix::Block<MatrixS,1,s_cols> row(sdt row) { return block<1,s_cols>(row, 0, 1, cols()); }
267  matrix::Block<const MatrixS,1,s_cols> row(sdt row) const { return block<1,s_cols>(row, 0, 1, cols()); }
268 
270  matrix::Block<MatrixS,s_rows,1> col(sdt col) { return block<s_rows,1>(0, col, rows(), 1); }
271  matrix::Block<const MatrixS,s_rows,1> col(sdt col) const { return block<s_rows,1>(0, col, rows(), 1); }
272 
274 
277  MatrixS& resize(sdt rows, sdt cols) { Storage::resize(rows, cols); return subc(); }
278 
282 
286 
288  matrix::Iter<MatrixS> iter(sdt i) { assertSize(i); return begin() + i; }
289  matrix::Iter<const MatrixS> iter(sdt i) const { assertSize(i); return begin() + i; }
290 
292  matrix::Iter<MatrixS> iter(sdt row, sdt col) { assertSize(row,col); return begin() + (row*cols()+col); }
293  matrix::Iter<const MatrixS> iter(sdt row, sdt col) const { assertSize(row,col); return begin() + (row*cols()+col); }
294 
296  template<class Num>
297  Num* toArray(Num* a, bool rowMajor = true) const
298  {
299  assert(a, "Array null");
300  if (!rowMajor) return subc().toColMajor(a);
301  for (sdt i = 0, end = size(); i < end; ++i) a[i] = (Num)m(i);
302  return a;
303  }
304  Real* toArray(Real* a, bool rowMajor = true) const
305  {
306  assert(a, "Array null");
307  if (!rowMajor) return subc().toColMajor(a);
308  matrix::priv::storageCopy(subc(), a);
309  return a;
310  }
311 
313  template<class Res>
314  Res&& transpose(Res&& res) const
315  {
316  res.resize(cols(), rows());
317  const sdt rows = this->rows(), cols = this->cols();
318  for (sdt i = 0; i < rows; ++i)
319  for (sdt j = 0; j < cols; ++j)
320  res(j,i) = m(i,j);
321  return forward<Res>(res);
322  }
323 
325  Matrix<s_cols,s_rows,Real> transpose() const { return subc().transpose(Matrix<s_cols,s_rows,Real>()); }
326 
329  {
330  static_assert(s_size == matrix::dynamic || s_rows == s_cols, "This matrix must be square");
331  assert(rows() == cols(), "This matrix must be square");
332 
333  const sdt rows = this->rows();
334  for (sdt i = 0; i < rows-1; ++i)
335  for (sdt j = i+1; j < rows; ++j)
336  std::swap(m(i*rows + j), m(i + rows*j));
337  }
338 
340  template<class T, class Res>
341  Res&& transposeMul(const T& rhs, Res&& res) const
342  {
343  static_assert( s_rows == matrix::dynamic || T::s_rows == matrix::dynamic ||
344  s_rows == T::s_rows, "Concatenation invalid with rhs dimensions");
345  assert(rows() == rhs.rows(), "Concatenation invalid with rhs dimensions");
346 
347  res.resize(cols(), rhs.cols()).fromZero();
348  const sdt rows = this->rows(), cols = this->cols(), cols2 = rhs.cols();
349  for (sdt i = 0; i < cols; ++i)
350  for (sdt j = 0; j < cols2; ++j)
351  for (sdt k = 0; k < rows; ++k)
352  res(i,j) += m(k,i) * rhs(k,j);
353  return forward<Res>(res);
354  }
355 
357  template<class T>
358  Matrix<s_cols, T::s_cols, Real> transposeMul(const T& rhs) const { return subc().transposeMul(rhs, Matrix<s_cols, T::s_cols, Real>()); }
359 
361  template<class T, class Res>
362  Res&& mulTranspose(const T& rhs, Res&& res) const
363  {
364  static_assert( s_cols == matrix::dynamic || T::s_cols == matrix::dynamic ||
365  s_cols == T::s_cols, "Concatenation invalid with rhs dimensions");
366  assert(cols() == rhs.cols(), "Concatenation invalid with rhs dimensions");
367 
368  res.resize(rows(), rhs.rows()).fromZero();
369  const sdt rows = this->rows(), cols = this->cols(), rows2 = rhs.rows();
370  for (sdt i = 0; i < rows; ++i)
371  for (sdt j = 0; j < rows2; ++j)
372  for (sdt k = 0; k < cols; ++k)
373  res(i,j) += m(i,k) * rhs(j,k);
374  return forward<Res>(res);
375  }
376 
378  template<class T>
379  Matrix<s_rows, T::s_rows, Real> mulTranspose(const T& rhs) const { return subc().mulTranspose(rhs, Matrix<s_rows, T::s_rows, Real>()); }
380 
382  template<class T, class Res>
383  Res&& transposeMulTranspose(const T& rhs, Res&& res) const
384  {
385  static_assert( s_rows == matrix::dynamic || T::s_cols == matrix::dynamic ||
386  s_rows == T::s_cols, "Concatenation invalid with rhs dimensions");
387  assert(rows() == rhs.cols(), "Concatenation invalid with rhs dimensions");
388 
389  res.resize(cols(), rhs.rows()).fromZero();
390  const sdt rows = this->rows(), cols = this->cols(), rows2 = rhs.rows();
391  for (sdt i = 0; i < cols; ++i)
392  for (sdt j = 0; j < rows2; ++j)
393  for (sdt k = 0; k < rows; ++k)
394  res(i,j) += m(k,i) * rhs(j,k);
395  return forward<Res>(res);
396  }
397 
399  template<class T>
400  Matrix<s_cols, T::s_rows, Real> transposeMulTranspose(const T& rhs) const { return subc().transposeMulTranspose(rhs, Matrix<s_cols, T::s_rows, Real>()); }
401 
403 
404  auto minor(sdt row, sdt col) const ->
405  Matrix< (s_rows > 0) ? s_rows-1 : s_rows,
406  (s_cols > 0) ? s_cols-1 : s_cols, Real>
407  {
408  assertIndex(row, col);
409  auto res = Matrix< (s_rows > 0) ? s_rows-1 : s_rows,
410  (s_cols > 0) ? s_cols-1 : s_cols, Real>
411  ().resize(rows()-1, cols()-1);
412  const sdt rows = this->rows()-row-1, cols = this->cols()-col-1;
413  res.block(0,0,row,col) = block(0,0,row,col); //UL
414  res.block(0,col,row,cols) = block(0,col+1,row,cols); //UR
415  res.block(row,0,rows,col) = block(row+1,0,rows,col); //LL
416  res.block(row,col,rows,cols) = block(row+1,col+1,rows,cols); //LR
417  return res;
418  }
419 
422  {
423  auto res = Matrix<s_cols, s_rows, Real>().resize(cols(), rows());
424 
425  if (rows() == cols() && rows() <= 3)
426  {
427  //Square
428  switch(rows())
429  {
430  case 1:
431  {
432  Real d = determinant();
433  if (det) det = d;
434  if (Alge::isNearZero(d))
435  {
436  if (det) det = 0;
437  return res.fromZero();
438  }
439  res(0,0) = 1 / d;
440  break;
441  }
442 
443  case 2:
444  {
445  Real d = determinant();
446  if (det) det = d;
447  if (Alge::isNearZero(d))
448  {
449  if (det) det = 0;
450  return res.fromZero();
451  }
452  res(0,0) = m(1,1);
453  res(0,1) = -m(0,1);
454  res(1,0) = -m(1,0);
455  res(1,1) = m(0,0);
456  res /= d;
457  break;
458  }
459 
460  case 3:
461  {
462  Real d = determinant3(res);
463  if (det) det = d;
464  if (Alge::isNearZero(d))
465  {
466  if (det) det = 0;
467  return res.fromZero();
468  }
469  res /= d;
470  break;
471  }
472  }
473  }
474  else
475  {
476  //Non-square or > 3x3
477  Svd svd(subc());
478  svd.inverse(res);
479  //Determinant is the product of all non-zero singular values (or 1 if all are zero)
480  if (det) det = reduce(svd.w(), Real(1), [](Real a, Real e) { return !Alge::isNearZero(e) ? a*e : a; });
481  }
482 
483  return res;
484  }
485 
488  {
489  Real res = 0;
490 
491  if (rows() == cols())
492  {
493  //Square
494  switch(rows())
495  {
496  case 1: res = m(0,0); break;
497  case 2: res = m(0,0)*m(1,1) - m(1,0)*m(0,1); break;
498  case 3: { MatrixS tmp(*this); res = determinant3(tmp); } break;
499  default:
500  {
501  for (sdt j = 0; j < cols(); j++)
502  {
503  auto minor_ = minor(0, j);
504  res += (1 - j%2 - j%2) * m(0,j) * minor_.determinant();
505  }
506  break;
507  }
508  }
509  }
510  else
511  {
512  //Non-square
513  //Determinant is the product of all non-zero singular values (or 1 if all are zero)
514  Svd svd;
515  res = reduce(svd.calcValues(subc()).w(), Real(1), [](Real a, Real e) { return !Alge::isNearZero(e) ? a*e : a; });
516  }
517  return res;
518  }
519 
521  Real cond() const
522  {
523  //Condition is a function of the non-zero singular values: max(sv) / min(sv)
524  Svd svd;
525  auto bounds = reduce(svd.calcValues(subc()).w(), make_tuple(Real_::inf, -Real_::inf),
526  [](tuple<Real,Real> a, Real e) { return !Alge::isNearZero(e) ? make_tuple(Alge::min(get<0>(a), e), Alge::max(get<1>(a), e)) : a; });
527  return get<1>(bounds) / get<0>(bounds);
528  }
529 
530  friend ostream& operator<<(ostream& os, const MatrixBase& mat)
531  {
532  //Get longest number for each column
533  vector<int> colLen;
534  auto oslen = os.tellp();
535  for (auto j : range(mat.cols()))
536  {
537  int lenMax = 0;
538  for (auto i : range(mat.rows()))
539  {
540  int len = (int)((os << mat(i,j)).tellp() - oslen);
541  os.seekp(oslen);
542  lenMax = Alge::max(lenMax, len);
543  }
544  colLen.push_back(lenMax);
545  }
546 
547  os << stringstream::indentInc << "[";
548  if (mat.cols() > 0)
549  {
550  for (auto i : range(mat.rows()))
551  {
552  if (i != 0) os << ",";
553  os << endl;
554  for (auto j : range(mat.cols()))
555  {
556  if (j != 0) os << ", ";
557  os << std::setw(colLen[j]) << mat(i,j);
558  }
559  }
560  }
561  return os << stringstream::indentDec << endl << "]";
562  }
563 
564 protected:
565 
567  const Real& m(sdt i) const { return (*this)(i); }
568  Real& m(sdt i) { return (*this)(i); }
570  const Real& m(sdt row, sdt col) const { return (*this)(row, col); }
571  Real& m(sdt row, sdt col) { return (*this)(row, col); }
572 
573  template<class Num>
574  MatrixS& fromColMajor(const Num* a)
575  {
576  const sdt rows = this->rows(), cols = this->cols();
577  for (sdt i = 0; i < rows; ++i)
578  for (sdt j = 0; j < cols; ++j)
579  m(i*cols+j) = (Real)a[j*rows+i];
580  return subc();
581  }
582 
583  template<class Num>
584  Num* toColMajor(Num* a) const
585  {
586  const sdt rows = this->rows(), cols = this->cols();
587  for (sdt i = 0; i < rows; ++i)
588  for (sdt j = 0; j < cols; ++j)
589  a[j*rows+i] = (Num)m(i*cols+j);
590  return a;
591  }
592 
593 private:
594 
596  template<class T>
597  Real determinant3(MatrixBase<T>& tmp) const
598  {
599  tmp(0,0) = m(1,1)*m(2,2)-m(1,2)*m(2,1);
600  tmp(0,1) = m(0,2)*m(2,1)-m(0,1)*m(2,2);
601  tmp(0,2) = m(0,1)*m(1,2)-m(0,2)*m(1,1);
602  tmp(1,0) = m(1,2)*m(2,0)-m(1,0)*m(2,2);
603  tmp(1,1) = m(0,0)*m(2,2)-m(0,2)*m(2,0);
604  tmp(1,2) = m(0,2)*m(1,0)-m(0,0)*m(1,2);
605  tmp(2,0) = m(1,0)*m(2,1)-m(1,1)*m(2,0);
606  tmp(2,1) = m(0,1)*m(2,0)-m(0,0)*m(2,1);
607  tmp(2,2) = m(0,0)*m(1,1)-m(0,1)*m(1,0);
608  return m(0,0)*tmp(0,0) + m(0,1)*tmp(1,0) + m(0,2)*tmp(2,0);
609  }
610 };
611 
612 }
613 
MatrixS & fromScalar(Real f)
Initialize with scalar in every element.
Definition: Base.h:72
(m x n)-dimensional matrix
Definition: Matrix.h:24
Real determinant() const
Get the determinant. Returns the pseudo-determinant if this matrix is not square. ...
Definition: Base.h:487
static const sdt dynamic
Definition: Traits.h:23
void storageFillZero(StorageBlock< T > &store)
Fill block storage with zeros.
Definition: Block.h:136
bool isZero() const
Check if each element is exactly zero.
Definition: Base.h:223
Real_::DoubleType Double_
Definition: Base.h:26
Algebra.
Definition: Alge.h:13
matrix::Iter< const MatrixS > iter(sdt row, sdt col) const
Definition: Base.h:293
bool operator>=(const MatrixBase< T > &rhs) const
Definition: Base.h:137
matrix::Block< MatrixS > block(sdt row, sdt col, sdt rows, sdt cols)
Get dynamic block at offset (row,col) with size (rows, cols)
Definition: Base.h:260
Matrix comma initializer.
Definition: Builder.h:11
Subclass MatrixS
Definition: Base.h:22
Matrix< s_cols, T::s_cols, Real > transposeMul(const T &rhs) const
Returns new matrix.
Definition: Base.h:358
MatrixS & fromColMajor(const Num *a)
Definition: Base.h:574
bool operator==(const MatrixBase< T > &rhs) const
Definition: Base.h:119
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
const Real & m(sdt i) const
Access matrix element at index. Wrapper for convenience only, more readable than (*this)(i) ...
Definition: Base.h:567
bool operator!=(const MatrixBase< T > &rhs) const
Definition: Base.h:129
const Real & m(sdt row, sdt col) const
Access matrix element with (row, column)
Definition: Base.h:570
matrix::Block< const MatrixS > block(sdt row, sdt col, sdt rows, sdt cols) const
Definition: Base.h:263
Matrix< s_cols, T::s_rows, Real > transposeMulTranspose(const T &rhs) const
Returns new matrix.
Definition: Base.h:400
matrix::Block< MatrixS, Rows, Cols > block(sdt row, sdt col, sdt rows=-1, sdt cols=-1)
Get block at offset (row,col) with size (Rows, Cols). If Rows or Cols is fixed then rows or cols may ...
Definition: Base.h:252
matrix::Block< const MatrixS, s_rows, 1 > col(sdt col) const
Definition: Base.h:271
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
MatrixS elemSub(Real rhs) const
Subtract rhs from each element. Returns a new matrix with the results.
Definition: Base.h:194
matrix::Iter< MatrixS > iter(sdt i)
Get an iterator to the element at index.
Definition: Base.h:288
Numeral< Real >::Real_ Real_
Definition: Base.h:25
MatrixS & operator+=(const MatrixBase< T > &rhs)
Definition: Base.h:147
Iter find(Range &&, Seqs &&..., Func &&pred)
Find an element in a series of sequences.
bool storageEqual(const StorageBlock< T > &lhs, const StorageBlock< T2 > &rhs)
Test between block storages.
Definition: Block.h:157
MatrixS elemMin(const MatrixBase< T > &rhs) const
Get the min of each element and its corresponding element in rhs. Returns a new matrix with the resul...
Definition: Base.h:217
bool isNearZero(Real tol=Real_::zeroTol) const
Check if each element is close to zero.
Definition: Base.h:225
Res && transposeMul(const T &rhs, Res &&res) const
Stores result in and returns res.
Definition: Base.h:341
matrix::Block< MatrixS, s_rows, 1 > col(sdt col)
Get column as a column vector.
Definition: Base.h:270
Real prod() const
Get the product of all elements.
Definition: Base.h:234
MatrixS operator-() const
Definition: Base.h:153
matrix::Block< MatrixS, 1, s_cols > row(sdt row)
Get row as a row vector.
Definition: Base.h:266
matrix::Block< const MatrixS, Rows, Cols > block(sdt row, sdt col, sdt rows=-1, sdt cols=-1) const
Definition: Base.h:256
Accum reduce(Range &&, Seqs &&..., Accum &&initVal, Func &&)
Accumulate a series of sequences into an output.
Matrix< s_cols, s_rows, Real > transpose() const
Returns new matrix.
Definition: Base.h:325
Double_::Real Double
Definition: Base.h:27
matrix::Iter< MatrixS > iter(sdt row, sdt col)
Get an iterator to the element at (row, col)
Definition: Base.h:292
std::enable_if< mt::isIterator< Iter1 >::value, Range_< Iter1, Iter2 > >::type range(Iter1 &&first, Iter2 &&last)
Range from iterators [first, last)
Definition: Range.h:116
MatrixS & fromIdentity()
Make matrix identity. For non-square matrices the identity is in the upper-left square block...
Definition: Base.h:75
Alge_< Real > Alge
Definition: Base.h:28
Matrix block view.
Definition: Block.h:188
Res && transposeMulTranspose(const T &rhs, Res &&res) const
Stores result in and returns res.
Definition: Base.h:383
static std::common_type< Num, Num2 >::type max(Num a, Num2 b)
Get the maximum of two numbers.
Definition: Alge.h:94
MatrixS & fromArray(const Real *a, bool rowMajor=true)
Definition: Base.h:61
MatrixS & elemDivEq(const MatrixBase< T > &rhs)
Divide each element by its corresponding element in rhs.
Definition: Base.h:208
matrix::Iter< const MatrixS > begin() const
Definition: Base.h:281
Real * toArray(Real *a, bool rowMajor=true) const
Definition: Base.h:304
Real & m(sdt row, sdt col)
Definition: Base.h:571
Res && mul(const T &rhs, Res &&res) const
Multiply with another matrix. This mat's column size must match rhs' row size. Stores result in and r...
Definition: Base.h:161
MatrixS elemMul(const MatrixBase< T > &rhs) const
Multiply each element with its corresponding element in rhs. Returns a new matrix with the results...
Definition: Base.h:199
static Int abs(Int x)
Get absolute value of signed integer.
Definition: Alge.h:21
Matrix element iterator.
Definition: Iter.h:9
static std::common_type< Num, Num2 >::type min(Num a, Num2 b)
Get the minimum of two numbers.
Definition: Alge.h:89
Matrix cast()
Convert to a matrix of another real type.
Definition: Base.h:111
MatrixS operator/(Real rhs) const
Definition: Base.h:184
static std::common_type< Num, Num2, Num3 >::type clamp(Num val, Num2 min, Num3 max)
Ensure that a number is within a range.
Definition: Alge.h:99
MatrixS operator+() const
Definition: Base.h:143
void storageTransform(const StorageBlock< Src > &src, StorageBlock< Dst > &dst, Func &&f)
Transform between block and dense storages.
Definition: Block.h:120
ostream & indentInc(ostream &os)
Increase stream indent level by 1.
Definition: Stream.h:32
matrix::Iter< MatrixS > begin()
Get an iterator over the elements in row-major order.
Definition: Base.h:280
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
Alge_< Double > Alge_d
Definition: Base.h:29
Num * toColMajor(Num *a) const
Definition: Base.h:584
N-dimensional vector.
Definition: Traits.h:12
ostream & indentDec(ostream &os)
Decrease stream indent level by 1.
Definition: Stream.h:34
Definition: Traits.h:20
Real mean() const
Get the mean of all elements.
Definition: Base.h:236
Singular Value Decomposition. Can be used to calculate the pseudo-inverse of any matrix or solve leas...
Definition: Base.h:13
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
Numeric type information, use numeral() to get instance safely from a static context.
Definition: Numeral.h:17
MatrixS & resize(sdt rows, sdt cols)
Sets number of rows/columns and reallocates only if the size has changed (rows*cols). All previous data is lost on reallocation. Returns self.
Definition: Base.h:277
Enables any type to be optional so it can exist in an uninitialized null state.
Definition: Optional.h:52
static bool isNearZero(Real val, Real tol=Real_::zeroTol)
Check whether a number is close to zero.
Definition: Alge.h:108
Res && add(const T &rhs, Res &&res) const
Add another matrix. Stores result in and returns res. res may reference the same matrix as this or rh...
Definition: Base.h:141
MatrixS & fromZero()
Zero all elements.
Definition: Base.h:70
Real cond() const
Get the condition value. A high value means the matrix is ill-conditioned and close to singular...
Definition: Base.h:521
Matrix< s_rows, T::s_rows, Real > mulTranspose(const T &rhs) const
Returns new matrix.
Definition: Base.h:379
matrix::Iter< const MatrixS > end() const
Definition: Base.h:285
friend MatrixS operator*(Real lhs, const MatrixBase &rhs)
Definition: Base.h:187
double Real
Definition: Real.h:14
void storageFill(StorageBlock< T > &store, typename StorageBlock< T >::Real f)
Fill block storage with scalar.
Definition: Block.h:128
MatrixS & operator*=(const MatrixBase< T > &rhs)
Definition: Base.h:181
Real & m(sdt i)
Definition: Base.h:568
MatrixS & elemAddEq(Real rhs)
Add rhs to each element.
Definition: Base.h:192
MatrixS elemAbs() const
Get the absolute value of each element. Returns a new matrix with the results.
Definition: Base.h:210
Matrix< s_rows, T::s_cols, Real > operator*(const T &rhs) const
Multiply with another matrix. Returns a new matrix.
Definition: Base.h:178
int size(const StdContainer &cont)
Safely get the size of a std container as a signed integer.
Definition: StdUtil.h:19
#define swap(a, i, j)
MatrixBase & operator=(const MatrixBase< T > &rhs)
Assign to matrix of any size. Asserts that any fixed dimensions in this matrix match those in rhs...
Definition: Base.h:97
MatrixS clamp(const MatrixBase< T > &min, const MatrixBase< T > &max) const
Clamp each element between its corresponding elements in min and max. Returns a new matrix with the r...
Definition: Base.h:228
MatrixS & elemMulEq(const MatrixBase< T > &rhs)
Multiply each element with its corresponding element in rhs.
Definition: Base.h:202
MatrixS & operator/=(Real rhs)
Definition: Base.h:185
MatrixS elemMax(const MatrixBase< T > &rhs) const
Get the max of each element and its corresponding element in rhs. Returns a new matrix with the resul...
Definition: Base.h:220
MatrixS & elemSubEq(Real rhs)
Subtract rhs from each element.
Definition: Base.h:196
Real max() const
Get the maximum element.
Definition: Base.h:240
Matrix< s_cols, s_rows, Real > inverse(optional< Real & > det=optnull) const
Get the pseudo-inverse of this matrix. The pseudo-determinant will be returned in det if specified...
Definition: Base.h:421
MatrixS elemAdd(Real rhs) const
Add rhs to each element. Returns a new matrix with the results.
Definition: Base.h:190
matrix::Builder< MatrixS > operator<<(T &&val)
Initialize matrix elements from scalars and other matrices using the comma operator: Matrix() << 1...
Definition: Base.h:93
auto minor(sdt row, sdt col) const -> Matrix< (s_rows > 0)?s_rows-1:s_rows, (s_cols > 0)?s_cols-1:s_cols, Real >
Returns a matrix without the selected row and column.
Definition: Base.h:404
MatrixS elemSqr() const
Square each element. Returns a new matrix with the results.
Definition: Base.h:212
MatrixS elemInverse() const
Inverse each element. Returns a new matrix with the results.
Definition: Base.h:214
Vec< s_rows, Real > VecCol
Definition: Base.h:48
matrix::Block< const MatrixS, 1, s_cols > row(sdt row) const
Definition: Base.h:267
friend ostream & operator<<(ostream &os, const MatrixBase &mat)
Definition: Base.h:530
matrix::priv::Traits< Subclass >::Storage Storage
Definition: Base.h:20
void storageCopy(const StorageBlock< Src > &src, StorageBlock< Dst > &dst)
Copy between block and dense storages.
Definition: Block.h:84
MatrixS elemDiv(const MatrixBase< T > &rhs) const
Divide each element by its corresponding element in rhs. Returns a new matrix with the results...
Definition: Base.h:205
Real sum() const
Get the sum of all elements.
Definition: Base.h:232
Res && sub(const T &rhs, Res &&res) const
Subtract another matrix. Stores result in and returns res. res may reference the same matrix as this ...
Definition: Base.h:151
Matrix base class.
Definition: Base.h:17
void transposeInPlace()
transpose and store in this matrix, only valid for square matrices
Definition: Base.h:328
Real min() const
Get the minimum element.
Definition: Base.h:238
MatrixS & operator*=(Real rhs)
Definition: Base.h:182
MatrixS & operator-=(const MatrixBase< T > &rhs)
Definition: Base.h:157
MatrixS & fromArray(const Num *a, bool rowMajor=true)
Initialize from array. If the array is in row-major format set rowMajor to true, otherwise set to fal...
Definition: Base.h:53
bool operator>(const MatrixBase< T > &rhs) const
Definition: Base.h:133
ostream & endl(ostream &os)
End line and apply any indentation to the next line.
Definition: Stream.h:40
Global Honeycomb namespace.
Vec< s_cols, Real, matrix::Option::vecRow > VecRow
Definition: Base.h:49
Trig_< Real > Trig
Definition: Base.h:30
matrix::Iter< MatrixS > end()
Get an iterator to the end of the iteration provided by begin()
Definition: Base.h:284
Res && transpose(Res &&res) const
transpose and store result in res. Returns res.
Definition: Base.h:314
Num * toArray(Num *a, bool rowMajor=true) const
Copy matrix into array. If the array is in row-major format set rowMajor to true, otherwise set to fa...
Definition: Base.h:297
Trigonometry.
Definition: Trig.h:52
Res && mulTranspose(const T &rhs, Res &&res) const
Stores result in and returns res.
Definition: Base.h:362
matrix::Iter< const MatrixS > iter(sdt i) const
Definition: Base.h:289
OutSeq && map(Range &&, Seqs &&..., OutSeq &&, Func &&)
Transform a series of sequences into an output.