PURIFY
Next-generation radio interferometric imaging
IndexMapping.h
Go to the documentation of this file.
1 #ifndef PURIFY_MAPPING_OPERATOR_H
2 #define PURIFY_MAPPING_OPERATOR_H
3 
4 #include "purify/config.h"
5 #include "purify/types.h"
6 #include <set>
7 #include <vector>
8 
9 namespace purify {
10 template <class STORAGE_INDEX_TYPE = t_int>
11 class IndexMapping {
12  public:
13  IndexMapping(const std::vector<STORAGE_INDEX_TYPE> &indices, const STORAGE_INDEX_TYPE N,
14  const STORAGE_INDEX_TYPE start = 0)
15  : indices(indices), N(N), start(start){};
16  template <class ITER>
17  IndexMapping(const ITER &first, const ITER &end, const STORAGE_INDEX_TYPE N,
18  const STORAGE_INDEX_TYPE start = 0)
19  : IndexMapping(std::vector<STORAGE_INDEX_TYPE>(first, end), N, start) {}
20  IndexMapping(const std::set<STORAGE_INDEX_TYPE> &indices, const STORAGE_INDEX_TYPE N,
21  const STORAGE_INDEX_TYPE start = 0)
22  : IndexMapping(indices.begin(), indices.end(), N, start) {}
23 
25  template <class T0, class T1>
26  void operator()(Eigen::MatrixBase<T0> const &input, Eigen::MatrixBase<T1> const &output) const {
27  auto &derived = output.const_cast_derived();
28  derived.resize(indices.size());
29  typename T0::Index i(0);
30  for (auto const &index : indices) {
31  assert(index >= start and index < (N + start));
32  assert(derived.size() > i);
33  derived(i++) = input(index - start);
34  }
35  }
36 
38  template <class T0, class T1>
39  void adjoint(Eigen::MatrixBase<T0> const &input, Eigen::MatrixBase<T1> const &output) const {
40  assert(static_cast<size_t>(input.size()) == indices.size());
41  auto &derived = output.const_cast_derived();
42  derived = T1::Zero(N, 1);
43  typename T0::Index i(0);
44  for (STORAGE_INDEX_TYPE const &index : indices) {
45  assert(index >= start and index < (N + start));
46  derived(index - start) += input(i++);
47  }
48  }
49 
50  t_int rows() const { return indices.size(); }
51  STORAGE_INDEX_TYPE cols() const { return N; }
52 
53  private:
54  std::vector<STORAGE_INDEX_TYPE> indices;
55  STORAGE_INDEX_TYPE start;
56  STORAGE_INDEX_TYPE N;
57 };
58 
60 template <class T0, class STORAGE_INDEX_TYPE = t_int>
61 std::set<STORAGE_INDEX_TYPE> non_empty_outers(Eigen::SparseMatrixBase<T0> const &matrix) {
62  std::set<STORAGE_INDEX_TYPE> result;
63  for (typename T0::Index k = 0; k < matrix.derived().outerSize(); ++k)
64  for (typename T0::InnerIterator it(matrix.derived(), k); it; ++it)
65  result.insert(static_cast<STORAGE_INDEX_TYPE>(it.col()));
66  return result;
67 }
68 
70 template <class T0>
72  static_assert(T0::IsRowMajor, "Not tested for col major");
73  auto const indices = non_empty_outers(matrix);
74 
76  mapping.reserve(indices.size());
77  t_int i(0);
78  for (auto const &index : indices) mapping.coeffRef(index) = i++;
79 
80  std::vector<typename Sparse<typename T0::Scalar>::Index> rows(matrix.rows() + 1, 0);
81  std::vector<typename Sparse<typename T0::Scalar>::Index> cols(matrix.nonZeros(), 0);
82  rows[matrix.rows()] = matrix.nonZeros();
83  t_int index = 0;
84  for (typename T0::Index k = 0; k < matrix.outerSize(); ++k) {
85  rows[k] = index;
86  for (typename T0::InnerIterator it(matrix, k); it; ++it) {
87  cols[index] = mapping.coeff(it.col());
88  index++;
89  }
90  }
91  return Eigen::MappedSparseMatrix<typename T0::Scalar, Eigen::RowMajor,
93  matrix.rows(), indices.size(), matrix.nonZeros(), rows.data(), cols.data(),
94  const_cast<typename T0::Scalar *>(matrix.derived().valuePtr()));
95 }
96 } // namespace purify
97 #endif
IndexMapping(const ITER &first, const ITER &end, const STORAGE_INDEX_TYPE N, const STORAGE_INDEX_TYPE start=0)
Definition: IndexMapping.h:17
IndexMapping(const std::vector< STORAGE_INDEX_TYPE > &indices, const STORAGE_INDEX_TYPE N, const STORAGE_INDEX_TYPE start=0)
Definition: IndexMapping.h:13
IndexMapping(const std::set< STORAGE_INDEX_TYPE > &indices, const STORAGE_INDEX_TYPE N, const STORAGE_INDEX_TYPE start=0)
Definition: IndexMapping.h:20
void adjoint(Eigen::MatrixBase< T0 > const &input, Eigen::MatrixBase< T1 > const &output) const
Vector of size N where non-zero elements are chosen from input at given indices.
Definition: IndexMapping.h:39
t_int rows() const
Definition: IndexMapping.h:50
STORAGE_INDEX_TYPE cols() const
Definition: IndexMapping.h:51
void operator()(Eigen::MatrixBase< T0 > const &input, Eigen::MatrixBase< T1 > const &output) const
Creates a vector of elements equal to re-indexed inpu.
Definition: IndexMapping.h:26
Eigen::SparseVector< T, Eigen::RowMajor, I > SparseVector
Definition: types.h:42
std::set< STORAGE_INDEX_TYPE > non_empty_outers(Eigen::SparseMatrixBase< T0 > const &matrix)
Indices of non empty outer indices.
Definition: IndexMapping.h:61
Eigen::SparseMatrix< T, Eigen::RowMajor, I > Sparse
A matrix of a given type.
Definition: types.h:40
Sparse< typename T0::Scalar > compress_outer(T0 const &matrix)
Indices of non empty outer indices.
Definition: IndexMapping.h:71