13#include <Eigen/Eigenvalues>
23PMNS_Maltoni::PMNS_Maltoni(
int numNus) :
PMNS_Base(numNus)
117 for (
int j = 0; j <
fNumNus; j++) {
118 for (
int i = 0; i <= j; i++) {
138 double lenghtEV = L *
kKm2eV;
139 double bufK = lenghtEV * 0.5;
143 for (
int i = 0; i <
fNumNus; i++) {
146 for (
int l = 0; l <
fNumNus; l++) {
149 for (
int k = 0; k <
fNumNus; k++) {
153 Hms_kl = conj(
fHms[l][k]);
155 if (
fIsNuBar && k != l) Hms_kl = conj(Hms_kl);
157 buffer[l] += conj(
fEvec[k][i]) * Hms_kl;
161 for (
int j = 0; j <= i; j++) {
164 for (
int l = 0; l <
fNumNus; l++) {
172 double arg = (
fEval[i] -
fEval[j]) * lenghtEV;
198 bool ismin = (L2 <= 0 &&
fcosT < 0);
220 for (
int j = 0; j <
fNumNus; j++) {
221 for (
int k = 0; k <
fNumNus; k++) {
225 for (
int i = 0; i <
fNumNus; i++) {
227 for (
int k = 0; k <
fNumNus; k++) {
242 for (
int j = 0; j <
fNumNus; j++) {
243 for (
int k = 0; k <
fNumNus; k++) {
246 for (
int l = 0; l <
fNumNus; l++) {
251 for (
int i = 0; i <= j; i++) {
254 for (
int k = 0; k <
fNumNus; k++) {
280 for (
int j = 0; j <
fNumNus; j++) {
283 for (
int i = 0; i <
fNumNus; i++) {
286 for (
int k = 0; k <
fNumNus; k++) {
307 for (
int i = 0; i <
fNumNus; i++) {
310 for (
int l = 0; l <
fNumNus; l++) {
311 for (
int k = 0; k <
fNumNus; k++) {
316 for (
int j = 0; j <= i; j++) {
317 for (
int l = 0; l <
fNumNus; l++) {
321 if (i != j) { K(j, i) = conj(K(i, j)); }
332 for (
int i = 0; i < int(
fNuPaths.size()); i++) {
353 for (
int i = 0; i <
fNumNus; i++) {
354 double arg =
fEval[i] * LengthIneV;
397 if (
fNumNus == 4) TemplateSolver<Eigen::Matrix4cd>(K, lambda, V);
398 if (
fNumNus == 3) TemplateSolver<Eigen::Matrix3cd>(K, lambda, V);
400 TemplateSolver<Eigen::Matrix2cd>(K, lambda, V);
402 TemplateSolver<Eigen::MatrixXcd>(K, lambda, V);
420 Eigen::SelfAdjointEigenSolver<T> eigensolver(R);
423 for (
int i = 0; i <
fNumNus; i++) {
424 lambda[i] = eigensolver.eigenvalues()(i);
425 for (
int j = 0; j <
fNumNus; j++) {
426 V[i][j] = eigensolver.eigenvectors()(i, j);
455 for (
int i = 0; i <
fNumNus; i++) {
456 for (
int k = 0; k <
fNumNus; k++) {
463 for (
int n = 0; n <
fNumNus; n++) { buffer[n] = SV[n] * conj(V[flvi][n]); }
466 for (
int j = 0; j <
fNumNus; j++) {
468 for (
int i = 0; i < j; i++) {
469 double arg = (lambda[i] - lambda[j]) * dbin / 2;
470 sinc[i][j] = sin(arg) / arg;
471 sinc[j][i] = sinc[i][j];
477 for (
int j = 0; j <
fNumNus; j++) {
478 for (
int i = 0; i <
fNumNus; i++) {
479 P += buffer[i] * conj(buffer[j]) * sinc[j][i];
512 if (E <= 0)
return 0;
517 if (dE <= 0)
return Prob(flvi, flvf, E);
522 return AvgProbLoE(flvi, flvf, LoEbin[0], LoEbin[1]);
553 if (LoE <= 0)
return 0;
568 for (
int j = 1; j < int(samples.size()); j++) {
570 double w = 1. / pow(samples[j], 2);
572 avgprob += w *
AvgAlgo(flvi, flvf, samples[j], samples[0], L);
579 return avgprob / sumw;
598 double d1oE = dLoE / L;
632 int n_div = ceil(3 * pow(dLoE / LoE, 0.8) * pow(LoE, 0.3) /
639 Samples.push_back(dLoE / n_div);
642 for (
int k = 0; k < n_div; k++) {
644 double bctr = LoE - dLoE / 2 + (k + 0.5) * dLoE / n_div;
646 Samples.push_back(bctr);
678 if (E <= 0)
return probs;
715 if (LoE <= 0)
return probs;
722 if (dLoE <= 0)
return ProbVector(flvi, L / LoE);
730 for (
int j = 1; j < int(samples.size()); j++) {
732 double w = 1. / pow(samples[j], 2);
734 for (
int flvf = 0; flvf <
fNumNus; flvf++) {
736 probs[flvf] += w *
AvgAlgo(flvi, flvf, samples[j], samples[0], L);
746 for (
int flvf = 0; flvf <
fNumNus; flvf++) {
775 if (E <= 0)
return probs;
780 if (dE <= 0)
return ProbMatrix(nflvi, nflvf, E);
808 if (LoE <= 0)
return probs;
815 if (dLoE <= 0)
return ProbMatrix(nflvi, nflvf, L / LoE);
823 for (
int j = 1; j < int(samples.size()); j++) {
825 double w = 1. / pow(samples[j], 2);
827 for (
int flvi = 0; flvi < nflvi; flvi++) {
828 for (
int flvf = 0; flvf < nflvf; flvf++) {
830 if (flvi == 0 && flvf == 0)
832 w *
AvgAlgo(flvi, flvf, samples[j], samples[0], L);
843 for (
int flvi = 0; flvi < nflvi; flvi++) {
844 for (
int flvf = 0; flvf < nflvf; flvf++) {
846 probs[flvi][flvf] /= sumw;
962 double cosT,
double dcosT)
964 if (E <= 0)
return 0;
965 if (cosT > 0)
return 0;
969 if (dE <= 0 && dcosT == 0)
return Prob(flvi, flvf, E);
970 if (dE <= 0)
return AvgProb(flvi, flvf, E, cosT, dcosT);
971 if (dcosT == 0)
return AvgProb(flvi, flvf, E, dE);
976 return AvgProbLoE(flvi, flvf, Ebin[0], Ebin[1], cosT, dcosT);
1009 double cosT,
double dcosT)
1011 if (LoE <= 0)
return 0;
1012 if (cosT > 0)
return 0;
1017 if (dLoE <= 0 && dcosT == 0)
return Prob(flvi, flvf,
fPath.
length / LoE);
1020 if (dcosT == 0)
return AvgProbLoE(flvi, flvf, LoE, dLoE);
1026 int rows = samples.size();
1027 int cols = samples[0].size();
1033 for (
int k = 1; k < int(rows); k++) {
1034 for (
int l = 1; l < int(cols); l++) {
1036 double w = 1. / pow(real(samples[k][l]), 2);
1039 w *
AvgAlgo(flvi, flvf, real(samples[k][l]), real(samples[0][0]),
1040 imag(samples[k][l]), imag(samples[0][0]));
1048 return avgprob / ((sumw));
1066 double cosT,
double dcosT)
1132 double cosT,
double dcosT)
1136 int n_divCosT = ceil(380 * pow(InvE, 0.5) * pow(abs(dcosT / cosT), 0.8) /
1138 int n_divE = ceil(260 * pow(dInvE / InvE, 0.8) * pow(InvE, 0.6) /
1145 Samples[0][0] =
complexD(dInvE / n_divE, dcosT / n_divCosT);
1148 for (
int k = 0; k < n_divE; k++) {
1150 double bctr_InvE = InvE - dInvE / 2 + (k + 0.5) * dInvE / n_divE;
1152 for (
int l = 0; l < n_divCosT; l++) {
1154 double bctr_CosT = cosT - dcosT / 2 + (l + 0.5) * dcosT / n_divCosT;
1156 Samples[k + 1][l + 1] =
complexD(bctr_InvE, bctr_CosT);
1177 for (
int i = 0; i <
fNumNus; i++) {
1178 for (
int j = 0; j <
fNumNus; j++) {
1179 for (
int k = 0; k <
fNumNus; k++) {
1188 for (
int i = 0; i <
fNumNus; i++) {
1189 for (
int j = i; j <
fNumNus; j++) {
1191 for (
int k = 0; k <
fNumNus; k++) {
1212 for (
int j = 0; j <
fNumNus; j++) {
1213 for (
int i = 0; i < j; i++) {
1214 double arg = (lambda[i] - lambda[j]) * dbin;
1215 sinc[i][j] = sin(arg) / arg;
1217 sinc[j][i] = sinc[i][j];
1221 for (
int i = 0; i <
fNumNus; i++) { sinc[i][i] = 1; }
1223 for (
int j = 0; j <
fNumNus; j++) {
1224 for (
int i = 0; i <
fNumNus; i++) {
1248 int n_div = ceil(35 * pow(E, -0.4) * pow(abs(dcosT / cosT), 0.8) /
1255 Samples.push_back(dcosT / n_div);
1258 for (
int k = 0; k < n_div; k++) {
1260 double bctr = cosT - dcosT / 2 + (k + 0.5) * dcosT / n_div;
1262 Samples.push_back(bctr);
1294 for (
int i = 0; i <
fNumNus; i++) {
1295 for (
int k = 0; k <
fNumNus; k++) {
1301 for (
int n = 0; n <
fNumNus; n++) { buffer[n] = SV[n] * conj(V[flvi][n]); }
1305 for (
int j = 0; j <
fNumNus; j++) {
1306 for (
int i = 0; i <
fNumNus; i++) {
1307 double arg = (lambda[j] - lambda[i]) * dE;
1308 expo[j][i] = exp(
complexD(0.0, arg));
1314 for (
int j = 0; j <
fNumNus; j++) {
1315 for (
int i = 0; i <
fNumNus; i++) {
1316 P += buffer[i] * conj(buffer[j]) * expo[j][i];
virtual std::vector< NuPath > GetNuPath()
Base class implementing general functions for computing neutrino oscillations.
virtual double P(int flv)
Return the probability of final state in flavour flv.
bool fIsNuBar
Anti-neutrino flag.
virtual matrixD AvgProbMatrixLoE(int nflvi, int nflvf, double LoE, double dLoE=0)
Compute the average probability matrix over a bin of L/E.
virtual vectorD ConvertEtoLoE(double E, double dE)
virtual double AvgProbLoE(vectorC nu_in, int flvf, double LoE, double dLoE=0)
Compute the average probability over a bin of L/E.
virtual vectorD AvgProbVectorLoE(vectorC nu_in, double LoE, double dLoE=0)
Compute the average probability vector over a bin of L/E.
int fNumNus
Number of neutrino flavours.
std::vector< NuPath > fNuPaths
Vector of neutrino paths.
static const double kKm2eV
km to eV^-1
double fAvgProbPrec
AvgProb precision.
matrixC fHms
matrix H*2E in eV^2
virtual vectorD AvgProbVector(vectorC nu_in, double E, double dE=0)
virtual double AvgProb(vectorC nu_in, int flvf, double E, double dE=0)
Compute the average probability over a bin of energy.
matrixC fEvec
Eigenvectors of the Hamiltonian.
virtual double Prob(vectorC nu_in, int flvf)
Compute the probability of nu_in going to flvf.
virtual matrixD AvgProbMatrix(int nflvi, int nflvf, double E, double dE=0)
NuPath fPath
Current neutrino path.
virtual void SolveHam()=0
virtual void SetEnergy(double E)
Set the neutrino energy in GeV.
vectorD fEval
Eigenvalues of the Hamiltonian.
virtual void SetCurPath(NuPath p)
Set the path currently in use by the class.
vectorC fPhases
Buffer for oscillation phases.
virtual void SetPath(NuPath p)
Set a single path.
virtual void SetAvgProbPrec(double prec)
Set the AvgProb precision.
virtual vectorD ProbVector(vectorC nu_in)
static const double kGeV2eV
GeV to eV.
virtual matrixD ProbMatrix(int nflvi, int nflvf)
Compute the probability matrix.
virtual void HadamardProduct(vectorD lambda, double dbin)
Apply an Hadamard Product to the density matrix.
matrixC fevolutionMatrixS
double fcosT
Cosine of zenith angle.
virtual double AvgAlgoCosT(int flvi, int flvf, double E, double cosT, double dcosT)
virtual void MultiplicationRuleS()
Product between two S matrices.
virtual matrixD AvgProbMatrix(int nflvi, int nflvf, double E, double dE)
Eigen::MatrixXcd fHam
The full Hamiltonian.
virtual void rotateK()
Rotate one K matrix.
virtual void SetIsOscProbAvg(bool isOscProbAvg)
Set flag for which averaging to use.
void TemplateSolver(Eigen::MatrixXcd &K, vectorD &lambda, matrixC &V)
Auxiliary function to choose eigensystem method.
virtual void BuildKcosT()
build K matrix for angle in flavor basis
matrixC fKmass
K matrix in mass basis for one layer.
virtual void UpdateHam()=0
Build the full Hamiltonian.
virtual double AvgFormulaExtrapolation(int flvi, int flvf, double dE, vectorD flambda, matrixC fV)
Formula for the extrapolation of probability.
matrixC fVInvE
Eigenvalues of K_invE.
virtual double LnDerivative()
Compute the derivation of one layer's length.
virtual double AlgorithmDensityMatrix(int flvi, int flvf)
Algorithm for the transformations on the density matrix.
Eigen::MatrixXcd fKcosT
K matrix for neutrino angle for the entire path.
virtual double ExtrapolationProb(int flvi, int flvf, double E, double dE)
Compute the probability of flvi going to flvf for an energy E+dE.
vectorD flambdaInvE
Eigenvectors of K_invE.
Eigen::MatrixXcd fKInvE
K matrix for the inverse of energy for the entire path.
virtual void InitializeTaylorsVectors()
Initialize all member vectors with zeros.
OscProb::PremModel fPrem
Earth model used.
int fdl
Length derivative.
virtual void rotateS()
Rotate the S matrix.
virtual void PropagateTaylor()
Propagate neutrino through full path.
virtual matrixD AvgProbMatrixLoE(int nflvi, int nflvf, double LoE, double dLoE)
virtual vectorD AvgProbVector(int flvi, double E, double dE)
virtual void PropagatePathTaylor(NuPath p)
Propagate neutrino through a single path.
virtual double AvgAlgo(int flvi, int flvf, double LoE, double dLoE, double L)
virtual void SetCosT(double cosT)
Set neutrino angle.
virtual vectorD AvgProbVectorLoE(int flvi, double LoE, double dLoE)
double fdInvE
Bin's width for the inverse of energy.
virtual double AvgFormula(int flvi, int flvf, double dbin, vectorD flambda, matrixC fV)
Formula for the average probability over a bin of width dbin.
virtual void SetPremModel(OscProb::PremModel &prem)
virtual void SetwidthBin(double dE, double dcosT)
Set bin's widths for energy and angle.
vectorD flambdaCosT
Eigenvectors of K_cosTheta.
double fdcosT
Bin's width for zenith angle.
virtual double AvgProbLoE(int flvi, int flvf, double LoE, double dLoE)
virtual void RotateDensityM(bool to_basis, matrixC V)
Apply rotation to the density matrix.
bool fIsOscProbAvg
Flag to call OscProb default or Maltoni average.
double fminRsq
Minimum square radius.
matrixC fdensityMatrix
The neutrino density matrix state.
matrixC fVcosT
Eigenvalues of K_cosTheta.
matrixC fSflavor
S matrix for one layer.
virtual vectorD GetSamplePointsAvgClass(double LoE, double dLoE)
Compute the sample points fo a bin of L/E with width dLoE.
virtual double AvgProb(int flvi, int flvf, double E, double dE)
void SolveK(Eigen::MatrixXcd &K, vectorD &lambda, matrixC &V)
Solve the K matrix for eigenvectors and eigenvalues.
virtual double ExtrapolationProbCosT(int flvi, int flvf, double cosT, double dcosT)
Compute the probability of flvi going to flvf for an angle cosT+dcosT.
virtual void BuildKE(double L)
build K matrix for the inverse of energy in mass basis
virtual void MultiplicationRuleK(Eigen::MatrixXcd &K)
Product between two K matrices.
double fDetRadius
Detector radius.
matrixC fKflavor
K matrix in flavor basis for one layer.
virtual double ExtrapolationProbLoE(int flvi, int flvf, double LoE, double dLoE)
Compute the probability of flvi going to flvf at LoE+dLoE.
Implements an earth model with spherical shells.
virtual double GetDetRadius()
virtual void LoadModel(std::string filename)
Load an earth model from a file.
int FillPath(double cosT, double phi=0)
Fill the path sequence in a vector.
virtual std::vector< PremLayer > GetPremLayers()
Some useful general definitions.
std::complex< double > complexD
std::vector< complexD > vectorC
std::vector< double > vectorD
std::vector< vectorD > matrixD
NuPath AvgPath(NuPath &p1, NuPath &p2)
Get the average of two paths.
std::vector< vectorC > matrixC
A struct representing a neutrino path segment.
double length
The length of the path segment in km.