GamR  0.0.0
GammaROOT
Loading...
Searching...
No Matches
StatTensor.cc
Go to the documentation of this file.
1
8
9#include <algorithm>
10#include <complex>
11#include <iostream>
12
13#include <Math/SpecFunc.h> /* legendre polynomials, 3j and 6j symbols */
14
15#include "AngDist.hh"
16#include "StatTensor.hh"
17#include "WignerD.hh"
18
19namespace GamR {
20 namespace AngDist {
27 {
28 this->j = j;
29 Clear();
30 }
31
40 StatTensor::StatTensor(std::vector<double> Pm, double j) : StatTensor(j)
41 {
42 Set(Pm);
43 }
44
45 void StatTensor::Set(std::vector<double> Pm) {
46 for (int ik = 0; ik < 2 * j + 1; ++ik) {
47 double k = (double)ik;
48
49 double sum = 0;
50 for (int im = 0; im < 2 * j + 1; ++im) {
51 double m = (double)im - j;
52 double value =
53 pow(-1, j - m) *
54 ROOT::Math::wigner_3j((int)(2 * j), (int)(2 * j), (int)(2 * k), (int)(2 * m), (int)(2 * -m), 0) *
55 // sqrt(2*k + 1) * /* removed to make consistent with Andrew's
56 // program
57 // see AES NIM A 485(2002)753, equation 1 and 2
58 // vs Morinaga and Yamazaki 2.36 */
59
60 Pm[im];
61 sum = sum + value;
62 }
63
64 this->rho[k][k] = std::complex<double>(sum * sqrt(2 * j + 1), 0);
65 }
66 }
67
72 {
73 this->rho.clear();
74 this->rho.reserve((int)(2*this->j+1));
75 for (int ik = 0; ik < 2 * this->j + 1; ++ik) {
76 double k = (double)ik;
77 this->rho.emplace_back();
78 for (int iq = 0; iq < 2 * ik + 1; ++iq) {
79 this->rho.at(this->rho.size()-1).emplace_back(0,0);
80 }
81 }
82 }
83
84 std::complex<double> StatTensor::Get(double k, double q)
85 {
86 int ik = std::round(k);
87 int iq = std::round(q);
88 return this->rho[ik][iq + ik];
89 }
90
91 std::complex<double> StatTensor::Set(double k, double q, std::complex<double> value)
92 {
93 int ik = std::round(k);
94 int iq = std::round(q);
95 this->rho[ik][iq + ik] = value;
96 return this->rho[ik][iq+ik];
97 }
98
105 std::complex<double> StatTensor::GetBk(double k)
106 {
107 return sqrt(2 * k + 1) * this->rho[(int)k][(int)k];
108 }
109
125 StatTensor *StatTensor::ObservedProp(double ji, double lambda, double lambdaPrime, double jf, double delta,
126 SolidAttenuation *Qk, double theta, double phi)
127 {
128
129 StatTensor *rhoAfter = new StatTensor(jf);
130 for (int ik2 = 0; ik2 < 2 * jf + 1; ++ik2) {
131 double k2 = (double)ik2;
132 for (int iq2 = 0; iq2 < 2 * ik2 + 1; ++iq2) {
133 double q2 = (double)iq2 - k2;
134 std::complex<double> sum = 0;
135 int Lmax = (int)std::max(lambda, lambdaPrime);
136 for (int ik = 0; ik < 2 * Lmax + 1; ++ik) {
137 double k = (double)ik;
138 for (int ik1 = 0; ik1 < 2 * this->j + 1; ++ik1) {
139 double k1 = (double)ik1;
140 for (int iq = 0; iq < 2 * ik + 1; ++iq) {
141 double q = (double)iq - k;
142 for (int iq1 = 0; iq1 < 2 * ik1 + 1; ++iq1) {
143 double q1 = (double)iq1 - k1;
144 sum = sum + Get(k1, q1) * pow(-1, k1 + q1) * sqrt((2 * k + 1) * (2 * k1 + 1) / (2 * k2 + 1)) *
145 ROOT::Math::wigner_3j((int)2*k1, (int)2*k, (int)2*k2, -(int)2*q1, (int)2*q, (int)2*q2) *
146 Agen(k, k1, k2, jf, lambda, lambdaPrime, ji, delta) * Qk->Get(k) *
147 std::conj(GamR::AngDist::BigD(k, q, 0, phi, theta, 0));
148 }
149 }
150 }
151 }
152 rhoAfter->Set(k2, q2, sum);
153 }
154 }
155 return rhoAfter;
156 }
157
173 StatTensor *StatTensor::UnobservedProp(double ji, double lambda, double lambdaPrime, double jf, double delta,
175 {
176 StatTensor *rhoAfter = new StatTensor(jf);
177 for (int ik2 = 0; ik2 < 2 * jf + 1; ++ik2) {
178 double k2 = (double)ik2;
179 for (int iq2 = 0; iq2 < 2 * ik2 + 1; ++iq2) {
180 double q2 = (double)iq2 - k2;
181 std::complex<double> sum = 0;
182 double k = 0;
183 double q = 0;
184 for (int ik1 = 0; ik1 < 2 * this->j + 1; ++ik1) {
185 double k1 = (double)ik1;
186 for (int iq1 = 0; iq1 < 2 * ik1 + 1; ++iq1) {
187 double q1 = (double)iq1 - k1;
188 sum = sum + Get(k1, q1) * pow(-1, k1 + q1) * sqrt((2 * k + 1) * (2 * k1 + 1) / (2 * k2 + 1)) *
189 ROOT::Math::wigner_3j((int)2*k1, (int)2*k, (int)2*k2, -(int)2*q1, (int)2*q, (int)2*q2) *
190 Agen(k, k1, k2, jf, lambda, lambdaPrime, ji, delta) * Qk->Get(k);
191 }
192 }
193 rhoAfter->Set(k2, q2, sum);
194 }
195 }
196 return rhoAfter;
197 }
198
206 StatTensor *StatTensor::Perturbation(std::function<std::complex<double>(double, double, double, double, double)> const &Gk, double t)
207 {
208 //std::cout << "PERTURBATION" << std::endl;
209 StatTensor *rhoAfter = new StatTensor(this->j);
210 double j = this->j;
211 for (int ik2 = 0; ik2 < 2*j + 1; ik2 = ik2 + 2) {
212 double k2 = (double)ik2;
213 for (int iq2 = 0; iq2 < 2*ik2 + 1; ++iq2) {
214 double q2 = (double)iq2 - k2;
215 //std::cout << "=====" << std::endl;
216 //std::cout << k2 << " " << q2 << std::endl;
217 std::complex<double> sum = 0;
218 for (int ik1 = 0; ik1 < 2*j + 1; ik1 = ik1 + 2) {
219 double k1 = (double)ik1;
220 for (int iq1 = 0; iq1<2*ik1 + 1; ++iq1) {
221 double q1 = (double)iq1 - k1;
222 std::complex<double> rhokq = Get(k1, q1);
223 std::complex<double> Gkk = std::conj(Gk(q1, q2, k1, k2, t));
224 sum = sum + rhokq * sqrt((2*k1 + 1)/(2*k2 + 1)) * Gkk;
225 // if (k2==k1) {
226 // std::cout << " " << q1 << " " << q2 << std::endl;
227 // printf(" Gkk = (%15.14f, %15.14f)\n", Gkk.real(), Gkk.imag());
228 // printf(" rhokq = (%15.14f, %15.14f)\n", rhokq.real(), rhokq.imag());
229 // }
230 }
231 }
232 //std::cout << "final = " << sum << std::endl;
233 rhoAfter->Set(k2, q2, sum);
234 }
235 }
236 return rhoAfter;
237 }
238
254 double StatTensor::W(double ji, double lambda, double lambdaPrime, double jf, double delta, SolidAttenuation *Qk,
255 double theta, double phi)
256 {
257 std::complex<double> W = 0;
258 for (int ik2 = 0; ik2 < 2 * (this->j) + 1; ik2 = ik2 + 2) {
259 double k2 = (double)ik2;
260 for (int iq2 = 0; iq2 < 2 * ik2 + 1; ++iq2) {
261 double q2 = (double)iq2 - k2;
262 //std::cout << k2 << " " << q2 << std::endl;
263 //std::cout << W << std::endl;
264 W = W + Get(k2, q2) * sqrt(2 * k2 + 1) * Ak(k2, ji, lambda, lambdaPrime, jf, delta) * Qk->Get(k2) *
265 std::conj(GamR::AngDist::BigD(k2, q2, 0, phi, theta, 0));
266
267 //std::cout << Get(k2, q2) * sqrt(2 * k2 + 1) * Ak(k2, ji, lambda, lambdaPrime, jf, delta) * Qk->Get(k2) *
268 // std::conj(GamR::AngDist::BigD(k2, q2, 0, phi, theta, 0)) << std::endl;
269
270 //printf("%16.15f\n", W.real());
271 }
272 }
273 //std::cout << W << std::endl;
274 if (abs(W.imag()) >= 1e-15) {
275 std::cout << "Warning: imaginary parts of statistical tensor do not cancel! " << std::endl;
276 std::cout << W.real() << " " << W.imag() << std::endl;
277 }
278 return W.real();
279 }
280
282 {
283 printf(" k q rho_k (real) rho_k (imaginary)\n");
284 for (int ik = 0; ik < (int)this->rho.size(); ++ik) {
285 for (int iq = 0; iq < (int)this->rho[ik].size(); ++iq) {
286 printf("%3d %3d %16.15f %16.15f\n", ik, iq - ik, this->rho[ik][iq].real(), this->rho[ik][iq].imag());
287 //std::cout << ik << " " << iq-ik << " " << this->rho[ik][iq].real() << " " << this->rho[ik][iq].imag() << std::endl;
288 }
289 }
290 }
291 } /* namespace AngDist */
292} /* namespace GamR */
StatTensor * Perturbation(std::function< std::complex< double >(double, double, double, double, double) > const &Gk, double t)
StatTensor * UnobservedProp(double ji, double lambda, double lambdaPrime, double jf, double delta, SolidAttenuation *Qk)
void Set(std::vector< double > Pm)
Definition StatTensor.cc:45
std::complex< double > GetBk(double k)
double W(double ji, double lambda, double lambdaPrime, double jf, double delta, SolidAttenuation *Qk, double theta, double phi)
std::complex< double > Get(double k, double q)
Definition StatTensor.cc:84
StatTensor * ObservedProp(double ji, double lambda, double lambdaPrime, double jf, double delta, SolidAttenuation *Qk, double theta, double phi)
std::complex< double > BigD(double j, double m, double mprime, double alpha, double beta, double gamma)
Definition WignerD.cc:66
double Ak(double k, double ji, double lambda, double lambdaPrime, double jf, double delta)
Definition AngDist.cc:66
double Agen(double k, double k1, double k2, double jf, double lambda, double lambdaPrime, double ji, double delta)
Definition AngDist.cc:76
Definition Gain.cc:19