Tomographer  v5.4
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) 2016 ETH Zurich, Institute for Theoretical Physics, Philippe Faist
7  * Copyright (c) 2017 Caltech, Institute for Quantum Information and Matter, Philippe Faist
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining a copy
10  * of this software and associated documentation files (the "Software"), to deal
11  * in the Software without restriction, including without limitation the rights
12  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13  * copies of the Software, and to permit persons to whom the Software is
14  * furnished to do so, subject to the following conditions:
15  *
16  * The above copyright notice and this permission notice shall be included in
17  * all copies or substantial portions of the Software.
18  *
19  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 #ifndef TOMOGRAPHER_DENSEDM_INDEPMEASLLH_H
29 #define TOMOGRAPHER_DENSEDM_INDEPMEASLLH_H
30 
31 #include <cstddef>
32 #include <string>
33 #include <iomanip> // std::setprecision, std::setw and friends.
34 
35 #include <Eigen/Eigen>
36 
37 #include <boost/serialization/serialization.hpp>
38 
39 #include <tomographer/tools/cxxutil.h> // StaticOrDynamic, TOMOGRAPHER_ENABLED_IF
41 #include <tomographer/tools/fmt.h> // streamstr
45 
52 namespace Tomographer {
53 namespace DenseDM {
54 
55 
56 
57 
66 template<typename DMTypes_, typename LLHValueType_ = typename DMTypes_::RealScalar,
67  typename IntFreqType_ = int, int FixedMaxParamList_ = Eigen::Dynamic,
68  bool UseNMeasAmplifyFactor_ = false>
69 class TOMOGRAPHER_EXPORT IndepMeasLLH
70 // : public Tools::NeedEigenAlignedOperatorNew::ProviderType -- not needed, matrices are Eigen::Dynamic for now
71 {
72 public:
74  typedef DMTypes_ DMTypes;
76  typedef LLHValueType_ LLHValueType;
78  typedef IntFreqType_ IntFreqType;
80  static constexpr int FixedMaxParamList = FixedMaxParamList_;
82  static constexpr bool IsDynamicMaxParamList = (FixedMaxParamList_ == Eigen::Dynamic);
84  static constexpr bool UseNMeasAmplifyFactor = UseNMeasAmplifyFactor_;
85 
90  enum {
92  LLHCalcType = LLHCalcTypeX
93  } ;
94 
98  typedef Eigen::Matrix<typename DMTypes::RealScalar, Eigen::Dynamic, DMTypes::FixedDim2,
99  Eigen::RowMajor, FixedMaxParamList, DMTypes::FixedDim2> VectorParamListType;
102 
107 
110  typedef Eigen::Array<IntFreqType, Eigen::Dynamic, 1,
111  0 /*Options*/, FixedMaxParamList, 1> FreqListType;
114 
115 
121  inline IndepMeasLLH(DMTypes dmt_)
122  : dmt(dmt_), _Exn(VectorParamListType::Zero(0, (Eigen::Index)dmt.dim2())), _Nx(FreqListType::Zero(0)),
123  _NMeasAmplifyFactor(1)
124  {
125  }
126 
131  inline IndepMeasLLH(DMTypes dmt_, VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_)
132  : dmt(dmt_), _Exn(VectorParamListType::Zero(0, dmt.dim2())), _Nx(FreqListType::Zero(0)), _NMeasAmplifyFactor(1)
133  {
134  setMeas(Exn_, Nx_);
135  }
136 
138  const DMTypes dmt;
139 
146  inline const IndexType numEffects() const { return _Exn.rows(); }
147 
158  inline const VectorParamListType & Exn() const { return _Exn; }
159 
167  {
168  return _Exn.row(i).transpose();
169  }
170 
171 
183  inline const FreqListType & Nx() const { return _Nx; }
184 
192  inline const IntFreqType Nx(IndexType i) const { return _Nx(i); }
193 
199  inline void resetMeas()
200  {
201  _Exn.resize(0, (Eigen::Index)dmt.dim2());
202  _Nx.resize(0);
203  }
204 
220  inline void addMeasEffect(typename DMTypes::VectorParamTypeConstRef E_x, IntFreqType n,
221  bool check_validity = true)
222  {
223  // no change if frequency count for the added effect == 0
224  if (n == 0) {
225  return;
226  }
227 
228  tomographer_assert(n > 0);
229 
230  if (check_validity) { // check validity of measurement data
231  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
232  E_m = ParamX<DMTypes>(dmt).XToHerm(E_x);
233  _check_effect(E_m);
234  }
235 
236  IndexType newi = _Exn.rows();
237  tomographer_assert(newi == _Nx.rows());
238 
239  _Exn.conservativeResize(newi + 1, Eigen::NoChange);
240  _Exn.row(newi) = E_x.transpose();
241  _Nx.conservativeResize(newi + 1, Eigen::NoChange);
242  _Nx(newi) = n;
243 
244  tomographer_assert(_Exn.rows() == _Nx.rows());
245  }
246 
256  inline void addMeasEffect(typename DMTypes::MatrixTypeConstRef E_m, IntFreqType n,
257  bool check_validity = true)
258  {
259  tomographer_assert(E_m.rows() == E_m.cols());
260  tomographer_assert(E_m.rows() == (IndexType)dmt.dim());
261 
262  // skip if no frequency count
263  if (n == 0) {
264  return;
265  }
266 
267  if (check_validity) { // check validity of measurement data
268  tomographer_assert(n > 0);
269  _check_effect(E_m);
270  }
271 
272  addMeasEffect(Tomographer::DenseDM::ParamX<DMTypes>(dmt).HermToX(E_m), n, false);
273  }
274 
279  inline void setMeas(VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_, bool check_validity = true)
280  {
281  tomographer_assert(Exn_.cols() == (IndexType)dmt.dim2());
282  tomographer_assert(Exn_.rows() == Nx_.rows());
283  tomographer_assert(Nx_.cols() == 1);
284 
285  if ((Nx_ > 0).all()) {
286  // all measurements are OK, so we can just copy the data.
287  _Exn.resize(Exn_.rows(), (Eigen::Index)dmt.dim2());
288  _Exn = Exn_;
289  _Nx.resize(Nx_.rows(), 1);
290  _Nx = Nx_;
291  } else {
292  // otherwise, we have to add all measurements one by one, and filter out the zero-count ones.
293  resetMeas();
294  for (IndexType i = 0; i < Exn_.rows(); ++i) {
295  addMeasEffect(Exn_.row(i), Nx_(i), false);
296  }
297  }
298  if (check_validity) {
299  checkAllMeas();
300  }
301  }
302 
303  inline void checkAllMeas() const
304  {
305  tomographer_assert(_Exn.cols() == (IndexType)dmt.dim2());
306  tomographer_assert(_Exn.rows() == _Nx.rows());
307  tomographer_assert(_Nx.cols() == 1);
308 
309  for (IndexType i = 0; i < _Exn.rows(); ++i) {
310 
311  tomographer_assert(_Nx(i) > 0);
312 
313  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
314  E_m = ParamX<DMTypes>(dmt).XToHerm(_Exn.row(i).transpose());
315  _check_effect(E_m);
316  }
317  }
318  inline void checkEffect(IndexType i) const
319  {
320  tomographer_assert(_Exn.cols() == (IndexType)dmt.dim2());
321  tomographer_assert(_Exn.rows() == _Nx.rows());
322  tomographer_assert(_Nx.cols() == 1);
323  tomographer_assert(i >= 0 && i < _Exn.rows());
324  tomographer_assert(_Nx(i) > 0);
325 
326  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
327  E_m = ParamX<DMTypes>(dmt).XToHerm(_Exn.row(i).transpose());
328  _check_effect(E_m);
329  }
330 
331 private:
332  inline void _check_effect(typename DMTypes::MatrixType E_m) const
333  {
334  if ( ! (double( (E_m - E_m.adjoint()).norm() ) < 1e-8) ) { // matrix not Hermitian
335  throw InvalidMeasData(streamstr("POVM effect is not hermitian : E_m =\n"
336  << std::setprecision(10) << E_m));
337  }
339  const typename DMTypes::RealScalar mineigval = slv.eigenvalues().minCoeff();
341  // not positive semidef
342  throw InvalidMeasData(streamstr("POVM effect is not positive semidefinite (min eigval="
343  << mineigval << ") : E_m =\n"
344  << std::setprecision(10) << E_m));
345  }
346  if ( ! (double(E_m.norm()) > 1e-6) ) { // POVM effect is zero
347  throw InvalidMeasData(streamstr("POVM effect is zero : E_m =\n" << E_m));
348  }
349  }
350 
351 public:
352 
358  TOMOGRAPHER_ENABLED_IF(UseNMeasAmplifyFactor)
359  inline LLHValueType NMeasAmplifyFactor() const { return _NMeasAmplifyFactor.value; }
360 
362  TOMOGRAPHER_ENABLED_IF(!UseNMeasAmplifyFactor)
363  inline LLHValueType NMeasAmplifyFactor() const { return LLHValueType(1); }
364 
371  TOMOGRAPHER_ENABLED_IF(UseNMeasAmplifyFactor)
372  inline void setNMeasAmplifyFactor(LLHValueType val) { _NMeasAmplifyFactor.value = val; }
373 
374 
385  {
386  return _mult_by_nmeasfactor(
387  (_Nx.template cast<LLHValueType>() * (_Exn * x).template cast<LLHValueType>().array().log()).sum()
388  );
389  }
390 
391 private:
392  template<typename Expr, TOMOGRAPHER_ENABLED_IF_TMPL(UseNMeasAmplifyFactor)>
393  inline auto _mult_by_nmeasfactor(Expr&& expr) const -> decltype(LLHValueType(1) * expr)
394  {
395  return _NMeasAmplifyFactor.value * expr;
396  }
397  template<typename Expr, TOMOGRAPHER_ENABLED_IF_TMPL(!UseNMeasAmplifyFactor)>
398  inline auto _mult_by_nmeasfactor(Expr&& expr) const -> decltype(std::forward<Expr>(expr))
399  {
400  return std::forward<Expr>(expr);
401  }
402 
403 private:
405  VectorParamListType _Exn;
407  FreqListType _Nx;
408 
411 
412  friend boost::serialization::access;
413  template<typename Archive>
414  void serialize(Archive & a, const unsigned int version)
415  {
416  a & _Exn;
417  a & _Nx;
418  maybe_serialize_nmeasamplifyfactor(a, version);
419  }
420  template<typename Archive, TOMOGRAPHER_ENABLED_IF_TMPL(UseNMeasAmplifyFactor)>
421  inline void maybe_serialize_nmeasamplifyfactor(Archive & a, const unsigned int /*version*/)
422  {
423  a & _NMeasAmplifyFactor.value;
424  }
425  template<typename Archive, TOMOGRAPHER_ENABLED_IF_TMPL(!UseNMeasAmplifyFactor)>
426  inline void maybe_serialize_nmeasamplifyfactor(Archive & , const unsigned int) { }
427 };
428 // define static members:
429 template<typename DMTypes_, typename LLHValueType_,
430  typename IntFreqType_, int FixedMaxParamList_,
431  bool UseNMeasAmplifyFactor_>
432 constexpr int
434 template<typename DMTypes_, typename LLHValueType_,
435  typename IntFreqType_, int FixedMaxParamList_,
436  bool UseNMeasAmplifyFactor_>
437 constexpr bool
439 template<typename DMTypes_, typename LLHValueType_,
440  typename IntFreqType_, int FixedMaxParamList_,
441  bool UseNMeasAmplifyFactor_>
442 constexpr bool
444 
445 } // namespace DenseDM
446 } // namespace Tomographer
447 
448 
449 //
450 // We need to work more for serializing IndepMeasLLH, because we need to provide it the
451 // right constructor arguments
452 //
453 namespace boost {
454 namespace serialization {
455 template<typename Archive,
456  typename DMTypes_, typename LLHValueType_, typename IntFreqType_,
457  int FixedMaxParamList_, bool UseNMeasAmplifyFactor_>
458 inline void save_construct_data(
459  Archive & a,
460  const Tomographer::DenseDM::IndepMeasLLH<DMTypes_, LLHValueType_, IntFreqType_,
461  FixedMaxParamList_, UseNMeasAmplifyFactor_> * t,
462  const unsigned int /*version*/)
463 {
464  // save data required to construct instance
465  Eigen::Index dim = t->dmt.dim();
466  a << dim; // for some reason, boost serialization archives require to provide lvalues...
467 }
468 
469 template<class Archive,
470  typename DMTypes_, typename LLHValueType_, typename IntFreqType_,
471  int FixedMaxParamList_, bool UseNMeasAmplifyFactor_>
472 inline void load_construct_data(
473  Archive & a,
474  Tomographer::DenseDM::IndepMeasLLH<DMTypes_, LLHValueType_, IntFreqType_,
475  FixedMaxParamList_, UseNMeasAmplifyFactor_> * t,
476  const unsigned int /*version*/)
477 {
478  typedef Tomographer::DenseDM::IndepMeasLLH<DMTypes_, LLHValueType_, IntFreqType_,
479  FixedMaxParamList_, UseNMeasAmplifyFactor_> TheFreakinType;
480  // retrieve data from archive required to construct new instance
481  Eigen::Index dim;
482  a >> dim;
483  // invoke inplace constructor to initialize instance of our class
484  ::new(t) TheFreakinType(typename TheFreakinType::DMTypes(dim));
485 }
486 } // namespace serialization
487 } // namespace boost
488 
489 
490 
491 
492 
493 
494 
495 
496 #endif
Utilities for formatting strings.
const Eigen::Ref< const VectorParamListType > & VectorParamListTypeConstRef
Const ref to a VectorParamListType.
Definition: indepmeasllh.h:101
const Eigen::Ref< const FreqListType > & FreqListTypeConstRef
Const ref to a FreqListType.
Definition: indepmeasllh.h:113
Base namespace for the Tomographer project.
Definition: densellh.h:45
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:131
const DMTypes dmt
The DMTypes object, storing e.g. the dimension of the problem.
Definition: indepmeasllh.h:138
void setMeas(VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_, bool check_validity=true)
Specify the full measurement data at once.
Definition: indepmeasllh.h:279
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:220
const IntFreqType Nx(IndexType i) const
The number of counts stored for the i-th POVM effect.
Definition: indepmeasllh.h:192
C++ types and functions for calculating the log-likelihood for POVM effects which can be written as a...
Definition: indepmeasllh.h:69
static constexpr int FixedDim2
The square of the dimension of the quantum system, or Eigen::Dynamic.
Definition: dmtypes.h:114
LLHValueType_ LLHValueType
Type used to calculate the log-likelihood function (see DenseLLH Interface)
Definition: indepmeasllh.h:76
Tools for parameterizing hermitian matrices with the X Parameterization.
Exception class notifying of invalid measurement data.
Definition: densellh.h:84
DMTypes_ DMTypes
The DMTypes in use here.
Definition: indepmeasllh.h:74
Some declarations for the DenseLLH type interface.
VectorParamListType::Index IndexType
Type used to index entries in VectorParamListType (and also used for indexing entries in FreqListType...
Definition: indepmeasllh.h:106
IntFreqType_ IntFreqType
Type used to store integer measurement counts.
Definition: indepmeasllh.h:78
const VectorParamListType & Exn() const
The stored individual POVM effects, in X Parameterization.
Definition: indepmeasllh.h:158
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:99
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:111
LLHValueType logLikelihoodX(typename DMTypes::VectorParamTypeConstRef x) const
Calculates the log-likelihood function, in X parameterization.
Definition: indepmeasllh.h:384
const IndexType numEffects() const
The number of POVM effects in the list.
Definition: indepmeasllh.h:146
#define streamstr(tokens)
Utility macro to format stream tokens to a std::string.
Definition: fmt.h:149
T setprecision(T... args)
void resetMeas()
Reset the measurement vectors and frequency counts.
Definition: indepmeasllh.h:199
IndepMeasLLH(DMTypes dmt_)
Simple constructor.
Definition: indepmeasllh.h:121
#define tomographer_assert(...)
Assertion test macro.
Definition: cxxdefs.h:84
RowMajor
The DenseLLH-compatible object exposes a method logLikelihoodX(), taking as argument a (const ref to ...
Definition: densellh.h:66
const FreqListType & Nx() const
The stored frequency counts for each individual POVM effect.
Definition: indepmeasllh.h:183
RealScalar_ RealScalar
Real scalar type, given in template parameter. Usually double is fine.
Definition: dmtypes.h:121
void addMeasEffect(typename DMTypes::MatrixTypeConstRef E_m, IntFreqType n, bool check_validity=true)
Store a POVM measurement effect with frequency count.
Definition: indepmeasllh.h:256
Eigen::Ref< const typename DMTypes::VectorParamType > Exn(IndexType i) const
The i-th stored POVM effect, in X Parameterization.
Definition: indepmeasllh.h:166