35#include <boost/core/ignore_unused.hpp>
43template <
typename DataType,
typename InnerMatrixType>
46 :
BaseType(0, 0, type), m_data(), m_rowSizes(), m_columnSizes(),
47 m_storageSize(), m_numberOfBlockRows(0), m_numberOfBlockColumns(0)
51template <
typename DataType,
typename InnerMatrixType>
53 unsigned int numberOfBlockRows,
unsigned int numberOfBlockColumns,
54 unsigned int rowsPerBlock,
unsigned int columnsPerBlock,
MatrixStorage type)
55 :
BaseType(numberOfBlockRows * rowsPerBlock,
56 numberOfBlockColumns * columnsPerBlock, type),
57 m_data(), m_rowSizes(numberOfBlockRows),
58 m_columnSizes(numberOfBlockColumns), m_storageSize(0),
59 m_numberOfBlockRows(numberOfBlockRows),
60 m_numberOfBlockColumns(numberOfBlockColumns)
62 m_storageSize = GetRequiredStorageSize();
64 m_storageSize, std::shared_ptr<InnerType>());
65 for (
unsigned int i = 1; i <= numberOfBlockRows; ++i)
67 m_rowSizes[i - 1] = i * rowsPerBlock - 1;
70 for (
unsigned int i = 1; i <= numberOfBlockColumns; ++i)
72 m_columnSizes[i - 1] = i * columnsPerBlock - 1;
76template <
typename DataType,
typename InnerMatrixType>
78 unsigned int numberOfBlockRows,
unsigned int numberOfBlockColumns,
79 const unsigned int *rowsPerBlock,
const unsigned int *columnsPerBlock,
82 std::accumulate(rowsPerBlock, rowsPerBlock + numberOfBlockRows, 0),
83 std::accumulate(columnsPerBlock,
84 columnsPerBlock + numberOfBlockColumns, 0),
86 m_data(), m_rowSizes(numberOfBlockRows),
87 m_columnSizes(numberOfBlockColumns), m_storageSize(0),
88 m_numberOfBlockRows(numberOfBlockRows),
89 m_numberOfBlockColumns(numberOfBlockColumns)
91 m_storageSize = GetRequiredStorageSize();
93 m_storageSize, std::shared_ptr<InnerType>());
94 Initialize(rowsPerBlock, columnsPerBlock);
97template <
typename DataType,
typename InnerMatrixType>
99 unsigned int numberOfBlockRows,
unsigned int numberOfBlockColumns,
102 :
BaseType(std::accumulate(rowsPerBlock.data(),
103 rowsPerBlock.data() + numberOfBlockRows, 0),
104 std::accumulate(columnsPerBlock.data(),
105 columnsPerBlock.data() + numberOfBlockColumns,
108 m_data(), m_rowSizes(numberOfBlockRows),
109 m_columnSizes(numberOfBlockColumns), m_storageSize(0),
110 m_numberOfBlockRows(numberOfBlockRows),
111 m_numberOfBlockColumns(numberOfBlockColumns)
113 m_storageSize = GetRequiredStorageSize();
115 m_storageSize, std::shared_ptr<InnerType>());
116 Initialize(rowsPerBlock.data(), columnsPerBlock.data());
119template <
typename DataType,
typename InnerMatrixType>
124 std::accumulate(rowsPerBlock.begin(), rowsPerBlock.end(), 0),
125 std::accumulate(columnsPerBlock.begin(), columnsPerBlock.end(), 0),
127 m_data(), m_rowSizes(rowsPerBlock.size()),
128 m_columnSizes(columnsPerBlock.size()), m_storageSize(0),
129 m_numberOfBlockRows(rowsPerBlock.size()),
130 m_numberOfBlockColumns(columnsPerBlock.size())
132 m_storageSize = GetRequiredStorageSize();
134 m_storageSize, std::shared_ptr<InnerType>());
135 Initialize(rowsPerBlock.data(), columnsPerBlock.data());
138template <
typename DataType,
typename InnerMatrixType>
141 : BaseType(rhs), m_data(rhs.m_data.size()), m_rowSizes(rhs.m_rowSizes),
142 m_columnSizes(rhs.m_columnSizes), m_storageSize(rhs.m_storageSize),
143 m_numberOfBlockRows(rhs.m_numberOfBlockRows),
144 m_numberOfBlockColumns(rhs.m_numberOfBlockColumns)
146 for (
unsigned int i = 0; i < rhs.m_data.size(); ++i)
148 m_data[i] = InnerType::CreateWrapper(rhs.m_data[i]);
152template <
typename DataType,
typename InnerMatrixType>
153unsigned int NekMatrix<NekMatrix<DataType, InnerMatrixType>,
154 BlockMatrixTag>::GetRequiredStorageSize()
const
156 return BaseType::GetRequiredStorageSize(this->GetStorageType(),
157 this->GetNumberOfBlockRows(),
158 this->GetNumberOfBlockColumns());
161template <
typename DataType,
typename InnerMatrixType>
163 BlockMatrixTag>::CalculateBlockIndex(
unsigned int row,
167 return BaseType::CalculateIndex(this->GetStorageType(), row, column,
168 m_numberOfBlockRows, m_numberOfBlockColumns,
169 this->GetTransposeFlag());
172template <
typename DataType,
typename InnerMatrixType>
174 BlockMatrixTag>::InnerType *
176 unsigned int row,
unsigned int column)
const
179 this->GetTransposeFlag() ==
'N' ? row < m_numberOfBlockRows
180 : row < m_numberOfBlockColumns,
181 std::string(
"Row ") + std::to_string(row) +
182 std::string(
" requested in a block matrix with a maximum of ") +
183 std::to_string(m_numberOfBlockRows) + std::string(
" rows"));
185 this->GetTransposeFlag() ==
'N' ? column < m_numberOfBlockColumns
186 : column < m_numberOfBlockColumns,
187 std::string(
"Column ") + std::to_string(column) +
188 std::string(
" requested in a block matrix with a maximum of ") +
189 std::to_string(m_numberOfBlockColumns) + std::string(
" columns"));
190 int x = CalculateBlockIndex(row, column);
197 return m_data[x].get();
201template <
typename DataType,
typename InnerMatrixType>
202std::shared_ptr<const typename NekMatrix<NekMatrix<DataType, InnerMatrixType>,
203 BlockMatrixTag>::InnerType>
205 unsigned int row,
unsigned int column)
const
208 this->GetTransposeFlag() ==
'N' ? row < m_numberOfBlockRows
209 : row < m_numberOfBlockColumns,
210 std::string(
"Row ") + std::to_string(row) +
211 std::string(
" requested in a block matrix with a maximum of ") +
212 std::to_string(m_numberOfBlockRows) + std::string(
" rows"));
214 this->GetTransposeFlag() ==
'N' ? column < m_numberOfBlockColumns
215 : column < m_numberOfBlockRows,
216 std::string(
"Column ") + std::to_string(column) +
217 std::string(
" requested in a block matrix with a maximum of ") +
218 std::to_string(m_numberOfBlockColumns) + std::string(
" columns"));
219 int x = CalculateBlockIndex(row, column);
222 return std::shared_ptr<const InnerType>();
230template <
typename DataType,
typename InnerMatrixType>
231std::shared_ptr<typename NekMatrix<NekMatrix<DataType, InnerMatrixType>,
232 BlockMatrixTag>::InnerType>
234 unsigned int row,
unsigned int column)
237 this->GetTransposeFlag() ==
'N' ? row < m_numberOfBlockRows
238 : row < m_numberOfBlockColumns,
239 std::string(
"Row ") + std::to_string(row) +
240 std::string(
" requested in a block matrix with a maximum of ") +
241 std::to_string(m_numberOfBlockRows) + std::string(
" rows"));
243 this->GetTransposeFlag() ==
'N' ? column < m_numberOfBlockColumns
244 : column < m_numberOfBlockRows,
245 std::string(
"Column ") + std::to_string(column) +
246 std::string(
" requested in a block matrix with a maximum of ") +
247 std::to_string(m_numberOfBlockColumns) + std::string(
" columns"));
248 int x = CalculateBlockIndex(row, column);
251 return m_nullBlockPtr;
259template <
typename DataType,
typename InnerMatrixType>
261 unsigned int row,
unsigned int column, std::shared_ptr<InnerType> &m)
264 this->GetTransposeFlag() ==
'N' ? row < m_numberOfBlockRows
265 : row < m_numberOfBlockColumns,
266 std::string(
"Row ") + std::to_string(row) +
267 std::string(
" requested in a block matrix with a maximum of ") +
268 std::to_string(m_numberOfBlockRows) + std::string(
" rows"));
270 this->GetTransposeFlag() ==
'N' ? column < m_numberOfBlockColumns
271 : column < m_numberOfBlockRows,
272 std::string(
"Column ") + std::to_string(column) +
273 std::string(
" requested in a block matrix with a maximum of ") +
274 std::to_string(m_numberOfBlockColumns) + std::string(
" columns"));
275 m_data[CalculateBlockIndex(row, column)] = InnerType::CreateWrapper(m);
278template <
typename DataType,
typename InnerMatrixType>
280 BlockMatrixTag>::ConstGetValueType
282 unsigned int row,
unsigned int col)
const
285 std::string(
"Row ") + std::to_string(row) +
286 std::string(
" requested in a matrix with a maximum of ") +
287 std::to_string(this->GetRows()) + std::string(
" rows"));
289 std::string(
"Column ") + std::to_string(col) +
290 std::string(
" requested in a matrix with a maximum of ") +
291 std::to_string(this->GetColumns()) + std::string(
" columns"));
296 if (this->GetTransposeFlag() ==
'T')
298 std::swap(rowSizes, columnSizes);
301 unsigned int blockRow =
302 std::lower_bound(rowSizes->begin(), rowSizes->end(), row) -
304 unsigned int blockColumn =
305 std::lower_bound(columnSizes->begin(), columnSizes->end(), col) -
306 columnSizes->begin();
307 const std::shared_ptr<const InnerType> block =
308 GetBlock(blockRow, blockColumn);
310 unsigned int actualRow = row;
313 actualRow = row - ((*rowSizes)[blockRow - 1]) - 1;
316 unsigned int actualCol = col;
319 actualCol = col - ((*columnSizes)[blockColumn - 1]) - 1;
324 return (*block)(actualRow, actualCol);
328 return m_zeroElement;
332template <
typename DataType,
typename InnerMatrixType>
334 BlockMatrixTag>::GetStorageSize()
const
336 return m_storageSize;
339template <
typename DataType,
typename InnerMatrixType>
341 BlockMatrixTag>::GetNumberOfBlockRows()
const
343 if (this->GetTransposeFlag() ==
'N')
345 return m_numberOfBlockRows;
349 return m_numberOfBlockColumns;
353template <
typename DataType,
typename InnerMatrixType>
355 BlockMatrixTag>::GetNumberOfBlockColumns()
const
357 if (this->GetTransposeFlag() ==
'N')
359 return m_numberOfBlockColumns;
363 return m_numberOfBlockRows;
367template <
typename DataType,
typename InnerMatrixType>
369 GetNumberOfRowsInBlockRow(
unsigned int blockRow)
const
371 if (this->GetTransposeFlag() ==
'N')
373 return GetNumberOfElementsInBlock(blockRow, m_numberOfBlockRows,
378 return GetNumberOfElementsInBlock(blockRow, m_numberOfBlockColumns,
383template <
typename DataType,
typename InnerMatrixType>
385 GetNumberOfColumnsInBlockColumn(
unsigned int blockCol)
const
387 if (this->GetTransposeFlag() ==
'T')
389 return GetNumberOfElementsInBlock(blockCol, m_numberOfBlockRows,
394 return GetNumberOfElementsInBlock(blockCol, m_numberOfBlockColumns,
399template <
typename DataType,
typename InnerMatrixType>
404 if (this->GetTransposeFlag() ==
'T')
406 rowSizes = m_columnSizes;
407 colSizes = m_rowSizes;
411 rowSizes = m_rowSizes;
412 colSizes = m_columnSizes;
416template <
typename DataType,
typename InnerMatrixType>
418 BlockMatrixTag>::iterator
424template <
typename DataType,
typename InnerMatrixType>
426 BlockMatrixTag>::iterator
432template <
typename DataType,
typename InnerMatrixType>
434 BlockMatrixTag>::const_iterator
440template <
typename DataType,
typename InnerMatrixType>
442 BlockMatrixTag>::const_iterator
448template <
typename DataType,
typename InnerMatrixType>
452 BlockMatrixTag> &rhs)
454 return ThisType(rhs);
457template <
typename DataType,
typename InnerMatrixType>
458std::shared_ptr<NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>>
459NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>::CreateWrapper(
460 const std::shared_ptr<
461 NekMatrix<NekMatrix<DataType, InnerMatrixType>, BlockMatrixTag>> &rhs)
463 return std::shared_ptr<ThisType>(
new ThisType(*rhs));
466template <
typename DataType,
typename InnerMatrixType>
468 GetNumberOfElementsInBlock(
unsigned int block,
unsigned int totalBlocks,
471 boost::ignore_unused(totalBlocks);
473 std::string(
"Block Element ") + std::to_string(block) +
474 std::string(
" requested in a matrix with a maximum of ") +
475 std::to_string(totalBlocks) + std::string(
" blocks."));
478 return sizes[block] + 1;
482 return sizes[block] - sizes[block - 1];
486template <
typename DataType,
typename InnerMatrixType>
488 BlockMatrixTag>::Initialize(
const unsigned int *rowsPerBlock,
489 const unsigned int *columnsPerBlock)
491 m_storageSize = this->GetRows() * this->GetColumns();
492 if (this->GetRows() > 0)
494 m_rowSizes[0] = rowsPerBlock[0] - 1;
495 for (
unsigned int i = 1; i < m_numberOfBlockRows; ++i)
497 m_rowSizes[i] = rowsPerBlock[i] + m_rowSizes[i - 1];
500 if (this->GetColumns() > 0)
502 m_columnSizes[0] = columnsPerBlock[0] - 1;
503 for (
unsigned int i = 1; i < m_numberOfBlockColumns; ++i)
505 m_columnSizes[i] = columnsPerBlock[i] + m_columnSizes[i - 1];
510template <
typename DataType,
typename InnerMatrixType>
511typename boost::call_traits<
513 BlockMatrixTag>::NumberType>::value_type
515 unsigned int row,
unsigned int column)
const
517 return (*
this)(row, column);
520template <
typename DataType,
typename InnerMatrixType>
522 BlockMatrixTag>::v_GetStorageSize()
const
524 return this->GetStorageSize();
527template <
typename DataType,
typename InnerMatrixType>
529 BlockMatrixTag>::v_Transpose()
531 for (
auto &ptr : m_data)
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
#define LIB_UTILITIES_EXPORT
iterator_base< const ThisType > const_iterator
iterator_base< ThisType > iterator
The above copyright notice and this permission notice shall be included.