Tomographer  v2.0
Tomographer C++ Framework Documentation
eigenutil.h
Go to the documentation of this file.
1 /* This file is part of the Tomographer project, which is distributed under the
2  * terms of the MIT license.
3  *
4  * The MIT License (MIT)
5  *
6  * Copyright (c) 2015 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a copy
9  * of this software and associated documentation files (the "Software"), to deal
10  * in the Software without restriction, including without limitation the rights
11  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12  * copies of the Software, and to permit persons to whom the Software is
13  * furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24  * SOFTWARE.
25  */
26 
27 #ifndef TOMOGRAPHER_TOOLS_EIGENUTIL_H
28 #define TOMOGRAPHER_TOOLS_EIGENUTIL_H
29 
37 #include <complex>
38 #include <vector>
39 
40 #include <Eigen/Core>
41 #include <Eigen/Dense>
42 #include <Eigen/StdVector>
43 
44 
45 
46 
47 
48 // -----------------------------------------------------------------------------
49 // Eigen and std::vector
50 // -----------------------------------------------------------------------------
51 
52 namespace Tomographer {
53 namespace Tools {
54 
69 template<typename EigenType>
71 {
73 };
74 
75 } // namespace Tools
76 } // namespace Tomographer
77 
78 // -----------------------------------------------------------------------------
79 // Random matrices in Eigen
80 // -----------------------------------------------------------------------------
81 
82 namespace Tomographer {
83 namespace Tools {
84 
85 namespace tomo_internal {
86 
87  template<typename Rng, typename RndDist, typename Scalar>
88  struct random_generator
89  {
90  typedef Scalar result_type;
91 
92  Rng & rng;
93  RndDist & rnddist;
94 
95  random_generator(Rng & rng_, RndDist & rnddist_)
96  : rng(rng_), rnddist(rnddist_)
97  {
98  }
99 
100  template<typename Index>
101  inline const result_type operator() (Index, Index = 0) const {
102  return rnddist(rng);
103  }
104  };
105 
106  template<typename Rng, typename RndDist, typename RealScalar>
107  struct random_generator<Rng, RndDist, std::complex<RealScalar> >
108  {
109  typedef std::complex<RealScalar> result_type;
110 
111  Rng & rng;
112  RndDist & rnddist;
113 
114  random_generator(Rng & rng_, RndDist & rnddist_)
115  : rng(rng_), rnddist(rnddist_)
116  {
117  }
118 
119  template<typename Index>
120  inline const result_type operator() (Index, Index = 0) const {
121  return result_type(rnddist(rng), rnddist(rng));
122  }
123  };
124 } // end namespace tomo_internal
125 
126 } // namespace Tools
127 } // namespace Tomographer
128 
129 namespace Eigen {
130  namespace internal {
132  template<typename Rng, typename RndDist, typename Scalar>
133  struct functor_traits<Tomographer::Tools::tomo_internal::random_generator<Rng, RndDist, Scalar> >
134  { enum { Cost = 50 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
135  }
136 } // end namespace Eigen
137 
138 
139 namespace Tomographer {
140 namespace Tools {
141 
142 
151 template<typename Der, typename Rng, typename RndDist, typename... IndexTypes>
152 inline auto denseRandom(Rng & rng, RndDist &rnddist, IndexTypes... sizes)
153  -> const Eigen::CwiseNullaryOp<
154  tomo_internal::random_generator<Rng, RndDist, typename Eigen::internal::traits<Der>::Scalar>,
155  Der
156  >
157 {
158  typedef typename Der::Scalar Scalar;
159 
161  sizes..., tomo_internal::random_generator<Rng, RndDist, Scalar>(rng, rnddist)
162  );
163 }
164 
165 
166 
167 // ---------------------------
168 
169 
170 
171 namespace tomo_internal {
173  template<typename Scalar, typename IndexType>
174  struct can_basis_vec_generator
175  {
176  typedef Scalar result_type;
177 
178  const IndexType k;
179  const IndexType j;
180 
181  can_basis_vec_generator(IndexType k_, IndexType j_ = 0)
182  : k(k_), j(j_)
183  {
184  }
185 
186  inline const result_type operator() (IndexType a, IndexType b = 0) const {
187  return (a == k) && (b == j) ? result_type(1) : result_type(0);
188  }
189  };
190 } // namespace tomo_internal
191 } // namespace Tools
192 } // namespace Tomographer
193 namespace Eigen {
194  namespace internal {
196  template<typename Scalar, typename IndexType>
197  struct functor_traits<Tomographer::Tools::tomo_internal::can_basis_vec_generator<Scalar, IndexType> >
198  { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = true }; };
199  template<typename Scalar, typename IndexType>
200  struct functor_has_linear_access<Tomographer::Tools::tomo_internal::can_basis_vec_generator<Scalar, IndexType> >
201  { enum { ret = 0 }; };
202  }
203 } // end namespace Eigen
204 
205 namespace Tomographer {
206 namespace Tools {
207 
211 template<typename Der, typename IndexType>
212 inline auto canonicalBasisVec(IndexType k, IndexType size)
213  -> const Eigen::CwiseNullaryOp<
214  tomo_internal::can_basis_vec_generator<typename Eigen::internal::traits<Der>::Scalar, IndexType>,
215  Der
216  >
217 {
218  typedef typename Der::Scalar Scalar;
219 
221  size, tomo_internal::can_basis_vec_generator<Scalar, IndexType>(k)
222  );
223 }
224 
229 template<typename Der, typename IndexType>
230 inline auto canonicalBasisVec(IndexType k, IndexType j, IndexType rows, IndexType cols)
231  -> const Eigen::CwiseNullaryOp<
232  tomo_internal::can_basis_vec_generator<typename Eigen::internal::traits<Der>::Scalar, IndexType>,
233  Der
234  >
235 {
236  typedef typename Der::Scalar Scalar;
237 
239  rows, cols, tomo_internal::can_basis_vec_generator<Scalar, IndexType>(k, j)
240  );
241 }
242 
243 
244 
245 
246 // ---------------------------
247 
248 
249 
250 namespace tomo_internal {
252  template<typename Scalar>
253  struct powers_of_two_generator
254  {
255  typedef typename Eigen::NumTraits<Scalar>::Real result_type;
256 
257  powers_of_two_generator() { }
258 
259  template<typename IndexType>
260  inline const result_type operator() (IndexType a) const {
261  return std::ldexp(result_type(1), a);
262  }
263 
264  template<typename IndexType>
265  inline const result_type operator() (IndexType a, IndexType b) const {
266  eigen_assert(b == 0 && "powers_of_two_generator may only be used with 1-D objects or with linear access!");
267  (void)b; // silence unused variable warning if eigen_assert is optimized out
268  return std::ldexp(result_type(1), a);
269  }
270 
271  };
272 } // namespace tomo_internal
273 } // namespace Tools
274 } // namespace Tomographer
275 namespace Eigen {
276  namespace internal {
278  template<typename Scalar>
279  struct functor_traits<Tomographer::Tools::tomo_internal::powers_of_two_generator<Scalar> >
280  { enum { Cost = 8 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = true }; };
281 
282  // template<typename Scalar>
283  // struct functor_has_linear_access<Tomographer::Tools::tomo_internal::powers_of_two_generator<Scalar> >
284  // { enum { ret = 0 }; };
285  }
286 } // end namespace Eigen
287 
288 namespace Tomographer {
289 namespace Tools {
290 
291 
304 template<typename Der, typename... IndexTypes>
305 inline auto powersOfTwo(IndexTypes... sizes)
306  -> const Eigen::CwiseNullaryOp<
307  tomo_internal::powers_of_two_generator<typename Eigen::internal::traits<Der>::Scalar>,
308  Der
309  >
310 {
311  typedef typename Der::Scalar Scalar;
312 
314  sizes..., tomo_internal::powers_of_two_generator<Scalar>()
315  );
316 }
317 
318 
319 
320 
321 
322 // -----------------------------------------------------------------------------
323 
339 template<int RowFactorCTime, int ColFactorCTime, typename Derived,
340  typename std::enable_if<(RowFactorCTime == Eigen::Dynamic || ColFactorCTime == Eigen::Dynamic),
341  bool>::type dummy = true>
342 inline auto replicated(const Eigen::DenseBase<Derived> & x, int row_factor, int col_factor)
344 {
345  eigen_assert(RowFactorCTime == Eigen::Dynamic || row_factor == RowFactorCTime);
346  eigen_assert(ColFactorCTime == Eigen::Dynamic || col_factor == ColFactorCTime);
347  return x.replicate(row_factor, col_factor);
348 }
353 template<int RowFactorCTime, int ColFactorCTime, typename Derived,
354  typename std::enable_if<(RowFactorCTime != Eigen::Dynamic && ColFactorCTime != Eigen::Dynamic),
355  bool>::type dummy2 = true>
356 inline auto replicated(const Eigen::DenseBase<Derived> & x, int row_factor, int col_factor)
358 {
359  eigen_assert(row_factor == RowFactorCTime); (void)row_factor; // "unused argument" warning
360  eigen_assert(col_factor == ColFactorCTime); (void)col_factor; // "unused argument" warning
361  return x.template replicate<RowFactorCTime, ColFactorCTime>();
362 }
363 
364 } // namespace Tools
365 } // namespace Tomographer
366 
367 
368 
369 
370 #endif
auto canonicalBasisVec(IndexType k, IndexType size) -> const Eigen::CwiseNullaryOp< tomo_internal::can_basis_vec_generator< typename Eigen::internal::traits< Der >::Scalar, IndexType >, Der >
Expression for the k-th canonical basis vector of given dimension.
Definition: eigenutil.h:212
static const CwiseNullaryOp< CustomNullaryOp, Derived > NullaryExpr(Index rows, Index cols, const CustomNullaryOp &func)
Base namespace for the Tomographer project.
Definition: densellh.h:44
auto powersOfTwo(IndexTypes...sizes) -> const Eigen::CwiseNullaryOp< tomo_internal::powers_of_two_generator< typename Eigen::internal::traits< Der >::Scalar >, Der >
Expression for a 1-D expression of powers of two.
Definition: eigenutil.h:305
STL class.
Use this if you need an std::vector of any Eigen type.
Definition: eigenutil.h:70
T ldexp(T...args)
auto replicated(const Eigen::DenseBase< Derived > &x, int row_factor, int col_factor) -> const Eigen::Replicate< Derived, Eigen::Dynamic, Eigen::Dynamic >
Replicate a Eigen Dense object; same call for compile-time & run-time dimensions. ...
Definition: eigenutil.h:342
STL class.
auto denseRandom(Rng &rng, RndDist &rnddist, IndexTypes...sizes) -> const Eigen::CwiseNullaryOp< tomo_internal::random_generator< Rng, RndDist, typename Eigen::internal::traits< Der >::Scalar >, Der >
a matrix populated with random entries using C++&#39;s random framework
Definition: eigenutil.h:152
const Replicate< Derived, RowFactor, ColFactor > replicate() const