00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef PLANCK_WIGNER_H
00033 #define PLANCK_WIGNER_H
00034
00035 #include <cmath>
00036 #include "arr.h"
00037
00038 #include "sse_utils_cxx.h"
00039
00040
00041
00042
00043 class wigner_d_halfpi_risbo_scalar
00044 {
00045 private:
00046 double pq;
00047 arr<double> sqt;
00048 arr2<double> d;
00049 int n;
00050
00051 void do_line0 (double *l1, int j);
00052 void do_line (const double *l1, double *l2, int j, int k);
00053
00054 public:
00055 wigner_d_halfpi_risbo_scalar(int lmax);
00056
00057 const arr2<double> &recurse ();
00058 };
00059
00060
00061
00062
00063 class wigner_d_risbo_scalar
00064 {
00065 private:
00066 double p,q;
00067 arr<double> sqt;
00068 arr2<double> d;
00069 int n;
00070
00071 void do_line0 (double *l1, int j);
00072 void do_line (const double *l1, double *l2, int j, int k);
00073
00074 public:
00075 wigner_d_risbo_scalar(int lmax, double ang);
00076
00077 const arr2<double> &recurse ();
00078 };
00079
00080
00081
00082
00083 class wigner_d_halfpi_risbo_openmp
00084 {
00085 private:
00086 double pq;
00087 arr<double> sqt;
00088 arr2<double> d,dd;
00089 int n;
00090
00091 public:
00092 wigner_d_halfpi_risbo_openmp(int lmax);
00093
00094 const arr2<double> &recurse ();
00095 };
00096
00097
00098
00099
00100 class wigner_d_risbo_openmp
00101 {
00102 private:
00103 double p,q;
00104 arr<double> sqt;
00105 arr2<double> d, dd;
00106 int n;
00107
00108 public:
00109 wigner_d_risbo_openmp(int lmax, double ang);
00110
00111 const arr2<double> &recurse ();
00112 };
00113
00114
00115
00116 class wignergen_scalar
00117 {
00118 protected:
00119 typedef double dbl3[3];
00120
00121
00122 double fsmall, fbig, eps;
00123 int lmax;
00124 arr<long double> logsum, lc05, ls05;
00125 arr<double> flm1, flm2, cf, costh, xl;
00126 arr<bool> thetaflip;
00127
00128
00129 int m1, m2, am1, am2, mlo, mhi, cosPow, sinPow;
00130 long double prefactor;
00131 arr<dbl3> fx;
00132 bool preMinus;
00133
00134
00135 arr<double> result;
00136
00137 enum { large_exponent2=90, minscale=-4, maxscale=14 };
00138
00139 public:
00140
00141
00142
00143
00144
00145 wignergen_scalar (int lmax_, const arr<double> &thetas, double epsilon);
00146
00147
00148
00149
00150
00151 void prepare (int m1_, int m2_);
00152
00153
00154
00155
00156
00157
00158
00159 const arr<double> &calc (int nth, int &firstl);
00160 void calc (int nth, int &firstl, arr<double> &resx) const;
00161 };
00162
00163 class wignergen: public wignergen_scalar
00164 {
00165 #ifdef __SSE2__
00166 private:
00167 arr_align<V2df,16> result2;
00168
00169 public:
00170 wignergen (int lmax_, const arr<double> &thetas, double epsilon)
00171 : wignergen_scalar (lmax_,thetas,epsilon), result2(lmax_+1) {}
00172
00173 using wignergen_scalar::calc;
00174 const arr_align<V2df,16> &calc (int nth1, int nth2, int &firstl);
00175 void calc (int nth1, int nth2, int &firstl, arr_align<V2df,16> &resx) const;
00176 #else
00177 public:
00178 wignergen (int lmax_, const arr<double> &thetas, double epsilon)
00179 : wignergen_scalar (lmax_,thetas,epsilon) {}
00180 #endif
00181 };
00182
00183 class wigner_estimator
00184 {
00185 private:
00186 int lmax, m1, m2, mbig;
00187 double xlmax, epsPow, cosm1m2;
00188
00189 public:
00190 wigner_estimator (int lmax_, double epsPow_);
00191
00192 void prepare_m (int m1_, int m2_);
00193 bool canSkip (double theta) const;
00194 };
00195
00196 #endif