SOPT
Sparse OPTimisation
sampling.h
Go to the documentation of this file.
1 #ifndef SOPT_SAMPLING_H
2 #define SOPT_SAMPLING_H
3 
4 #include "sopt/config.h"
5 #include <initializer_list>
6 #include <memory>
7 #include <random>
8 #include <vector> // for std::vector<>
9 #include <Eigen/Core>
10 #include "sopt/linear_transform.h"
11 #include "sopt/types.h"
12 
13 namespace sopt {
14 
17 class Sampling {
18  public:
20  Sampling(t_uint size, std::vector<t_uint> const &indices) : indices_(indices), size(size) {}
22  template <typename RNG>
23  Sampling(t_uint size, t_uint samples, RNG &&rng);
25  Sampling(t_uint size, t_uint samples)
26  : Sampling(size, samples, std::mt19937_64(std::random_device()())) {}
27 
28  // Performs sampling
29  template <typename T0, typename T1>
30  void operator()(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T1> const &x) const;
31  // Performs sampling
32  template <typename T0, typename T1>
33  void operator()(Eigen::DenseBase<T0> &&out, Eigen::DenseBase<T1> const &x) const {
34  operator()(out, x);
35  }
36  // Performs adjunct of sampling
37  template <typename T0, typename T1>
38  void adjoint(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T1> const &x) const;
39  // Performs adjunct sampling
40  template <typename T0, typename T1>
41  void adjoint(Eigen::DenseBase<T0> &&out, Eigen::DenseBase<T1> const &x) const {
42  adjoint(out, x);
43  }
44 
46  t_uint cols() const { return size; }
48  t_uint rows() const { return indices_.size(); }
49 
51  std::vector<t_uint> const &indices() const { return indices_; }
52 
53  protected:
55  std::vector<t_uint> indices_;
57  t_uint size;
58 };
59 
60 template <typename T0, typename T1>
61 void Sampling::operator()(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T1> const &x) const {
62  out.resize(indices_.size());
63  for (decltype(indices_.size()) i(0); i < indices_.size(); ++i) {
64  assert(indices_[i] < static_cast<t_uint>(x.size()));
65  out[i] = x[indices_[i]];
66  }
67 }
68 
69 template <typename T0, typename T1>
70 void Sampling::adjoint(Eigen::DenseBase<T0> &out, Eigen::DenseBase<T1> const &x) const {
71  assert(static_cast<t_uint>(x.size()) == indices_.size());
72  out.resize(out.size());
73  out.fill(0);
74  for (decltype(indices_.size()) i(0); i < indices_.size(); ++i) {
75  assert(indices_[i] < static_cast<t_uint>(out.size()));
76  out[indices_[i]] = x[i];
77  }
78 }
79 
81 template <typename T>
83  return linear_transform<Vector<T>>(
84  [sampling](Vector<T> &out, Vector<T> const &x) { sampling(out, x); },
85  {{0, 1, static_cast<t_int>(sampling.rows())}},
86  [sampling](Vector<T> &out, Vector<T> const &x) { sampling.adjoint(out, x); },
87  {{0, 1, static_cast<t_int>(sampling.cols())}});
88 }
89 
90 template <typename RNG>
91 Sampling::Sampling(t_uint size, t_uint samples, RNG &&rng) : indices_(size), size(size) {
92  std::iota(indices_.begin(), indices_.end(), 0);
93  std::shuffle(indices_.begin(), indices_.end(), rng);
94  indices_.resize(samples);
95 }
96 
97 } // namespace sopt
98 #endif
Joins together direct and indirect operators.
An operator that samples a set of measurements.
Definition: sampling.h:17
Sampling(t_uint size, std::vector< t_uint > const &indices)
Constructs from a vector.
Definition: sampling.h:20
Sampling(t_uint size, t_uint samples)
Constructs from the size and the number of samples to pick.
Definition: sampling.h:25
void adjoint(Eigen::DenseBase< T0 > &&out, Eigen::DenseBase< T1 > const &x) const
Definition: sampling.h:41
void adjoint(Eigen::DenseBase< T0 > &out, Eigen::DenseBase< T1 > const &x) const
Definition: sampling.h:70
void operator()(Eigen::DenseBase< T0 > &&out, Eigen::DenseBase< T1 > const &x) const
Definition: sampling.h:33
t_uint rows() const
Number of measurements.
Definition: sampling.h:48
void operator()(Eigen::DenseBase< T0 > &out, Eigen::DenseBase< T1 > const &x) const
Definition: sampling.h:61
std::vector< t_uint > const & indices() const
Indices of sampled points.
Definition: sampling.h:51
t_uint cols() const
Size of the vector returned by the adjoint operation.
Definition: sampling.h:46
LinearTransform< VECTOR > linear_transform(OperatorFunction< VECTOR > const &direct, OperatorFunction< VECTOR > const &indirect, std::array< t_int, 3 > const &sizes={{1, 1, 0}})
int t_int
Root of the type hierarchy for signed integers.
Definition: types.h:13
size_t t_uint
Root of the type hierarchy for unsigned integers.
Definition: types.h:15
Eigen::Matrix< T, Eigen::Dynamic, 1 > Vector
A vector of a given type.
Definition: types.h:24