C++QEDCore  v2 Milestone 10
a framework for simulating open quantum dynamics – core
Sigma.tcc
1 // Copyright András Vukics 2006–2014. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE.txt)
2 // -*- C++ -*-
3 /// \briefFile{Defines quantumoperator::DirectProduct & helpers}
4 #ifndef CPPQEDCORE_QUANTUMOPERATOR_SIGMA_TCC_INCLUDED
5 #define CPPQEDCORE_QUANTUMOPERATOR_SIGMA_TCC_INCLUDED
6 
7 #include "Sigma.h"
8 
9 namespace quantumoperator {
10 
11 
12 /// A direct-product clause, representing a germinal expression-template mechanism for direct products of Sigma`<L,R>` instances with `OTHER` types.
13 /**
14  * \tparam OTHER The type of the other member of the clause. Models:
15  * -# Another class Sigma`<L1,R1>`
16  * -# A Tridiagonal type
17  * -# Another DirectProduct type (recursivity)
18  * \tparam IS_HEAD Signifies whether Sigma`<L,R>` stands at the head or at the tail of the direct product
19  *
20  * The class is nicely described by the signature of the related `operator*` operators
21  */
22 template<int L, int R, typename OTHER, bool IS_HEAD>
23 class DirectProduct
24 {
25 public:
26  static const int N_RANK=OTHER::N_RANK+1; ///< Reports the rank of the class for recursive usage
27 
28  typedef typename quantumdata::Types<N_RANK>::StateVectorLow StateVectorLow;
29 
30  DirectProduct(const OTHER& other) : other_(other) {} ///< The object has to store a reference to the `OTHER` object to enable DirectProduct::apply as an operator
31 
32  /// Applies the clause on a state vector `psi`, adding the result to `dpsidt`, analogously to Tridiagonal::apply and structure::Hamiltonian::addContribution
33  /**
34  * It is implemented as taking the partial projection (quantumoperator::partialProject) of the state vectors according to `L` and `R`
35  * (which at this point are converted into runtime data), and calling the `apply` function of the `OTHER` type.
36  */
37  void
38  apply(const StateVectorLow& psi, StateVectorLow& dpsidt) const
39  {
40  typename quantumdata::Types<N_RANK-1>::StateVectorLow dpsidtProjected(partialProject<N_RANK,IS_HEAD>(dpsidt,L));
41  other_.apply(partialProject<N_RANK,IS_HEAD>(psi,R),dpsidtProjected);
42  }
43 
44 private:
45  const OTHER& other_;
46 
47 };
48 
49 
50 template<int L, int R, typename OTHER>
51 const DirectProduct<L,R,OTHER,true >
52 operator*(const Sigma<L,R>&, const OTHER& other)
53 {
54  return DirectProduct<L,R,OTHER,true >(other);
55 }
56 
57 
58 template<int L, int R, typename OTHER>
59 const DirectProduct<L,R,OTHER,false>
60 operator*(const OTHER& other, const Sigma<L,R>&)
61 {
62  return DirectProduct<L,R,OTHER,false>(other);
63 }
64 
65 
66 template<int L1, int R1, int L2, int R2>
67 const DirectProduct<L1,R1,Sigma<L2,R2>,true>
68 operator*(const Sigma<L1,R1>&, const Sigma<L2,R2>& sigma)
69 {
70  return DirectProduct<L1,R2,Sigma<L2,R2>,true>(sigma);
71 }
72 
73 } // quantumoperator
74 
75 #endif // CPPQEDCORE_QUANTUMOPERATOR_SIGMA_TCC_INCLUDED