TRIQS/triqs_ctint 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
block_matrix.hpp
1// Copyright (c) 2020--present, The Simons Foundation
2// This file is part of TRIQS/ctint and is licensed under the terms of GPLv3 or later.
3// SPDX-License-Identifier: GPL-3.0-or-later
4// See LICENSE in the root of this distribution for details.
5
6#pragma once
7
8#include <string>
9#include <vector>
10#include <algorithm>
11#include <mpi/vector.hpp>
12#include <mpi/string.hpp>
13#include <triqs/utility/is_complex.hpp>
14#include <nda/nda.hpp>
15#include <boost/serialization/access.hpp>
16
17namespace triqs {
18 namespace arrays {
19
21
24 template <typename T> struct block_matrix {
25
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;
30
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() {}
34
36 int size() const { return matrix_vec.size(); }
37
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)];
43 }
44
46 matrix_t &operator[](int i) { return matrix_vec[i]; }
47
49 nda::matrix_const_view<T> operator[](int i) const { return matrix_vec[i]; }
50
51 // Add block matrix
52 block_matrix &operator+=(block_matrix const &b) {
53 assert(b.block_names == block_names);
54 for (int i = 0; i < size(); ++i) matrix_vec[i] += b[i];
55 return *this;
56 }
57 block_matrix operator+(block_matrix const &b) {
58 auto res = *this;
59 res += b;
60 return res;
61 }
62
63 // Subtract block matrix
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];
67 return *this;
68 }
69 block_matrix operator-(block_matrix const &b) {
70 auto res = *this;
71 res -= b;
72 return res;
73 }
74
75 // Multiply by block matrix
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];
79 return *this;
80 }
81 block_matrix operator*(block_matrix const &b) {
82 auto res = *this;
83 res *= b;
84 return res;
85 }
86
87 // Multiply by scalar
88 template <typename Scalar> block_matrix &operator*=(Scalar const &s) {
89 for (auto &m : matrix_vec) m *= s;
90 return *this;
91 }
92 template <typename Scalar> block_matrix operator*(Scalar const &s) {
93 auto res = *this;
94 res *= s;
95 return res;
96 }
97 template <typename Scalar> friend block_matrix operator*(Scalar const &s, block_matrix const &b) {
98 auto res = b;
99 res *= s;
100 return res;
101 }
102
103 // Divide by scalar
104 template <typename Scalar> block_matrix &operator/=(Scalar const &s) {
105 for (auto &m : matrix_vec) m /= s;
106 return *this;
107 }
108 template <typename Scalar> block_matrix operator/(Scalar const &s) {
109 auto res = *this;
110 res /= s;
111 return res;
112 }
113
114 // Unary minus
115 block_matrix operator-() {
116 auto res = *this;
117 res *= T(-1);
118 return res;
119 }
120
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;
124 return out;
125 }
126
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);
131 return m_tot;
132 }
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);
136 }
137
138 // Boost.Serialization
139 friend class boost::serialization::access;
140 template <class Archive> void serialize(Archive &ar, const unsigned int /* version */) {
141 ar & block_names;
142 ar & matrix_vec;
143 }
144
145 static std::string hdf5_format() { return is_complex<T>::value ? "BlockMatrixComplex" : "BlockMatrix"; }
146
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);
153 }
154
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_;
159
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_);
163 }
164 };
165 } // namespace arrays
166} // namespace triqs
Block-diagonal matrix with named blocks.
friend std::ostream & operator<<(std::ostream &out, block_matrix const &c)
Stream output.
matrix_t & operator[](int i)
Subscript operator (fast).
int size() const
Number of diagonal blocks.
friend void h5_read(h5::group fg, std::string subgroup_name, block_matrix &c)
Read from HDF5.
nda::matrix_const_view< T > operator[](int i) const
Subscript operator (fast).
friend void h5_write(h5::group fg, std::string subgroup_name, block_matrix const &c)
Write to HDF5.
friend block_matrix mpi_reduce(block_matrix const &m, mpi::communicator c, int root, bool all, MPI_Op op)
MPI.
nda::matrix_view< T > operator()(std::string const &name)
Call operator with a string (slow).