145 CovarianceMatrix::operator
Matrix()
const {
150 for (
const Block &c : correlations_) {
151 MatrixView Aview = A(c.get_row_range(), c.get_column_range());
153 Aview = c.get_dense();
155 Aview =
static_cast<const Matrix>(c.get_sparse());
159 std::tie(ci, cj) = c.get_indices();
161 MatrixView ATview = A(c.get_column_range(), c.get_row_range());
165 ATview =
transpose(static_cast<const Matrix>(c.get_sparse()));
178 MatrixView Aview = A(c.get_row_range(), c.get_column_range());
180 Aview = c.get_dense();
182 Aview =
static_cast<const Matrix>(c.get_sparse());
186 std::tie(ci, cj) = c.get_indices();
188 MatrixView ATview = A(c.get_column_range(), c.get_row_range());
192 ATview =
transpose(static_cast<const Matrix>(c.get_sparse()));
204 std::tie(i, j) = c.get_indices();
213 std::tie(i, j) = c.get_indices();
229 std::tie(i, j) = c.get_indices();
246 result |= b.get_indices() == std::make_pair(i, j);
258 std::tie(bi, bj) = b.get_indices();
259 if (((i == bi) && (j == bj)) || ((i == -1) && (j == bj)) ||
260 ((i == -1) && (j == -1))) {
269 for (
Index i = 0; i < static_cast<Index>(jis.size()); ++
i) {
272 if (b.get_indices() == std::make_pair(
i,
i)) {
284 auto pred = [&jis](
const Block &b) {
286 std::tie(i, j) = b.get_indices();
288 Index row_start = jis[
i][0];
289 Index row_extent = jis[
i][1] - jis[
i][0] + 1;
290 Range row_range = b.get_row_range();
291 if ((row_range.
get_start() != row_start) ||
296 Index column_start = jis[j][0];
297 Index column_extent = jis[j][1] - jis[j][0] + 1;
298 Range column_range = b.get_column_range();
299 if ((column_range.
get_start() != column_start) ||
300 (column_range.
get_extent() != column_extent)) {
321 std::tie(ii, jj) = c.get_indices();
323 if ((ii == i) && (c.nrows() != b.
nrows())) {
327 if ((jj == j) && (c.ncols() != b.
ncols())) {
331 if ((ii == i) && (jj == j)) {
340 if (indices == b.get_indices()) {
348 std::vector<std::vector<const Block *>> &corr_blocks)
const {
355 std::queue<Index> rq_queue{};
357 if (!has_blocks[
i]) {
364 has_blocks[
i] =
true;
365 corr_blocks.push_back(std::vector<const Block *>{&
correlations_[
i]});
367 while (!rq_queue.empty()) {
368 Index rq_index = rq_queue.front();
372 if (!has_blocks[j]) {
374 if ((ci == rq_index) || (cj == rq_index)) {
375 if (ci != rq_index) {
378 if (cj != rq_index) {
382 has_blocks[j] =
true;
392 std::vector<std::vector<const Block *>> correlation_blocks{};
394 for (std::vector<const Block *> &cb : correlation_blocks) {
400 std::vector<Block> &inverses, std::vector<const Block *> &blocks)
const {
402 assert(blocks.size() > 0);
405 auto comp = [](
const Block *a,
const Block *b) {
408 std::tie(b1, b2) = b->get_indices();
409 return ((a1 < b1) || ((a1 == b1) && (a2 < b2)));
412 std::sort(blocks.begin(), blocks.end(), comp);
414 auto block_has_inverse = [
this](
const Block *a) {
417 if (std::all_of(blocks.begin(), blocks.end(), block_has_inverse))
return;
429 std::map<Index, Index> block_start{};
430 std::map<Index, Index> block_extent{};
431 std::map<Index, Index> block_start_cont{};
432 std::map<Index, Index> block_extent_cont{};
433 std::vector<Index> block_indices{};
435 for (
size_t i = 0;
i < blocks.size(); ++
i) {
437 std::tie(ci, cj) = blocks[
i]->get_indices();
440 Index extent = blocks[
i]->get_row_range().get_extent();
442 std::make_pair(ci, blocks[
i]->get_row_range().get_start()));
444 std::make_pair(ci, blocks[
i]->get_row_range().get_extent()));
445 block_start_cont.insert(std::make_pair(ci, n));
446 block_extent_cont.insert(std::make_pair(ci, extent));
447 block_indices.push_back(ci);
456 for (
size_t i = 0;
i < blocks.size(); ++
i) {
458 std::tie(ci, cj) = blocks[
i]->get_indices();
459 Range row_range(block_start_cont[ci], block_extent_cont[ci]);
460 Range column_range(block_start_cont[cj], block_extent_cont[cj]);
461 MatrixView A_view = A(row_range, column_range);
464 A_view = blocks[
i]->get_dense();
466 A_view =
static_cast<const Matrix>(blocks[
i]->get_sparse());
471 for (
Index j =
i + 1; j <
n; ++j) {
493 for (
Index bi : block_indices) {
494 for (
Index bj : block_indices) {
496 Range row_range_A(block_start_cont[bi], block_extent_cont[bi]);
497 Range column_range_A(block_start_cont[bj], block_extent_cont[bj]);
498 Range row_range(block_start[bi], block_extent[bi]);
499 Range column_range(block_start[bj], block_extent[bj]);
500 MatrixView A_view = A(row_range_A, column_range_A);
501 inverses.push_back(
Block(row_range,
503 std::make_pair(bi, bj),
504 std::make_shared<Matrix>(A_view)));
520 tie(i, j) = b.get_indices();
523 diag[b.get_row_range()] = b.diagonal();
535 tie(i, j) = b.get_indices();
538 diag[b.get_row_range()] = b.diagonal();
618 os <<
"Covariance Matrix, ";
619 os <<
"\tDimensions: [" << covmat.
nrows() <<
" x " << covmat.
ncols() <<
"]" 621 os <<
"Blocks:" << std::endl;
625 os <<
"\ti = " << i <<
", j = " << j <<
": " 628 os <<
", has inverse: " 629 << (covmat.
has_inverse(std::make_pair(i, j)) ?
"yes" :
"no");
std::pair< Index, Index > IndexPair
INDEX Index
The type to use for all integer numbers and indices.
std::shared_ptr< Sparse > sparse_
Range get_column_range() const
bool has_block(Index i, Index j)
Check if the block with indices (i, j) is contained in the covariance matrix.
void transpose_mult(VectorView y, const Sparse &M, ConstVectorView x)
Sparse matrix - Vector multiplication.
friend MatrixView & operator+=(MatrixView &, const CovarianceMatrix &)
std::shared_ptr< Matrix > dense_
const Matrix & get_dense() const
const Sparse & get_sparse() const
bool has_inverse(IndexPair indices) const
cmplx FADDEEVA() w(cmplx z, double relerr)
Vector inverse_diagonal() const
Diagonal of the inverse of the covariance matrix as vector.
constexpr Index get_start() const
Returns the start index of the range.
friend void add_inv(MatrixView, const CovarianceMatrix &)
MatrixType get_matrix_type() const
bool is_consistent(const ArrayOfArrayOfIndex &jis) const
Checks that the dimensions of the blocks in the covariance matrix are consistent with ranges occupied...
Index ncols() const
Returns the number of columns.
Header files of CovarianceMatrix class.
void swap(ComplexVector &v1, ComplexVector &v2)
Swaps two objects.
friend void solve(VectorView, const CovarianceMatrix &, ConstVectorView)
constexpr Index get_extent() const
Returns the extent of the range.
void generate_blocks(std::vector< std::vector< const Block *>> &) const
std::vector< Block > correlations_
Range get_row_range() const
void invert_correlation_block(std::vector< Block > &inverses, std::vector< const Block *> &blocks) const
Vector diagonal() const
Diagonal elements as vector.
ConstComplexMatrixView transpose(ConstComplexMatrixView m)
Const version of transpose.
void compute_inverse() const
Compute the inverse of this correlation matrix.
void inv(MatrixView Ainv, ConstMatrixView A)
Matrix Inverse.
friend void mult_inv(MatrixView, ConstMatrixView, const CovarianceMatrix &)
A constant view of a Vector.
A constant view of a Matrix.
friend void mult(MatrixView, ConstMatrixView, const CovarianceMatrix &)
const Block * get_block(Index i=-1, Index j=-1)
Return a pointer to the block with indices (i,j).
void add_correlation_inverse(Block c)
Add block inverse to covariance matrix.
Index nblocks() const
! The number of blocks in the matrix excluding inverses.
friend std::ostream & operator<<(std::ostream &os, const CovarianceMatrix &v)
Index ndiagblocks() const
! The number of diagonal blocks in the matrix excluding inverses.
void add_correlation(Block c)
Add block to covariance matrix.
void mult(MatrixView C, ConstMatrixView A, const Block &B)
Interface for the LAPACK library.
std::vector< Block > inverses_
IndexPair get_indices() const
invlib::Matrix< ArtsMatrix > Matrix
invlib wrapper type for ARTS matrices.
bool has_diagonal_blocks(const ArrayOfArrayOfIndex &jis) const
Checks that the covariance matrix contains one diagonal block per retrieval quantity.
Index nrows() const
Returns the number of rows.
Matrix get_inverse() const
MatrixView & operator+=(MatrixView &A, const Block &B)