Tomographer  v2.0
Tomographer C++ Framework Documentation
indepmeasllh.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_DENSEDM_INDEPMEASLLH_H
28 #define TOMOGRAPHER_DENSEDM_INDEPMEASLLH_H
29 
30 #include <cstddef>
31 #include <string>
32 #include <iomanip> // std::setprecision, std::setw and friends.
33 
34 #include <Eigen/Eigen>
35 
36 #include <tomographer2/tools/cxxutil.h> // StaticOrDynamic, TOMOGRAPHER_ENABLED_IF
38 #include <tomographer2/tools/fmt.h> // streamstr
42 
49 namespace Tomographer {
50 namespace DenseDM {
51 
52 
53 
54 
60 template<typename DMTypes_, typename LLHValueType_ = typename DMTypes_::RealScalar,
61  typename IntFreqType_ = int, int FixedMaxParamList_ = Eigen::Dynamic,
62  bool UseNMeasAmplifyFactor_ = false>
65 {
66 public:
68  typedef DMTypes_ DMTypes;
70  typedef LLHValueType_ LLHValueType;
72  typedef IntFreqType_ IntFreqType;
74  static constexpr int FixedMaxParamList = FixedMaxParamList_;
76  static constexpr bool IsDynamicMaxParamList = (FixedMaxParamList_ == Eigen::Dynamic);
78  static constexpr bool UseNMeasAmplifyFactor = UseNMeasAmplifyFactor_;
79 
84  enum {
87  } ;
88 
92  typedef Eigen::Matrix<typename DMTypes::RealScalar, Eigen::Dynamic, DMTypes::FixedDim2,
96 
101 
104  typedef Eigen::Array<IntFreqType, Eigen::Dynamic, 1,
105  0 /*Options*/, FixedMaxParamList, 1> FreqListType;
108 
109 
115  inline IndepMeasLLH(DMTypes dmt_)
116  : dmt(dmt_), _Exn(VectorParamListType::Zero(0, dmt.dim2())), _Nx(FreqListType::Zero(0)),
117  _NMeasAmplifyFactor(1)
118  {
119  }
120 
125  inline IndepMeasLLH(DMTypes dmt_, VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_)
126  : dmt(dmt_), _Exn(VectorParamListType::Zero(0, dmt.dim2())), _Nx(FreqListType::Zero(0)), _NMeasAmplifyFactor(1)
127  {
128  setMeas(Exn_, Nx_);
129  }
130 
132  const DMTypes dmt;
133 
140  inline const IndexType numEffects() const { return _Exn.rows(); }
141 
152  inline const VectorParamListType & Exn() const { return _Exn; }
153 
161  {
162  return _Exn.row(i).transpose();
163  }
164 
165 
177  inline const FreqListType & Nx() const { return _Nx; }
178 
186  inline const IntFreqType Nx(IndexType i) const { return _Nx(i); }
187 
193  inline void resetMeas()
194  {
195  _Exn.resize(0, dmt.dim2());
196  _Nx.resize(0);
197  }
198 
214  inline void addMeasEffect(typename DMTypes::VectorParamTypeConstRef E_x, IntFreqType n,
215  bool check_validity = true)
216  {
217  // no change if frequency count for the added effect == 0
218  if (n == 0) {
219  return;
220  }
221 
222  tomographer_assert(n > 0);
223 
224  if (check_validity) { // check validity of measurement data
225  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
226  E_m = ParamX<DMTypes>(dmt).XToHerm(E_x);
227  _check_effect(E_m);
228  }
229 
230  IndexType newi = _Exn.rows();
231  tomographer_assert(newi == _Nx.rows());
232 
233  _Exn.conservativeResize(newi + 1, Eigen::NoChange);
234  _Exn.row(newi) = E_x.transpose();
235  _Nx.conservativeResize(newi + 1, Eigen::NoChange);
236  _Nx(newi) = n;
237 
238  tomographer_assert(_Exn.rows() == _Nx.rows());
239  }
240 
250  inline void addMeasEffect(typename DMTypes::MatrixTypeConstRef E_m, IntFreqType n,
251  bool check_validity = true)
252  {
253  tomographer_assert(E_m.rows() == E_m.cols());
254  tomographer_assert(E_m.rows() == (IndexType)dmt.dim());
255 
256  // skip if no frequency count
257  if (n == 0) {
258  return;
259  }
260 
261  if (check_validity) { // check validity of measurement data
262  tomographer_assert(n > 0);
263  _check_effect(E_m);
264  }
265 
266  addMeasEffect(Tomographer::DenseDM::ParamX<DMTypes>(dmt).HermToX(E_m), n, false);
267  }
268 
273  inline void setMeas(VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_, bool check_validity = true)
274  {
275  tomographer_assert(Exn_.cols() == (IndexType)dmt.dim2());
276  tomographer_assert(Exn_.rows() == Nx_.rows());
277  tomographer_assert(Nx_.cols() == 1);
278 
279  if ((Nx_ > 0).all()) {
280  // all measurements are OK, so we can just copy the data.
281  _Exn.resize(Exn_.rows(), dmt.dim2());
282  _Exn = Exn_;
283  _Nx.resize(Nx_.rows(), 1);
284  _Nx = Nx_;
285  } else {
286  // otherwise, we have to add all measurements one by one, and filter out the zero-count ones.
287  resetMeas();
288  for (IndexType i = 0; i < Exn_.rows(); ++i) {
289  addMeasEffect(Exn_.row(i), Nx_(i));
290  }
291  }
292  if (check_validity) {
293  checkAllMeas();
294  }
295  }
296 
297  inline void checkAllMeas() const
298  {
299  tomographer_assert(_Exn.cols() == (IndexType)dmt.dim2());
300  tomographer_assert(_Exn.rows() == _Nx.rows());
301  tomographer_assert(_Nx.cols() == 1);
302 
303  for (IndexType i = 0; i < _Exn.rows(); ++i) {
304 
305  tomographer_assert(_Nx(i) > 0);
306 
307  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
308  E_m = ParamX<DMTypes>(dmt).XToHerm(_Exn.row(i).transpose());
309  _check_effect(E_m);
310  }
311  }
312  inline void checkEffect(IndexType i) const
313  {
314  tomographer_assert(_Exn.cols() == (IndexType)dmt.dim2());
315  tomographer_assert(_Exn.rows() == _Nx.rows());
316  tomographer_assert(_Nx.cols() == 1);
317  tomographer_assert(i >= 0 && i < _Exn.rows());
318  tomographer_assert(_Nx(i) > 0);
319 
320  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
321  E_m = ParamX<DMTypes>(dmt).XToHerm(_Exn.row(i).transpose());
322  _check_effect(E_m);
323  }
324 
325 private:
326  inline void _check_effect(typename DMTypes::MatrixType E_m) const
327  {
328  if ( ! (double( (E_m - E_m.adjoint()).norm() ) < 1e-8) ) { // matrix not Hermitian
329  throw InvalidMeasData(streamstr("POVM effect is not hermitian : E_m =\n"
330  << std::setprecision(10) << E_m));
331  }
333  const double mineigval = slv.eigenvalues().minCoeff();
334  if ( ! (mineigval >= -1e-12) ) { // not positive semidef
335  throw InvalidMeasData(streamstr("POVM effect is not positive semidefinite (min eigval="<<mineigval<<") : E_m =\n"
336  << std::setprecision(10) << E_m));
337  }
338  if ( ! (double(E_m.norm()) > 1e-6) ) { // POVM effect is zero
339  throw InvalidMeasData(streamstr("POVM effect is zero : E_m =\n" << E_m));
340  }
341  }
342 
343 public:
344 
350  TOMOGRAPHER_ENABLED_IF(UseNMeasAmplifyFactor)
351  inline LLHValueType NMeasAmplifyFactor() const { return _NMeasAmplifyFactor.value; }
352 
354  TOMOGRAPHER_ENABLED_IF(!UseNMeasAmplifyFactor)
355  inline LLHValueType NMeasAmplifyFactor() const { return LLHValueType(1); }
356 
363  TOMOGRAPHER_ENABLED_IF(UseNMeasAmplifyFactor)
364  inline void setNMeasAmplifyFactor(LLHValueType val) { _NMeasAmplifyFactor.value = val; }
365 
366 
377  {
378  return _mult_by_nmeasfactor(
379  (_Nx.template cast<LLHValueType>() * (_Exn * x).template cast<LLHValueType>().array().log()).sum()
380  );
381  }
382 
383 private:
384  template<typename Expr, TOMOGRAPHER_ENABLED_IF_TMPL(UseNMeasAmplifyFactor)>
385  inline auto _mult_by_nmeasfactor(Expr&& expr) const -> decltype(LLHValueType(1) * expr)
386  {
387  return _NMeasAmplifyFactor.value * expr;
388  }
389  template<typename Expr, TOMOGRAPHER_ENABLED_IF_TMPL(!UseNMeasAmplifyFactor)>
390  inline auto _mult_by_nmeasfactor(Expr&& expr) const -> decltype(std::forward<Expr>(expr))
391  {
392  return std::forward<Expr>(expr);
393  }
394 
395 private:
397  VectorParamListType _Exn;
399  FreqListType _Nx;
400 
403 };
404 // define static members:
405 template<typename DMTypes_, typename LLHValueType_,
406  typename IntFreqType_, int FixedMaxParamList_,
407  bool UseNMeasAmplifyFactor_>
408 constexpr int
410 template<typename DMTypes_, typename LLHValueType_,
411  typename IntFreqType_, int FixedMaxParamList_,
412  bool UseNMeasAmplifyFactor_>
413 constexpr bool
415 template<typename DMTypes_, typename LLHValueType_,
416  typename IntFreqType_, int FixedMaxParamList_,
417  bool UseNMeasAmplifyFactor_>
418 constexpr bool
420 
421 
422 
423 
424 
425 } // namespace DenseDM
426 } // namespace Tomographer
427 
428 
429 
430 
431 
432 
433 
434 
435 #endif
Utilities for formatting strings.
const Eigen::Ref< const VectorParamListType > & VectorParamListTypeConstRef
Const ref to a VectorParamListType.
Definition: indepmeasllh.h:95
const Eigen::Ref< const FreqListType > & FreqListTypeConstRef
Const ref to a FreqListType.
Definition: indepmeasllh.h:107
RowXpr row(Index i)
Provides correct operator-new implementation for Eigen types via the NeedOwnOperatorNew mechanism...
Base namespace for the Tomographer project.
Definition: densellh.h:44
static constexpr bool IsDynamicMaxParamList
Whether the dimension is specified dynamically at run-time or statically at compile-time.
Definition: indepmeasllh.h:76
const RealVectorType & eigenvalues() const
C++ types for describing dense density matrices in various parameterizations.
internal::traits< Matrix< typename DMTypes::RealScalar, Eigen::Dynamic, DMTypes::FixedDim2, Eigen::RowMajor, FixedMaxParamList, DMTypes::FixedDim2 > >::Index Index
IndepMeasLLH(DMTypes dmt_, VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_)
Constructor with full measurement data.
Definition: indepmeasllh.h:125
const DMTypes dmt
The DMTypes object, storing e.g. the dimension of the problem.
Definition: indepmeasllh.h:132
void setMeas(VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_, bool check_validity=true)
Specify the full measurement data at once.
Definition: indepmeasllh.h:273
const IndexType numEffects() const
The number of POVM effects in the list.
Definition: indepmeasllh.h:140
Eigen::Ref< const typename DMTypes::VectorParamType > Exn(IndexType i) const
The i-th stored POVM effect, in X Parameterization.
Definition: indepmeasllh.h:160
void addMeasEffect(typename DMTypes::VectorParamTypeConstRef E_x, IntFreqType n, bool check_validity=true)
Store a measurement POVM effect along with a frequency count.
Definition: indepmeasllh.h:214
const FreqListType & Nx() const
The stored frequency counts for each individual POVM effect.
Definition: indepmeasllh.h:177
C++ types and functions for calculating the log-likelihood for POVM effects which can be written as a...
Definition: indepmeasllh.h:63
#define streamstr(tokens)
Utility macro to format stream tokens to a std::string.
Definition: fmt.h:145
LLHValueType NMeasAmplifyFactor() const
Factor by which to artificially amplify the number of measurements.
Definition: indepmeasllh.h:351
static constexpr int FixedDim2
The square of the dimension of the quantum system, or Eigen::Dynamic.
Definition: dmtypes.h:112
LLHValueType_ LLHValueType
Type used to calculate the log-likelihood function (see DenseLLH Interface)
Definition: indepmeasllh.h:70
static constexpr int FixedMaxParamList
Maximum number of POVM effects, fixed at compile-time or Eigen::Dynamic.
Definition: indepmeasllh.h:74
void conservativeResize(Index nbRows, Index nbCols)
const VectorParamListType & Exn() const
The stored individual POVM effects, in X Parameterization.
Definition: indepmeasllh.h:152
Tools for parameterizing hermitian matrices with the X Parameterization.
Exception class notifying of invalid measurement data.
Definition: densellh.h:83
DMTypes_ DMTypes
The DMTypes in use here.
Definition: indepmeasllh.h:68
const IntFreqType Nx(IndexType i) const
The number of counts stored for the i-th POVM effect.
Definition: indepmeasllh.h:186
Some declarations for the DenseLLH type interface.
static constexpr bool UseNMeasAmplifyFactor
Whether we allow NMeasAmplifyFactor to be set.
Definition: indepmeasllh.h:78
VectorParamListType::Index IndexType
Type used to index entries in VectorParamListType (and also used for indexing entries in FreqListType...
Definition: indepmeasllh.h:100
IntFreqType_ IntFreqType
Type used to store integer measurement counts.
Definition: indepmeasllh.h:72
Some C++ utilities, with a tad of C++11 tricks.
Eigen::Matrix< typename DMTypes::RealScalar, Eigen::Dynamic, DMTypes::FixedDim2, Eigen::RowMajor, FixedMaxParamList, DMTypes::FixedDim2 > VectorParamListType
dynamic Matrix with rows = dim*dim Vectors (row-major) [maximum FixedMaxParamList rows...
Definition: indepmeasllh.h:93
Managing the need for specific overrides to operator new() for some types (especially Eigen types) ...
Eigen::Array< IntFreqType, Eigen::Dynamic, 1, 0, FixedMaxParamList, 1 > FreqListType
dynamic Array of integers [maximum FixedMaxParamList entries or Dynamic]
Definition: indepmeasllh.h:105
LLHValueType logLikelihoodX(typename DMTypes::VectorParamTypeConstRef x) const
Calculates the log-likelihood function, in X parameterization.
Definition: indepmeasllh.h:376
Declare that this DenseLLH object exposes a logLikelihoodX() method.
Definition: indepmeasllh.h:86
void setNMeasAmplifyFactor(LLHValueType val)
Set the factor by which to artificially multiply all frequency counts.
Definition: indepmeasllh.h:364
const CwiseUnaryOp< internal::scalar_log_op< Scalar >, const Array< _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols > > log() const
void resize(Index nbRows, Index nbCols)
T setprecision(T...args)
void resetMeas()
Reset the measurement vectors and frequency counts.
Definition: indepmeasllh.h:193
IndepMeasLLH(DMTypes dmt_)
Simple constructor.
Definition: indepmeasllh.h:115
RowMajor
The DenseLLH-compatible object exposes a method logLikelihoodX(), taking as argument a (const ref to ...
Definition: densellh.h:65
RealScalar_ RealScalar
Real scalar type, given in template parameter. Usually double is fine.
Definition: dmtypes.h:119
void addMeasEffect(typename DMTypes::MatrixTypeConstRef E_m, IntFreqType n, bool check_validity=true)
Store a POVM measurement effect with frequency count.
Definition: indepmeasllh.h:250