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 SetIsOscProbAvg(true);
31}
32
33//.............................................................................
38
39//.............................................................................
47{
48 // buffer = rho . U
49 for (int i = 0; i < fNumNus; i++) {
50 for (int j = 0; j < fNumNus; j++) {
51 fMBuffer[i][j] = 0;
52 for (int k = 0; k < fNumNus; k++) {
53 if (to_basis)
54 fMBuffer[i][j] += fRho[i][k] * U[k][j];
55 else
56 fMBuffer[i][j] += fRho[i][k] * conj(U[j][k]);
57 }
58 }
59 }
60
61 // rho = U^\dagger . buffer = U^\dagger . rho . U
62 // Final matrix is Hermitian, so copy upper to lower triangle
63 for (int i = 0; i < fNumNus; i++) {
64 for (int j = i; j < fNumNus; j++) {
65 fRho[i][j] = 0;
66 for (int k = 0; k < fNumNus; k++) {
67 if (to_basis)
68 fRho[i][j] += conj(U[k][i]) * fMBuffer[k][j];
69 else
70 fRho[i][j] += U[i][k] * fMBuffer[k][j];
71 }
72 if (j > i) fRho[j][i] = conj(fRho[i][j]);
73 }
74 }
75}
76
77//.............................................................................
89{
90 assert(flv >= 0 && flv < fNumNus);
91
93
94 for (int i = 0; i < fNumNus; ++i) {
95 for (int j = 0; j < fNumNus; ++j) {
96 if (i == flv && i == j)
97 fRho[i][j] = one;
98 else
99 fRho[i][j] = zero;
100 }
101 }
102}
103
104//.............................................................................
118{
119 assert(flv >= 0 && flv < fNumNus);
120 return abs(fRho[flv][flv]);
121}
122
123//.............................................................................
130{
131 assert(nu_in.size() == fNumNus);
132
133 for (int i = 0; i < fNumNus; i++) {
134 for (int j = 0; j < fNumNus; j++) {
135 fRho[i][j] = conj(nu_in[i]) * nu_in[j];
136 }
137 }
138}
139
140//.............................................................................
152{
153 assert(rho_in.size() == fNumNus);
154 assert(rho_in[0].size() == fNumNus);
155
156 double eps = 1e-12;
157
158 double trace = 0;
159 complexD rho_array[3][3];
160 for (int i = 0; i < fNumNus; i++) {
161 trace += abs(rho_in[i][i]);
162 for (int j = i; j < fNumNus; j++) {
163 // Ensure rho_in is hermitian
164 assert(abs(rho_in[i][j] - conj(rho_in[j][i])) < eps);
165 rho_array[i][j] = rho_in[i][j];
166 }
167 }
168
169 // Ensure rho_in has trace 1
170 assert(abs(trace - 1) < eps);
171
172 double fEvalGLoBES[3];
173 complexD fEvecGLoBES[3][3];
174
175 // Find the eigenvalues of rho_in
176 zheevh3(rho_array, fEvecGLoBES, fEvalGLoBES);
177
178 // Ensure rho_in is positive definite
179 for (int i = 0; i < fNumNus; i++) assert(fEvalGLoBES[i] >= -eps);
180
181 fRho = rho_in;
182}
183
184//.............................................................................
199{
200 THROW_ON_INVALID_ARG(nflvi >= 0, nflvi);
201 THROW_ON_INVALID_ARG(nflvi <= fNumNus, nflvi, fNumNus);
202 THROW_ON_INVALID_ARG(nflvf >= 0, nflvf);
203 THROW_ON_INVALID_ARG(nflvf <= fNumNus, nflvf, fNumNus);
204
205 // Output probabilities
206 matrixD probs(nflvi, vectorD(nflvf));
207
208 // List of states
209 vector<matrixC> allstates(nflvi, matrixC(fNumNus, vectorC(fNumNus)));
210
211 // Reset all initial states
212 for (int i = 0; i < nflvi; i++) {
214 allstates[i] = fRho;
215 }
216
217 // Propagate all states in parallel
218 for (int i = 0; i < int(fNuPaths.size()); i++) {
219 for (int flvi = 0; flvi < nflvi; flvi++) {
220 fRho = allstates[flvi];
222 allstates[flvi] = fRho;
223 }
224 }
225
226 // Get all probabilities
227 for (int flvi = 0; flvi < nflvi; flvi++) {
228 for (int flvj = 0; flvj < nflvf; flvj++) {
229 probs[flvi][flvj] = abs(allstates[flvi][flvj][flvj]);
230 }
231 }
232
233 return probs;
234}
235
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 SetIsOscProbAvg(bool isOscProbAvg)
Deactivate Maltoni.
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:87
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