Tomographer  v5.2
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 <tomographer/tools/cxxutil.h> // StaticOrDynamic, TOMOGRAPHER_ENABLED_IF
39 #include <tomographer/tools/fmt.h> // streamstr
43 
50 namespace Tomographer {
51 namespace DenseDM {
52 
53 
54 
55 
61 template<typename DMTypes_, typename LLHValueType_ = typename DMTypes_::RealScalar,
62  typename IntFreqType_ = int, int FixedMaxParamList_ = Eigen::Dynamic,
63  bool UseNMeasAmplifyFactor_ = false>
64 class TOMOGRAPHER_EXPORT IndepMeasLLH
65 // : public Tools::NeedEigenAlignedOperatorNew::ProviderType -- not needed, matrices are Eigen::Dynamic for now
66 {
67 public:
69  typedef DMTypes_ DMTypes;
71  typedef LLHValueType_ LLHValueType;
73  typedef IntFreqType_ IntFreqType;
75  static constexpr int FixedMaxParamList = FixedMaxParamList_;
77  static constexpr bool IsDynamicMaxParamList = (FixedMaxParamList_ == Eigen::Dynamic);
79  static constexpr bool UseNMeasAmplifyFactor = UseNMeasAmplifyFactor_;
80 
85  enum {
87  LLHCalcType = LLHCalcTypeX
88  } ;
89 
93  typedef Eigen::Matrix<typename DMTypes::RealScalar, Eigen::Dynamic, DMTypes::FixedDim2,
94  Eigen::RowMajor, FixedMaxParamList, DMTypes::FixedDim2> VectorParamListType;
97 
102 
105  typedef Eigen::Array<IntFreqType, Eigen::Dynamic, 1,
106  0 /*Options*/, FixedMaxParamList, 1> FreqListType;
109 
110 
116  inline IndepMeasLLH(DMTypes dmt_)
117  : dmt(dmt_), _Exn(VectorParamListType::Zero(0, (Eigen::Index)dmt.dim2())), _Nx(FreqListType::Zero(0)),
118  _NMeasAmplifyFactor(1)
119  {
120  }
121 
126  inline IndepMeasLLH(DMTypes dmt_, VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_)
127  : dmt(dmt_), _Exn(VectorParamListType::Zero(0, dmt.dim2())), _Nx(FreqListType::Zero(0)), _NMeasAmplifyFactor(1)
128  {
129  setMeas(Exn_, Nx_);
130  }
131 
133  const DMTypes dmt;
134 
141  inline const IndexType numEffects() const { return _Exn.rows(); }
142 
153  inline const VectorParamListType & Exn() const { return _Exn; }
154 
162  {
163  return _Exn.row(i).transpose();
164  }
165 
166 
178  inline const FreqListType & Nx() const { return _Nx; }
179 
187  inline const IntFreqType Nx(IndexType i) const { return _Nx(i); }
188 
194  inline void resetMeas()
195  {
196  _Exn.resize(0, (Eigen::Index)dmt.dim2());
197  _Nx.resize(0);
198  }
199 
215  inline void addMeasEffect(typename DMTypes::VectorParamTypeConstRef E_x, IntFreqType n,
216  bool check_validity = true)
217  {
218  // no change if frequency count for the added effect == 0
219  if (n == 0) {
220  return;
221  }
222 
223  tomographer_assert(n > 0);
224 
225  if (check_validity) { // check validity of measurement data
226  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
227  E_m = ParamX<DMTypes>(dmt).XToHerm(E_x);
228  _check_effect(E_m);
229  }
230 
231  IndexType newi = _Exn.rows();
232  tomographer_assert(newi == _Nx.rows());
233 
234  _Exn.conservativeResize(newi + 1, Eigen::NoChange);
235  _Exn.row(newi) = E_x.transpose();
236  _Nx.conservativeResize(newi + 1, Eigen::NoChange);
237  _Nx(newi) = n;
238 
239  tomographer_assert(_Exn.rows() == _Nx.rows());
240  }
241 
251  inline void addMeasEffect(typename DMTypes::MatrixTypeConstRef E_m, IntFreqType n,
252  bool check_validity = true)
253  {
254  tomographer_assert(E_m.rows() == E_m.cols());
255  tomographer_assert(E_m.rows() == (IndexType)dmt.dim());
256 
257  // skip if no frequency count
258  if (n == 0) {
259  return;
260  }
261 
262  if (check_validity) { // check validity of measurement data
263  tomographer_assert(n > 0);
264  _check_effect(E_m);
265  }
266 
267  addMeasEffect(Tomographer::DenseDM::ParamX<DMTypes>(dmt).HermToX(E_m), n, false);
268  }
269 
274  inline void setMeas(VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_, bool check_validity = true)
275  {
276  tomographer_assert(Exn_.cols() == (IndexType)dmt.dim2());
277  tomographer_assert(Exn_.rows() == Nx_.rows());
278  tomographer_assert(Nx_.cols() == 1);
279 
280  if ((Nx_ > 0).all()) {
281  // all measurements are OK, so we can just copy the data.
282  _Exn.resize(Exn_.rows(), (Eigen::Index)dmt.dim2());
283  _Exn = Exn_;
284  _Nx.resize(Nx_.rows(), 1);
285  _Nx = Nx_;
286  } else {
287  // otherwise, we have to add all measurements one by one, and filter out the zero-count ones.
288  resetMeas();
289  for (IndexType i = 0; i < Exn_.rows(); ++i) {
290  addMeasEffect(Exn_.row(i), Nx_(i), false);
291  }
292  }
293  if (check_validity) {
294  checkAllMeas();
295  }
296  }
297 
298  inline void checkAllMeas() const
299  {
300  tomographer_assert(_Exn.cols() == (IndexType)dmt.dim2());
301  tomographer_assert(_Exn.rows() == _Nx.rows());
302  tomographer_assert(_Nx.cols() == 1);
303 
304  for (IndexType i = 0; i < _Exn.rows(); ++i) {
305 
306  tomographer_assert(_Nx(i) > 0);
307 
308  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
309  E_m = ParamX<DMTypes>(dmt).XToHerm(_Exn.row(i).transpose());
310  _check_effect(E_m);
311  }
312  }
313  inline void checkEffect(IndexType i) const
314  {
315  tomographer_assert(_Exn.cols() == (IndexType)dmt.dim2());
316  tomographer_assert(_Exn.rows() == _Nx.rows());
317  tomographer_assert(_Nx.cols() == 1);
318  tomographer_assert(i >= 0 && i < _Exn.rows());
319  tomographer_assert(_Nx(i) > 0);
320 
321  typename DMTypes::MatrixType E_m(dmt.initMatrixType());
322  E_m = ParamX<DMTypes>(dmt).XToHerm(_Exn.row(i).transpose());
323  _check_effect(E_m);
324  }
325 
326 private:
327  inline void _check_effect(typename DMTypes::MatrixType E_m) const
328  {
329  if ( ! (double( (E_m - E_m.adjoint()).norm() ) < 1e-8) ) { // matrix not Hermitian
330  throw InvalidMeasData(streamstr("POVM effect is not hermitian : E_m =\n"
331  << std::setprecision(10) << E_m));
332  }
334  const typename DMTypes::RealScalar mineigval = slv.eigenvalues().minCoeff();
336  // not positive semidef
337  throw InvalidMeasData(streamstr("POVM effect is not positive semidefinite (min eigval="
338  << mineigval << ") : E_m =\n"
339  << std::setprecision(10) << E_m));
340  }
341  if ( ! (double(E_m.norm()) > 1e-6) ) { // POVM effect is zero
342  throw InvalidMeasData(streamstr("POVM effect is zero : E_m =\n" << E_m));
343  }
344  }
345 
346 public:
347 
353  TOMOGRAPHER_ENABLED_IF(UseNMeasAmplifyFactor)
354  inline LLHValueType NMeasAmplifyFactor() const { return _NMeasAmplifyFactor.value; }
355 
357  TOMOGRAPHER_ENABLED_IF(!UseNMeasAmplifyFactor)
358  inline LLHValueType NMeasAmplifyFactor() const { return LLHValueType(1); }
359 
366  TOMOGRAPHER_ENABLED_IF(UseNMeasAmplifyFactor)
367  inline void setNMeasAmplifyFactor(LLHValueType val) { _NMeasAmplifyFactor.value = val; }
368 
369 
380  {
381  return _mult_by_nmeasfactor(
382  (_Nx.template cast<LLHValueType>() * (_Exn * x).template cast<LLHValueType>().array().log()).sum()
383  );
384  }
385 
386 private:
387  template<typename Expr, TOMOGRAPHER_ENABLED_IF_TMPL(UseNMeasAmplifyFactor)>
388  inline auto _mult_by_nmeasfactor(Expr&& expr) const -> decltype(LLHValueType(1) * expr)
389  {
390  return _NMeasAmplifyFactor.value * expr;
391  }
392  template<typename Expr, TOMOGRAPHER_ENABLED_IF_TMPL(!UseNMeasAmplifyFactor)>
393  inline auto _mult_by_nmeasfactor(Expr&& expr) const -> decltype(std::forward<Expr>(expr))
394  {
395  return std::forward<Expr>(expr);
396  }
397 
398 private:
400  VectorParamListType _Exn;
402  FreqListType _Nx;
403 
406 };
407 // define static members:
408 template<typename DMTypes_, typename LLHValueType_,
409  typename IntFreqType_, int FixedMaxParamList_,
410  bool UseNMeasAmplifyFactor_>
411 constexpr int
413 template<typename DMTypes_, typename LLHValueType_,
414  typename IntFreqType_, int FixedMaxParamList_,
415  bool UseNMeasAmplifyFactor_>
416 constexpr bool
418 template<typename DMTypes_, typename LLHValueType_,
419  typename IntFreqType_, int FixedMaxParamList_,
420  bool UseNMeasAmplifyFactor_>
421 constexpr bool
423 
424 
425 
426 
427 
428 } // namespace DenseDM
429 } // namespace Tomographer
430 
431 
432 
433 
434 
435 
436 
437 
438 #endif
Utilities for formatting strings.
const Eigen::Ref< const VectorParamListType > & VectorParamListTypeConstRef
Const ref to a VectorParamListType.
Definition: indepmeasllh.h:96
const Eigen::Ref< const FreqListType > & FreqListTypeConstRef
Const ref to a FreqListType.
Definition: indepmeasllh.h:108
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:126
const DMTypes dmt
The DMTypes object, storing e.g. the dimension of the problem.
Definition: indepmeasllh.h:133
void setMeas(VectorParamListTypeConstRef Exn_, FreqListTypeConstRef Nx_, bool check_validity=true)
Specify the full measurement data at once.
Definition: indepmeasllh.h:274
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:215
const IntFreqType Nx(IndexType i) const
The number of counts stored for the i-th POVM effect.
Definition: indepmeasllh.h:187
C++ types and functions for calculating the log-likelihood for POVM effects which can be written as a...
Definition: indepmeasllh.h:64
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:71
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:69
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:101
IntFreqType_ IntFreqType
Type used to store integer measurement counts.
Definition: indepmeasllh.h:73
const VectorParamListType & Exn() const
The stored individual POVM effects, in X Parameterization.
Definition: indepmeasllh.h:153
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:94
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:106
LLHValueType logLikelihoodX(typename DMTypes::VectorParamTypeConstRef x) const
Calculates the log-likelihood function, in X parameterization.
Definition: indepmeasllh.h:379
const IndexType numEffects() const
The number of POVM effects in the list.
Definition: indepmeasllh.h:141
#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:194
IndepMeasLLH(DMTypes dmt_)
Simple constructor.
Definition: indepmeasllh.h:116
#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:178
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:251
Eigen::Ref< const typename DMTypes::VectorParamType > Exn(IndexType i) const
The i-th stored POVM effect, in X Parameterization.
Definition: indepmeasllh.h:161