00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <math.h>
00022 #include <stdio.h>
00023 #include "infft.h"
00024 #include "wigner.h"
00025
00026 double SO3_gamma(int m1, int m2, int j)
00027 {
00028 double dj, dm1, dm2, M, mini;
00029 static int i;
00030 static double result;
00031
00032 dj = (double) j;
00033 dm1 = (double) m1;
00034 dm2 = (double) m2;
00035 M = (double) (ABS(m1) > ABS(m2) ? ABS(m1) : ABS(m2));
00036 mini = (double) (ABS(m1) < ABS(m2) ? ABS(m1) : ABS(m2));
00037
00038 if (j == -1)
00039 {
00040
00041 result = 1.0;
00042 for (i = 1; i <= M - mini; i++)
00043 {
00044
00045 result *= (M + mini + i) / (4.0 * i);
00046 }
00047
00048 if (m1 < m2 && (ABS(m1) + ABS(m2)) % 2 == 1)
00049 result = -(1 / POW(2, mini) * SQRT(result));
00050 else
00051 result = (1 / POW(2, mini) * SQRT(result));
00052
00053 return result;
00054
00055 }
00056 else if (j <= M)
00057 {
00058 return (0.0);
00059 }
00060 else
00061 {
00062 return (
00063
00064 -(dj + 1.) / SQRT(((dj + 1.) * (dj + 1.) - dm1 * dm1) * ((dj + 1.) * (dj
00065 + 1.) - dm2 * dm2)) * SQRT((dj * dj - dm1 * dm1)
00066 * (dj * dj - dm2 * dm2)) / dj);
00067 }
00068 }
00069
00070 inline double SO3_alpha(int m1, int m2, int j)
00071 {
00072 double dj, dm1, dm2, M, mini, neg;
00073 dj = (double) j;
00074 dm1 = (double) m1;
00075 dm2 = (double) m2;
00076 M = (double) (ABS(m1) > ABS(m2) ? ABS(m1) : ABS(m2));
00077 mini = (double) (ABS(m1) < ABS(m2) ? ABS(m1) : ABS(m2));
00078
00081 if ((dm1 < 0 && dm2 >= 0) || (dm2 < 0 && dm1 >= 0))
00082 {
00083 neg = -1.0;
00084 }
00085 else
00086 {
00087 neg = 1.0;
00088 }
00089
00090 if (j == -1)
00091 {
00092 return (0.0);
00093 }
00094 else if (j == 0)
00095 {
00096 if (dm1 == dm2)
00097 {
00098 return 1.0;
00099 }
00100 else
00101 {
00102 return (int) (dm1 + dm2) % 2 == 0 ? -1.0 : 0.0;
00103 }
00104 }
00105 else if (j < M - mini)
00106 {
00107 return j % 2 == 0 ? -1.0 : 1.0;
00108 }
00109 else if (j < M)
00110 {
00111 return 1.0 * neg;
00112 }
00113 else
00114 {
00115 return (
00116
00117
00118 (dj + 1.) * (2. * dj + 1.) / SQRT(((dj + 1.) * (dj + 1.) - dm1 * dm1)
00119 * ((dj + 1.) * (dj + 1.) - dm2 * dm2)));
00120 }
00121 }
00122
00123 double SO3_beta(int m1, int m2, int j)
00124 {
00125 double dj, dm1, dm2, M, mini;
00126
00127 dj = (double) j;
00128 dm1 = (double) m1;
00129 dm2 = (double) m2;
00130 M = (double) (ABS(m1) > ABS(m2) ? ABS(m1) : ABS(m2));
00131 mini = (double) (ABS(m1) < ABS(m2) ? ABS(m1) : ABS(m2));
00132
00133 if (0 <= j && j < M)
00134 {
00135 return (1.0);
00136
00137 }
00138 else
00139 {
00140 if (dm1 == 0. || dm2 == 0.)
00141 return (0.0);
00142 else
00143 return ((-dm1 * dm2 * (2. * dj + 1.) / dj) / SQRT(((dj + 1.) * (dj + 1.)
00144 - dm1 * dm1) * ((dj + 1.) * (dj + 1.) - dm2 * dm2)));
00145 }
00146
00147 }
00148
00149
00150
00151 inline void SO3_alpha_row(double *alpha, int N, int k, int m)
00152 {
00153 int j;
00154 double *alpha_act = alpha;
00155 for (j = -1; j <= N; j++)
00156 {
00157 *alpha_act = SO3_alpha(k, m, j);
00158 alpha_act++;
00159 }
00160 }
00161
00162 inline void SO3_beta_row(double *beta, int N, int k, int m)
00163 {
00164 int j;
00165 double *beta_act = beta;
00166 for (j = -1; j <= N; j++)
00167 {
00168 *beta_act = SO3_beta(k, m, j);
00169 beta_act++;
00170 }
00171 }
00172
00173 inline void SO3_gamma_row(double *gamma, int N, int k, int m)
00174 {
00175 int j;
00176 double *gamma_act = gamma;
00177 for (j = -1; j <= N; j++)
00178 {
00179 *gamma_act = SO3_gamma(k, m, j);
00180 gamma_act++;
00181 }
00182 }
00183
00184
00185
00186 inline void SO3_alpha_matrix(double *alpha, int N, int m)
00187 {
00188 int i, j;
00189 double *alpha_act = alpha;
00190 for (i = -N; i <= N; i++)
00191 {
00192 for (j = -1; j <= N; j++)
00193 {
00194 *alpha_act = SO3_alpha(i, m, j);
00195 alpha_act++;
00196 }
00197 }
00198 }
00199
00200 inline void SO3_beta_matrix(double *alpha, int N, int m)
00201 {
00202 int i, j;
00203 double *alpha_act = alpha;
00204 for (i = -N; i <= N; i++)
00205 {
00206 for (j = -1; j <= N; j++)
00207 {
00208 *alpha_act = SO3_beta(i, m, j);
00209 alpha_act++;
00210 }
00211 }
00212 }
00213
00214 inline void SO3_gamma_matrix(double *alpha, int N, int m)
00215 {
00216 int i, j;
00217 double *alpha_act = alpha;
00218 for (i = -N; i <= N; i++)
00219 {
00220 for (j = -1; j <= N; j++)
00221 {
00222 *alpha_act = SO3_gamma(i, m, j);
00223 alpha_act++;
00224 }
00225 }
00226 }
00227
00228
00229
00230 inline void SO3_alpha_all(double *alpha, int N)
00231 {
00232 int q;
00233 int i, j, m;
00234 double *alpha_act = alpha;
00235 q = 0;
00236 for (m = -N; m <= N; m++)
00237 {
00238 for (i = -N; i <= N; i++)
00239 {
00240 for (j = -1; j <= N; j++)
00241 {
00242 *alpha_act = SO3_alpha(i, m, j);
00243 fprintf(stdout, "alpha_all_%d^[%d,%d]=%f\n", j, i, m,
00244 SO3_alpha(i, m, j));
00245 alpha_act++;
00246 q = q + 1;
00247
00248 }
00249 }
00250 }
00251 }
00252
00253 inline void SO3_beta_all(double *alpha, int N)
00254 {
00255 int i, j, m;
00256 double *alpha_act = alpha;
00257 for (m = -N; m <= N; m++)
00258 {
00259 for (i = -N; i <= N; i++)
00260 {
00261 for (j = -1; j <= N; j++)
00262 {
00263 *alpha_act = SO3_beta(i, m, j);
00264 alpha_act++;
00265 }
00266 }
00267 }
00268 }
00269
00270 inline void SO3_gamma_all(double *alpha, int N)
00271 {
00272 int i, j, m;
00273 double *alpha_act = alpha;
00274 for (m = -N; m <= N; m++)
00275 {
00276 for (i = -N; i <= N; i++)
00277 {
00278 for (j = -1; j <= N; j++)
00279 {
00280 *alpha_act = SO3_gamma(i, m, j);
00281 alpha_act++;
00282 }
00283 }
00284 }
00285 }
00286
00287 inline void eval_wigner(double *x, double *y, int size, int k, double *alpha,
00288 double *beta, double *gamma)
00289 {
00290
00291
00292
00293 int i, j;
00294 double a, b, x_val_act, a_old;
00295 double *x_act, *y_act;
00296 double *alpha_act, *beta_act, *gamma_act;
00297
00298
00299 x_act = x;
00300 y_act = y;
00301 for (i = 0; i < size; i++)
00302 {
00303 a = 1.0;
00304 b = 0.0;
00305 x_val_act = *x_act;
00306
00307 if (k == 0)
00308 {
00309 *y_act = 1.0;
00310 }
00311 else
00312 {
00313 alpha_act = &(alpha[k]);
00314 beta_act = &(beta[k]);
00315 gamma_act = &(gamma[k]);
00316 for (j = k; j > 1; j--)
00317 {
00318 a_old = a;
00319 a = b + a_old * ((*alpha_act) * x_val_act + (*beta_act));
00320 b = a_old * (*gamma_act);
00321 alpha_act--;
00322 beta_act--;
00323 gamma_act--;
00324 }
00325 *y_act = (a * ((*alpha_act) * x_val_act + (*beta_act)) + b);
00326 }
00327 x_act++;
00328 y_act++;
00329 }
00330 }
00331
00332 inline int eval_wigner_thresh(double *x, double *y, int size, int k,
00333 double *alpha, double *beta, double *gamma, double threshold)
00334 {
00335
00336 int i, j;
00337 double a, b, x_val_act, a_old;
00338 double *x_act, *y_act;
00339 double *alpha_act, *beta_act, *gamma_act;
00340
00341
00342 x_act = x;
00343 y_act = y;
00344 for (i = 0; i < size; i++)
00345 {
00346 a = 1.0;
00347 b = 0.0;
00348 x_val_act = *x_act;
00349
00350 if (k == 0)
00351 {
00352 *y_act = 1.0;
00353 }
00354 else
00355 {
00356 alpha_act = &(alpha[k]);
00357 beta_act = &(beta[k]);
00358 gamma_act = &(gamma[k]);
00359 for (j = k; j > 1; j--)
00360 {
00361 a_old = a;
00362 a = b + a_old * ((*alpha_act) * x_val_act + (*beta_act));
00363 b = a_old * (*gamma_act);
00364 alpha_act--;
00365 beta_act--;
00366 gamma_act--;
00367 }
00368 *y_act = (a * ((*alpha_act) * x_val_act + (*beta_act)) + b);
00369 if (fabs(*y_act) > threshold)
00370 {
00371 return 1;
00372 }
00373 }
00374 x_act++;
00375 y_act++;
00376 }
00377 return 0;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389 double wigner_start(int m1, int m2, double theta)
00390 {
00391
00392 int i, l, delta;
00393 int cosPower, sinPower;
00394 int absM1, absM2;
00395 double dl, dm1, dm2, normFactor, sinSign;
00396 double dCP, dSP;
00397 double max;
00398 double min;
00399
00400 max = (double) (ABS(m1) > ABS(m2) ? ABS(m1) : ABS(m2));
00401 min = (double) (ABS(m1) < ABS(m2) ? ABS(m1) : ABS(m2));
00402
00403 l = max;
00404 delta = l - min;
00405
00406 absM1 = ABS(m1);
00407 absM2 = ABS(m2);
00408 dl = (double) l;
00409 dm1 = (double) m1;
00410 dm2 = (double) m2;
00411 sinSign = 1.;
00412 normFactor = 1.;
00413
00414 for (i = 0; i < delta; i++)
00415 normFactor *= SQRT((2. * dl - ((double) i)) / (((double) i) + 1.));
00416
00417
00418
00419 normFactor *= SQRT((2. * dl + 1.) / 2.);
00420
00421 if (l == absM1)
00422 if (m1 >= 0)
00423 {
00424 cosPower = l + m2;
00425 sinPower = l - m2;
00426 if ((l - m2) % 2)
00427 sinSign = -1.;
00428 }
00429 else
00430 {
00431 cosPower = l - m2;
00432 sinPower = l + m2;
00433 }
00434 else if (m2 >= 0)
00435 {
00436 cosPower = l + m1;
00437 sinPower = l - m1;
00438 }
00439 else
00440 {
00441 cosPower = l - m1;
00442 sinPower = l + m1;
00443 if ((l + m1) % 2)
00444 sinSign = -1.;
00445 }
00446
00447 dCP = (double) cosPower;
00448 dSP = (double) sinPower;
00449
00450 return normFactor * sinSign * POW(sin(theta / 2), dSP) * POW(cos(theta / 2),
00451 dCP);
00452 }