OscProb
PMNS_DensityMatrix.cxx
Go to the documentation of this file.
1
2//
3// Base class for methods using density matrices
4//
5// This class inherits from the PMNS_Base class
6//
7// jcoelho\@apc.in2p3.fr
9
10#include <cassert>
11
13
14#include "PMNS_DensityMatrix.h"
15#include "exceptions.h"
16
17using namespace OscProb;
18
19using namespace std;
20
21//.............................................................................
27PMNS_DensityMatrix::PMNS_DensityMatrix()
28 : PMNS_Fast(), fRho(3, vectorC(3, 0)), fMBuffer(3, vectorC(3, 0))
29{
30}
31
32//.............................................................................
37
38//.............................................................................
46{
47 // buffer = rho . U
48 for (int i = 0; i < fNumNus; i++) {
49 for (int j = 0; j < fNumNus; j++) {
50 fMBuffer[i][j] = 0;
51 for (int k = 0; k < fNumNus; k++) {
52 if (to_basis)
53 fMBuffer[i][j] += fRho[i][k] * U[k][j];
54 else
55 fMBuffer[i][j] += fRho[i][k] * conj(U[j][k]);
56 }
57 }
58 }
59
60 // rho = U^\dagger . buffer = U^\dagger . rho . U
61 // Final matrix is Hermitian, so copy upper to lower triangle
62 for (int i = 0; i < fNumNus; i++) {
63 for (int j = i; j < fNumNus; j++) {
64 fRho[i][j] = 0;
65 for (int k = 0; k < fNumNus; k++) {
66 if (to_basis)
67 fRho[i][j] += conj(U[k][i]) * fMBuffer[k][j];
68 else
69 fRho[i][j] += U[i][k] * fMBuffer[k][j];
70 }
71 if (j > i) fRho[j][i] = conj(fRho[i][j]);
72 }
73 }
74}
75
76//.............................................................................
88{
89 assert(flv >= 0 && flv < fNumNus);
90
92
93 for (int i = 0; i < fNumNus; ++i) {
94 for (int j = 0; j < fNumNus; ++j) {
95 if (i == flv && i == j)
96 fRho[i][j] = one;
97 else
98 fRho[i][j] = zero;
99 }
100 }
101}
102
103//.............................................................................
117{
118 assert(flv >= 0 && flv < fNumNus);
119 return abs(fRho[flv][flv]);
120}
121
122//.............................................................................
129{
130 assert(nu_in.size() == fNumNus);
131
132 for (int i = 0; i < fNumNus; i++) {
133 for (int j = 0; j < fNumNus; j++) {
134 fRho[i][j] = conj(nu_in[i]) * nu_in[j];
135 }
136 }
137}
138
139//.............................................................................
151{
152 assert(rho_in.size() == fNumNus);
153 assert(rho_in[0].size() == fNumNus);
154
155 double eps = 1e-12;
156
157 double trace = 0;
158 complexD rho_array[3][3];
159 for (int i = 0; i < fNumNus; i++) {
160 trace += abs(rho_in[i][i]);
161 for (int j = i; j < fNumNus; j++) {
162 // Ensure rho_in is hermitian
163 assert(abs(rho_in[i][j] - conj(rho_in[j][i])) < eps);
164 rho_array[i][j] = rho_in[i][j];
165 }
166 }
167
168 // Ensure rho_in has trace 1
169 assert(abs(trace - 1) < eps);
170
171 double fEvalGLoBES[3];
172 complexD fEvecGLoBES[3][3];
173
174 // Find the eigenvalues of rho_in
175 zheevh3(rho_array, fEvecGLoBES, fEvalGLoBES);
176
177 // Ensure rho_in is positive definite
178 for (int i = 0; i < fNumNus; i++) assert(fEvalGLoBES[i] >= -eps);
179
180 fRho = rho_in;
181}
182
183//.............................................................................
198{
199 THROW_ON_INVALID_ARG(nflvi >= 0, nflvi);
200 THROW_ON_INVALID_ARG(nflvi <= fNumNus, nflvi, fNumNus);
201 THROW_ON_INVALID_ARG(nflvf >= 0, nflvf);
202 THROW_ON_INVALID_ARG(nflvf <= fNumNus, nflvf, fNumNus);
203
204 // Output probabilities
205 matrixD probs(nflvi, vectorD(nflvf));
206
207 // List of states
208 vector<matrixC> allstates(nflvi, matrixC(fNumNus, vectorC(fNumNus)));
209
210 // Reset all initial states
211 for (int i = 0; i < nflvi; i++) {
213 allstates[i] = fRho;
214 }
215
216 // Propagate all states in parallel
217 for (int i = 0; i < int(fNuPaths.size()); i++) {
218 for (int flvi = 0; flvi < nflvi; flvi++) {
219 fRho = allstates[flvi];
221 allstates[flvi] = fRho;
222 }
223 }
224
225 // Get all probabilities
226 for (int flvi = 0; flvi < nflvi; flvi++) {
227 for (int flvj = 0; flvj < nflvf; flvj++) {
228 probs[flvi][flvj] = abs(allstates[flvi][flvj][flvj]);
229 }
230 }
231
232 return probs;
233}
234
static const complexD zero
zero in complex
Definition: PMNS_Base.h:211
int fNumNus
Number of neutrino flavours.
Definition: PMNS_Base.h:277
std::vector< NuPath > fNuPaths
Vector of neutrino paths.
Definition: PMNS_Base.h:295
static const complexD one
one in complex
Definition: PMNS_Base.h:212
virtual void ResetToFlavour(int flv)
Reset neutrino state to pure flavour flv.
Definition: PMNS_Base.cxx:1034
virtual void SetPureState(vectorC nu_in)
Set the density matrix from a pure state.
virtual void ResetToFlavour(int flv)
Reset neutrino state to pure flavour flv.
virtual void RotateState(bool to_basis, matrixC U)
Rotate rho to/from a given basis.
virtual ~PMNS_DensityMatrix()
Destructor.
virtual matrixD ProbMatrix(int nflvi, int nflvf)
matrixC fMBuffer
Some memory buffer for matrix operations.
virtual double P(int flv)
Return the probability of final state in flavour flv.
virtual void PropagatePath(NuPath p)=0
Propagate neutrino through a single path.
virtual void SetInitialRho(matrixC rho_in)
Set the density matrix from an arbitrary state.
matrixC fRho
The neutrino density matrix state.
Implementation of oscillations of neutrinos in matter in a three-neutrino framework.
Definition: PMNS_Fast.h:40
#define THROW_ON_INVALID_ARG(condition,...)
Definition: exceptions.h:85
Some useful general definitions.
Definition: Absorption.h:6
std::complex< double > complexD
Definition: Definitions.h:21
std::vector< complexD > vectorC
Definition: Definitions.h:22
std::vector< double > vectorD
Definition: Definitions.h:18
std::vector< vectorD > matrixD
Definition: Definitions.h:19
std::vector< vectorC > matrixC
Definition: Definitions.h:23
Definition: EigenPoint.h:44
int zheevh3(std::complex< double > A[3][3], std::complex< double > Q[3][3], double w[3])
Definition: zheevh3.cxx:31