Honeycomb  0.1
Component-Model Framework
Block.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 
5 
6 namespace honey
7 {
8 
9 namespace matrix
10 {
11 
12 namespace priv
13 {
15  template<class Subclass>
16  class StorageBlock : public StorageDense<Subclass>
17  {
19  public:
20  using Super::s_rows;
21  using Super::s_cols;
22  using typename Super::ElemT;
24 
25  ElemT* operator[](sdt row) const { this->assertIndex(row,0); return &parent()(_row + row, _col); }
26  ElemT& operator()(sdt i) const { this->assertIndex(i); return parent()(_row + i / _cols, _col + i % _cols); }
27  ElemT& operator()(sdt row, sdt col) const { this->assertIndex(row,col); return parent()(_row + row, _col + col); }
28 
30  ElemT* data() const { return &parent()(row(),col()); }
31 
33  MatrixP& parent() const { return *_m; }
35  sdt row() const { return _row; }
37  sdt col() const { return _col; }
39  sdt rows() const { return _rows; }
41  sdt cols() const { return _cols; }
43  sdt size() const { return _size; }
44 
45  protected:
46  void initBlock(MatrixP& m, sdt row, sdt col, sdt rows, sdt cols)
47  {
48  _m = &m;
49  _row = row;
50  _col = col;
51  _rows = s_rows == dynamic ? rows : s_rows;
52  _cols = s_cols == dynamic ? cols : s_cols;
53  _size = _rows*_cols;
54 
55  assert(_rows >= 0 && _cols >= 0, "Block size must be zero or greater");
56  assert(_row >= 0 && _row + _rows <= _m->rows(), sout()
57  << "Block row bounds out of matrix range. Matrix rows: " << _m->rows()
58  << " ; Block range: [" << _row << ", " << _row + _rows << ")");
59  assert(_col >= 0 && _col + _cols <= _m->cols(), sout()
60  << "Block column bounds out of matrix range. Matrix columns: " << _m->cols()
61  << " ; Block range: [" << _col << ", " << _col + _cols << ")");
62  }
63 
64  private:
65  MatrixP* _m;
66  sdt _row;
67  sdt _col;
68  sdt _rows;
69  sdt _cols;
70  sdt _size;
71  };
72 
74  template<class Src, class Dst>
76  {
77  if (!src.size()) return;
78  for (sdt i = 0; i < src.rows(); ++i)
79  std::copy_n(&src(i, 0), src.cols(), &dst(i, 0));
80  }
81 
83  template<class Src, class Dst>
84  void storageCopy(const StorageBlock<Src>& src, StorageBlock<Dst>& dst) { storageRowCopy(src, dst); }
85  template<class Src, class Dst>
86  void storageCopy(const StorageBlock<Src>& src, StorageDense<Dst>& dst) { storageRowCopy(src, dst); }
87  template<class Src, class Dst>
88  void storageCopy(const StorageDense<Src>& src, StorageBlock<Dst>& dst) { storageRowCopy(src, dst); }
89 
91  template<class Dst>
92  void storageCopy(const typename StorageBlock<Dst>::Real* src, StorageBlock<Dst>& dst)
93  {
94  if (!dst.size()) return;
95  for (sdt i = 0; i < dst.rows(); ++i)
96  std::copy_n(src + i*dst.cols(), dst.cols(), &dst(i, 0));
97  }
98  template<class Src>
99  void storageCopy(const StorageBlock<Src>& src, typename StorageBlock<Src>::Real* dst)
100  {
101  if (!src.size()) return;
102  for (sdt i = 0; i < src.rows(); ++i)
103  std::copy_n(&src(i, 0), src.cols(), dst + i*src.cols());
104  }
105 
107  template<class Src, class Dst, class Func>
108  void storageRowTransform(const StorageDense<Src>& src, StorageDense<Dst>& dst, const Func& f)
109  {
110  if (!src.size()) return;
111  for (sdt i = 0; i < src.rows(); ++i)
112  {
113  auto srcRow = &src(i, 0);
114  std::transform(srcRow, srcRow + src.cols(), &dst(i, 0), f);
115  }
116  }
117 
119  template<class Src, class Dst, class Func>
120  void storageTransform(const StorageBlock<Src>& src, StorageBlock<Dst>& dst, Func&& f) { storageRowTransform(src, dst, f); }
121  template<class Src, class Dst, class Func>
122  void storageTransform(const StorageBlock<Src>& src, StorageDense<Dst>& dst, Func&& f) { storageRowTransform(src, dst, f); }
123  template<class Src, class Dst, class Func>
124  void storageTransform(const StorageDense<Src>& src, StorageBlock<Dst>& dst, Func&& f) { storageRowTransform(src, dst, f); }
125 
127  template<class T>
129  {
130  if (!store.size()) return;
131  for (sdt i = 0; i < store.rows(); ++i)
132  std::fill_n(&store(i, 0), store.cols(), f);
133  }
135  template<class T>
137  {
138  if (!store.size()) return;
139  for (sdt i = 0; i < store.rows(); ++i)
140  std::fill_n(reinterpret_cast<uint8*>(&store(i, 0)), store.cols()*sizeof(typename StorageBlock<T>::Real), uint8(0));
141  }
142 
144  template<class T, class T2>
145  bool storageRowEqual(const StorageDense<T>& lhs, const StorageDense<T2>& rhs)
146  {
147  static_assert((std::is_same<typename StorageDense<T>::Real, typename StorageDense<T2>::Real>::value), "Comparing different element types not supported");
148  if (!lhs.size()) return true;
149  for (sdt i = 0; i < lhs.rows(); ++i)
150  if (memcmp(&lhs(i,0), &rhs(i,0), lhs.cols()*sizeof(typename StorageDense<T>::Real)) != 0)
151  return false;
152  return true;
153  }
154 
156  template<class T, class T2>
157  bool storageEqual(const StorageBlock<T>& lhs, const StorageBlock<T2>& rhs) { return storageRowEqual(lhs, rhs); }
159  template<class T, class T2>
160  bool storageEqual(const StorageBlock<T>& lhs, const StorageDense<T2>& rhs) { return storageRowEqual(lhs, rhs); }
161  template<class T, class T2>
162  bool storageEqual(const StorageDense<T>& lhs, const StorageBlock<T2>& rhs) { return storageRowEqual(lhs, rhs); }
163 
164 
165  template<class MatrixP_, sdt Rows, sdt Cols>
166  struct BlockTraits
167  {
171  typedef MatrixP_ MatrixP;
172  typedef typename MatrixP::Real Real;
174  typedef typename std::conditional<std::is_const<MatrixP>::value, const typename MatrixP::ElemT, typename MatrixP::ElemT>::type
176  static const sdt rows = Rows;
177  static const sdt cols = Cols;
178  static const int options = MatrixP::options;
179  typedef typename MatrixP::Alloc Alloc;
180  };
181 
182  template<class MatrixP, sdt Rows, sdt Cols>
183  struct Traits<Block<MatrixP,Rows,Cols>> : BlockTraits<MatrixP,Rows,Cols> {};
184 }
185 
187 template<class MatrixP, sdt s_rows, sdt s_cols>
188 class Block : public priv::Traits<Block<MatrixP,s_rows,s_cols>>::Base
189 {
190  typedef typename priv::Traits<Block<MatrixP,s_rows,s_cols>>::Base Super;
191 public:
193 
194  Block() {}
195  Block(MatrixP& m, sdt row, sdt col, sdt rows = -1, sdt cols = -1)
196  { this->initBlock(m, row, col, rows, cols); }
197 
199  template<class T>
200  Block& operator=(const MatrixBase<T>& rhs) { Super::operator=(rhs.subc()); return *this; }
201 
203  MatrixEval eval() const { return MatrixEval(*this); }
205  operator MatrixEval() const { return eval(); }
206 };
207 
208 } //namespace matrix
209 
210 namespace vec { namespace priv
211 {
213  template<class Vec, sdt Dim>
214  struct Segment
215  {
217  typedef matrix::Block<Vec, Traits::cols == 1 ? Dim : 1,
218  Traits::cols == 1 ? 1 : Dim> type;
219 
220  static type create(Vec& v, sdt i, sdt dim = -1) { return Traits::cols == 1 ? type(v,i,0,dim,1) : type(v,0,i,1,dim); }
221  };
222 } }
223 
224 }
(m x n)-dimensional matrix
Definition: Matrix.h:24
static const sdt dynamic
Definition: Traits.h:23
Block()
Definition: Block.h:194
void storageFillZero(StorageBlock< T > &store)
Fill block storage with zeros.
Definition: Block.h:136
std::conditional< std::is_const< MatrixP >::value, const typename MatrixP::ElemT, typename MatrixP::ElemT >::type ElemT
Our element access is const if matrix is const.
Definition: Block.h:175
Traits< Subclass >::Real Real
Definition: Storage.h:12
MatrixP::Real Real
Definition: Block.h:172
static const sdt s_cols
Definition: Storage.h:16
static type create(Vec &v, sdt i, sdt dim=-1)
Definition: Block.h:220
Traits< Subclass >::ElemT ElemT
Definition: Storage.h:14
sdt size() const
Get size.
Definition: Block.h:43
Vector segment view.
Definition: Block.h:214
sdt size() const
Definition: Storage.h:36
Block(MatrixP &m, sdt row, sdt col, sdt rows=-1, sdt cols=-1)
Definition: Block.h:195
bool storageRowEqual(const StorageDense< T > &lhs, const StorageDense< T2 > &rhs)
Test by row between dense storages.
Definition: Block.h:145
ptrdiff_t sdt
Size difference type, shorthand for ptrdiff_t.
Definition: Core.h:92
Definition: Block.h:166
bool storageEqual(const StorageBlock< T > &lhs, const StorageBlock< T2 > &rhs)
Test between block storages.
Definition: Block.h:157
sdt rows() const
Get row size.
Definition: Block.h:39
static const sdt s_rows
Definition: Storage.h:15
matrix::Block< Vec, Traits::cols==1?Dim:1, Traits::cols==1?1:Dim > type
Definition: Block.h:218
Block wrapper around any constant matrix with auto / dynamic dense storage type. Fully recursive...
Definition: Block.h:16
void initBlock(MatrixP &m, sdt row, sdt col, sdt rows, sdt cols)
Definition: Block.h:46
Matrix block view.
Definition: Block.h:188
ElemT & operator()(sdt row, sdt col) const
Definition: Block.h:27
static const sdt cols
Definition: Block.h:177
ElemT * data() const
Get as array. Top-left corner of block sub-section is at index 0.
Definition: Block.h:30
ElemT * operator[](sdt row) const
Definition: Block.h:25
static const sdt rows
Definition: Block.h:176
unsigned char uint8
Definition: Core.h:12
void assertIndex(sdt i) const
Definition: Storage.h:50
MatrixP::Alloc Alloc
Definition: Block.h:179
ostringstream sout()
Shorthand to create ostringstream.
Definition: Stream.h:15
Definition: Storage.h:10
void storageTransform(const StorageBlock< Src > &src, StorageBlock< Dst > &dst, Func &&f)
Transform between block and dense storages.
Definition: Block.h:120
#define assert(...)
Forwards to assert_#args. See assert_1(), assert_2().
Definition: Debug.h:24
N-dimensional vector.
Definition: Traits.h:12
static const sdt cols
Definition: Vec.h:21
Definition: Traits.h:20
Matrix< s_rows, s_cols, typename Super::Real, Super::options, typename Super::Alloc > MatrixEval
Definition: Block.h:192
float Real
Real number type. See Real_ for real number operations and constants.
Definition: Real.h:21
void storageRowTransform(const StorageDense< Src > &src, StorageDense< Dst > &dst, const Func &f)
Tranform by row between dense storages.
Definition: Block.h:108
sdt col() const
Get column offset.
Definition: Block.h:37
Traits< Subclass >::MatrixP MatrixP
Definition: Block.h:23
MatrixP & parent() const
Get parent matrix that contains this sub-block.
Definition: Block.h:33
void storageFill(StorageBlock< T > &store, typename StorageBlock< T >::Real f)
Fill block storage with scalar.
Definition: Block.h:128
sdt cols() const
Definition: Storage.h:35
MatrixBase< Subclass > Base
Definition: Block.h:169
Block< MatrixP_, Rows, Cols > Subclass
Definition: Block.h:168
sdt rows() const
Definition: Storage.h:34
void storageRowCopy(const StorageDense< Src > &src, StorageDense< Dst > &dst)
Copy by row between dense storages.
Definition: Block.h:75
MatrixP_ MatrixP
Definition: Block.h:171
static const int options
Definition: Block.h:178
sdt row() const
Get row offset.
Definition: Block.h:35
matrix::priv::Traits< typename std::remove_const< Vec >::type > Traits
Definition: Block.h:216
void storageCopy(const StorageBlock< Src > &src, StorageBlock< Dst > &dst)
Copy between block and dense storages.
Definition: Block.h:84
Block & operator=(const MatrixBase< T > &rhs)
Assign to matrix.
Definition: Block.h:200
Matrix base class.
Definition: Base.h:17
sdt cols() const
Get column size.
Definition: Block.h:41
ElemT & operator()(sdt i) const
Definition: Block.h:26
Global Honeycomb namespace.
StorageBlock< Subclass > Storage
Definition: Block.h:170
MatrixEval eval() const
Convert to matrix.
Definition: Block.h:203