24 template <
typename T>
struct block_matrix {
26 using matrix_t = nda::matrix<T>;
27 using regular_type = block_matrix<T>;
28 std::vector<std::string> block_names;
29 std::vector<matrix_t> matrix_vec;
31 block_matrix(std::vector<std::string>
const &block_names, std::vector<matrix_t>
const &matrix_vec)
32 : block_names(block_names), matrix_vec(matrix_vec) {}
33 block_matrix() : block_names(), matrix_vec() {}
36 int size()
const {
return matrix_vec.size(); }
39 nda::matrix_view<T>
operator()(std::string
const &name) {
40 auto it = std::find(block_names.begin(), block_names.end(), name);
41 if (it == block_names.end()) TRIQS_RUNTIME_ERROR <<
"block_matrix: Block name " << name <<
" is incorrect";
42 return matrix_vec[std::distance(block_names.begin(), it)];
49 nda::matrix_const_view<T>
operator[](
int i)
const {
return matrix_vec[i]; }
53 assert(b.block_names == block_names);
54 for (
int i = 0; i <
size(); ++i) matrix_vec[i] += b[i];
57 block_matrix operator+(block_matrix
const &b) {
64 block_matrix &operator-=(block_matrix
const &b) {
65 assert(b.block_names == block_names);
66 for (
int i = 0; i <
size(); ++i) matrix_vec[i] -= b[i];
69 block_matrix operator-(block_matrix
const &b) {
76 block_matrix &operator*=(block_matrix
const &b) {
77 assert(b.block_names == block_names);
78 for (
int i = 0; i <
size(); ++i) matrix_vec[i] = matrix_vec[i] * b[i];
81 block_matrix operator*(block_matrix
const &b) {
88 template <
typename Scalar> block_matrix &operator*=(Scalar
const &s) {
89 for (
auto &m : matrix_vec) m *= s;
92 template <
typename Scalar> block_matrix operator*(Scalar
const &s) {
97 template <
typename Scalar>
friend block_matrix operator*(Scalar
const &s, block_matrix
const &b) {
104 template <
typename Scalar> block_matrix &operator/=(Scalar
const &s) {
105 for (
auto &m : matrix_vec) m /= s;
108 template <
typename Scalar> block_matrix operator/(Scalar
const &s) {
115 block_matrix operator-() {
122 friend std::ostream &
operator<<(std::ostream &out, block_matrix
const &c) {
123 for (
int i = 0; i < c.block_names.size(); ++i) out << c.block_names[i] <<
": " << c.matrix_vec[i] << std::endl;
128 friend block_matrix
mpi_reduce(block_matrix
const &m, mpi::communicator c,
int root,
bool all, MPI_Op op) {
129 block_matrix m_tot(m);
130 for (
int i = 0; i < m.
size(); ++i) m_tot[i] = mpi::reduce(m[i], c, root, all, op);
133 friend void mpi_broadcast(
block_matrix &m, mpi::communicator c,
int root) {
134 mpi::broadcast(m.block_names, c, root);
135 mpi::broadcast(m.matrix_vec, c, root);
139 friend class boost::serialization::access;
140 template <
class Archive>
void serialize(Archive &ar,
const unsigned int ) {
145 static std::string hdf5_format() {
return is_complex<T>::value ?
"BlockMatrixComplex" :
"BlockMatrix"; }
148 friend void h5_write(h5::group fg, std::string subgroup_name, block_matrix
const &c) {
149 h5::group gr = fg.create_group(subgroup_name);
150 write_hdf5_format(gr, c);
151 h5_write(gr,
"block_names", c.block_names);
152 h5_write(gr,
"matrix_vec", c.matrix_vec);
155 friend void h5_read(h5::group fg, std::string subgroup_name, block_matrix &c) {
156 h5::group gr = fg.open_group(subgroup_name);
157 std::vector<std::string> block_names_;
158 std::vector<matrix_t> matrix_vec_;
160 h5_read(gr,
"block_names", block_names_);
161 h5_read(gr,
"matrix_vec", matrix_vec_);
162 c = block_matrix<T>(block_names_, matrix_vec_);