Line data Source code
1 1 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : /// \file
5 : /// `blaze::DynamicMatrix` is a general-purpose dynamically sized matrix type.
6 : /// This file implements interoperability of `blaze::DynamicMatrix` with our
7 : /// data structures.
8 :
9 : #pragma once
10 :
11 : #include <blaze/math/DynamicMatrix.h>
12 : #include <cstddef>
13 : #include <pup.h>
14 : #include <type_traits>
15 : #include <vector>
16 :
17 : #include "Options/Options.hpp"
18 : #include "Options/ParseError.hpp"
19 : #include "Utilities/Gsl.hpp"
20 :
21 : namespace PUP {
22 : /// @{
23 : /// Serialization of blaze::DynamicMatrix
24 : template <typename Type, bool SO, typename Alloc, typename Tag>
25 : void pup(er& p, blaze::DynamicMatrix<Type, SO, Alloc, Tag>& t) {
26 : size_t rows = t.rows();
27 : size_t columns = t.columns();
28 : p | rows;
29 : p | columns;
30 : if (p.isUnpacking()) {
31 : t.resize(rows, columns);
32 : }
33 : const size_t spacing = t.spacing();
34 : const size_t data_size = spacing * (SO == blaze::rowMajor ? rows : columns);
35 : if (std::is_fundamental_v<Type>) {
36 : PUParray(p, t.data(), data_size);
37 : } else {
38 : for (size_t i = 0; i < data_size; ++i) {
39 : p | t.data()[i];
40 : }
41 : }
42 : }
43 : template <typename Type, bool SO, typename Alloc, typename Tag>
44 : void operator|(er& p, blaze::DynamicMatrix<Type, SO, Alloc, Tag>& t) {
45 : pup(p, t);
46 : }
47 : /// @}
48 : } // namespace PUP
49 :
50 : namespace DynamicMatrix_detail {
51 : template <typename Type>
52 : std::vector<std::vector<Type>> parse_to_vectors(const Options::Option& options);
53 : } // namespace DynamicMatrix_detail
54 :
55 : template <typename Type, bool SO, typename Alloc, typename Tag>
56 0 : struct Options::create_from_yaml<blaze::DynamicMatrix<Type, SO, Alloc, Tag>> {
57 : template <typename Metavariables>
58 0 : static blaze::DynamicMatrix<Type, SO, Alloc, Tag> create(
59 : const Options::Option& options) {
60 : const auto data = DynamicMatrix_detail::parse_to_vectors<Type>(options);
61 : const size_t num_rows = data.size();
62 : size_t num_cols = 0;
63 : if (num_rows > 0) {
64 : num_cols = data[0].size();
65 : }
66 : blaze::DynamicMatrix<Type, SO, Alloc, Tag> result(num_rows, num_cols);
67 : for (size_t i = 0; i < num_rows; i++) {
68 : const auto& row = gsl::at(data, i);
69 : if (row.size() != num_cols) {
70 : PARSE_ERROR(options.context(),
71 : "All matrix rows must have the same size.");
72 : }
73 : std::copy(row.begin(), row.end(), blaze::row(result, i).begin());
74 : }
75 : return result;
76 : }
77 : };
78 :
79 : /// Write a `blaze::DynamicMatrix` to a CSV file.
80 : template <typename Type, bool SO, typename Alloc, typename Tag>
81 1 : std::ostream& write_csv(
82 : std::ostream& os, const blaze::DynamicMatrix<Type, SO, Alloc, Tag>& matrix,
83 : const std::string& delimiter = ",") {
84 : for (size_t i = 0; i < matrix.rows(); ++i) {
85 : for (size_t j = 0; j < matrix.columns(); ++j) {
86 : os << matrix(i, j);
87 : if (j + 1 != matrix.columns()) {
88 : os << delimiter;
89 : }
90 : }
91 : os << '\n';
92 : }
93 : return os;
94 : }
|