33 #ifndef GKO_CORE_BASE_MATRIX_DATA_HPP_ 34 #define GKO_CORE_BASE_MATRIX_DATA_HPP_ 37 #include <ginkgo/core/base/dim.hpp> 38 #include <ginkgo/core/base/math.hpp> 39 #include <ginkgo/core/base/range.hpp> 40 #include <ginkgo/core/base/range_accessors.hpp> 41 #include <ginkgo/core/base/types.hpp> 57 template <
typename ValueType,
typename IndexType>
65 template <
typename ValueType,
typename Distribution,
typename Generator>
66 typename std::enable_if<!is_complex<ValueType>(), ValueType>::type
67 get_rand_value(Distribution &&dist, Generator &&gen)
73 template <
typename ValueType,
typename Distribution,
typename Generator>
74 typename std::enable_if<is_complex<ValueType>(), ValueType>::type
75 get_rand_value(Distribution &&dist, Generator &&gen)
77 return ValueType(dist(gen), dist(gen));
101 template <
typename ValueType = default_precision,
typename IndexType =
int32>
103 using value_type = ValueType;
104 using index_type = IndexType;
113 : row(r), column(c), value(v)
116 #define GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(_op) \ 117 bool operator _op(const nonzero_type &other) const \ 119 return std::tie(this->row, this->column, this->value) \ 120 _op std::tie(other.row, other.column, other.value); \ 123 GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(==);
124 GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(!=);
125 GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(<);
126 GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(>);
127 GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(<=);
128 GKO_DEFINE_DEFAULT_COMPARE_OPERATOR(>=);
130 #undef GKO_DEFINE_DEFAULT_COMPARE_OPERATOR 146 if (value == zero<ValueType>()) {
149 for (
size_type row = 0; row < size[0]; ++row) {
150 for (
size_type col = 0; col < size[1]; ++col) {
151 nonzeros.emplace_back(row, col, value);
166 template <
typename RandomDistribution,
typename RandomEngine>
170 for (
size_type row = 0; row < size[0]; ++row) {
171 for (
size_type col = 0; col < size[1]; ++col) {
173 detail::get_rand_value<ValueType>(dist, engine);
174 if (value != zero<ValueType>()) {
175 nonzeros.emplace_back(row, col, value);
186 matrix_data(std::initializer_list<std::initializer_list<ValueType>> values)
187 : size{values.size(), 0}
189 for (
size_type row = 0; row < values.size(); ++row) {
190 const auto row_data = begin(values)[row];
191 size[1] = std::max(size[1], row_data.size());
192 for (
size_type col = 0; col < row_data.size(); ++col) {
193 const auto &val = begin(row_data)[col];
194 if (val != zero<ValueType>()) {
195 nonzeros.emplace_back(row, col, val);
209 std::initializer_list<detail::input_triple<ValueType, IndexType>>
211 : size{size_}, nonzeros()
213 nonzeros.reserve(nonzeros_.size());
214 for (
const auto &elem : nonzeros_) {
215 nonzeros.emplace_back(elem.row, elem.col, elem.val);
226 : size{size_ * block.
size}
228 nonzeros.reserve(size_[0] * size_[1] * block.nonzeros.size());
229 for (
size_type row = 0; row < size_[0]; ++row) {
230 for (
size_type col = 0; col < size_[1]; ++col) {
231 for (
const auto &elem : block.nonzeros) {
232 nonzeros.emplace_back(row * block.size[0] + elem.row,
233 col * block.size[1] + elem.column,
238 this->ensure_row_major_order();
248 template <
typename Accessor>
254 if (data(row, col) != zero<ValueType>()) {
255 nonzeros.emplace_back(row, col, data(row, col));
272 if (value != zero<ValueType>()) {
273 const auto num_nnz = std::min(size_[0], size_[1]);
275 for (
size_type i = 0; i < num_nnz; ++i) {
276 res.
nonzeros.emplace_back(i, i, value);
291 std::initializer_list<ValueType> nonzeros_)
294 res.
nonzeros.reserve(nonzeros_.size());
296 for (
auto value : nonzeros_) {
297 res.
nonzeros.emplace_back(pos, pos, value);
314 const auto num_blocks = std::min(size_[0], size_[1]);
316 for (
size_type b = 0; b < num_blocks; ++b) {
317 for (
const auto &elem : block.
nonzeros) {
319 b * block.
size[1] + elem.column,
337 template <
typename ForwardIterator>
342 return dim<2>{s[0] + d.size[0], s[1] + d.size[1]};
347 for (
auto it = begin; it != end; ++it) {
348 for (
const auto &elem : it->nonzeros) {
349 res.
nonzeros.emplace_back(row_offset + elem.row,
350 col_offset + elem.column, elem.value);
352 row_offset += it->size[0];
353 col_offset += it->size[1];
369 return diag(begin(blocks), end(blocks));
391 template <
typename RandomDistribution,
typename RandomEngine>
394 RandomDistribution &&dist, RandomEngine &&engine,
398 std::vector<ValueType> mtx_data(size * size, zero<ValueType>());
399 std::vector<ValueType> ref_data(size);
400 std::vector<ValueType> work(size);
401 range matrix(mtx_data.data(), size, size, size);
402 range reflector(ref_data.data(), size, 1u, 1u);
404 initialize_diag_with_cond(condition_number, matrix);
405 for (
size_type i = 0; i < num_reflectors; ++i) {
406 generate_random_reflector(dist, engine, reflector);
407 reflect_domain(reflector, matrix, work.data());
408 generate_random_reflector(dist, engine, reflector);
409 reflect_range(reflector, matrix, work.data());
435 template <
typename RandomDistribution,
typename RandomEngine>
438 RandomDistribution &&dist, RandomEngine &&engine)
440 return cond(size, condition_number,
441 std::forward<RandomDistribution>(dist),
442 std::forward<RandomEngine>(engine), size - 1);
466 return std::tie(x.row, x.column) < std::tie(y.row, y.column);
471 template <
typename Accessor>
472 static void initialize_diag_with_cond(
477 const auto size = matrix.
length(0);
478 const auto min_sigma =
one(condition_number) / sqrt(condition_number);
479 const auto max_sigma = sqrt(condition_number);
481 matrix =
zero(matrix);
483 matrix(i, i) = max_sigma *
static_cast<sigma_type
>(size - i - 1) /
484 static_cast<sigma_type>(size - 1) +
485 min_sigma *
static_cast<sigma_type
>(i) /
486 static_cast<sigma_type>(size - 1);
490 template <
typename RandomDistribution,
typename RandomEngine,
492 static void generate_random_reflector(RandomDistribution &&dist,
493 RandomEngine &&engine,
497 reflector(i, 0) = detail::get_rand_value<ValueType>(dist, engine);
501 template <
typename Accessor>
504 ValueType *work_data)
506 const auto two = one<ValueType>() + one<ValueType>();
508 matrix.
length(0), 1u, 1u);
509 work = mmul(matrix, reflector);
511 const auto scale = two / mmul(ct_reflector, reflector)(0, 0);
512 matrix = matrix - scale * mmul(work, ct_reflector);
515 template <
typename Accessor>
518 ValueType *work_data)
520 const auto two = one<ValueType>() + one<ValueType>();
524 work = mmul(ct_reflector, matrix);
525 const auto scale = two / mmul(ct_reflector, reflector)(0, 0);
526 matrix = matrix - scale * mmul(reflector, work);
534 #endif // GKO_CORE_BASE_MATRIX_DATA_HPP_ static matrix_data diag(dim< 2 > size_, const matrix_data &block)
Initializes a block-diagonal matrix.
Definition: matrix_data.hpp:311
constexpr T zero()
Returns the additive identity for T.
Definition: math.hpp:292
static matrix_data cond(size_type size, remove_complex< ValueType > condition_number, RandomDistribution &&dist, RandomEngine &&engine, size_type num_reflectors)
Initializes a random dense matrix with a specific condition number.
Definition: matrix_data.hpp:392
std::size_t size_type
Integral type used for allocation quantities.
Definition: types.hpp:94
matrix_data(dim< 2 > size_, std::initializer_list< detail::input_triple< ValueType, IndexType >> nonzeros_)
Initializes the structure from a list of nonzeros.
Definition: matrix_data.hpp:207
constexpr size_type length(size_type dimension) const
Returns the length of the specified dimension of the range.
Definition: range.hpp:387
matrix_data(std::initializer_list< std::initializer_list< ValueType >> values)
List-initializes the structure from a matrix of values.
Definition: matrix_data.hpp:186
The Ginkgo namespace.
Definition: abstract_factory.hpp:45
static matrix_data diag(dim< 2 > size_, ValueType value)
Initializes a diagonal matrix.
Definition: matrix_data.hpp:269
static matrix_data diag(dim< 2 > size_, std::initializer_list< ValueType > nonzeros_)
Initializes a diagonal matrix using a list of diagonal elements.
Definition: matrix_data.hpp:290
matrix_data(dim< 2 > size_, RandomDistribution &&dist, RandomEngine &&engine)
Initializes a matrix with random values from the specified distribution.
Definition: matrix_data.hpp:167
dim< 2 > size
Size of the matrix.
Definition: matrix_data.hpp:448
matrix_data(dim< 2 > size_, const matrix_data &block)
Initializes a matrix out of a matrix block via duplication.
Definition: matrix_data.hpp:225
void ensure_row_major_order()
Sorts the nonzero vector so the values follow row-major order.
Definition: matrix_data.hpp:462
static matrix_data diag(ForwardIterator begin, ForwardIterator end)
Initializes a block-diagonal matrix from a list of diagonal blocks.
Definition: matrix_data.hpp:338
static matrix_data cond(size_type size, remove_complex< ValueType > condition_number, RandomDistribution &&dist, RandomEngine &&engine)
Initializes a random dense matrix with a specific condition number.
Definition: matrix_data.hpp:436
T conj(const T &x)
Returns the conjugate of an object.
Definition: math.hpp:439
matrix_data(const range< Accessor > &data)
Initializes a matrix from a range.
Definition: matrix_data.hpp:249
std::vector< nonzero_type > nonzeros
A vector of tuples storing the non-zeros of the matrix.
Definition: matrix_data.hpp:457
typename detail::remove_complex_impl< T >::type remove_complex
Obtains a real counterpart of a std::complex type, and leaves the type unchanged if it is not a compl...
Definition: math.hpp:93
Type used to store nonzeros.
Definition: matrix_data.hpp:109
static matrix_data diag(std::initializer_list< matrix_data > blocks)
Initializes a block-diagonal matrix from a list of diagonal blocks.
Definition: matrix_data.hpp:367
This structure is used as an intermediate data type to store a sparse matrix.
Definition: matrix_data.hpp:102
A range is a multidimensional view of the memory.
Definition: range.hpp:296
constexpr dim< 2, DimensionType > transpose(const dim< 2, DimensionType > &dimensions) noexcept
Returns a dim<2> object with its dimensions swapped.
Definition: dim.hpp:234
matrix_data(dim< 2 > size_=dim< 2 >{}, ValueType value=zero< ValueType >())
Initializes a matrix filled with the specified value.
Definition: matrix_data.hpp:143
constexpr T one()
Returns the multiplicative identity for T.
Definition: math.hpp:319