54 int el, m, mm, ind, t;
56 double *sqrt_tbl, *signs;
57 int el2pel, inds_offset;
59 double ssign, elfactor;
63 int f_stride, Fmt_stride, Fmt_offset, Fmm_stride, Fmm_offset;
66 int dl_offset, dl_stride;
69 int elmmsign, elssign;
73 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
75 signs = (
double*)calloc(L+1,
sizeof(
double));
81 inds = (
int*)calloc(2*L-1,
sizeof(
int));
85 for (el=0; el<=2*(L-1)+1; el++)
86 sqrt_tbl[el] = sqrt((
double)el);
87 for (m=0; m<=L-1; m=m+2) {
91 ssign = signs[abs(spin)];
92 spinneg = spin <= 0 ? spin : -spin;
94 for (m=-(L-1); m<=L-1; m++)
95 expsm[m + exps_offset] = cexp(I*
SSHT_PION2*(m+spin));
96 for (mm=-(L-1); mm<=L-1; mm++)
97 expsmm[mm + exps_offset] = cexp(-I*mm*
SSHT_PI/(2.0*L-1.0));
102 "Computing adjoint inverse transform using MW sampling with ");
103 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
104 L,
",", spin,
", FALSE)");
107 "Using routine ssht_adjoint_mw_inverse_sov_sym...");
118 plan = fftw_plan_dft_1d(2*L-1, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
119 for (t=0; t<=L-1; t++) {
120 memcpy(inout, &f[t*f_stride], f_stride*
sizeof(
SSHT_COMPLEX(
double)));
121 fftw_execute_dft(plan, inout, inout);
122 for(m=0; m<=L-1; m++)
123 Fmt[(m+Fmt_offset)*Fmt_stride + t] = inout[m];
124 for(m=-(L-1); m<=-1; m++)
125 Fmt[(m+Fmt_offset)*Fmt_stride + t] = inout[m+2*L-1];
129 for (m=-(L-1); m<=L-1; m++)
130 for (t=L; t<=2*L-2; t++)
131 Fmt[(m+Fmt_offset)*Fmt_stride + t] = 0.0;
138 for (m=-(L-1); m<=L-1; m++) {
139 memcpy(inout, &Fmt[(m+Fmt_offset)*Fmt_stride], Fmt_stride*
sizeof(
SSHT_COMPLEX(
double)));
140 fftw_execute_dft(plan, inout, inout);
141 for(mm=0; mm<=L-1; mm++)
142 Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset] =
144 for(mm=-(L-1); mm<=-1; mm++)
145 Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset] =
148 fftw_destroy_plan(plan);
152 for (mm=-(L-1); mm<=L-1; mm++)
153 for (m=-(L-1); m<=L-1; m++)
154 Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset] *=
155 expsmm[mm + exps_offset];
167 for (el=0; el<=L-1; el++) {
168 for (m=-el; m<=el; m++) {
169 ssht_sampling_elm2ind(&ind, el, m);
173 for (el=abs(spin); el<=L-1; el++) {
179 if (el!=0 && el==abs(spin)) {
180 for(eltmp=0; eltmp<=abs(spin); eltmp++)
183 eltmp, sqrt_tbl, signs);
194 el, sqrt_tbl, signs);
205 if (el!=0 && el==abs(spin)) {
206 for(eltmp=0; eltmp<=abs(spin); eltmp++)
229 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
230 el2pel = el *el + el;
231 for (m=-el; m<=el; m++)
232 inds[m + inds_offset] = el2pel + m;
233 elssign = spin <= 0 ? 1.0 : signs[el];
235 for (m=-el; m<=-1; m++) {
237 ind = inds[m + inds_offset];
241 * expsm[m + exps_offset]
242 * signs[el] * dl[0*dl_stride - m + dl_offset]
243 * elssign * dl[0*dl_stride - spinneg + dl_offset]
244 * Fmm[(0+Fmm_offset)*Fmm_stride + m + Fmm_offset];
246 for (m=0; m<=el; m++) {
248 ind = inds[m + inds_offset];
252 * expsm[m + exps_offset]
253 * dl[0*dl_stride + m + dl_offset]
254 * elssign * dl[0*dl_stride - spinneg + dl_offset]
255 * Fmm[(0+Fmm_offset)*Fmm_stride + m + Fmm_offset];
258 for (mm=1; mm<=el; mm++) {
259 elmmsign = signs[el] * signs[mm];
260 elssign = spin <= 0 ? 1.0 : elmmsign;
262 for (m=-el; m<=-1; m++) {
263 ind = inds[m + inds_offset];
267 * expsm[m + exps_offset]
268 * elmmsign * dl[mm*dl_stride - m + dl_offset]
269 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
270 * ( Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]
272 * Fmm[(-mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]);
274 for (m=0; m<=el; m++) {
275 ind = inds[m + inds_offset];
279 * expsm[m + exps_offset]
280 * dl[mm*dl_stride + m + dl_offset]
281 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
282 * ( Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]
284 * Fmm[(-mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]);
305 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint inverse transform computed!");
331 int el, m, mm, ind, ind_nm, t;
333 double *sqrt_tbl, *signs;
334 int el2pel, inds_offset;
336 double ssign, elfactor;
341 int f_stride, Fmt_stride, Fmt_offset, Fmm_stride, Fmm_offset;
344 int dl_offset, dl_stride;
347 int elmmsign, elssign;
352 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
354 signs = (
double*)calloc(L+1,
sizeof(
double));
360 inds = (
int*)calloc(L,
sizeof(
int));
364 for (el=0; el<=2*(L-1)+1; el++)
365 sqrt_tbl[el] = sqrt((
double)el);
366 for (m=0; m<=L-1; m=m+2) {
370 ssign = signs[abs(spin)];
371 spinneg = spin <= 0 ? spin : -spin;
373 for (m=0; m<=L-1; m++)
375 for (mm=-(L-1); mm<=L-1; mm++)
376 expsmm[mm + exps_offset] = cexp(-I*mm*
SSHT_PI/(2.0*L-1.0));
381 "Computing adjoint inverse transform using MW sampling with ");
382 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
383 L,
",", spin,
", TRUE)");
386 "Using routine ssht_adjoint_mw_inverse_sov_sym_real...");
394 in_real = (
double*)calloc(2*L-1,
sizeof(
double));
398 plan = fftw_plan_dft_r2c_1d(2*L-1, in_real, out, FFTW_MEASURE);
399 for (t=0; t<=L-1; t++) {
400 memcpy(in_real, &f[t*f_stride], f_stride*
sizeof(
double));
401 fftw_execute_dft_r2c(plan, in_real, out);
402 for(m=0; m<=L-1; m++)
403 Fmt[m*Fmt_stride + t] = out[m];
407 fftw_destroy_plan(plan);
410 for (m=0; m<=L-1; m++)
411 for (t=L; t<=2*L-2; t++)
412 Fmt[m*Fmt_stride + t] = 0.0;
421 plan = fftw_plan_dft_1d(2*L-1, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
422 for (m=0; m<=L-1; m++) {
423 memcpy(inout, &Fmt[m*Fmt_stride], Fmt_stride*
sizeof(
SSHT_COMPLEX(
double)));
424 fftw_execute_dft(plan, inout, inout);
425 for(mm=0; mm<=L-1; mm++)
426 Fmm[(mm+Fmm_offset)*Fmm_stride + m] =
428 for(mm=-(L-1); mm<=-1; mm++)
429 Fmm[(mm+Fmm_offset)*Fmm_stride + m] =
432 fftw_destroy_plan(plan);
436 for (mm=-(L-1); mm<=L-1; mm++)
437 for (m=0; m<=L-1; m++)
438 Fmm[(mm+Fmm_offset)*Fmm_stride + m] *=
439 expsmm[mm + exps_offset];
451 for (el=0; el<=L-1; el++) {
452 for (m=0; m<=el; m++) {
453 ssht_sampling_elm2ind(&ind, el, m);
457 for (el=abs(spin); el<=L-1; el++) {
463 if (el!=0 && el==abs(spin)) {
464 for(eltmp=0; eltmp<=abs(spin); eltmp++)
467 eltmp, sqrt_tbl, signs);
478 el, sqrt_tbl, signs);
489 if (el!=0 && el==abs(spin)) {
490 for(eltmp=0; eltmp<=abs(spin); eltmp++)
514 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
515 el2pel = el *el + el;
516 for (m=0; m<=el; m++)
517 inds[m + inds_offset] = el2pel + m;
518 elssign = spin <= 0 ? 1.0 : signs[el];
520 for (m=0; m<=el; m++) {
522 ind = inds[m + inds_offset];
527 * dl[0*dl_stride + m + dl_offset]
528 * elssign * dl[0*dl_stride - spinneg + dl_offset]
529 * Fmm[(0+Fmm_offset)*Fmm_stride + m];
532 for (mm=1; mm<=el; mm++) {
533 elmmsign = signs[el] * signs[mm];
534 elssign = spin <= 0 ? 1.0 : elmmsign;
536 for (m=0; m<=el; m++) {
537 ind = inds[m + inds_offset];
542 * dl[mm*dl_stride + m + dl_offset]
543 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
544 * ( Fmm[(mm+Fmm_offset)*Fmm_stride + m]
546 * Fmm[(-mm+Fmm_offset)*Fmm_stride + m]);
554 for (el=abs(spin); el<=L-1; el++) {
555 for (m=1; m<=el; m++) {
556 ssht_sampling_elm2ind(&ind, el, m);
557 ssht_sampling_elm2ind(&ind_nm, el, -m);
558 flm[ind_nm] = signs[m] * conj(flm[ind]);
576 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint inverse transform computed!");
604 double *sqrt_tbl, *signs;
605 int el2pel, inds_offset;
607 double ssign, elfactor;
611 int dl_offset, dl_stride;
614 double elmmsign, elssign;
617 int Fmm_offset, Fmm_stride;
619 fftw_plan plan, plan_bwd, plan_fwd;
624 int f_stride, Ftm_stride, Ftm_offset;
629 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
631 signs = (
double*)calloc(L+1,
sizeof(
double));
635 inds = (
int*)calloc(2*L-1,
sizeof(
int));
639 for (el=0; el<=2*(L-1)+1; el++)
640 sqrt_tbl[el] = sqrt((
double)el);
641 for (m=0; m<=L-1; m=m+2) {
645 ssign = signs[abs(spin)];
646 spinneg = spin <= 0 ? spin : -spin;
648 for (m=-(L-1); m<=L-1; m++)
649 exps[m + exps_offset] = cexp(-I*
SSHT_PION2*(m+spin));
654 "Computing adjoint forward transform using MW sampling with ");
655 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
656 L,
",", spin,
", FALSE)");
659 "Using routine ssht_adjoint_mw_forward_sov_sym...");
676 for (el=abs(spin); el<=L-1; el++) {
682 if (el!=0 && el==abs(spin)) {
683 for(eltmp=0; eltmp<=abs(spin); eltmp++)
686 eltmp, sqrt_tbl, signs);
697 el, sqrt_tbl, signs);
708 if (el!=0 && el==abs(spin)) {
709 for(eltmp=0; eltmp<=abs(spin); eltmp++)
732 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
733 el2pel = el *el + el;
734 for (m=-el; m<=el; m++)
735 inds[m + inds_offset] = el2pel + m;
736 for (mm=0; mm<=el; mm++) {
737 elmmsign = signs[el] * signs[mm];
738 elssign = spin <= 0 ? 1.0 : elmmsign;
740 for (m=-el; m<=-1; m++) {
741 ind = inds[m + inds_offset];
742 Fmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] +=
745 * exps[m + exps_offset]
746 * elmmsign * dl[mm*dl_stride - m + dl_offset]
747 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
750 for (m=0; m<=el; m++) {
751 ind = inds[m + inds_offset];
752 Fmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] +=
755 * exps[m + exps_offset]
756 * dl[mm*dl_stride + m + dl_offset]
757 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
771 for (m=-(L-1); m<=L-1; m++)
772 for (mm=-(L-1); mm<=-1; mm++)
773 Fmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] =
774 signs[abs(m)] * ssign
775 * Fmm[(m + Fmm_offset)*Fmm_stride - mm + Fmm_offset];
781 for (mm=-2*(L-1); mm<=2*(L-1); mm++)
782 w[mm+w_offset] = ssht_sampling_weight_mw(mm);
789 plan_bwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
790 plan_fwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
791 for (mm=1; mm<=2*L-2; mm++)
792 inout[mm + w_offset] = w[mm - 2*(L-1) - 1 + w_offset];
793 for (mm=-2*(L-1); mm<=0; mm++)
794 inout[mm + w_offset] = w[mm + 2*(L-1) + w_offset];
795 fftw_execute_dft(plan_bwd, inout, inout);
796 for (mm=0; mm<=2*L-2; mm++)
797 wr[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
798 for (mm=-2*(L-1); mm<=-1; mm++)
799 wr[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
808 for (m=-(L-1); m<=L-1; m++) {
811 for (mm=-2*(L-1); mm<=-L; mm++)
812 Fmm_pad[mm+w_offset] = 0.0;
813 for (mm=L; mm<=2*(L-1); mm++)
814 Fmm_pad[mm+w_offset] = 0.0;
815 for (mm=-(L-1); mm<=L-1; mm++)
816 Fmm_pad[mm + w_offset] =
817 Fmm[(m+Fmm_offset)*Fmm_stride + mm + Fmm_offset];
820 for (mm=1; mm<=2*L-2; mm++)
821 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
822 for (mm=-2*(L-1); mm<=0; mm++)
823 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
824 fftw_execute_dft(plan_bwd, inout, inout);
825 for (mm=0; mm<=2*L-2; mm++)
826 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
827 for (mm=-2*(L-1); mm<=-1; mm++)
828 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
831 for (r=-2*(L-1); r<=2*(L-1); r++)
832 Fmm_pad[r + w_offset] *= wr[-r + w_offset];
835 for (mm=1; mm<=2*L-2; mm++)
836 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
837 for (mm=-2*(L-1); mm<=0; mm++)
838 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
839 fftw_execute_dft(plan_fwd, inout, inout);
840 for (mm=0; mm<=2*L-2; mm++)
841 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
842 for (mm=-2*(L-1); mm<=-1; mm++)
843 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
846 for (mm=-(L-1); mm<=L-1; mm++)
847 Gmm[(m+Fmm_offset)*Fmm_stride + mm + Fmm_offset] =
848 Fmm_pad[mm + w_offset] * 2.0 *
SSHT_PI / (4.0*L-3.0);
851 fftw_destroy_plan(plan_bwd);
852 fftw_destroy_plan(plan_fwd);
856 for (mm=-(L-1); mm<=L-1; mm++) {
857 mmfactor = cexp(I*mm*
SSHT_PI/(2.0*L-1.0));
858 for (m=-(L-1); m<=L-1; m++)
859 Gmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] *=
866 plan = fftw_plan_dft_1d(2*L-1, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
871 for (m=-(L-1); m<=L-1; m++) {
873 for(mm=0; mm<=L-1; mm++)
874 inout[mm] = Gmm[(m+Fmm_offset)*Fmm_stride + mm + Fmm_offset];
875 for(mm=-(L-1); mm<=-1; mm++)
876 inout[mm+2*L-1] = Gmm[(m+Fmm_offset)*Fmm_stride + mm + Fmm_offset];
877 fftw_execute_dft(plan, inout, inout);
879 for(t=0; t<=2*L-2; t++)
880 Ftm[t*Ftm_stride + m + Ftm_offset] = inout[t] / (2.0*L-1.0);
885 for(t=0; t<=L-2; t++)
886 for (m=-(L-1); m<=L-1; m++)
887 Ftm[t*Ftm_stride + m + Ftm_offset] =
888 Ftm[t*Ftm_stride + m + Ftm_offset]
889 + signs[abs(m)] * ssign * Ftm[(2*L-2-t)*Ftm_stride + m + Ftm_offset];
893 for(t=0; t<=L-1; t++) {
895 for(m=0; m<=L-1; m++)
896 inout[m] = Ftm[t*Ftm_stride + m + Ftm_offset];
897 for(m=-(L-1); m<=-1; m++)
898 inout[m+2*L-1] = Ftm[t*Ftm_stride + m + Ftm_offset];
899 fftw_execute_dft(plan, inout, inout);
901 for(p=0; p<=2*L-2; p++)
902 f[t*f_stride + p] = inout[p] / (2.0*L-1.0);
905 fftw_destroy_plan(plan);
925 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint forward transform computed!");
954 double *sqrt_tbl, *signs;
955 int el2pel, inds_offset;
957 double ssign, elfactor;
961 int dl_offset, dl_stride;
964 double elmmsign, elssign;
967 int Fmm_offset, Fmm_stride;
969 fftw_plan plan, plan_bwd, plan_fwd;
974 int f_stride, Ftm_stride;
983 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
985 signs = (
double*)calloc(L+1,
sizeof(
double));
989 inds = (
int*)calloc(2*L-1,
sizeof(
int));
993 for (el=0; el<=2*(L-1)+1; el++)
994 sqrt_tbl[el] = sqrt((
double)el);
995 for (m=0; m<=L-1; m=m+2) {
999 ssign = signs[abs(spin)];
1000 spinneg = spin <= 0 ? spin : -spin;
1002 for (m=-(L-1); m<=L-1; m++)
1003 exps[m + exps_offset] = cexp(-I*
SSHT_PION2*(m+spin));
1006 if (verbosity > 0) {
1008 "Computing adjoint forward transform using MW sampling with ");
1009 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
1010 L,
",", spin,
", FALSE)");
1013 "Using routine ssht_adjoint_mw_forward_sov_sym_real...");
1030 for (el=abs(spin); el<=L-1; el++) {
1033 switch (dl_method) {
1036 if (el!=0 && el==abs(spin)) {
1037 for(eltmp=0; eltmp<=abs(spin); eltmp++)
1040 eltmp, sqrt_tbl, signs);
1051 el, sqrt_tbl, signs);
1062 if (el!=0 && el==abs(spin)) {
1063 for(eltmp=0; eltmp<=abs(spin); eltmp++)
1086 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
1087 el2pel = el *el + el;
1088 for (m=0; m<=el; m++)
1089 inds[m + inds_offset] = el2pel + m;
1090 for (mm=0; mm<=el; mm++) {
1091 elmmsign = signs[el] * signs[mm];
1092 elssign = spin <= 0 ? 1.0 : elmmsign;
1094 for (m=0; m<=el; m++) {
1095 ind = inds[m + inds_offset];
1096 Fmm[m*Fmm_stride + mm + Fmm_offset] +=
1099 * exps[m + exps_offset]
1100 * dl[mm*dl_stride + m + dl_offset]
1101 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
1115 for (m=0; m<=L-1; m++)
1116 for (mm=-(L-1); mm<=-1; mm++)
1117 Fmm[m*Fmm_stride + mm + Fmm_offset] =
1118 signs[abs(m)] * ssign
1119 * Fmm[m*Fmm_stride - mm + Fmm_offset];
1125 for (mm=-2*(L-1); mm<=2*(L-1); mm++)
1126 w[mm+w_offset] = ssht_sampling_weight_mw(mm);
1133 plan_bwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
1134 plan_fwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
1135 for (mm=1; mm<=2*L-2; mm++)
1136 inout[mm + w_offset] = w[mm - 2*(L-1) - 1 + w_offset];
1137 for (mm=-2*(L-1); mm<=0; mm++)
1138 inout[mm + w_offset] = w[mm + 2*(L-1) + w_offset];
1139 fftw_execute_dft(plan_bwd, inout, inout);
1140 for (mm=0; mm<=2*L-2; mm++)
1141 wr[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
1142 for (mm=-2*(L-1); mm<=-1; mm++)
1143 wr[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
1153 for (m=0; m<=L-1; m++) {
1156 for (mm=-2*(L-1); mm<=-L; mm++)
1157 Fmm_pad[mm+w_offset] = 0.0;
1158 for (mm=L; mm<=2*(L-1); mm++)
1159 Fmm_pad[mm+w_offset] = 0.0;
1160 for (mm=-(L-1); mm<=L-1; mm++)
1161 Fmm_pad[mm + w_offset] =
1162 Fmm[m*Fmm_stride + mm + Fmm_offset];
1165 for (mm=1; mm<=2*L-2; mm++)
1166 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
1167 for (mm=-2*(L-1); mm<=0; mm++)
1168 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
1169 fftw_execute_dft(plan_bwd, inout, inout);
1170 for (mm=0; mm<=2*L-2; mm++)
1171 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
1172 for (mm=-2*(L-1); mm<=-1; mm++)
1173 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
1176 for (r=-2*(L-1); r<=2*(L-1); r++)
1177 Fmm_pad[r + w_offset] *= wr[-r + w_offset];
1180 for (mm=1; mm<=2*L-2; mm++)
1181 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
1182 for (mm=-2*(L-1); mm<=0; mm++)
1183 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
1184 fftw_execute_dft(plan_fwd, inout, inout);
1185 for (mm=0; mm<=2*L-2; mm++)
1186 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
1187 for (mm=-2*(L-1); mm<=-1; mm++)
1188 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
1191 for (mm=-(L-1); mm<=L-1; mm++)
1192 Gmm[m*Gmm_stride + mm + Fmm_offset] =
1193 Fmm_pad[mm + w_offset] * 2.0 *
SSHT_PI / (4.0*L-3.0);
1196 fftw_destroy_plan(plan_bwd);
1197 fftw_destroy_plan(plan_fwd);
1201 for (mm=-(L-1); mm<=L-1; mm++) {
1202 mmfactor = cexp(I*mm*
SSHT_PI/(2.0*L-1.0));
1203 for (m=0; m<=L-1; m++)
1204 Gmm[m*Gmm_stride + mm + Fmm_offset] *=
1211 plan = fftw_plan_dft_1d(2*L-1, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
1215 for (m=0; m<=L-1; m++) {
1217 for(mm=0; mm<=L-1; mm++)
1218 inout[mm] = Gmm[m*Gmm_stride + mm + Fmm_offset];
1219 for(mm=-(L-1); mm<=-1; mm++)
1220 inout[mm+2*L-1] = Gmm[m*Gmm_stride + mm + Fmm_offset];
1221 fftw_execute_dft(plan, inout, inout);
1223 for(t=0; t<=2*L-2; t++)
1224 Ftm[t*Ftm_stride + m] = inout[t] / (2.0*L-1.0);
1227 fftw_destroy_plan(plan);
1231 for(t=0; t<=L-2; t++)
1232 for (m=0; m<=L-1; m++)
1233 Ftm[t*Ftm_stride + m] =
1234 Ftm[t*Ftm_stride + m]
1235 + signs[abs(m)] * ssign * Ftm[(2*L-2-t)*Ftm_stride + m];
1238 out_real = (
double*)calloc(2*L-1,
sizeof(
double));
1242 plan = fftw_plan_dft_c2r_1d(2*L-1, in, out_real, FFTW_MEASURE);
1244 for(t=0; t<=L-1; t++) {
1246 memcpy(in, &Ftm[t*Ftm_stride], Ftm_stride*
sizeof(
SSHT_COMPLEX(
double)));
1247 fftw_execute_dft_c2r(plan, in, out_real);
1249 for(p=0; p<=2*L-2; p++)
1250 f[t*f_stride + p] = out_real[p] / (2.0*L-1.0);
1253 fftw_destroy_plan(plan);
1274 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint forward transform computed!");
1312 int f_stride = 2*L-1;
1320 dl_method, verbosity);
1323 memcpy(f, f_full, (L-1)*(2*L-1)*
sizeof(
SSHT_COMPLEX(
double)));
1324 *f_sp = f_full[(L-1)*f_stride + 0];
1358 int f_stride = 2*L-1;
1361 f_full = (
double*)calloc(L*(2*L-1),
sizeof(double));
1366 dl_method, verbosity);
1369 memcpy(f, f_full, (L-1)*(2*L-1)*
sizeof(
double));
1370 *f_sp = f_full[(L-1)*f_stride + 0];
1405 int p, f_stride = 2*L-1;
1411 memcpy(f_full, f, (L-1)*(2*L-1)*
sizeof(
SSHT_COMPLEX(
double)));
1414 for (p=0; p<=2*L-2; p++) {
1416 f_full[(L-1)*f_stride + p] = f_sp * cexp(I*spin*(phi-phi_sp));
1421 dl_method, verbosity);
1454 int p, f_stride = 2*L-1;
1457 f_full = (
double*)calloc(L*(2*L-1),
sizeof(double));
1459 memcpy(f_full, f, (L-1)*(2*L-1)*
sizeof(
double));
1462 for (p=0; p<=2*L-2; p++)
1463 f_full[(L-1)*f_stride + p] = f_sp;
1467 dl_method, verbosity);
1500 int el, m, mm, ind, t;
1502 double *sqrt_tbl, *signs;
1503 int el2pel, inds_offset;
1505 double ssign, elfactor;
1509 int f_stride, Fmt_stride, Fmt_offset, Fmm_stride, Fmm_offset;
1512 int dl_offset, dl_stride;
1515 int elmmsign, elssign;
1519 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
1521 signs = (
double*)calloc(L+1,
sizeof(
double));
1527 inds = (
int*)calloc(2*L-1,
sizeof(
int));
1531 for (el=0; el<=2*(L-1)+1; el++)
1532 sqrt_tbl[el] = sqrt((
double)el);
1533 for (m=0; m<=L-1; m=m+2) {
1537 ssign = signs[abs(spin)];
1538 spinneg = spin <= 0 ? spin : -spin;
1540 for (m=-(L-1); m<=L-1; m++)
1541 expsm[m + exps_offset] = cexp(I*
SSHT_PION2*(m+spin));
1542 for (mm=-(L-1); mm<=L-1; mm++)
1543 expsmm[mm + exps_offset] = cexp(-I*mm*
SSHT_PI/(2.0*L-1.0));
1546 if (verbosity > 0) {
1548 "Computing adjoint inverse transform using MW symmetric sampling with ");
1549 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
1550 L,
",", spin,
", FALSE)");
1553 "Using routine ssht_adjoint_mw_inverse_sov_sym_ss...");
1566 plan = fftw_plan_dft_1d(2*L, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
1567 for (t=0; t<=L; t++) {
1568 memcpy(inout, &f[t*f_stride], f_stride*
sizeof(
SSHT_COMPLEX(
double)));
1569 fftw_execute_dft(plan, inout, inout);
1571 Fmt[(m+Fmt_offset)*Fmt_stride + t] = inout[m];
1572 for(m=-(L-1); m<=-1; m++)
1573 Fmt[(m+Fmt_offset)*Fmt_stride + t] = inout[m+2*L-1+1];
1575 fftw_destroy_plan(plan);
1579 for (m=-(L-1); m<=L; m++)
1580 for (t=L+1; t<=2*L-1; t++)
1581 Fmt[(m+Fmt_offset)*Fmt_stride + t] = 0.0;
1591 plan = fftw_plan_dft_1d(2*L, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
1592 for (m=-(L-1); m<=L; m++) {
1593 memcpy(inout, &Fmt[(m+Fmt_offset)*Fmt_stride], Fmt_stride*
sizeof(
SSHT_COMPLEX(
double)));
1594 fftw_execute_dft(plan, inout, inout);
1595 for(mm=0; mm<=L; mm++)
1596 Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset] =
1598 for(mm=-(L-1); mm<=-1; mm++)
1599 Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset] =
1602 fftw_destroy_plan(plan);
1615 for (el=0; el<=L-1; el++) {
1616 for (m=-el; m<=el; m++) {
1617 ssht_sampling_elm2ind(&ind, el, m);
1621 for (el=abs(spin); el<=L-1; el++) {
1624 switch (dl_method) {
1627 if (el!=0 && el==abs(spin)) {
1628 for(eltmp=0; eltmp<=abs(spin); eltmp++)
1631 eltmp, sqrt_tbl, signs);
1642 el, sqrt_tbl, signs);
1653 if (el!=0 && el==abs(spin)) {
1654 for(eltmp=0; eltmp<=abs(spin); eltmp++)
1677 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
1678 el2pel = el *el + el;
1679 for (m=-el; m<=el; m++)
1680 inds[m + inds_offset] = el2pel + m;
1681 elssign = spin <= 0 ? 1.0 : signs[el];
1683 for (m=-el; m<=-1; m++) {
1685 ind = inds[m + inds_offset];
1689 * expsm[m + exps_offset]
1690 * signs[el] * dl[0*dl_stride - m + dl_offset]
1691 * elssign * dl[0*dl_stride - spinneg + dl_offset]
1692 * Fmm[(0+Fmm_offset)*Fmm_stride + m + Fmm_offset];
1694 for (m=0; m<=el; m++) {
1696 ind = inds[m + inds_offset];
1700 * expsm[m + exps_offset]
1701 * dl[0*dl_stride + m + dl_offset]
1702 * elssign * dl[0*dl_stride - spinneg + dl_offset]
1703 * Fmm[(0+Fmm_offset)*Fmm_stride + m + Fmm_offset];
1706 for (mm=1; mm<=el; mm++) {
1707 elmmsign = signs[el] * signs[mm];
1708 elssign = spin <= 0 ? 1.0 : elmmsign;
1710 for (m=-el; m<=-1; m++) {
1711 ind = inds[m + inds_offset];
1715 * expsm[m + exps_offset]
1716 * elmmsign * dl[mm*dl_stride - m + dl_offset]
1717 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
1718 * ( Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]
1720 * Fmm[(-mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]);
1722 for (m=0; m<=el; m++) {
1723 ind = inds[m + inds_offset];
1727 * expsm[m + exps_offset]
1728 * dl[mm*dl_stride + m + dl_offset]
1729 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
1730 * ( Fmm[(mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]
1732 * Fmm[(-mm+Fmm_offset)*Fmm_stride + m + Fmm_offset]);
1753 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint inverse transform computed!");
1778 int el, m, mm, ind, ind_nm, t;
1780 double *sqrt_tbl, *signs;
1781 int el2pel, inds_offset;
1783 double ssign, elfactor;
1788 int f_stride, Fmt_stride, Fmt_offset, Fmm_stride, Fmm_offset;
1791 int dl_offset, dl_stride;
1794 int elmmsign, elssign;
1799 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
1801 signs = (
double*)calloc(L+1,
sizeof(
double));
1805 inds = (
int*)calloc(L,
sizeof(
int));
1809 for (el=0; el<=2*(L-1)+1; el++)
1810 sqrt_tbl[el] = sqrt((
double)el);
1811 for (m=0; m<=L-1; m=m+2) {
1815 ssign = signs[abs(spin)];
1816 spinneg = spin <= 0 ? spin : -spin;
1817 for (m=0; m<=L-1; m++)
1821 if (verbosity > 0) {
1823 "Computing adjoint inverse transform using MW symmetric sampling with ");
1824 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
1825 L,
",", spin,
", TRUE)");
1828 "Using routine ssht_adjoint_mw_inverse_sov_sym_ss_real...");
1838 in_real = (
double*)calloc(2*L,
sizeof(
double));
1842 plan = fftw_plan_dft_r2c_1d(2*L, in_real, out, FFTW_MEASURE);
1843 for (t=0; t<=L; t++) {
1844 memcpy(in_real, &f[t*f_stride], f_stride*
sizeof(
double));
1845 fftw_execute_dft_r2c(plan, in_real, out);
1847 Fmt[m*Fmt_stride + t] = out[m];
1851 fftw_destroy_plan(plan);
1854 for (m=0; m<=L; m++)
1855 for (t=L+1; t<=2*L-1; t++)
1856 Fmt[m*Fmt_stride + t] = 0.0;
1866 plan = fftw_plan_dft_1d(2*L, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
1867 for (m=0; m<=L; m++) {
1868 memcpy(inout, &Fmt[m*Fmt_stride], Fmt_stride*
sizeof(
SSHT_COMPLEX(
double)));
1869 fftw_execute_dft(plan, inout, inout);
1870 for(mm=0; mm<=L; mm++)
1871 Fmm[(mm+Fmm_offset)*Fmm_stride + m] =
1873 for(mm=-(L-1); mm<=-1; mm++)
1874 Fmm[(mm+Fmm_offset)*Fmm_stride + m] =
1877 fftw_destroy_plan(plan);
1890 for (el=0; el<=L-1; el++) {
1891 for (m=0; m<=el; m++) {
1892 ssht_sampling_elm2ind(&ind, el, m);
1896 for (el=abs(spin); el<=L-1; el++) {
1899 switch (dl_method) {
1902 if (el!=0 && el==abs(spin)) {
1903 for(eltmp=0; eltmp<=abs(spin); eltmp++)
1906 eltmp, sqrt_tbl, signs);
1917 el, sqrt_tbl, signs);
1928 if (el!=0 && el==abs(spin)) {
1929 for(eltmp=0; eltmp<=abs(spin); eltmp++)
1952 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
1953 el2pel = el *el + el;
1954 for (m=0; m<=el; m++)
1955 inds[m + inds_offset] = el2pel + m;
1956 elssign = spin <= 0 ? 1.0 : signs[el];
1958 for (m=0; m<=el; m++) {
1960 ind = inds[m + inds_offset];
1965 * dl[0*dl_stride + m + dl_offset]
1966 * elssign * dl[0*dl_stride - spinneg + dl_offset]
1967 * Fmm[(0+Fmm_offset)*Fmm_stride + m];
1970 for (mm=1; mm<=el; mm++) {
1971 elmmsign = signs[el] * signs[mm];
1972 elssign = spin <= 0 ? 1.0 : elmmsign;
1974 for (m=0; m<=el; m++) {
1975 ind = inds[m + inds_offset];
1980 * dl[mm*dl_stride + m + dl_offset]
1981 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
1982 * ( Fmm[(mm+Fmm_offset)*Fmm_stride + m]
1984 * Fmm[(-mm+Fmm_offset)*Fmm_stride + m]);
1992 for (el=abs(spin); el<=L-1; el++) {
1993 for (m=1; m<=el; m++) {
1994 ssht_sampling_elm2ind(&ind, el, m);
1995 ssht_sampling_elm2ind(&ind_nm, el, -m);
1996 flm[ind_nm] = signs[m] * conj(flm[ind]);
2013 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint inverse transform computed!");
2041 double *sqrt_tbl, *signs;
2042 int el2pel, inds_offset;
2044 double ssign, elfactor;
2047 int dl_offset, dl_stride;
2050 double elmmsign, elssign;
2053 int Fmm_offset, Fmm_stride;
2055 fftw_plan plan, plan_bwd, plan_fwd;
2060 int f_stride, Ftm_stride, Ftm_offset;
2064 int Gmm_offset, Gmm_stride;
2067 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
2069 signs = (
double*)calloc(L+1,
sizeof(
double));
2073 inds = (
int*)calloc(2*L-1,
sizeof(
int));
2077 for (el=0; el<=2*(L-1)+1; el++)
2078 sqrt_tbl[el] = sqrt((
double)el);
2079 for (m=0; m<=L-1; m=m+2) {
2083 ssign = signs[abs(spin)];
2084 spinneg = spin <= 0 ? spin : -spin;
2086 for (m=-(L-1); m<=L-1; m++)
2087 exps[m + exps_offset] = cexp(-I*
SSHT_PION2*(m+spin));
2090 if (verbosity > 0) {
2092 "Computing adjoint forward transform using MW symmetric sampling with ");
2093 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
2094 L,
",", spin,
", FALSE)");
2097 "Using routine ssht_adjoint_mw_forward_sov_sym_ss...");
2114 for (el=abs(spin); el<=L-1; el++) {
2117 switch (dl_method) {
2120 if (el!=0 && el==abs(spin)) {
2121 for(eltmp=0; eltmp<=abs(spin); eltmp++)
2124 eltmp, sqrt_tbl, signs);
2135 el, sqrt_tbl, signs);
2146 if (el!=0 && el==abs(spin)) {
2147 for(eltmp=0; eltmp<=abs(spin); eltmp++)
2170 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
2171 el2pel = el *el + el;
2172 for (m=-el; m<=el; m++)
2173 inds[m + inds_offset] = el2pel + m;
2174 for (mm=0; mm<=el; mm++) {
2175 elmmsign = signs[el] * signs[mm];
2176 elssign = spin <= 0 ? 1.0 : elmmsign;
2178 for (m=-el; m<=-1; m++) {
2179 ind = inds[m + inds_offset];
2180 Fmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] +=
2183 * exps[m + exps_offset]
2184 * elmmsign * dl[mm*dl_stride - m + dl_offset]
2185 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
2188 for (m=0; m<=el; m++) {
2189 ind = inds[m + inds_offset];
2190 Fmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] +=
2193 * exps[m + exps_offset]
2194 * dl[mm*dl_stride + m + dl_offset]
2195 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
2209 for (m=-(L-1); m<=L-1; m++)
2210 for (mm=-(L-1); mm<=-1; mm++)
2211 Fmm[(m + Fmm_offset)*Fmm_stride + mm + Fmm_offset] =
2212 signs[abs(m)] * ssign
2213 * Fmm[(m + Fmm_offset)*Fmm_stride - mm + Fmm_offset];
2219 for (mm=-2*(L-1); mm<=2*(L-1); mm++)
2220 w[mm+w_offset] = ssht_sampling_weight_mw(mm);
2227 plan_bwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
2228 plan_fwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
2229 for (mm=1; mm<=2*L-2; mm++)
2230 inout[mm + w_offset] = w[mm - 2*(L-1) - 1 + w_offset];
2231 for (mm=-2*(L-1); mm<=0; mm++)
2232 inout[mm + w_offset] = w[mm + 2*(L-1) + w_offset];
2233 fftw_execute_dft(plan_bwd, inout, inout);
2234 for (mm=0; mm<=2*L-2; mm++)
2235 wr[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
2236 for (mm=-2*(L-1); mm<=-1; mm++)
2237 wr[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
2248 for (m=-(L-1); m<=L-1; m++) {
2251 for (mm=-2*(L-1); mm<=-L; mm++)
2252 Fmm_pad[mm+w_offset] = 0.0;
2253 for (mm=L; mm<=2*(L-1); mm++)
2254 Fmm_pad[mm+w_offset] = 0.0;
2255 for (mm=-(L-1); mm<=L-1; mm++)
2256 Fmm_pad[mm + w_offset] =
2257 Fmm[(m+Fmm_offset)*Fmm_stride + mm + Fmm_offset];
2260 for (mm=1; mm<=2*L-2; mm++)
2261 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
2262 for (mm=-2*(L-1); mm<=0; mm++)
2263 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
2264 fftw_execute_dft(plan_bwd, inout, inout);
2265 for (mm=0; mm<=2*L-2; mm++)
2266 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
2267 for (mm=-2*(L-1); mm<=-1; mm++)
2268 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
2271 for (r=-2*(L-1); r<=2*(L-1); r++)
2272 Fmm_pad[r + w_offset] *= wr[-r + w_offset];
2275 for (mm=1; mm<=2*L-2; mm++)
2276 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
2277 for (mm=-2*(L-1); mm<=0; mm++)
2278 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
2279 fftw_execute_dft(plan_fwd, inout, inout);
2280 for (mm=0; mm<=2*L-2; mm++)
2281 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
2282 for (mm=-2*(L-1); mm<=-1; mm++)
2283 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
2286 for (mm=-(L-1); mm<=L-1; mm++)
2287 Gmm[(m+Gmm_offset)*Gmm_stride + mm + Gmm_offset] =
2288 Fmm_pad[mm + w_offset] * 2.0 *
SSHT_PI / (4.0*L-3.0);
2291 fftw_destroy_plan(plan_bwd);
2292 fftw_destroy_plan(plan_fwd);
2298 plan = fftw_plan_dft_1d(2*L, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
2303 for (m=-(L-1); m<=L; m++) {
2305 for(mm=0; mm<=L; mm++)
2306 inout[mm] = Gmm[(m+Gmm_offset)*Gmm_stride + mm + Gmm_offset];
2307 for(mm=-(L-1); mm<=-1; mm++)
2308 inout[mm+2*L-1+1] = Gmm[(m+Gmm_offset)*Gmm_stride + mm + Gmm_offset];
2309 fftw_execute_dft(plan, inout, inout);
2311 for(t=0; t<=2*L-1; t++)
2312 Ftm[t*Ftm_stride + m + Ftm_offset] = inout[t] / (2.0*L);
2317 for(t=1; t<=L-1; t++)
2318 for (m=-(L-1); m<=L; m++)
2319 Ftm[t*Ftm_stride + m + Ftm_offset] =
2320 Ftm[t*Ftm_stride + m + Ftm_offset]
2321 + signs[abs(m)] * ssign * Ftm[(2*L-t)*Ftm_stride + m + Ftm_offset];
2325 for(t=0; t<=L; t++) {
2328 inout[m] = Ftm[t*Ftm_stride + m + Ftm_offset];
2329 for(m=-(L-1); m<=-1; m++)
2330 inout[m+2*L-1+1] = Ftm[t*Ftm_stride + m + Ftm_offset];
2331 fftw_execute_dft(plan, inout, inout);
2333 for(p=0; p<=2*L-1; p++)
2334 f[t*f_stride + p] = inout[p] / (2.0*L);
2337 fftw_destroy_plan(plan);
2357 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint forward transform computed!");
2386 double *sqrt_tbl, *signs;
2387 int el2pel, inds_offset;
2389 double ssign, elfactor;
2392 int dl_offset, dl_stride;
2395 double elmmsign, elssign;
2398 int Fmm_offset, Fmm_stride;
2400 fftw_plan plan, plan_bwd, plan_fwd;
2405 int f_stride, Ftm_stride;
2410 int Gmm_offset, Gmm_stride;
2414 sqrt_tbl = (
double*)calloc(2*(L-1)+2,
sizeof(double));
2416 signs = (
double*)calloc(L+1,
sizeof(
double));
2420 inds = (
int*)calloc(2*L-1,
sizeof(
int));
2424 for (el=0; el<=2*(L-1)+1; el++)
2425 sqrt_tbl[el] = sqrt((
double)el);
2426 for (m=0; m<=L-1; m=m+2) {
2430 ssign = signs[abs(spin)];
2431 spinneg = spin <= 0 ? spin : -spin;
2433 for (m=-(L-1); m<=L-1; m++)
2434 exps[m + exps_offset] = cexp(-I*
SSHT_PION2*(m+spin));
2437 if (verbosity > 0) {
2439 "Computing adjoint forward transform using MW symmetric sampling with ");
2440 printf(
"%s%s%d%s%d%s\n",
SSHT_PROMPT,
"parameters (L,spin,reality) = (",
2441 L,
",", spin,
", FALSE)");
2444 "Using routine ssht_adjoint_mw_forward_sov_sym_ss_real...");
2461 for (el=abs(spin); el<=L-1; el++) {
2464 switch (dl_method) {
2467 if (el!=0 && el==abs(spin)) {
2468 for(eltmp=0; eltmp<=abs(spin); eltmp++)
2471 eltmp, sqrt_tbl, signs);
2482 el, sqrt_tbl, signs);
2493 if (el!=0 && el==abs(spin)) {
2494 for(eltmp=0; eltmp<=abs(spin); eltmp++)
2517 elfactor = sqrt((
double)(2.0*el+1.0)/(4.0*
SSHT_PI));
2518 el2pel = el *el + el;
2519 for (m=0; m<=el; m++)
2520 inds[m + inds_offset] = el2pel + m;
2521 for (mm=0; mm<=el; mm++) {
2522 elmmsign = signs[el] * signs[mm];
2523 elssign = spin <= 0 ? 1.0 : elmmsign;
2525 for (m=0; m<=el; m++) {
2526 ind = inds[m + inds_offset];
2527 Fmm[m*Fmm_stride + mm + Fmm_offset] +=
2530 * exps[m + exps_offset]
2531 * dl[mm*dl_stride + m + dl_offset]
2532 * elssign * dl[mm*dl_stride - spinneg + dl_offset]
2546 for (m=0; m<=L-1; m++)
2547 for (mm=-(L-1); mm<=-1; mm++)
2548 Fmm[m*Fmm_stride + mm + Fmm_offset] =
2549 signs[abs(m)] * ssign
2550 * Fmm[m*Fmm_stride - mm + Fmm_offset];
2556 for (mm=-2*(L-1); mm<=2*(L-1); mm++)
2557 w[mm+w_offset] = ssht_sampling_weight_mw(mm);
2564 plan_bwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
2565 plan_fwd = fftw_plan_dft_1d(4*L-3, inout, inout, FFTW_FORWARD, FFTW_MEASURE);
2566 for (mm=1; mm<=2*L-2; mm++)
2567 inout[mm + w_offset] = w[mm - 2*(L-1) - 1 + w_offset];
2568 for (mm=-2*(L-1); mm<=0; mm++)
2569 inout[mm + w_offset] = w[mm + 2*(L-1) + w_offset];
2570 fftw_execute_dft(plan_bwd, inout, inout);
2571 for (mm=0; mm<=2*L-2; mm++)
2572 wr[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
2573 for (mm=-2*(L-1); mm<=-1; mm++)
2574 wr[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
2585 for (m=0; m<=L-1; m++) {
2588 for (mm=-2*(L-1); mm<=-L; mm++)
2589 Fmm_pad[mm+w_offset] = 0.0;
2590 for (mm=L; mm<=2*(L-1); mm++)
2591 Fmm_pad[mm+w_offset] = 0.0;
2592 for (mm=-(L-1); mm<=L-1; mm++)
2593 Fmm_pad[mm + w_offset] =
2594 Fmm[m*Fmm_stride + mm + Fmm_offset];
2597 for (mm=1; mm<=2*L-2; mm++)
2598 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
2599 for (mm=-2*(L-1); mm<=0; mm++)
2600 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
2601 fftw_execute_dft(plan_bwd, inout, inout);
2602 for (mm=0; mm<=2*L-2; mm++)
2603 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
2604 for (mm=-2*(L-1); mm<=-1; mm++)
2605 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
2608 for (r=-2*(L-1); r<=2*(L-1); r++)
2609 Fmm_pad[r + w_offset] *= wr[-r + w_offset];
2612 for (mm=1; mm<=2*L-2; mm++)
2613 inout[mm + w_offset] = Fmm_pad[mm - 2*(L-1) - 1 + w_offset];
2614 for (mm=-2*(L-1); mm<=0; mm++)
2615 inout[mm + w_offset] = Fmm_pad[mm + 2*(L-1) + w_offset];
2616 fftw_execute_dft(plan_fwd, inout, inout);
2617 for (mm=0; mm<=2*L-2; mm++)
2618 Fmm_pad[mm + w_offset] = inout[mm - 2*(L-1) + w_offset];
2619 for (mm=-2*(L-1); mm<=-1; mm++)
2620 Fmm_pad[mm + w_offset] = inout[mm + 2*(L-1) + 1 + w_offset];
2623 for (mm=-(L-1); mm<=L-1; mm++)
2624 Gmm[m*Gmm_stride + mm + Gmm_offset] =
2625 Fmm_pad[mm + w_offset] * 2.0 *
SSHT_PI / (4.0*L-3.0);
2628 fftw_destroy_plan(plan_bwd);
2629 fftw_destroy_plan(plan_fwd);
2635 plan = fftw_plan_dft_1d(2*L, inout, inout, FFTW_BACKWARD, FFTW_MEASURE);
2639 for (m=0; m<=L; m++) {
2641 for(mm=0; mm<=L; mm++)
2642 inout[mm] = Gmm[m*Gmm_stride + mm + Gmm_offset];
2643 for(mm=-(L-1); mm<=-1; mm++)
2644 inout[mm+2*L-1+1] = Gmm[m*Gmm_stride + mm + Gmm_offset];
2645 fftw_execute_dft(plan, inout, inout);
2647 for(t=0; t<=2*L-1; t++)
2648 Ftm[t*Ftm_stride + m] = inout[t] / (2.0*L);
2651 fftw_destroy_plan(plan);
2655 for(t=1; t<=L-1; t++)
2656 for (m=0; m<=L; m++)
2657 Ftm[t*Ftm_stride + m] =
2658 Ftm[t*Ftm_stride + m]
2659 + signs[abs(m)] * ssign * Ftm[(2*L-t)*Ftm_stride + m];
2662 out_real = (
double*)calloc(2*L,
sizeof(
double));
2666 plan = fftw_plan_dft_c2r_1d(2*L, in, out_real, FFTW_MEASURE);
2668 for(t=0; t<=L; t++) {
2670 memcpy(in, &Ftm[t*Ftm_stride], Ftm_stride*
sizeof(
SSHT_COMPLEX(
double)));
2671 fftw_execute_dft_c2r(plan, in, out_real);
2673 for(p=0; p<=2*L-1; p++)
2674 f[t*f_stride + p] = out_real[p] / (2.0*L);
2677 fftw_destroy_plan(plan);
2698 printf(
"%s%s",
SSHT_PROMPT,
"Adjoint forward transform computed!");
2740 int t, f_stride = 2*L;
2748 dl_method, verbosity);
2751 for (t=1; t<=L-1; t++)
2752 memcpy(&f[(t-1)*f_stride], &f_full[t*f_stride],
2756 *f_sp = f_full[L*f_stride + 0];
2792 int t, f_stride = 2*L;
2795 f_full = (
double*)calloc((L+1)*(2*L),
sizeof(
double));
2800 dl_method, verbosity);
2803 for (t=1; t<=L-1; t++)
2804 memcpy(&f[(t-1)*f_stride], &f_full[t*f_stride],
2805 (2*L)*
sizeof(
double));
2807 *f_sp = f_full[L*f_stride + 0];
2846 int t, p, f_stride = 2*L;
2852 for (t=1; t<=L-1; t++)
2853 memcpy(&f_full[t*f_stride], &f[(t-1)*f_stride],
2857 for (p=0; p<=2*L-1; p++) {
2859 f_full[0*f_stride + p] = f_np * cexp(-I*spin*(phi-phi_np));
2860 f_full[L*f_stride + p] = f_sp * cexp(I*spin*(phi-phi_sp));
2865 dl_method, verbosity);
2900 int t, p, f_stride = 2*L;
2903 f_full = (
double*)calloc((L+1)*(2*L),
sizeof(
double));
2905 for (t=1; t<=L-1; t++)
2906 memcpy(&f_full[t*f_stride], &f[(t-1)*f_stride],
2907 (2*L)*
sizeof(
double));
2910 for (p=0; p<=2*L-1; p++) {
2911 f_full[0*f_stride + p] = f_np;
2912 f_full[L*f_stride + p] = f_sp;
2917 dl_method, verbosity);