00001
00002
00003
00004
00005
00006
00007
00008
00016
00017 module ssht_core_mod
00018
00019 use ssht_types_mod
00020 use ssht_error_mod
00021 use ssht_dl_mod
00022 use ssht_sampling_mod
00023
00024 implicit none
00025
00026 private
00027
00028
00029
00030
00031
00032
00033 public :: &
00034 ssht_core_dh_inverse, &
00035 ssht_core_dh_forward, &
00036 ssht_core_gl_inverse, &
00037 ssht_core_gl_forward, &
00038 ssht_core_mweo_inverse, &
00039 ssht_core_mweo_forward, &
00040 ssht_core_mw_inverse, &
00041 ssht_core_mw_forward, &
00042 ssht_core_dh_inverse_real, &
00043 ssht_core_dh_forward_real, &
00044 ssht_core_gl_inverse_real, &
00045 ssht_core_gl_forward_real, &
00046 ssht_core_mweo_inverse_real, &
00047 ssht_core_mweo_forward_real, &
00048 ssht_core_mw_inverse_real, &
00049 ssht_core_mw_forward_real
00050
00051
00052
00053
00054
00055
00056
00057
00059 interface ssht_core_dh_inverse
00060 module procedure ssht_core_dh_inverse_sov_sym
00061 end interface
00062
00064 interface ssht_core_dh_forward
00065 module procedure ssht_core_dh_forward_sov_sym
00066 end interface
00067
00069 interface ssht_core_dh_inverse_real
00070 module procedure ssht_core_dh_inverse_sov_sym_real
00071 end interface
00072
00074 interface ssht_core_dh_forward_real
00075 module procedure ssht_core_dh_forward_sov_sym_real
00076 end interface
00077
00078
00079
00080
00081
00082
00083
00084
00085
00087 interface ssht_core_gl_inverse
00088 module procedure ssht_core_gl_inverse_sov_sym
00089 end interface
00090
00092 interface ssht_core_gl_forward
00093 module procedure ssht_core_gl_forward_sov_sym
00094 end interface
00095
00097 interface ssht_core_gl_inverse_real
00098 module procedure ssht_core_gl_inverse_sov_sym_real
00099 end interface
00100
00102 interface ssht_core_gl_forward_real
00103 module procedure ssht_core_gl_forward_sov_sym_real
00104 end interface
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00116 interface ssht_core_mweo_inverse
00117 module procedure ssht_core_mweo_inverse_sp
00118 end interface
00119
00121 interface ssht_core_mweo_forward
00122 module procedure ssht_core_mweo_forward_sp
00123 end interface
00124
00126 interface ssht_core_mweo_inverse_real
00127 module procedure ssht_core_mweo_inverse_real_sp
00128 end interface
00129
00131 interface ssht_core_mweo_forward_real
00132 module procedure ssht_core_mweo_forward_real_sp
00133 end interface
00134
00135
00136
00138 interface ssht_core_mweo_inverse_rsp
00139 module procedure ssht_core_mweo_inverse_sov_sym
00140 end interface
00141
00143 interface ssht_core_mweo_forward_rsp
00144 module procedure ssht_core_mweo_forward_sov_conv_sym
00145 end interface
00146
00148 interface ssht_core_mweo_inverse_real_rsp
00149 module procedure ssht_core_mweo_inverse_sov_sym_real
00150 end interface
00151
00153 interface ssht_core_mweo_forward_real_rsp
00154 module procedure ssht_core_mweo_forward_sov_conv_sym_real
00155 end interface
00156
00157
00158
00159
00160
00161
00162
00163
00165 interface ssht_core_mw_inverse
00166 module procedure ssht_core_mw_inverse_sp
00167 end interface
00168
00170 interface ssht_core_mw_forward
00171 module procedure ssht_core_mw_forward_sp
00172 end interface
00173
00175 interface ssht_core_mw_inverse_real
00176 module procedure ssht_core_mw_inverse_real_sp
00177 end interface
00178
00180 interface ssht_core_mw_forward_real
00181 module procedure ssht_core_mw_forward_real_sp
00182 end interface
00183
00184
00185
00187 interface ssht_core_mw_inverse_rsp
00188 module procedure ssht_core_mw_inverse_sov_sym
00189 end interface
00190
00192 interface ssht_core_mw_forward_rsp
00193 module procedure ssht_core_mw_forward_sov_conv_sym
00194 end interface
00195
00197 interface ssht_core_mw_inverse_real_rsp
00198 module procedure ssht_core_mw_inverse_sov_sym_real
00199 end interface
00200
00202 interface ssht_core_mw_forward_real_rsp
00203 module procedure ssht_core_mw_forward_sov_conv_sym_real
00204 end interface
00205
00206
00207
00208
00209
00210
00211 integer, parameter :: FFTW_ESTIMATE=64, FFTW_MEASURE=0
00212 integer, parameter :: FFTW_FORWARD=-1, FFTW_BACKWARD=1
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 contains
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00258
00259 subroutine ssht_core_mweo_inverse_sp(f, f_sp, phi_sp, flm, L, spin, verbosity)
00260
00261 integer, intent(in) :: L
00262 integer, intent(in) :: spin
00263 integer, intent(in), optional :: verbosity
00264 complex(dpc), intent(in) :: flm(0:L**2-1)
00265 real(dp), intent(out) :: phi_sp
00266 complex(dpc), intent(out) :: f_sp
00267 complex(dpc), intent(out) :: f(0:L-2, 0:2*L-2)
00268
00269 complex(dpc) :: f_ext(0:L-1, 0:2*L-2)
00270
00271 call ssht_core_mweo_inverse_rsp(f_ext, flm, L, spin, verbosity)
00272
00273 f(0:L-2, 0:2*L-2) = f_ext(0:L-2, 0:2*L-2)
00274 f_sp = f_ext(L-1, 0)
00275 phi_sp = ssht_sampling_mweo_p2phi(0, L)
00276
00277 end subroutine ssht_core_mweo_inverse_sp
00278
00279
00280
00281
00282
00301
00302 subroutine ssht_core_mweo_forward_sp(flm, f, f_sp, phi_sp, L, spin, verbosity)
00303
00304 integer, intent(in) :: L
00305 integer, intent(in) :: spin
00306 integer, intent(in), optional :: verbosity
00307 complex(dpc), intent(in) :: f(0:L-2 ,0:2*L-2)
00308 real(dp), intent(in) :: phi_sp
00309 complex(dpc), intent(in) :: f_sp
00310 complex(dpc), intent(out) :: flm(0:L**2-1)
00311
00312 complex(dpc) :: f_ext(0:L-1, 0:2*L-2)
00313 integer :: p
00314 real(dp) :: phi
00315
00316 f_ext(0:L-2 ,0:2*L-2) = f(0:L-2 ,0:2*L-2)
00317 do p = 0, 2*L-2
00318 phi = ssht_sampling_mweo_p2phi(p, L)
00319 f_ext(L-1, p) = f_sp * exp(I*spin*(phi-phi_sp))
00320 end do
00321
00322 call ssht_core_mweo_forward_rsp(flm, f_ext, L, spin, verbosity)
00323
00324 end subroutine ssht_core_mweo_forward_sp
00325
00326
00327
00328
00329
00346
00347 subroutine ssht_core_mweo_inverse_real_sp(f, f_sp, flm, L, verbosity)
00348
00349 integer, intent(in) :: L
00350 integer, intent(in), optional :: verbosity
00351 complex(dpc), intent(in) :: flm(0:L**2-1)
00352 real(dp), intent(out) :: f_sp
00353 real(dp), intent(out) :: f(0:L-2, 0:2*L-2)
00354
00355 real(dp) :: f_ext(0:L-1, 0:2*L-2)
00356
00357 call ssht_core_mweo_inverse_real_rsp(f_ext, flm, L, verbosity)
00358
00359 f(0:L-2, 0:2*L-2) = f_ext(0:L-2, 0:2*L-2)
00360 f_sp = f_ext(L-1, 0)
00361
00362 end subroutine ssht_core_mweo_inverse_real_sp
00363
00364
00365
00366
00367
00384
00385 subroutine ssht_core_mweo_forward_real_sp(flm, f, f_sp, L, verbosity)
00386
00387 integer, intent(in) :: L
00388 integer, intent(in), optional :: verbosity
00389 real(dp), intent(in) :: f(0:L-2, 0:2*L-2)
00390 real(dp), intent(in) :: f_sp
00391 complex(dpc), intent(out) :: flm(0:L**2-1)
00392
00393 real(dp) :: f_ext(0:L-1, 0:2*L-2)
00394
00395 f_ext(0:L-2, 0:2*L-2) = f(0:L-2, 0:2*L-2)
00396 f_ext(L-1, 0:2*L-2) = f_sp
00397
00398 call ssht_core_mweo_forward_real_rsp(flm, f_ext, L, verbosity)
00399
00400 end subroutine ssht_core_mweo_forward_real_sp
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00429
00430 subroutine ssht_core_mw_inverse_sp(f, f_sp, phi_sp, flm, L, spin, verbosity)
00431
00432 integer, intent(in) :: L
00433 integer, intent(in) :: spin
00434 integer, intent(in), optional :: verbosity
00435 complex(dpc), intent(in) :: flm(0:L**2-1)
00436 real(dp), intent(out) :: phi_sp
00437 complex(dpc), intent(out) :: f_sp
00438 complex(dpc), intent(out) :: f(0:L-2, 0:2*L-2)
00439
00440 complex(dpc) :: f_ext(0:L-1, 0:2*L-2)
00441
00442 call ssht_core_mw_inverse_rsp(f_ext, flm, L, spin, verbosity)
00443
00444 f(0:L-2, 0:2*L-2) = f_ext(0:L-2, 0:2*L-2)
00445 f_sp = f_ext(L-1, 0)
00446 phi_sp = ssht_sampling_mw_p2phi(0, L)
00447
00448 end subroutine ssht_core_mw_inverse_sp
00449
00450
00451
00452
00453
00472
00473 subroutine ssht_core_mw_forward_sp(flm, f, f_sp, phi_sp, L, spin, verbosity)
00474
00475 integer, intent(in) :: L
00476 integer, intent(in) :: spin
00477 integer, intent(in), optional :: verbosity
00478 complex(dpc), intent(in) :: f(0:L-2 ,0:2*L-2)
00479 real(dp), intent(in) :: phi_sp
00480 complex(dpc), intent(in) :: f_sp
00481 complex(dpc), intent(out) :: flm(0:L**2-1)
00482
00483 complex(dpc) :: f_ext(0:L-1, 0:2*L-2)
00484 integer :: p
00485 real(dp) :: phi
00486
00487 f_ext(0:L-2 ,0:2*L-2) = f(0:L-2 ,0:2*L-2)
00488 do p = 0, 2*L-2
00489 phi = ssht_sampling_mw_p2phi(p, L)
00490 f_ext(L-1, p) = f_sp * exp(I*spin*(phi-phi_sp))
00491 end do
00492
00493 call ssht_core_mw_forward_rsp(flm, f_ext, L, spin, verbosity)
00494
00495 end subroutine ssht_core_mw_forward_sp
00496
00497
00498
00499
00500
00517
00518 subroutine ssht_core_mw_inverse_real_sp(f, f_sp, flm, L, verbosity)
00519
00520 integer, intent(in) :: L
00521 integer, intent(in), optional :: verbosity
00522 complex(dpc), intent(in) :: flm(0:L**2-1)
00523 real(dp), intent(out) :: f_sp
00524 real(dp), intent(out) :: f(0:L-2, 0:2*L-2)
00525
00526 real(dp) :: f_ext(0:L-1, 0:2*L-2)
00527
00528 call ssht_core_mw_inverse_real_rsp(f_ext, flm, L, verbosity)
00529
00530 f(0:L-2, 0:2*L-2) = f_ext(0:L-2, 0:2*L-2)
00531 f_sp = f_ext(L-1, 0)
00532
00533 end subroutine ssht_core_mw_inverse_real_sp
00534
00535
00536
00537
00538
00555
00556 subroutine ssht_core_mw_forward_real_sp(flm, f, f_sp, L, verbosity)
00557
00558 integer, intent(in) :: L
00559 integer, intent(in), optional :: verbosity
00560 real(dp), intent(in) :: f(0:L-2, 0:2*L-2)
00561 real(dp), intent(in) :: f_sp
00562 complex(dpc), intent(out) :: flm(0:L**2-1)
00563
00564 real(dp) :: f_ext(0:L-1, 0:2*L-2)
00565
00566 f_ext(0:L-2, 0:2*L-2) = f(0:L-2, 0:2*L-2)
00567 f_ext(L-1, 0:2*L-2) = f_sp
00568
00569 call ssht_core_mw_forward_real_rsp(flm, f_ext, L, verbosity)
00570
00571 end subroutine ssht_core_mw_forward_real_sp
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00605
00606 subroutine ssht_core_dh_inverse_direct(f, flm, L, spin, verbosity)
00607
00608 integer, intent(in) :: L
00609 integer, intent(in) :: spin
00610 integer, intent(in), optional :: verbosity
00611 complex(dpc), intent(in) :: flm(0:L**2-1)
00612 complex(dpc), intent(out) :: f(0:2*L-1, 0:2*L-2)
00613
00614 integer :: el, m, t, p, ind
00615 real(dp) :: theta, phi
00616 real(dp) :: elfactor
00617 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
00618 character(len=STRING_LEN) :: format_spec
00619
00620
00621 if (present(verbosity)) then
00622 if (verbosity > 0) then
00623 write(*,'(a,a)') SSHT_PROMPT, &
00624 'Computing inverse transform using Driscoll and Healy sampling with'
00625 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
00626 write(*,trim(format_spec)) SSHT_PROMPT, &
00627 'parameters (L,spin,reality) = (', &
00628 L, ',', spin, ',FALSE)...'
00629 end if
00630 if (verbosity > 1) then
00631 write(*,'(a,a)') SSHT_PROMPT, &
00632 'Using routine ssht_core_dh_inverse_direct...'
00633 end if
00634 end if
00635
00636 f(0:2*L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
00637 do el = abs(spin), L-1
00638 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
00639 do t = 0, 2*L-1
00640 theta = ssht_sampling_dh_t2theta(t, L)
00641 call ssht_dl_beta_operator(dl(-el:el,-el:el), theta, el)
00642 do m = -el, el
00643 call ssht_sampling_elm2ind(ind, el, m)
00644 do p = 0, 2*L-2
00645 phi = ssht_sampling_dh_p2phi(p, L)
00646 f(t,p) = f(t,p) + &
00647 (-1)**spin * elfactor &
00648 * exp(I*m*phi) &
00649 * dl(m,-spin) * flm(ind)
00650 end do
00651 end do
00652
00653 end do
00654 end do
00655
00656
00657 if (present(verbosity)) then
00658 if (verbosity > 0) then
00659 write(*,'(a,a)') SSHT_PROMPT, &
00660 'Inverse transform computed!'
00661 end if
00662 end if
00663
00664 end subroutine ssht_core_dh_inverse_direct
00665
00666
00667
00668
00669
00688
00689 subroutine ssht_core_dh_inverse_direct_factored(f, flm, L, spin, verbosity)
00690
00691 integer, intent(in) :: L
00692 integer, intent(in) :: spin
00693 integer, intent(in), optional :: verbosity
00694 complex(dpc), intent(in) :: flm(0:L**2-1)
00695 complex(dpc), intent(out) :: f(0:2*L-1, 0:2*L-2)
00696
00697 integer :: el, m, mm, t, p, ind
00698 real(dp) :: theta, phi
00699 real(dp) :: elfactor
00700 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
00701 character(len=STRING_LEN) :: format_spec
00702
00703
00704 if (present(verbosity)) then
00705 if (verbosity > 0) then
00706 write(*,'(a,a)') SSHT_PROMPT, &
00707 'Computing inverse transform using Driscoll and Healy sampling with'
00708 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
00709 write(*,trim(format_spec)) SSHT_PROMPT, &
00710 'parameters (L,spin,reality) = (', &
00711 L, ',', spin, ',FALSE)...'
00712 end if
00713 if (verbosity > 1) then
00714 write(*,'(a,a)') SSHT_PROMPT, &
00715 'Using routine ssht_core_dh_inverse_direct_factored...'
00716 end if
00717 end if
00718
00719 f(0:2*L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
00720 do el = abs(spin), L-1
00721 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
00722 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
00723 do m = -el, el
00724 call ssht_sampling_elm2ind(ind, el, m)
00725 do mm = -el, el
00726 do t = 0, 2*L-1
00727 theta = ssht_sampling_dh_t2theta(t, L)
00728 do p = 0, 2*L-2
00729 phi = ssht_sampling_dh_p2phi(p, L)
00730 f(t,p) = f(t,p) + &
00731 (-1)**spin * elfactor &
00732 * exp(-I*PION2*(m+spin)) &
00733 * exp(I*m*phi + I*mm*theta) &
00734 * dl(mm,m) * dl(mm,-spin) &
00735 * flm(ind)
00736 end do
00737 end do
00738 end do
00739 end do
00740 end do
00741
00742
00743 if (present(verbosity)) then
00744 if (verbosity > 0) then
00745 write(*,'(a,a)') SSHT_PROMPT, &
00746 'Inverse transform computed!'
00747 end if
00748 end if
00749
00750 end subroutine ssht_core_dh_inverse_direct_factored
00751
00752
00753
00754
00755
00774
00775 subroutine ssht_core_dh_inverse_sov_direct(f, flm, L, spin, verbosity)
00776
00777 integer, intent(in) :: L
00778 integer, intent(in) :: spin
00779 integer, intent(in), optional :: verbosity
00780 complex(dpc), intent(in) :: flm(0:L**2-1)
00781 complex(dpc), intent(out) :: f(0:2*L-1, 0:2*L-2)
00782
00783 integer :: el, m, mm, t, p, ind
00784 real(dp) :: theta, phi
00785 real(dp) :: elfactor
00786 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
00787 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
00788 complex(dpc) :: fmt(-(L-1):L-1, 0:2*L-1)
00789
00790 character(len=STRING_LEN) :: format_spec
00791
00792
00793 if (present(verbosity)) then
00794 if (verbosity > 0) then
00795 write(*,'(a,a)') SSHT_PROMPT, &
00796 'Computing inverse transform using Driscoll and Healy sampling with'
00797 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
00798 write(*,trim(format_spec)) SSHT_PROMPT, &
00799 'parameters (L,spin,reality) = (', &
00800 L, ',', spin, ',FALSE)...'
00801 end if
00802 if (verbosity > 1) then
00803 write(*,'(a,a)') SSHT_PROMPT, &
00804 'Using routine ssht_core_dh_inverse_sov_direct...'
00805 end if
00806 end if
00807
00808
00809 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
00810 do el = abs(spin), L-1
00811 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
00812 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
00813 do m = -el, el
00814 call ssht_sampling_elm2ind(ind, el, m)
00815 do mm = -el, el
00816 Fmm(m,mm) = Fmm(m,mm) + &
00817 (-1)**spin * elfactor &
00818 * exp(-I*PION2*(m+spin)) &
00819 * dl(mm,m) * dl(mm,-spin) &
00820 * flm(ind)
00821 end do
00822 end do
00823 end do
00824
00825
00826 fmt(-(L-1):L-1, 0:2*L-1) = cmplx(0d0, 0d0)
00827 do t = 0, 2*L-1
00828 theta = ssht_sampling_dh_t2theta(t, L)
00829 do m = -(L-1), L-1
00830 do mm = -(L-1), L-1
00831 fmt(m,t) = fmt(m,t) + &
00832 Fmm(m,mm) * exp(I*mm*theta)
00833 end do
00834 end do
00835 end do
00836
00837
00838 f(0:2*L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
00839 do t = 0, 2*L-1
00840 do p = 0, 2*L-2
00841 phi = ssht_sampling_dh_p2phi(p, L)
00842 do m = -(L-1), L-1
00843 f(t,p) = f(t,p) + &
00844 fmt(m,t) * exp(I*m*phi)
00845 end do
00846 end do
00847 end do
00848
00849
00850 if (present(verbosity)) then
00851 if (verbosity > 0) then
00852 write(*,'(a,a)') SSHT_PROMPT, &
00853 'Inverse transform computed!'
00854 end if
00855 end if
00856
00857 end subroutine ssht_core_dh_inverse_sov_direct
00858
00859
00860
00861
00862
00878
00879 subroutine ssht_core_dh_inverse_sov(f, flm, L, spin, verbosity)
00880
00881 integer, intent(in) :: L
00882 integer, intent(in) :: spin
00883 integer, intent(in), optional :: verbosity
00884 complex(dpc), intent(in) :: flm(0:L**2-1)
00885 complex(dpc), intent(out) :: f(0:2*L-1, 0:2*L-2)
00886
00887 integer :: el, m, mm, t, p, ind
00888 real(dp) :: theta, phi
00889 real(dp) :: elfactor
00890 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
00891 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
00892 complex(dpc) :: fmt(-(L-1):L-1, 0:2*L-1)
00893 integer*8 :: fftw_plan
00894 character(len=STRING_LEN) :: format_spec
00895
00896
00897 if (present(verbosity)) then
00898 if (verbosity > 0) then
00899 write(*,'(a,a)') SSHT_PROMPT, &
00900 'Computing inverse transform using Driscoll and Healy sampling with'
00901 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
00902 write(*,trim(format_spec)) SSHT_PROMPT, &
00903 'parameters (L,spin,reality) = (', &
00904 L, ',', spin, ',FALSE)...'
00905 end if
00906 if (verbosity > 1) then
00907 write(*,'(a,a)') SSHT_PROMPT, &
00908 'Using routine ssht_core_dh_inverse_sov...'
00909 end if
00910 end if
00911
00912
00913
00914 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
00915 do el = abs(spin), L-1
00916 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
00917 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
00918 do m = -el, el
00919 call ssht_sampling_elm2ind(ind, el, m)
00920 do mm = -el, el
00921 Fmm(m,mm) = Fmm(m,mm) + &
00922 (-1)**spin * elfactor &
00923 * exp(-I*PION2*(m+spin)) &
00924 * dl(mm,m) * dl(mm,-spin) &
00925 * flm(ind)
00926 end do
00927 end do
00928 end do
00929
00930
00931 fmt(-(L-1):L-1, 0:2*L-1) = cmplx(0d0, 0d0)
00932 do t = 0, 2*L-1
00933 theta = ssht_sampling_dh_t2theta(t, L)
00934 do m = -(L-1), L-1
00935 do mm = -(L-1), L-1
00936 fmt(m,t) = fmt(m,t) + &
00937 Fmm(m,mm) * exp(I*mm*theta)
00938 end do
00939 end do
00940 end do
00941
00942
00943 f(0:2*L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
00944 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, f(0,0:2*L-2), &
00945 f(0,0:2*L-2), FFTW_BACKWARD, FFTW_MEASURE)
00946 do t = 0, 2*L-1
00947
00948
00949 f(t,0:L-1) = fmt(0:L-1,t)
00950 f(t,L:2*L-2) = fmt(-(L-1):-1,t)
00951
00952 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), f(t,0:2*L-2))
00953
00954 end do
00955 call dfftw_destroy_plan(fftw_plan)
00956
00957
00958 if (present(verbosity)) then
00959 if (verbosity > 0) then
00960 write(*,'(a,a)') SSHT_PROMPT, &
00961 'Inverse transform computed!'
00962 end if
00963 end if
00964
00965 end subroutine ssht_core_dh_inverse_sov
00966
00967
00968
00969
00970
00987
00988 subroutine ssht_core_dh_inverse_sov_sym(f, flm, L, spin, verbosity)
00989
00990 integer, intent(in) :: L
00991 integer, intent(in) :: spin
00992 integer, intent(in), optional :: verbosity
00993 complex(dpc), intent(in) :: flm(0:L**2-1)
00994 complex(dpc), intent(out) :: f(0:2*L-1, 0:2*L-2)
00995
00996 integer :: el, m, mm, t, p, ind
00997 real(dp) :: theta, phi
00998 real(dp) :: elfactor
00999 real(dp) :: dl(0:L-1, -(L-1):L-1)
01000 complex(dpc) :: Fmm(-(L-1):L-1, 0:L-1)
01001 complex(dpc) :: fmt(-(L-1):L-1, 0:2*L-1)
01002 integer*8 :: fftw_plan
01003 character(len=STRING_LEN) :: format_spec
01004
01005 integer :: eltmp
01006 real(dp) :: signs(0:L), ssign
01007 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
01008
01009
01010 do el = 0, 2*(L-1) + 1
01011 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
01012 end do
01013 do m = 0, L-1, 2
01014 signs(m) = 1.0_dp
01015 signs(m+1) = -1.0_dp
01016 enddo
01017 ssign = signs(abs(spin))
01018
01019
01020 if (present(verbosity)) then
01021 if (verbosity > 0) then
01022 write(*,'(a,a)') SSHT_PROMPT, &
01023 'Computing inverse transform using Driscoll and Healy sampling with'
01024 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
01025 write(*,trim(format_spec)) SSHT_PROMPT, &
01026 'parameters (L,spin,reality) = (', &
01027 L, ',', spin, ',FALSE)...'
01028 end if
01029 if (verbosity > 1) then
01030 write(*,'(a,a)') SSHT_PROMPT, &
01031 'Using routine ssht_core_dh_inverse_sov_sym...'
01032 end if
01033 end if
01034
01035
01036 Fmm(-(L-1):L-1, 0:L-1) = cmplx(0d0, 0d0)
01037 do el = abs(spin), L-1
01038 if (el /= 0 .and. el == abs(spin)) then
01039
01040 do eltmp = 0, abs(spin)
01041 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
01042 sqrt_tbl(0:2*eltmp+1))
01043 end do
01044 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
01045 el, signs)
01046 else
01047 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
01048 sqrt_tbl(0:2*el+1))
01049 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
01050 el, signs)
01051 end if
01052
01053 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01054 do m = -el, el
01055 call ssht_sampling_elm2ind(ind, el, m)
01056 do mm = 0, el
01057 Fmm(m,mm) = Fmm(m,mm) + &
01058 ssign * elfactor &
01059 * exp(-I*PION2*(m+spin)) &
01060 * dl(mm,m) * dl(mm,-spin) &
01061 * flm(ind)
01062 end do
01063 end do
01064 end do
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086 fmt(-(L-1):L-1, 0:2*L-1) = cmplx(0d0, 0d0)
01087 do t = 0, 2*L-1
01088 theta = ssht_sampling_dh_t2theta(t, L)
01089 do m = -(L-1), L-1
01090 fmt(m,t) = fmt(m,t) + Fmm(m,0)
01091 end do
01092 do mm = 1, L-1
01093 do m = -(L-1), L-1
01094 fmt(m,t) = fmt(m,t) + &
01095
01096
01097 Fmm(m,mm) * &
01098 (exp(I*mm*theta) + signs(abs(m)) * ssign * exp(-I*mm*theta))
01099 end do
01100 end do
01101 end do
01102
01103
01104
01105 f(0:2*L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
01106 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, f(0,0:2*L-2), &
01107 f(0,0:2*L-2), FFTW_BACKWARD, FFTW_MEASURE)
01108 do t = 0, 2*L-1
01109
01110
01111 f(t,0:L-1) = fmt(0:L-1,t)
01112 f(t,L:2*L-2) = fmt(-(L-1):-1,t)
01113
01114 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), f(t,0:2*L-2))
01115
01116 end do
01117 call dfftw_destroy_plan(fftw_plan)
01118
01119
01120 if (present(verbosity)) then
01121 if (verbosity > 0) then
01122 write(*,'(a,a)') SSHT_PROMPT, &
01123 'Inverse transform computed!'
01124 end if
01125 end if
01126
01127 end subroutine ssht_core_dh_inverse_sov_sym
01128
01129
01130
01131
01132
01150
01151 subroutine ssht_core_dh_inverse_sov_sym_real(f, flm, L, verbosity)
01152
01153 integer, intent(in) :: L
01154 integer, intent(in), optional :: verbosity
01155 complex(dpc), intent(in) :: flm(0:L**2-1)
01156 real(dp), intent(out) :: f(0:2*L-1, 0:2*L-2)
01157
01158 integer :: el, m, mm, t, p, ind
01159 real(dp) :: theta, phi
01160 real(dp) :: elfactor
01161 real(dp) :: dl(0:L-1, 0:L-1)
01162 complex(dpc) :: Fmm(0:L-1, 0:L-1)
01163 complex(dpc) :: fmt(0:L-1, 0:2*L-1)
01164 integer*8 :: fftw_plan
01165
01166 character(len=STRING_LEN) :: format_spec
01167
01168 integer :: spin
01169 integer :: eltmp
01170 real(dp) :: signs(0:L), ssign
01171 real(dp) :: dl_mm_spin
01172 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
01173
01174
01175 do el = 0, 2*(L-1) + 1
01176 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
01177 end do
01178 do m = 0, L-1, 2
01179 signs(m) = 1.0_dp
01180 signs(m+1) = -1.0_dp
01181 enddo
01182
01183
01184 spin = 0
01185 ssign = signs(abs(spin))
01186
01187
01188 if (present(verbosity)) then
01189 if (verbosity > 0) then
01190 write(*,'(a,a)') SSHT_PROMPT, &
01191 'Computing inverse transform using Driscoll and Healy sampling with'
01192 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
01193 write(*,trim(format_spec)) SSHT_PROMPT, &
01194 'parameters (L,spin,reality) = (', &
01195 L, ',', spin, ',TRUE)...'
01196 end if
01197 if (verbosity > 1) then
01198 write(*,'(a,a)') SSHT_PROMPT, &
01199 'Using routine ssht_core_dh_inverse_sov_sym_real...'
01200 end if
01201 end if
01202
01203
01204 Fmm(0:L-1, 0:L-1) = cmplx(0d0, 0d0)
01205 do el = abs(spin), L-1
01206 if (el /= 0 .and. el == abs(spin)) then
01207
01208 do eltmp = 0, abs(spin)
01209 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
01210 sqrt_tbl(0:2*eltmp+1))
01211 end do
01212 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
01213 el, signs(0:el))
01214 else
01215 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
01216 sqrt_tbl(0:2*el+1))
01217 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
01218 el, signs(0:el))
01219 end if
01220
01221
01222 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01223 do m = 0, el
01224 call ssht_sampling_elm2ind(ind, el, m)
01225 do mm = 0, el
01226 if (spin <= 0) then
01227 dl_mm_spin = dl(mm,-spin)
01228 else
01229 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
01230 end if
01231 Fmm(m,mm) = Fmm(m,mm) + &
01232 ssign * elfactor &
01233 * exp(-I*PION2*(m+spin)) &
01234 * dl(mm,m) * dl_mm_spin &
01235 * flm(ind)
01236 end do
01237 end do
01238 end do
01239
01240
01241 fmt(0:L-1, 0:2*L-1) = cmplx(0d0, 0d0)
01242 do t = 0, 2*L-1
01243 theta = ssht_sampling_dh_t2theta(t, L)
01244
01245 do m = 0, L-1
01246 fmt(m,t) = fmt(m,t) + Fmm(m,0)
01247 end do
01248 do mm = 1, L-1
01249 do m = 0, L-1
01250 fmt(m,t) = fmt(m,t) + &
01251 Fmm(m,mm) * (exp(I*mm*theta) + signs(m) * ssign * exp(-I*mm*theta))
01252 end do
01253 end do
01254 end do
01255
01256
01257 f(0:2*L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
01258 call dfftw_plan_dft_c2r_1d(fftw_plan, 2*L-1, Fmm(0:L-1,0), &
01259 f(0,0:2*L-2), FFTW_MEASURE)
01260 do t = 0, 2*L-1
01261 call dfftw_execute_dft_c2r(fftw_plan, fmt(0:L-1,t), f(t,0:2*L-2))
01262 end do
01263 call dfftw_destroy_plan(fftw_plan)
01264
01265
01266 if (present(verbosity)) then
01267 if (verbosity > 0) then
01268 write(*,'(a,a)') SSHT_PROMPT, &
01269 'Inverse transform computed!'
01270 end if
01271 end if
01272
01273 end subroutine ssht_core_dh_inverse_sov_sym_real
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01300
01301 subroutine ssht_core_gl_inverse_sov_sym(f, flm, L, spin, verbosity)
01302
01303 integer, intent(in) :: L
01304 integer, intent(in) :: spin
01305 integer, intent(in), optional :: verbosity
01306 complex(dpc), intent(in) :: flm(0:L**2-1)
01307 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
01308
01309 integer :: el, m, mm, t, p, ind
01310 real(dp) :: theta, phi
01311 real(dp) :: elfactor
01312 real(dp) :: dl(0:L-1, -(L-1):L-1)
01313 complex(dpc) :: Fmm(-(L-1):L-1, 0:L-1)
01314 complex(dpc) :: fmt(-(L-1):L-1, 0:L-1)
01315 integer*8 :: fftw_plan
01316 character(len=STRING_LEN) :: format_spec
01317
01318 real(dp) :: thetas(0:L-1)
01319 real(dp) :: weights(0:L-1)
01320
01321 integer :: eltmp
01322 real(dp) :: signs(0:L), ssign
01323 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
01324
01325
01326 do el = 0, 2*(L-1) + 1
01327 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
01328 end do
01329 do m = 0, L-1, 2
01330 signs(m) = 1.0_dp
01331 signs(m+1) = -1.0_dp
01332 enddo
01333 ssign = signs(abs(spin))
01334
01335
01336 if (present(verbosity)) then
01337 if (verbosity > 0) then
01338 write(*,'(a,a)') SSHT_PROMPT, &
01339 'Computing inverse transform using Gauss-Legendre sampling with'
01340 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
01341 write(*,trim(format_spec)) SSHT_PROMPT, &
01342 'parameters (L,spin,reality) = (', &
01343 L, ',', spin, ',FALSE)...'
01344 end if
01345 if (verbosity > 1) then
01346 write(*,'(a,a)') SSHT_PROMPT, &
01347 'Using routine ssht_core_gl_inverse_sov_sym...'
01348 end if
01349 end if
01350
01351
01352 call ssht_sampling_gl_thetas_weights(thetas, weights, L)
01353
01354
01355 Fmm(-(L-1):L-1, 0:L-1) = cmplx(0d0, 0d0)
01356 do el = abs(spin), L-1
01357 if (el /= 0 .and. el == abs(spin)) then
01358
01359 do eltmp = 0, abs(spin)
01360 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
01361 sqrt_tbl(0:2*eltmp+1))
01362 end do
01363 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
01364 el, signs)
01365 else
01366 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
01367 sqrt_tbl(0:2*el+1))
01368 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
01369 el, signs)
01370 end if
01371
01372 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01373 do m = -el, el
01374 call ssht_sampling_elm2ind(ind, el, m)
01375 do mm = 0, el
01376 Fmm(m,mm) = Fmm(m,mm) + &
01377 ssign * elfactor &
01378 * exp(-I*PION2*(m+spin)) &
01379 * dl(mm,m) * dl(mm,-spin) &
01380 * flm(ind)
01381 end do
01382 end do
01383 end do
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405 fmt(-(L-1):L-1, 0:L-1) = cmplx(0d0, 0d0)
01406 do t = 0, L-1
01407 theta = thetas(t)
01408 do m = -(L-1), L-1
01409 fmt(m,t) = fmt(m,t) + Fmm(m,0)
01410 end do
01411 do mm = 1, L-1
01412 do m = -(L-1), L-1
01413 fmt(m,t) = fmt(m,t) + &
01414
01415
01416 Fmm(m,mm) * &
01417 (exp(I*mm*theta) + signs(abs(m)) * ssign * exp(-I*mm*theta))
01418 end do
01419 end do
01420 end do
01421
01422
01423 f(0:L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
01424 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, f(0,0:2*L-2), &
01425 f(0,0:2*L-2), FFTW_BACKWARD, FFTW_MEASURE)
01426 do t = 0, L-1
01427
01428
01429 f(t,0:L-1) = fmt(0:L-1,t)
01430 f(t,L:2*L-2) = fmt(-(L-1):-1,t)
01431
01432 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), f(t,0:2*L-2))
01433
01434 end do
01435 call dfftw_destroy_plan(fftw_plan)
01436
01437
01438 if (present(verbosity)) then
01439 if (verbosity > 0) then
01440 write(*,'(a,a)') SSHT_PROMPT, &
01441 'Inverse transform computed!'
01442 end if
01443 end if
01444
01445 end subroutine ssht_core_gl_inverse_sov_sym
01446
01447
01448
01449
01450
01468
01469 subroutine ssht_core_gl_inverse_sov_sym_real(f, flm, L, verbosity)
01470
01471 integer, intent(in) :: L
01472 integer, intent(in), optional :: verbosity
01473 complex(dpc), intent(in) :: flm(0:L**2-1)
01474 real(dp), intent(out) :: f(0:L-1, 0:2*L-2)
01475
01476 integer :: el, m, mm, t, p, ind
01477 real(dp) :: theta, phi
01478 real(dp) :: elfactor
01479 real(dp) :: dl(0:L-1, 0:L-1)
01480 complex(dpc) :: Fmm(0:L-1, 0:L-1)
01481 complex(dpc) :: fmt(0:L-1, 0:L-1)
01482 integer*8 :: fftw_plan
01483
01484 character(len=STRING_LEN) :: format_spec
01485
01486 real(dp) :: thetas(0:L-1)
01487 real(dp) :: weights(0:L-1)
01488
01489 integer :: spin
01490 integer :: eltmp
01491 real(dp) :: signs(0:L), ssign
01492 real(dp) :: dl_mm_spin
01493 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
01494
01495
01496 do el = 0, 2*(L-1) + 1
01497 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
01498 end do
01499 do m = 0, L-1, 2
01500 signs(m) = 1.0_dp
01501 signs(m+1) = -1.0_dp
01502 enddo
01503
01504
01505 spin = 0
01506 ssign = signs(abs(spin))
01507
01508
01509 if (present(verbosity)) then
01510 if (verbosity > 0) then
01511 write(*,'(a,a)') SSHT_PROMPT, &
01512 'Computing inverse transform using Gauss-Legendre sampling with'
01513 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
01514 write(*,trim(format_spec)) SSHT_PROMPT, &
01515 'parameters (L,spin,reality) = (', &
01516 L, ',', spin, ',TRUE)...'
01517 end if
01518 if (verbosity > 1) then
01519 write(*,'(a,a)') SSHT_PROMPT, &
01520 'Using routine ssht_core_gl_inverse_sov_sym_real...'
01521 end if
01522 end if
01523
01524
01525 call ssht_sampling_gl_thetas_weights(thetas, weights, L)
01526
01527
01528 Fmm(0:L-1, 0:L-1) = cmplx(0d0, 0d0)
01529 do el = abs(spin), L-1
01530 if (el /= 0 .and. el == abs(spin)) then
01531
01532 do eltmp = 0, abs(spin)
01533 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
01534 sqrt_tbl(0:2*eltmp+1))
01535 end do
01536 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
01537 el, signs(0:el))
01538 else
01539 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
01540 sqrt_tbl(0:2*el+1))
01541 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
01542 el, signs(0:el))
01543 end if
01544
01545 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01546 do m = 0, el
01547 call ssht_sampling_elm2ind(ind, el, m)
01548 do mm = 0, el
01549 if (spin <= 0) then
01550 dl_mm_spin = dl(mm,-spin)
01551 else
01552 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
01553 end if
01554
01555 Fmm(m,mm) = Fmm(m,mm) + &
01556 ssign * elfactor &
01557 * exp(-I*PION2*(m+spin)) &
01558 * dl(mm,m) * dl_mm_spin &
01559 * flm(ind)
01560 end do
01561 end do
01562 end do
01563
01564
01565 fmt(0:L-1, 0:L-1) = cmplx(0d0, 0d0)
01566 do t = 0, L-1
01567 theta = thetas(t)
01568 do m = 0, L-1
01569 fmt(m,t) = fmt(m,t) + Fmm(m,0)
01570 end do
01571 do mm = 1, L-1
01572 do m = 0, L-1
01573 fmt(m,t) = fmt(m,t) + &
01574 Fmm(m,mm) * (exp(I*mm*theta) + signs(m) * ssign * exp(-I*mm*theta))
01575 end do
01576 end do
01577 end do
01578
01579
01580 f(0:L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
01581 call dfftw_plan_dft_c2r_1d(fftw_plan, 2*L-1, Fmm(0:L-1,0), &
01582 f(0,0:2*L-2), FFTW_MEASURE)
01583 do t = 0, L-1
01584 call dfftw_execute_dft_c2r(fftw_plan, fmt(0:L-1,t), f(t,0:2*L-2))
01585 end do
01586 call dfftw_destroy_plan(fftw_plan)
01587
01588
01589 if (present(verbosity)) then
01590 if (verbosity > 0) then
01591 write(*,'(a,a)') SSHT_PROMPT, &
01592 'Inverse transform computed!'
01593 end if
01594 end if
01595
01596 end subroutine ssht_core_gl_inverse_sov_sym_real
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01625
01626 subroutine ssht_core_mweo_inverse_direct(f, flm, L, spin, verbosity)
01627
01628 integer, intent(in) :: L
01629 integer, intent(in) :: spin
01630 integer, intent(in), optional :: verbosity
01631 complex(dpc), intent(in) :: flm(0:L**2-1)
01632 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
01633
01634 integer :: el, m, t, p, ind
01635 real(dp) :: theta, phi
01636 real(dp) :: elfactor
01637 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
01638 character(len=STRING_LEN) :: format_spec
01639
01640
01641 if (present(verbosity)) then
01642 if (verbosity > 0) then
01643 write(*,'(a,a,a)') SSHT_PROMPT, &
01644 'Computing inverse transform using McEwen and Wiaux', &
01645 ' even-odd sampling with'
01646 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
01647 digit(spin),',a)'
01648 write(*,trim(format_spec)) SSHT_PROMPT, &
01649 'parameters (L,spin,reality) = (', &
01650 L, ',', spin, ',FALSE)...'
01651 end if
01652 if (verbosity > 1) then
01653 write(*,'(a,a)') SSHT_PROMPT, &
01654 'Using routine ssht_core_mweo_inverse_direct...'
01655 end if
01656 end if
01657
01658 f(0:L-1 ,0:2*L-2) = cmplx(0d0, 0d0)
01659 do el = abs(spin), L-1
01660 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01661 do t = 0, L-1
01662 theta = ssht_sampling_mweo_t2theta(t, L)
01663 call ssht_dl_beta_operator(dl(-el:el,-el:el), theta, el)
01664 do m = -el, el
01665 call ssht_sampling_elm2ind(ind, el, m)
01666 do p = 0, 2*L-2
01667 phi = ssht_sampling_mweo_p2phi(p, L)
01668 f(t,p) = f(t,p) + &
01669 (-1)**spin * elfactor &
01670 * exp(I*m*phi) &
01671 * dl(m,-spin) * flm(ind)
01672 end do
01673 end do
01674
01675 end do
01676 end do
01677
01678
01679 if (present(verbosity)) then
01680 if (verbosity > 0) then
01681 write(*,'(a,a)') SSHT_PROMPT, &
01682 'Inverse transform computed!'
01683 end if
01684 end if
01685
01686 end subroutine ssht_core_mweo_inverse_direct
01687
01688
01689
01690
01691
01710
01711 subroutine ssht_core_mweo_inverse_sov_direct(f, flm, L, spin, verbosity)
01712
01713 integer, intent(in) :: L
01714 integer, intent(in) :: spin
01715 integer, intent(in), optional :: verbosity
01716 complex(dpc), intent(in) :: flm(0:L**2-1)
01717 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
01718
01719 integer :: el, m, mm, t, p, ind
01720 real(dp) :: theta, phi
01721 real(dp) :: elfactor
01722 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
01723 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
01724 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
01725 character(len=STRING_LEN) :: format_spec
01726
01727
01728 if (present(verbosity)) then
01729 if (verbosity > 0) then
01730 write(*,'(a,a,a)') SSHT_PROMPT, &
01731 'Computing inverse transform using McEwen and Wiaux', &
01732 ' even-odd sampling with'
01733 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
01734 digit(spin),',a)'
01735 write(*,trim(format_spec)) SSHT_PROMPT, &
01736 'parameters (L,spin,reality) = (', &
01737 L, ',', spin, ',FALSE)...'
01738 end if
01739 if (verbosity > 1) then
01740 write(*,'(a,a)') SSHT_PROMPT, &
01741 'Using routine ssht_core_mweo_inverse_sov_direct...'
01742 end if
01743 end if
01744
01745
01746 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
01747 do el = abs(spin), L-1
01748 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
01749 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01750 do m = -el, el
01751 call ssht_sampling_elm2ind(ind, el, m)
01752 do mm = -el, el
01753 Fmm(m,mm) = Fmm(m,mm) + &
01754 (-1)**spin * elfactor &
01755 * exp(-I*PION2*(m+spin)) &
01756 * dl(mm,m) * dl(mm,-spin) &
01757 * flm(ind)
01758 end do
01759 end do
01760 end do
01761
01762
01763 fext(0:2*L-2, 0:2*L-2) = cmplx(0d0, 0d0)
01764 do t = 0, 2*L-2
01765 theta = ssht_sampling_mweo_t2theta(t, L)
01766 do p = 0, 2*L-2
01767 phi = ssht_sampling_mweo_p2phi(p, L)
01768 do m = -(L-1), L-1
01769 do mm = -(L-1), L-1
01770 fext(t,p) = fext(t,p) + &
01771 Fmm(m,mm) * exp(I*m*phi + I*mm*theta)
01772 end do
01773 end do
01774 end do
01775 end do
01776
01777
01778 f(0:L-1, 0:2*L-2) = fext(0:L-1, 0:2*L-2)
01779
01780
01781 if (present(verbosity)) then
01782 if (verbosity > 0) then
01783 write(*,'(a,a)') SSHT_PROMPT, &
01784 'Inverse transform computed!'
01785 end if
01786 end if
01787
01788 end subroutine ssht_core_mweo_inverse_sov_direct
01789
01790
01791
01792
01793
01809
01810 subroutine ssht_core_mweo_inverse_sov(f, flm, L, spin, verbosity)
01811
01812 integer, intent(in) :: L
01813 integer, intent(in) :: spin
01814 integer, intent(in), optional :: verbosity
01815 complex(dpc), intent(in) :: flm(0:L**2-1)
01816 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
01817
01818 integer :: el, m, mm, t, p, ind
01819 real(dp) :: theta, phi
01820 real(dp) :: elfactor
01821 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
01822 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
01823 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
01824 integer*8 :: fftw_plan
01825 character(len=STRING_LEN) :: format_spec
01826
01827
01828 if (present(verbosity)) then
01829 if (verbosity > 0) then
01830 write(*,'(a,a,a)') SSHT_PROMPT, &
01831 'Computing inverse transform using McEwen and Wiaux', &
01832 ' even-odd sampling with'
01833 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
01834 digit(spin),',a)'
01835 write(*,trim(format_spec)) SSHT_PROMPT, &
01836 'parameters (L,spin,reality) = (', &
01837 L, ',', spin, ',FALSE)...'
01838 end if
01839 if (verbosity > 1) then
01840 write(*,'(a,a)') SSHT_PROMPT, &
01841 'Using routine ssht_core_mweo_inverse_sov...'
01842 end if
01843 end if
01844
01845
01846 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
01847 do el = abs(spin), L-1
01848 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
01849 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
01850 do m = -el, el
01851 call ssht_sampling_elm2ind(ind, el, m)
01852 do mm = -el, el
01853 Fmm(m,mm) = Fmm(m,mm) + &
01854 (-1)**spin * elfactor &
01855 * exp(-I*PION2*(m+spin)) &
01856 * dl(mm,m) * dl(mm,-spin) &
01857 * flm(ind)
01858 end do
01859 end do
01860 end do
01861
01862
01863
01864
01865
01866
01867
01868 do m = -(L-1), L-1
01869 do mm = -(L-1), L-1
01870 Fmm(m,mm) = Fmm(m,mm) * exp(I*(m+mm)*PI/(2d0*L-1d0))
01871 end do
01872 end do
01873
01874
01875 fext(0:L-1, 0:L-1) = Fmm(0:L-1,0:L-1)
01876 fext(L:2*L-2, 0:L-1) = Fmm(-(L-1):-1,0:L-1)
01877 fext(0:L-1, L:2*L-2) = Fmm(0:L-1,-(L-1):-1)
01878 fext(L:2*L-2, L:2*L-2) = Fmm(-(L-1):-1,-(L-1):-1)
01879
01880
01881
01882
01883 call dfftw_plan_dft_2d(fftw_plan, 2*L-1, 2*L-1, fext(0:2*L-2,0:2*L-2), &
01884 fext(0:2*L-2,0:2*L-2), FFTW_BACKWARD, FFTW_ESTIMATE)
01885 call dfftw_execute_dft(fftw_plan, fext(0:2*L-2,0:2*L-2), fext(0:2*L-2,0:2*L-2))
01886 call dfftw_destroy_plan(fftw_plan)
01887
01888
01889
01890
01891 f(0:L-1, 0:2*L-2) = transpose(fext(0:2*L-2, 0:L-1))
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904 if (present(verbosity)) then
01905 if (verbosity > 0) then
01906 write(*,'(a,a)') SSHT_PROMPT, &
01907 'Inverse transform computed!'
01908 end if
01909 end if
01910
01911 end subroutine ssht_core_mweo_inverse_sov
01912
01913
01914
01915
01916
01933
01934 subroutine ssht_core_mweo_inverse_sov_sym(f, flm, L, spin, verbosity)
01935
01936 integer, intent(in) :: L
01937 integer, intent(in) :: spin
01938 integer, intent(in), optional :: verbosity
01939 complex(dpc), intent(in) :: flm(0:L**2-1)
01940 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
01941
01942 integer :: el, m, mm, t, p, ind
01943 real(dp) :: theta, phi
01944 real(dp) :: elfactor
01945 real(dp) :: dl(0:L-1, -(L-1):L-1)
01946 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
01947 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
01948 integer*8 :: fftw_plan
01949 character(len=STRING_LEN) :: format_spec
01950
01951 integer :: eltmp
01952 real(dp) :: signs(0:L), ssign
01953 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
01954
01955
01956 do el = 0, 2*(L-1) + 1
01957 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
01958 end do
01959 do m = 0, L-1, 2
01960 signs(m) = 1.0_dp
01961 signs(m+1) = -1.0_dp
01962 enddo
01963 ssign = signs(abs(spin))
01964
01965
01966 if (present(verbosity)) then
01967 if (verbosity > 0) then
01968 write(*,'(a,a,a)') SSHT_PROMPT, &
01969 'Computing inverse transform using McEwen and Wiaux', &
01970 ' even-odd sampling with'
01971 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
01972 digit(spin),',a)'
01973 write(*,trim(format_spec)) SSHT_PROMPT, &
01974 'parameters (L,spin,reality) = (', &
01975 L, ',', spin, ',FALSE)...'
01976 end if
01977 if (verbosity > 1) then
01978 write(*,'(a,a)') SSHT_PROMPT, &
01979 'Using routine ssht_core_mweo_inverse_sov_sym...'
01980 end if
01981 end if
01982
01983
01984 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
01985 do el = abs(spin), L-1
01986 if (el /= 0 .and. el == abs(spin)) then
01987
01988 do eltmp = 0, abs(spin)
01989 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
01990 sqrt_tbl(0:2*eltmp+1))
01991 end do
01992 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
01993 el, signs)
01994 else
01995 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
01996 sqrt_tbl(0:2*el+1))
01997 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
01998 el, signs)
01999 end if
02000
02001 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02002 do m = -el, el
02003 call ssht_sampling_elm2ind(ind, el, m)
02004 do mm = 0, el
02005 Fmm(m,mm) = Fmm(m,mm) + &
02006 ssign * elfactor &
02007 * exp(-I*PION2*(m+spin)) &
02008 * dl(mm,m) * dl(mm,-spin) &
02009 * flm(ind)
02010 end do
02011 end do
02012 end do
02013
02014
02015 do mm = -(L-1), -1
02016 do m = -(L-1), L-1
02017 Fmm(m,mm) = signs(abs(m)) * ssign * Fmm(m,-mm)
02018 end do
02019 end do
02020
02021
02022
02023
02024
02025
02026
02027 do mm = -(L-1), L-1
02028 do m = -(L-1), L-1
02029 Fmm(m,mm) = Fmm(m,mm) * exp(I*(m+mm)*PI/(2d0*L-1d0))
02030 end do
02031 end do
02032
02033
02034 fext(0:L-1, 0:L-1) = Fmm(0:L-1,0:L-1)
02035 fext(L:2*L-2, 0:L-1) = Fmm(-(L-1):-1,0:L-1)
02036 fext(0:L-1, L:2*L-2) = Fmm(0:L-1,-(L-1):-1)
02037 fext(L:2*L-2, L:2*L-2) = Fmm(-(L-1):-1,-(L-1):-1)
02038
02039
02040
02041
02042 call dfftw_plan_dft_2d(fftw_plan, 2*L-1, 2*L-1, fext(0:2*L-2,0:2*L-2), &
02043 fext(0:2*L-2,0:2*L-2), FFTW_BACKWARD, FFTW_ESTIMATE)
02044 call dfftw_execute_dft(fftw_plan, fext(0:2*L-2,0:2*L-2), fext(0:2*L-2,0:2*L-2))
02045 call dfftw_destroy_plan(fftw_plan)
02046
02047
02048
02049
02050 f(0:L-1, 0:2*L-2) = transpose(fext(0:2*L-2, 0:L-1))
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063 if (present(verbosity)) then
02064 if (verbosity > 0) then
02065 write(*,'(a,a)') SSHT_PROMPT, &
02066 'Inverse transform computed!'
02067 end if
02068 end if
02069
02070 end subroutine ssht_core_mweo_inverse_sov_sym
02071
02072
02073
02074
02075
02093
02094 subroutine ssht_core_mweo_inverse_sov_sym_real(f, flm, L, verbosity)
02095
02096 integer, intent(in) :: L
02097 integer, intent(in), optional :: verbosity
02098 complex(dpc), intent(in) :: flm(0:L**2-1)
02099 real(dp), intent(out) :: f(0:L-1, 0:2*L-2)
02100
02101 integer :: el, m, mm, t, p, ind
02102 real(dp) :: theta, phi
02103 real(dp) :: elfactor
02104 real(dp) :: dl(0:L-1, 0:L-1)
02105 complex(dpc) :: Fmm(0:L-1, -(L-1):L-1)
02106 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
02107 real(dp) :: fext_real(0:2*L-2,0:2*L-2)
02108 integer*8 :: fftw_plan
02109 character(len=STRING_LEN) :: format_spec
02110
02111 integer :: spin
02112 integer :: eltmp
02113 real(dp) :: signs(0:L), ssign
02114 real(dp) :: dl_mm_spin
02115 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
02116
02117
02118 do el = 0, 2*(L-1) + 1
02119 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
02120 end do
02121 do m = 0, L-1, 2
02122 signs(m) = 1.0_dp
02123 signs(m+1) = -1.0_dp
02124 enddo
02125
02126
02127 spin = 0
02128 ssign = signs(abs(spin))
02129
02130
02131 if (present(verbosity)) then
02132 if (verbosity > 0) then
02133 write(*,'(a,a,a)') SSHT_PROMPT, &
02134 'Computing inverse transform using McEwen and Wiaux', &
02135 ' even-odd sampling with'
02136 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
02137 digit(spin),',a)'
02138 write(*,trim(format_spec)) SSHT_PROMPT, &
02139 'parameters (L,spin,reality) = (', &
02140 L, ',', spin, ',TRUE)...'
02141 end if
02142 if (verbosity > 1) then
02143 write(*,'(a,a)') SSHT_PROMPT, &
02144 'Using routine ssht_core_mweo_inverse_sov_sym_real...'
02145 end if
02146 end if
02147
02148
02149 Fmm(0:L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02150 do el = abs(spin), L-1
02151 if (el /= 0 .and. el == abs(spin)) then
02152
02153 do eltmp = 0, abs(spin)
02154 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
02155 sqrt_tbl(0:2*eltmp+1))
02156 end do
02157 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
02158 el, signs(0:el))
02159 else
02160 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
02161 sqrt_tbl(0:2*el+1))
02162 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
02163 el, signs(0:el))
02164 end if
02165 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02166 do m = 0, el
02167 call ssht_sampling_elm2ind(ind, el, m)
02168 do mm = 0, el
02169 if (spin <= 0) then
02170 dl_mm_spin = dl(mm,-spin)
02171 else
02172 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
02173 end if
02174
02175 Fmm(m,mm) = Fmm(m,mm) + &
02176 ssign * elfactor &
02177 * exp(-I*PION2*(m+spin)) &
02178 * dl(mm,m) * dl_mm_spin &
02179 * flm(ind)
02180 end do
02181 end do
02182 end do
02183
02184
02185 do m = 0, L-1
02186 do mm = -(L-1), -1
02187 Fmm(m,mm) = signs(m) * ssign * Fmm(m,-mm)
02188 end do
02189 end do
02190
02191
02192 do mm = -(L-1), L-1
02193 do m = 0, L-1
02194 Fmm(m,mm) = Fmm(m,mm) * exp(I*(m+mm)*PI/(2d0*L-1d0))
02195 end do
02196 end do
02197
02198
02199 fext(0:L-1, 0:L-1) = Fmm(0:L-1,0:L-1)
02200 fext(0:L-1, L:2*L-2) = Fmm(0:L-1,-(L-1):-1)
02201
02202
02203 call dfftw_plan_dft_c2r_2d(fftw_plan, 2*L-1, 2*L-1, fext(0:L-1,0:2*L-2), &
02204 fext_real(0:2*L-2,0:2*L-2), FFTW_ESTIMATE)
02205 call dfftw_execute_dft_c2r(fftw_plan, fext(0:L-1,0:2*L-2), fext_real(0:2*L-2,0:2*L-2))
02206 call dfftw_destroy_plan(fftw_plan)
02207
02208
02209
02210
02211 f(0:L-1, 0:2*L-2) = transpose(fext_real(0:2*L-2, 0:L-1))
02212
02213
02214 if (present(verbosity)) then
02215 if (verbosity > 0) then
02216 write(*,'(a,a)') SSHT_PROMPT, &
02217 'Inverse transform computed!'
02218 end if
02219 end if
02220
02221 end subroutine ssht_core_mweo_inverse_sov_sym_real
02222
02223
02224
02225
02226
02227
02228
02229
02230
02231
02250
02251 subroutine ssht_core_mw_inverse_sov_direct(f, flm, L, spin, verbosity)
02252
02253 integer, intent(in) :: L
02254 integer, intent(in) :: spin
02255 integer, intent(in), optional :: verbosity
02256 complex(dpc), intent(in) :: flm(0:L**2-1)
02257 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
02258
02259 integer :: el, m, mm, t, p, ind
02260 real(dp) :: theta, phi
02261 real(dp) :: elfactor
02262 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
02263 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
02264 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
02265 character(len=STRING_LEN) :: format_spec
02266
02267
02268 if (present(verbosity)) then
02269 if (verbosity > 0) then
02270 write(*,'(a,a,a)') SSHT_PROMPT, &
02271 'Computing inverse transform using McEwen and Wiaux', &
02272 ' sampling with'
02273 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
02274 digit(spin),',a)'
02275 write(*,trim(format_spec)) SSHT_PROMPT, &
02276 'parameters (L,spin,reality) = (', &
02277 L, ',', spin, ',FALSE)...'
02278 end if
02279 if (verbosity > 1) then
02280 write(*,'(a,a)') SSHT_PROMPT, &
02281 'Using routine ssht_core_mweo_inverse_direct...'
02282 end if
02283 end if
02284
02285
02286 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02287 do el = abs(spin), L-1
02288 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
02289 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02290 do m = -el, el
02291 call ssht_sampling_elm2ind(ind, el, m)
02292 do mm = -el, el
02293 Fmm(m,mm) = Fmm(m,mm) + &
02294 (-1)**spin * elfactor &
02295 * exp(-I*PION2*(m+spin)) &
02296 * dl(mm,m) * dl(mm,-spin) &
02297 * flm(ind)
02298 end do
02299 end do
02300 end do
02301
02302
02303 fext(0:2*L-2, 0:2*L-2) = cmplx(0d0, 0d0)
02304 do t = 0, 2*L-2
02305 theta = ssht_sampling_mw_t2theta(t, L)
02306 do p = 0, 2*L-2
02307 phi = ssht_sampling_mw_p2phi(p, L)
02308 do m = -(L-1), L-1
02309 do mm = -(L-1), L-1
02310 fext(t,p) = fext(t,p) + &
02311 Fmm(m,mm) * exp(I*m*phi + I*mm*theta)
02312 end do
02313 end do
02314 end do
02315 end do
02316
02317
02318 f(0:L-1, 0:2*L-2) = fext(0:L-1, 0:2*L-2)
02319
02320
02321 if (present(verbosity)) then
02322 if (verbosity > 0) then
02323 write(*,'(a,a)') SSHT_PROMPT, &
02324 'Inverse transform computed!'
02325 end if
02326 end if
02327
02328 end subroutine ssht_core_mw_inverse_sov_direct
02329
02330
02331
02332
02333
02349
02350 subroutine ssht_core_mw_inverse_sov(f, flm, L, spin, verbosity)
02351
02352 integer, intent(in) :: L
02353 integer, intent(in) :: spin
02354 integer, intent(in), optional :: verbosity
02355 complex(dpc), intent(in) :: flm(0:L**2-1)
02356 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
02357
02358 integer :: el, m, mm, t, p, ind
02359 real(dp) :: theta, phi
02360 real(dp) :: elfactor
02361 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
02362 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
02363 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
02364 integer*8 :: fftw_plan
02365 character(len=STRING_LEN) :: format_spec
02366
02367
02368 if (present(verbosity)) then
02369 if (verbosity > 0) then
02370 write(*,'(a,a,a)') SSHT_PROMPT, &
02371 'Computing inverse transform using McEwen and Wiaux', &
02372 ' sampling with'
02373 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
02374 digit(spin),',a)'
02375 write(*,trim(format_spec)) SSHT_PROMPT, &
02376 'parameters (L,spin,reality) = (', &
02377 L, ',', spin, ',FALSE)...'
02378 end if
02379 if (verbosity > 1) then
02380 write(*,'(a,a)') SSHT_PROMPT, &
02381 'Using routine ssht_core_mw_inverse_sov...'
02382 end if
02383 end if
02384
02385
02386 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02387 do el = abs(spin), L-1
02388 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
02389 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02390 do m = -el, el
02391 call ssht_sampling_elm2ind(ind, el, m)
02392 do mm = -el, el
02393 Fmm(m,mm) = Fmm(m,mm) + &
02394 (-1)**spin * elfactor &
02395 * exp(-I*PION2*(m+spin)) &
02396 * dl(mm,m) * dl(mm,-spin) &
02397 * flm(ind)
02398 end do
02399 end do
02400 end do
02401
02402
02403 do mm = -(L-1), L-1
02404 Fmm(-(L-1):L-1,mm) = Fmm(-(L-1):L-1,mm) * exp(I*mm*PI/(2d0*L-1d0))
02405 end do
02406
02407
02408 fext(0:L-1, 0:L-1) = Fmm(0:L-1,0:L-1)
02409 fext(L:2*L-2, 0:L-1) = Fmm(-(L-1):-1,0:L-1)
02410 fext(0:L-1, L:2*L-2) = Fmm(0:L-1,-(L-1):-1)
02411 fext(L:2*L-2, L:2*L-2) = Fmm(-(L-1):-1,-(L-1):-1)
02412
02413
02414 call dfftw_plan_dft_2d(fftw_plan, 2*L-1, 2*L-1, fext(0:2*L-2,0:2*L-2), &
02415 fext(0:2*L-2,0:2*L-2), FFTW_BACKWARD, FFTW_ESTIMATE)
02416 call dfftw_execute_dft(fftw_plan, fext(0:2*L-2,0:2*L-2), fext(0:2*L-2,0:2*L-2))
02417 call dfftw_destroy_plan(fftw_plan)
02418
02419
02420 f(0:L-1, 0:2*L-2) = transpose(fext(0:2*L-2, 0:L-1))
02421
02422
02423 if (present(verbosity)) then
02424 if (verbosity > 0) then
02425 write(*,'(a,a)') SSHT_PROMPT, &
02426 'Inverse transform computed!'
02427 end if
02428 end if
02429
02430 end subroutine ssht_core_mw_inverse_sov
02431
02432
02433
02434
02435
02452
02453 subroutine ssht_core_mw_inverse_sov_sym(f, flm, L, spin, verbosity)
02454
02455 integer, intent(in) :: L
02456 integer, intent(in) :: spin
02457 integer, intent(in), optional :: verbosity
02458 complex(dpc), intent(in) :: flm(0:L**2-1)
02459 complex(dpc), intent(out) :: f(0:L-1, 0:2*L-2)
02460
02461 integer :: el, m, mm, t, p, ind
02462 real(dp) :: theta, phi
02463 real(dp) :: elfactor
02464 real(dp) :: dl(0:L-1, -(L-1):L-1)
02465 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
02466 complex(dpc) :: fext(0:2*L-2, 0:2*L-2)
02467 integer*8 :: fftw_plan
02468 character(len=STRING_LEN) :: format_spec
02469
02470 integer :: eltmp
02471 real(dp) :: signs(0:L), ssign
02472 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
02473
02474
02475 do el = 0, 2*(L-1) + 1
02476 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
02477 end do
02478 do m = 0, L-1, 2
02479 signs(m) = 1.0_dp
02480 signs(m+1) = -1.0_dp
02481 enddo
02482 ssign = signs(abs(spin))
02483
02484
02485 if (present(verbosity)) then
02486 if (verbosity > 0) then
02487 write(*,'(a,a,a)') SSHT_PROMPT, &
02488 'Computing inverse transform using McEwen and Wiaux', &
02489 ' sampling with'
02490 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
02491 digit(spin),',a)'
02492 write(*,trim(format_spec)) SSHT_PROMPT, &
02493 'parameters (L,spin,reality) = (', &
02494 L, ',', spin, ',FALSE)...'
02495 end if
02496 if (verbosity > 1) then
02497 write(*,'(a,a)') SSHT_PROMPT, &
02498 'Using routine ssht_core_mw_inverse_sov_sym...'
02499 end if
02500 end if
02501
02502
02503 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02504 do el = abs(spin), L-1
02505
02506 if (el /= 0 .and. el == abs(spin)) then
02507
02508 do eltmp = 0, abs(spin)
02509 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
02510 sqrt_tbl(0:2*eltmp+1))
02511 end do
02512 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
02513 el, signs)
02514 else
02515 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
02516 sqrt_tbl(0:2*el+1))
02517 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
02518 el, signs)
02519 end if
02520
02521 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02522 do m = -el, el
02523 call ssht_sampling_elm2ind(ind, el, m)
02524 do mm = 0, el
02525 Fmm(m,mm) = Fmm(m,mm) + &
02526 ssign * elfactor &
02527 * exp(-I*PION2*(m+spin)) &
02528 * dl(mm,m) * dl(mm,-spin) &
02529 * flm(ind)
02530 end do
02531 end do
02532 end do
02533
02534
02535 do mm = -(L-1), -1
02536 do m = -(L-1), L-1
02537 Fmm(m,mm) = signs(abs(m)) * ssign * Fmm(m,-mm)
02538 end do
02539 end do
02540
02541
02542 do mm = -(L-1), L-1
02543 Fmm(-(L-1):L-1,mm) = Fmm(-(L-1):L-1,mm) * exp(I*mm*PI/(2d0*L-1d0))
02544 end do
02545
02546
02547 fext(0:L-1, 0:L-1) = Fmm(0:L-1,0:L-1)
02548 fext(L:2*L-2, 0:L-1) = Fmm(-(L-1):-1,0:L-1)
02549 fext(0:L-1, L:2*L-2) = Fmm(0:L-1,-(L-1):-1)
02550 fext(L:2*L-2, L:2*L-2) = Fmm(-(L-1):-1,-(L-1):-1)
02551
02552
02553 call dfftw_plan_dft_2d(fftw_plan, 2*L-1, 2*L-1, fext(0:2*L-2,0:2*L-2), &
02554 fext(0:2*L-2,0:2*L-2), FFTW_BACKWARD, FFTW_ESTIMATE)
02555 call dfftw_execute_dft(fftw_plan, fext(0:2*L-2,0:2*L-2), fext(0:2*L-2,0:2*L-2))
02556 call dfftw_destroy_plan(fftw_plan)
02557
02558
02559 f(0:L-1, 0:2*L-2) = transpose(fext(0:2*L-2, 0:L-1))
02560
02561
02562 if (present(verbosity)) then
02563 if (verbosity > 0) then
02564 write(*,'(a,a)') SSHT_PROMPT, &
02565 'Inverse transform computed!'
02566 end if
02567 end if
02568
02569 end subroutine ssht_core_mw_inverse_sov_sym
02570
02571
02572
02573
02574
02592
02593 subroutine ssht_core_mw_inverse_sov_sym_real(f, flm, L, verbosity)
02594
02595 integer, intent(in) :: L
02596 integer, intent(in), optional :: verbosity
02597 complex(dpc), intent(in) :: flm(0:L**2-1)
02598 real(dp), intent(out) :: f(0:L-1, 0:2*L-2)
02599
02600 integer :: el, m, mm, t, p, ind
02601 real(dp) :: theta, phi
02602 real(dp) :: elfactor
02603 real(dp) :: dl(0:L-1, 0:L-1)
02604 complex(dpc) :: Fmm(0:L-1, -(L-1):L-1)
02605 complex(dpc) :: fext(0:L-1, 0:2*L-2)
02606 real(dp) :: fext_real(0:2*L-2,0:2*L-2)
02607 integer*8 :: fftw_plan
02608 character(len=STRING_LEN) :: format_spec
02609
02610 integer :: spin
02611 integer :: eltmp
02612 real(dp) :: signs(0:L), ssign
02613 real(dp) :: dl_mm_spin
02614 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
02615
02616
02617 do el = 0, 2*(L-1) + 1
02618 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
02619 end do
02620 do m = 0, L-1, 2
02621 signs(m) = 1.0_dp
02622 signs(m+1) = -1.0_dp
02623 enddo
02624
02625
02626 spin = 0
02627 ssign = signs(abs(spin))
02628
02629
02630 if (present(verbosity)) then
02631 if (verbosity > 0) then
02632 write(*,'(a,a,a)') SSHT_PROMPT, &
02633 'Computing inverse transform using McEwen and Wiaux', &
02634 ' sampling with'
02635 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
02636 digit(spin),',a)'
02637 write(*,trim(format_spec)) SSHT_PROMPT, &
02638 'parameters (L,spin,reality) = (', &
02639 L, ',', spin, ',TRUE)...'
02640 end if
02641 if (verbosity > 1) then
02642 write(*,'(a,a)') SSHT_PROMPT, &
02643 'Using routine ssht_core_mw_inverse_sov_sym...'
02644 end if
02645 end if
02646
02647
02648 Fmm(0:L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02649 do el = abs(spin), L-1
02650 if (el /= 0 .and. el == abs(spin)) then
02651
02652 do eltmp = 0, abs(spin)
02653 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
02654 sqrt_tbl(0:2*eltmp+1))
02655 end do
02656 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
02657 el, signs(0:el))
02658 else
02659 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
02660 sqrt_tbl(0:2*el+1))
02661 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
02662 el, signs(0:el))
02663 end if
02664
02665 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02666 do m = 0, el
02667 call ssht_sampling_elm2ind(ind, el, m)
02668 do mm = 0, el
02669 if (spin <= 0) then
02670 dl_mm_spin = dl(mm,-spin)
02671 else
02672 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
02673 end if
02674
02675 Fmm(m,mm) = Fmm(m,mm) + &
02676 ssign * elfactor &
02677 * exp(-I*PION2*(m+spin)) &
02678
02679 * dl(mm,m) * dl_mm_spin &
02680 * flm(ind)
02681 end do
02682 end do
02683 end do
02684
02685
02686 do mm = -(L-1), -1
02687 do m = 0, L-1
02688 Fmm(m,mm) = signs(m) * ssign * Fmm(m,-mm)
02689 end do
02690 end do
02691
02692
02693 do mm = -(L-1), L-1
02694 Fmm(0:L-1,mm) = Fmm(0:L-1,mm) * exp(I*mm*PI/(2d0*L-1d0))
02695 end do
02696
02697
02698 fext(0:L-1, 0:L-1) = Fmm(0:L-1,0:L-1)
02699 fext(0:L-1, L:2*L-2) = Fmm(0:L-1,-(L-1):-1)
02700
02701
02702 call dfftw_plan_dft_c2r_2d(fftw_plan, 2*L-1, 2*L-1, fext(0:L-1,0:2*L-2), &
02703 fext_real(0:2*L-2,0:2*L-2), FFTW_ESTIMATE)
02704 call dfftw_execute_dft_c2r(fftw_plan, fext(0:L-1,0:2*L-2), fext_real(0:2*L-2,0:2*L-2))
02705 call dfftw_destroy_plan(fftw_plan)
02706
02707
02708 f(0:L-1, 0:2*L-2) = transpose(fext_real(0:2*L-2, 0:L-1))
02709
02710
02711 if (present(verbosity)) then
02712 if (verbosity > 0) then
02713 write(*,'(a,a)') SSHT_PROMPT, &
02714 'Inverse transform computed!'
02715 end if
02716 end if
02717
02718 end subroutine ssht_core_mw_inverse_sov_sym_real
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733
02752
02753 subroutine ssht_core_dh_forward_sov_direct(flm, f, L, spin, verbosity)
02754
02755 integer, intent(in) :: L
02756 integer, intent(in) :: spin
02757 integer, intent(in), optional :: verbosity
02758 complex(dpc), intent(in) :: f(0:2*L-1 ,0:2*L-2)
02759 complex(dpc), intent(out) :: flm(0:L**2-1)
02760
02761 integer :: p, m, t, mm, el, ind
02762 real(dp) :: theta, phi
02763 real(dp) :: elfactor
02764 real(dp) :: w
02765 complex(dpc) :: fmt(-(L-1):L-1, 0:2*L-1)
02766 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
02767 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
02768 character(len=STRING_LEN) :: format_spec
02769
02770
02771 if (present(verbosity)) then
02772 if (verbosity > 0) then
02773 write(*,'(a,a)') SSHT_PROMPT, &
02774 'Computing forward transform using Driscoll and Healy sampling with'
02775 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
02776 write(*,trim(format_spec)) SSHT_PROMPT, &
02777 'parameters (L,spin,reality) = (', &
02778 L, ',', spin, ',FALSE)...'
02779 end if
02780 if (verbosity > 1) then
02781 write(*,'(a,a)') SSHT_PROMPT, &
02782 'Using routine ssht_core_dh_forward_sov_direct...'
02783 end if
02784 end if
02785
02786
02787 fmt(-(L-1):L-1, 0:2*L-1) = cmplx(0d0, 0d0)
02788 do p = 0, 2*L-2
02789 phi = ssht_sampling_dh_p2phi(p, L)
02790 do m = -(L-1), L-1
02791 do t = 0, 2*L-1
02792 fmt(m,t) = fmt(m,t) + &
02793 f(t,p) * exp(-I*m*phi)
02794 end do
02795 end do
02796 end do
02797 fmt(-(L-1):L-1, 0:2*L-1) = fmt(-(L-1):L-1, 0:2*L-1) &
02798 * 2d0*PI / (2d0*L-1d0)
02799
02800
02801 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02802 do t = 0, 2*L-1
02803 theta = ssht_sampling_dh_t2theta(t, L)
02804 w = ssht_sampling_weight_dh(theta, L)
02805 do m = -(L-1), L-1
02806 do mm = -(L-1), L-1
02807 Fmm(m,mm) = Fmm(m,mm) + &
02808 fmt(m,t) * exp(-I*mm*theta) * w
02809 end do
02810 end do
02811 end do
02812
02813
02814 flm(0::L**2-1) = cmplx(0d0, 0d0)
02815 do el = abs(spin), L-1
02816 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
02817 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02818 do m = -el, el
02819 call ssht_sampling_elm2ind(ind, el, m)
02820 do mm = -el, el
02821 flm(ind) = flm(ind) + &
02822 (-1)**spin * elfactor &
02823 * exp(I*PION2*(m+spin)) &
02824 * dl(mm,m) * dl(mm,-spin) &
02825 * Fmm(m,mm)
02826 end do
02827 end do
02828 end do
02829
02830
02831 if (present(verbosity)) then
02832 if (verbosity > 0) then
02833 write(*,'(a,a)') SSHT_PROMPT, &
02834 'Forward transform computed!'
02835 end if
02836 end if
02837
02838 end subroutine ssht_core_dh_forward_sov_direct
02839
02840
02841
02842
02843
02859
02860 subroutine ssht_core_dh_forward_sov(flm, f, L, spin, verbosity)
02861
02862 integer, intent(in) :: L
02863 integer, intent(in) :: spin
02864 integer, intent(in), optional :: verbosity
02865 complex(dpc), intent(in) :: f(0:2*L-1 ,0:2*L-2)
02866 complex(dpc), intent(out) :: flm(0:L**2-1)
02867
02868 integer :: p, m, t, mm, el, ind
02869 real(dp) :: theta, phi
02870 real(dp) :: elfactor
02871 real(dp) :: w
02872 complex(dpc) :: fmt(-(L-1):L-1, 0:2*L-1)
02873 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
02874 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
02875 integer*8 :: fftw_plan
02876 complex(dpc) :: tmp(0:2*L-2)
02877 character(len=STRING_LEN) :: format_spec
02878
02879
02880 if (present(verbosity)) then
02881 if (verbosity > 0) then
02882 write(*,'(a,a)') SSHT_PROMPT, &
02883 'Computing forward transform using Driscoll and Healy sampling with'
02884 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
02885 write(*,trim(format_spec)) SSHT_PROMPT, &
02886 'parameters (L,spin,reality) = (', &
02887 L, ',', spin, ',FALSE)...'
02888 end if
02889 if (verbosity > 1) then
02890 write(*,'(a,a)') SSHT_PROMPT, &
02891 'Using routine ssht_core_dh_forward_sov...'
02892 end if
02893 end if
02894
02895
02896 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, fmt(-(L-1):L-1,0), &
02897 fmt(-(L-1):L-1,0), FFTW_FORWARD, FFTW_MEASURE)
02898 do t = 0, 2*L-1
02899
02900 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), tmp(0:2*L-2))
02901
02902
02903 fmt(0:L-1, t) = tmp(0:L-1)
02904 fmt(-(L-1):-1, t) = tmp(L:2*L-2)
02905 end do
02906 call dfftw_destroy_plan(fftw_plan)
02907 fmt(-(L-1):L-1, 0:2*L-1) = fmt(-(L-1):L-1, 0:2*L-1) &
02908 * 2d0*PI / (2d0*L-1d0)
02909
02910
02911 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
02912 do t = 0, 2*L-1
02913 theta = ssht_sampling_dh_t2theta(t, L)
02914 w = ssht_sampling_weight_dh(theta, L)
02915 do m = -(L-1), L-1
02916 do mm = -(L-1), L-1
02917 Fmm(m,mm) = Fmm(m,mm) + &
02918 fmt(m,t) * exp(-I*mm*theta) * w
02919 end do
02920 end do
02921 end do
02922
02923
02924 flm(0::L**2-1) = cmplx(0d0, 0d0)
02925 do el = abs(spin), L-1
02926 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
02927 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
02928 do m = -el, el
02929 call ssht_sampling_elm2ind(ind, el, m)
02930 do mm = -el, el
02931 flm(ind) = flm(ind) + &
02932 (-1)**spin * elfactor &
02933 * exp(I*PION2*(m+spin)) &
02934 * dl(mm,m) * dl(mm,-spin) &
02935 * Fmm(m,mm)
02936 end do
02937 end do
02938 end do
02939
02940
02941 if (present(verbosity)) then
02942 if (verbosity > 0) then
02943 write(*,'(a,a)') SSHT_PROMPT, &
02944 'Forward transform computed!'
02945 end if
02946 end if
02947
02948 end subroutine ssht_core_dh_forward_sov
02949
02950
02951
02952
02953
02970
02971 subroutine ssht_core_dh_forward_sov_sym(flm, f, L, spin, verbosity)
02972
02973 integer, intent(in) :: L
02974 integer, intent(in) :: spin
02975 integer, intent(in), optional :: verbosity
02976 complex(dpc), intent(in) :: f(0:2*L-1 ,0:2*L-2)
02977 complex(dpc), intent(out) :: flm(0:L**2-1)
02978
02979 integer :: p, m, t, mm, el, ind
02980 real(dp) :: theta, phi
02981 real(dp) :: elfactor
02982 real(dp) :: w
02983 complex(dpc) :: fmt(-(L-1):L-1, 0:2*L-1)
02984 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
02985 real(dp) :: dl(0:L-1, -(L-1):L-1)
02986 integer*8 :: fftw_plan
02987 complex(dpc) :: tmp(0:2*L-2)
02988 character(len=STRING_LEN) :: format_spec
02989
02990 real(dp) :: signs(0:L), ssign
02991 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
02992 integer :: eltmp
02993
02994
02995 do el = 0, 2*(L-1) + 1
02996 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
02997 end do
02998 do m = 0, L-1, 2
02999 signs(m) = 1.0_dp
03000 signs(m+1) = -1.0_dp
03001 enddo
03002
03003
03004 ssign = signs(abs(spin))
03005
03006
03007 if (present(verbosity)) then
03008 if (verbosity > 0) then
03009 write(*,'(a,a)') SSHT_PROMPT, &
03010 'Computing forward transform using Driscoll and Healy sampling with'
03011 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
03012 write(*,trim(format_spec)) SSHT_PROMPT, &
03013 'parameters (L,spin,reality) = (', &
03014 L, ',', spin, ',FALSE)...'
03015 end if
03016 if (verbosity > 1) then
03017 write(*,'(a,a)') SSHT_PROMPT, &
03018 'Using routine ssht_core_dh_forward_sov_sym...'
03019 end if
03020 end if
03021
03022
03023 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, fmt(-(L-1):L-1,0), &
03024 fmt(-(L-1):L-1,0), FFTW_FORWARD, FFTW_MEASURE)
03025 do t = 0, 2*L-1
03026
03027 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), tmp(0:2*L-2))
03028
03029
03030 fmt(0:L-1, t) = tmp(0:L-1)
03031 fmt(-(L-1):-1, t) = tmp(L:2*L-2)
03032 end do
03033 call dfftw_destroy_plan(fftw_plan)
03034 fmt(-(L-1):L-1, 0:2*L-1) = fmt(-(L-1):L-1, 0:2*L-1) &
03035 * 2d0*PI / (2d0*L-1d0)
03036
03037
03038 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03039 do t = 0, 2*L-1
03040 theta = ssht_sampling_dh_t2theta(t, L)
03041 w = ssht_sampling_weight_dh(theta, L)
03042 do mm = -(L-1), L-1
03043 do m = -(L-1), L-1
03044 Fmm(m,mm) = Fmm(m,mm) + &
03045 fmt(m,t) * exp(-I*mm*theta) * w
03046 end do
03047 end do
03048 end do
03049
03050
03051 flm(0::L**2-1) = cmplx(0d0, 0d0)
03052 do el = abs(spin), L-1
03053 if (el /= 0 .and. el == abs(spin)) then
03054
03055 do eltmp = 0, abs(spin)
03056 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
03057 sqrt_tbl(0:2*eltmp+1))
03058 end do
03059 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
03060 el, signs(0:el))
03061 else
03062 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
03063 sqrt_tbl(0:2*el+1))
03064 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
03065 el, signs(0:el))
03066 end if
03067
03068 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
03069 do m = -el, el
03070 call ssht_sampling_elm2ind(ind, el, m)
03071
03072 flm(ind) = flm(ind) + &
03073 ssign * elfactor &
03074 * exp(I*PION2*(m+spin)) &
03075 * dl(0,m) * dl(0,-spin) &
03076 * Fmm(m,0)
03077
03078 do mm = 1, el
03079 flm(ind) = flm(ind) + &
03080 ssign * elfactor &
03081 * exp(I*PION2*(m+spin)) &
03082 * dl(mm,m) * dl(mm,-spin) &
03083 * (Fmm(m,mm) + signs(abs(m)) * ssign * Fmm(m,-mm))
03084
03085 end do
03086 end do
03087 end do
03088
03089
03090 if (present(verbosity)) then
03091 if (verbosity > 0) then
03092 write(*,'(a,a)') SSHT_PROMPT, &
03093 'Forward transform computed!'
03094 end if
03095 end if
03096
03097 end subroutine ssht_core_dh_forward_sov_sym
03098
03099
03100
03101
03102
03120
03121 subroutine ssht_core_dh_forward_sov_sym_real(flm, f, L, verbosity)
03122
03123 integer, intent(in) :: L
03124 integer, intent(in), optional :: verbosity
03125 real(dp), intent(in) :: f(0:2*L-1 ,0:2*L-2)
03126 complex(dpc), intent(out) :: flm(0:L**2-1)
03127
03128 integer :: p, m, t, mm, el, ind
03129 real(dp) :: theta, phi
03130 real(dp) :: elfactor
03131 real(dp) :: w
03132 complex(dpc) :: fmt(0:L-1, 0:2*L-1)
03133 complex(dpc) :: Fmm(0:L-1, -(L-1):L-1)
03134 real(dp) :: dl(0:L-1, 0:L-1)
03135 integer*8 :: fftw_plan
03136
03137 integer :: spin
03138 real(dp) :: tmp(0:2*L-2)
03139 integer :: ind_nm
03140 character(len=STRING_LEN) :: format_spec
03141 integer :: eltmp
03142
03143 real(dp) :: signs(0:L), ssign
03144 real(dp) :: dl_mm_spin, dl_0_spin
03145 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
03146
03147
03148 do el = 0, 2*(L-1) + 1
03149 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
03150 end do
03151 do m = 0, L-1, 2
03152 signs(m) = 1.0_dp
03153 signs(m+1) = -1.0_dp
03154 enddo
03155
03156
03157 spin = 0
03158 ssign = signs(abs(spin))
03159
03160
03161 if (present(verbosity)) then
03162 if (verbosity > 0) then
03163 write(*,'(a,a)') SSHT_PROMPT, &
03164 'Computing forward transform using Driscoll and Healy sampling with'
03165 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
03166 write(*,trim(format_spec)) SSHT_PROMPT, &
03167 'parameters (L,spin,reality) = (', &
03168 L, ',', spin, ',TRUE)...'
03169 end if
03170 if (verbosity > 1) then
03171 write(*,'(a,a)') SSHT_PROMPT, &
03172 'Using routine ssht_core_dh_forward_sov_sym_real...'
03173 end if
03174 end if
03175
03176
03177 call dfftw_plan_dft_r2c_1d(fftw_plan, 2*L-1, tmp(0:2*L-2), &
03178 fmt(0:L-1,0), FFTW_MEASURE)
03179 do t = 0, 2*L-1
03180 call dfftw_execute_dft_r2c(fftw_plan, f(t,0:2*L-2), fmt(0:L-1,t))
03181 end do
03182 call dfftw_destroy_plan(fftw_plan)
03183 fmt(0:L-1, 0:2*L-1) = fmt(0:L-1, 0:2*L-1) &
03184 * 2d0*PI / (2d0*L-1d0)
03185
03186
03187 Fmm(0:L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03188 do t = 0, 2*L-1
03189 theta = ssht_sampling_dh_t2theta(t, L)
03190 w = ssht_sampling_weight_dh(theta, L)
03191
03192 do mm = -(L-1), L-1
03193 do m = 0, L-1
03194 Fmm(m,mm) = Fmm(m,mm) + &
03195 fmt(m,t) * exp(-I*mm*theta) * w
03196 end do
03197 end do
03198 end do
03199
03200
03201 flm(0::L**2-1) = cmplx(0d0, 0d0)
03202 do el = abs(spin), L-1
03203 if (el /= 0 .and. el == abs(spin)) then
03204
03205 do eltmp = 0, abs(spin)
03206 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
03207 sqrt_tbl(0:2*eltmp+1))
03208 end do
03209 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
03210 el, signs(0:el))
03211 else
03212 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
03213 sqrt_tbl(0:2*el+1))
03214 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
03215 el, signs(0:el))
03216 end if
03217
03218 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
03219 do m = 0, el
03220 call ssht_sampling_elm2ind(ind, el, m)
03221
03222 if (spin <= 0) then
03223 dl_0_spin = dl(0,-spin)
03224 else
03225 dl_0_spin = signs(el) * dl(0,spin)
03226 end if
03227
03228 flm(ind) = flm(ind) + &
03229 ssign * elfactor &
03230 * exp(I*PION2*(m+spin)) &
03231 * dl(0,m) * dl_0_spin &
03232 * Fmm(m,0)
03233
03234 do mm = 1, el
03235
03236 if (spin <= 0) then
03237 dl_mm_spin = dl(mm,-spin)
03238 else
03239 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
03240 end if
03241
03242 flm(ind) = flm(ind) + &
03243 (-1)**spin * elfactor &
03244 * exp(I*PION2*(m+spin)) &
03245 * dl(mm,m) * dl_mm_spin &
03246 * (Fmm(m,mm) + signs(m) * ssign * Fmm(m,-mm))
03247
03248 end do
03249 end do
03250 end do
03251
03252
03253 do el = abs(spin), L-1
03254 do m = 1, el
03255 call ssht_sampling_elm2ind(ind, el, m)
03256 call ssht_sampling_elm2ind(ind_nm, el, -m)
03257 flm(ind_nm) = signs(m) * conjg(flm(ind))
03258 end do
03259 end do
03260
03261
03262 if (present(verbosity)) then
03263 if (verbosity > 0) then
03264 write(*,'(a,a)') SSHT_PROMPT, &
03265 'Forward transform computed!'
03266 end if
03267 end if
03268
03269 end subroutine ssht_core_dh_forward_sov_sym_real
03270
03271
03272
03273
03274
03275
03276
03277
03278
03279
03296
03297 subroutine ssht_core_gl_forward_sov_sym(flm, f, L, spin, verbosity)
03298
03299 integer, intent(in) :: L
03300 integer, intent(in) :: spin
03301 integer, intent(in), optional :: verbosity
03302 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
03303 complex(dpc), intent(out) :: flm(0:L**2-1)
03304
03305 integer :: p, m, t, mm, el, ind
03306 real(dp) :: theta, phi
03307 real(dp) :: elfactor
03308 real(dp) :: w
03309 complex(dpc) :: fmt(-(L-1):L-1, 0:L-1)
03310 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
03311 real(dp) :: dl(0:L-1, -(L-1):L-1)
03312 integer*8 :: fftw_plan
03313 complex(dpc) :: tmp(0:2*L-2)
03314 character(len=STRING_LEN) :: format_spec
03315
03316 real(dp) :: thetas(0:L-1)
03317 real(dp) :: weights(0:L-1)
03318
03319 real(dp) :: signs(0:L), ssign
03320 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
03321 integer :: eltmp
03322
03323
03324 do el = 0, 2*(L-1) + 1
03325 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
03326 end do
03327 do m = 0, L-1, 2
03328 signs(m) = 1.0_dp
03329 signs(m+1) = -1.0_dp
03330 enddo
03331
03332
03333 ssign = signs(abs(spin))
03334
03335
03336 if (present(verbosity)) then
03337 if (verbosity > 0) then
03338 write(*,'(a,a)') SSHT_PROMPT, &
03339 'Computing forward transform using Gauss-Legendre sampling with'
03340 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
03341 write(*,trim(format_spec)) SSHT_PROMPT, &
03342 'parameters (L,spin,reality) = (', &
03343 L, ',', spin, ',FALSE)...'
03344 end if
03345 if (verbosity > 1) then
03346 write(*,'(a,a)') SSHT_PROMPT, &
03347 'Using routine ssht_core_gl_forward_sov_sym...'
03348 end if
03349 end if
03350
03351
03352 call ssht_sampling_gl_thetas_weights(thetas, weights, L)
03353
03354
03355 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, fmt(-(L-1):L-1,0), &
03356 fmt(-(L-1):L-1,0), FFTW_FORWARD, FFTW_MEASURE)
03357 do t = 0, L-1
03358
03359 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), tmp(0:2*L-2))
03360
03361
03362 fmt(0:L-1, t) = tmp(0:L-1)
03363 fmt(-(L-1):-1, t) = tmp(L:2*L-2)
03364 end do
03365 call dfftw_destroy_plan(fftw_plan)
03366 fmt(-(L-1):L-1, 0:L-1) = fmt(-(L-1):L-1, 0:L-1) &
03367 * 2d0*PI / (2d0*L-1d0)
03368
03369
03370 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03371 do t = 0, L-1
03372 theta = thetas(t)
03373 w = weights(t)
03374 do mm = -(L-1), L-1
03375 do m = -(L-1), L-1
03376 Fmm(m,mm) = Fmm(m,mm) + &
03377 fmt(m,t) * exp(-I*mm*theta) * w
03378 end do
03379 end do
03380 end do
03381
03382
03383 flm(0::L**2-1) = cmplx(0d0, 0d0)
03384 do el = abs(spin), L-1
03385 if (el /= 0 .and. el == abs(spin)) then
03386
03387 do eltmp = 0, abs(spin)
03388 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
03389 sqrt_tbl(0:2*eltmp+1))
03390 end do
03391 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
03392 el, signs(0:el))
03393 else
03394 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
03395 sqrt_tbl(0:2*el+1))
03396 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
03397 el, signs(0:el))
03398 end if
03399
03400
03401 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
03402 do m = -el, el
03403 call ssht_sampling_elm2ind(ind, el, m)
03404
03405 flm(ind) = flm(ind) + &
03406 ssign * elfactor &
03407 * exp(I*PION2*(m+spin)) &
03408 * dl(0,m) * dl(0,-spin) &
03409 * Fmm(m,0)
03410
03411 do mm = 1, el
03412 flm(ind) = flm(ind) + &
03413 ssign * elfactor &
03414 * exp(I*PION2*(m+spin)) &
03415 * dl(mm,m) * dl(mm,-spin) &
03416 * (Fmm(m,mm) + signs(abs(m)) * ssign * Fmm(m,-mm))
03417
03418 end do
03419 end do
03420 end do
03421
03422
03423 if (present(verbosity)) then
03424 if (verbosity > 0) then
03425 write(*,'(a,a)') SSHT_PROMPT, &
03426 'Forward transform computed!'
03427 end if
03428 end if
03429
03430 end subroutine ssht_core_gl_forward_sov_sym
03431
03432
03433
03434
03435
03453
03454 subroutine ssht_core_gl_forward_sov_sym_real(flm, f, L, verbosity)
03455
03456 integer, intent(in) :: L
03457 integer, intent(in), optional :: verbosity
03458 real(dp), intent(in) :: f(0:L-1 ,0:2*L-2)
03459 complex(dpc), intent(out) :: flm(0:L**2-1)
03460
03461 integer :: p, m, t, mm, el, ind
03462 real(dp) :: theta, phi
03463 real(dp) :: elfactor
03464 real(dp) :: w
03465 complex(dpc) :: fmt(0:L-1, 0:L-1)
03466 complex(dpc) :: Fmm(0:L-1, -(L-1):L-1)
03467 real(dp) :: dl(0:L-1, 0:L-1)
03468 integer*8 :: fftw_plan
03469
03470 integer :: spin
03471 real(dp) :: tmp(0:2*L-2)
03472 integer :: ind_nm
03473 character(len=STRING_LEN) :: format_spec
03474
03475 real(dp) :: thetas(0:L-1)
03476 real(dp) :: weights(0:L-1)
03477
03478 real(dp) :: signs(0:L), ssign
03479 real(dp) :: dl_mm_spin, dl_0_spin
03480 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
03481 integer :: eltmp
03482
03483
03484 do el = 0, 2*(L-1) + 1
03485 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
03486 end do
03487 do m = 0, L-1, 2
03488 signs(m) = 1.0_dp
03489 signs(m+1) = -1.0_dp
03490 enddo
03491
03492
03493 spin = 0
03494 ssign = signs(abs(spin))
03495
03496
03497 if (present(verbosity)) then
03498 if (verbosity > 0) then
03499 write(*,'(a,a)') SSHT_PROMPT, &
03500 'Computing forward transform using Gauss-Legendre sampling with'
03501 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', digit(spin),',a)'
03502 write(*,trim(format_spec)) SSHT_PROMPT, &
03503 'parameters (L,spin,reality) = (', &
03504 L, ',', spin, ',TRUE)...'
03505 end if
03506 if (verbosity > 1) then
03507 write(*,'(a,a)') SSHT_PROMPT, &
03508 'Using routine ssht_core_gl_forward_sov_sym_real...'
03509 end if
03510 end if
03511
03512
03513 call ssht_sampling_gl_thetas_weights(thetas, weights, L)
03514
03515
03516 call dfftw_plan_dft_r2c_1d(fftw_plan, 2*L-1, tmp(0:2*L-2), &
03517 fmt(0:L-1,0), FFTW_MEASURE)
03518 do t = 0, L-1
03519 call dfftw_execute_dft_r2c(fftw_plan, f(t,0:2*L-2), fmt(0:L-1,t))
03520 end do
03521 call dfftw_destroy_plan(fftw_plan)
03522 fmt(0:L-1, 0:L-1) = fmt(0:L-1, 0:L-1) &
03523 * 2d0*PI / (2d0*L-1d0)
03524
03525
03526 Fmm(0:L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03527 do t = 0, L-1
03528 theta = thetas(t)
03529 w = weights(t)
03530 do mm = -(L-1), L-1
03531 do m = 0, L-1
03532 Fmm(m,mm) = Fmm(m,mm) + &
03533 fmt(m,t) * exp(-I*mm*theta) * w
03534 end do
03535 end do
03536 end do
03537
03538
03539 flm(0::L**2-1) = cmplx(0d0, 0d0)
03540 do el = abs(spin), L-1
03541 if (el /= 0 .and. el == abs(spin)) then
03542
03543 do eltmp = 0, abs(spin)
03544 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
03545 sqrt_tbl(0:2*eltmp+1))
03546 end do
03547 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
03548 el, signs(0:el))
03549 else
03550 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
03551 sqrt_tbl(0:2*el+1))
03552 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
03553 el, signs(0:el))
03554 end if
03555
03556 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
03557 do m = 0, el
03558 call ssht_sampling_elm2ind(ind, el, m)
03559
03560 if (spin <= 0) then
03561 dl_0_spin = dl(0,-spin)
03562 else
03563 dl_0_spin = signs(el) * dl(0,spin)
03564 end if
03565
03566 flm(ind) = flm(ind) + &
03567 ssign * elfactor &
03568 * exp(I*PION2*(m+spin)) &
03569 * dl(0,m) * dl_0_spin &
03570 * Fmm(m,0)
03571
03572 do mm = 1, el
03573
03574 if (spin <= 0) then
03575 dl_mm_spin = dl(mm,-spin)
03576 else
03577 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
03578 end if
03579
03580 flm(ind) = flm(ind) + &
03581 ssign * elfactor &
03582 * exp(I*PION2*(m+spin)) &
03583 * dl(mm,m) * dl_mm_spin &
03584 * (Fmm(m,mm) + signs(m) * ssign * Fmm(m,-mm))
03585
03586 end do
03587 end do
03588 end do
03589
03590
03591 do el = abs(spin), L-1
03592 do m = 1, el
03593 call ssht_sampling_elm2ind(ind, el, m)
03594 call ssht_sampling_elm2ind(ind_nm, el, -m)
03595 flm(ind_nm) = signs(m) * conjg(flm(ind))
03596 end do
03597 end do
03598
03599
03600 if (present(verbosity)) then
03601 if (verbosity > 0) then
03602 write(*,'(a,a)') SSHT_PROMPT, &
03603 'Forward transform computed!'
03604 end if
03605 end if
03606
03607 end subroutine ssht_core_gl_forward_sov_sym_real
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03636
03637 subroutine ssht_core_mweo_forward_sov_direct(flm, f, L, spin, verbosity)
03638
03639 integer, intent(in) :: L
03640 integer, intent(in) :: spin
03641 integer, intent(in), optional :: verbosity
03642 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
03643 complex(dpc), intent(out) :: flm(0:L**2-1)
03644
03645 integer :: p, m, t, mm, el, ind, k
03646 real(dp) :: theta, phi
03647 real(dp) :: elfactor
03648
03649 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
03650 complex(dpc) :: fe(0:2*L-2 ,0:2*L-2)
03651 complex(dpc) :: fo(0:2*L-2 ,0:2*L-2)
03652 complex(dpc) :: Fmme(-(L-1):L-1, -(L-1):L-1)
03653 complex(dpc) :: Fmmo(-(L-1):L-1, -(L-1):L-1)
03654 complex(dpc) :: Gmme(-(L-1):L-1, -(L-1):L-1)
03655 complex(dpc) :: Gmmo(-(L-1):L-1, -(L-1):L-1)
03656 complex(dpc) :: Gmm_term
03657 character(len=STRING_LEN) :: format_spec
03658
03659
03660 if (present(verbosity)) then
03661 if (verbosity > 0) then
03662 write(*,'(a,a,a)') SSHT_PROMPT, &
03663 'Computing forward transform using McEwen and Wiaux', &
03664 ' even-odd sampling with'
03665 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
03666 digit(spin),',a)'
03667 write(*,trim(format_spec)) SSHT_PROMPT, &
03668 'parameters (L,spin,reality) = (', &
03669 L, ',', spin, ',FALSE)...'
03670 end if
03671 if (verbosity > 1) then
03672 write(*,'(a,a)') SSHT_PROMPT, &
03673 'Using routine ssht_core_mweo_forward_sov_direct...'
03674 end if
03675 end if
03676
03677
03678
03679 fe(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
03680 fe(L:2*L-2, 0:2*L-2) = f(L-2:0:-1, 0:2*L-2)
03681 fo(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
03682 fo(L:2*L-2, 0:2*L-2) = -f(L-2:0:-1, 0:2*L-2)
03683
03684
03685 Fmme(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03686 Fmmo(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03687 do p = 0, 2*L-2
03688 phi = ssht_sampling_mweo_p2phi(p, L)
03689 do t = 0, 2*L-2
03690 theta = ssht_sampling_mweo_t2theta(t, L)
03691 do m = -(L-1), L-1
03692 do mm = -(L-1), L-1
03693 Fmme(m,mm) = Fmme(m,mm) + &
03694 fe(t,p) * exp(-I*(m*phi + mm*theta))
03695 Fmmo(m,mm) = Fmmo(m,mm) + &
03696 fo(t,p) * exp(-I*(m*phi + mm*theta))
03697 end do
03698 end do
03699
03700 end do
03701 end do
03702 Fmme(-(L-1):L-1, -(L-1):L-1) = Fmme(-(L-1):L-1, -(L-1):L-1) &
03703 / (2d0*L-1d0)**2
03704 Fmmo(-(L-1):L-1, -(L-1):L-1) = Fmmo(-(L-1):L-1, -(L-1):L-1) &
03705 / (2d0*L-1d0)**2
03706
03707
03708
03709 Gmme(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03710 Gmmo(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03711 do m = -(L-1), L-1
03712 do mm = -(L-1), L-1
03713 do k = -(L-1), L-1
03714 Gmme(m,mm) = Gmme(m,mm) + &
03715 Fmme(m,k) * ssht_sampling_weight_mw(k - mm) * 2d0 * PI
03716 Gmmo(m,mm) = Gmmo(m,mm) + &
03717 Fmmo(m,k) *ssht_sampling_weight_mw(k - mm) * 2d0 * PI
03718 end do
03719 end do
03720 end do
03721
03722
03723 flm(0::L**2-1) = cmplx(0d0, 0d0)
03724 do el = abs(spin), L-1
03725 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
03726 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
03727 do m = -el, el
03728 call ssht_sampling_elm2ind(ind, el, m)
03729 do mm = -el, el
03730 if (mod(m+spin,2) == 0) then
03731
03732 Gmm_term = Gmme(m,mm)
03733 else
03734
03735 Gmm_term = Gmmo(m,mm)
03736 end if
03737
03738 flm(ind) = flm(ind) + &
03739 (-1)**spin * elfactor &
03740 * exp(I*PION2*(m+spin)) &
03741 * dl(mm,m) * dl(mm,-spin) &
03742 * Gmm_term
03743
03744 end do
03745 end do
03746 end do
03747
03748
03749 if (present(verbosity)) then
03750 if (verbosity > 0) then
03751 write(*,'(a,a)') SSHT_PROMPT, &
03752 'Forward transform computed!'
03753 end if
03754 end if
03755
03756 end subroutine ssht_core_mweo_forward_sov_direct
03757
03758
03759
03760
03761
03777
03778 subroutine ssht_core_mweo_forward_sov(flm, f, L, spin, verbosity)
03779
03780 integer, intent(in) :: L
03781 integer, intent(in) :: spin
03782 integer, intent(in), optional :: verbosity
03783 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
03784 complex(dpc), intent(out) :: flm(0:L**2-1)
03785
03786 integer :: p, m, t, mm, el, ind, k
03787 real(dp) :: theta, phi
03788 real(dp) :: elfactor
03789
03790 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
03791 complex(dpc) :: fe(0:2*L-2 ,0:2*L-2)
03792 complex(dpc) :: fo(0:2*L-2 ,0:2*L-2)
03793 complex(dpc) :: Fmme(-(L-1):L-1, -(L-1):L-1)
03794 complex(dpc) :: Fmmo(-(L-1):L-1, -(L-1):L-1)
03795 complex(dpc) :: Gmme(-(L-1):L-1, -(L-1):L-1)
03796 complex(dpc) :: Gmmo(-(L-1):L-1, -(L-1):L-1)
03797 complex(dpc) :: Gmm_term
03798 integer*8 :: fftw_plan
03799 character(len=STRING_LEN) :: format_spec
03800
03801
03802 if (present(verbosity)) then
03803 if (verbosity > 0) then
03804 write(*,'(a,a,a)') SSHT_PROMPT, &
03805 'Computing forward transform using McEwen and Wiaux', &
03806 ' even-odd sampling with'
03807 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
03808 digit(spin),',a)'
03809 write(*,trim(format_spec)) SSHT_PROMPT, &
03810 'parameters (L,spin,reality) = (', &
03811 L, ',', spin, ',FALSE)...'
03812 end if
03813 if (verbosity > 1) then
03814 write(*,'(a,a)') SSHT_PROMPT, &
03815 'Using routine ssht_core_mweo_forward_sov...'
03816 end if
03817 end if
03818
03819
03820
03821 fe(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
03822 fe(L:2*L-2, 0:2*L-2) = f(L-2:0:-1, 0:2*L-2)
03823 fo(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
03824 fo(L:2*L-2, 0:2*L-2) = -f(L-2:0:-1, 0:2*L-2)
03825
03826
03827
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837 call dfftw_plan_dft_2d(fftw_plan, 2*L-1, 2*L-1, fe(0:2*L-2,0:2*L-2), &
03838 fe(0:2*L-2,0:2*L-2), FFTW_FORWARD, FFTW_ESTIMATE)
03839 call dfftw_execute_dft(fftw_plan, fe(0:2*L-2,0:2*L-2), fe(0:2*L-2,0:2*L-2))
03840 call dfftw_execute_dft(fftw_plan, fo(0:2*L-2,0:2*L-2), fo(0:2*L-2,0:2*L-2))
03841 call dfftw_destroy_plan(fftw_plan)
03842
03843
03844
03845
03846
03847
03848 fe(0:2*L-2,0:2*L-2) = transpose(fe(0:2*L-2,0:2*L-2)) * exp(I*(L-1)*2d0*PI/(2d0*L-1d0))
03849 fo(0:2*L-2,0:2*L-2) = transpose(fo(0:2*L-2,0:2*L-2)) * exp(I*(L-1)*2d0*PI/(2d0*L-1d0))
03850 Fmme(0:L-1,0:L-1) = fe(0:L-1, 0:L-1)
03851 Fmme(-(L-1):-1,0:L-1) = fe(L:2*L-2, 0:L-1)
03852 Fmme(0:L-1,-(L-1):-1) = fe(0:L-1, L:2*L-2)
03853 Fmme(-(L-1):-1,-(L-1):-1) = fe(L:2*L-2, L:2*L-2)
03854 Fmmo(0:L-1,0:L-1) = fo(0:L-1, 0:L-1)
03855 Fmmo(-(L-1):-1,0:L-1) = fo(L:2*L-2, 0:L-1)
03856 Fmmo(0:L-1,-(L-1):-1) = fo(0:L-1, L:2*L-2)
03857 Fmmo(-(L-1):-1,-(L-1):-1) = fo(L:2*L-2, L:2*L-2)
03858
03859
03860 do m = 0, 2*L-2
03861 do mm = 0, 2*L-2
03862 Fmme(m-(L-1),mm-(L-1)) = Fmme(m-(L-1),mm-(L-1)) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
03863 Fmmo(m-(L-1),mm-(L-1)) = Fmmo(m-(L-1),mm-(L-1)) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
03864 end do
03865 end do
03866
03867 Fmme(-(L-1):L-1, -(L-1):L-1) = Fmme(-(L-1):L-1, -(L-1):L-1) &
03868 / (2d0*L-1d0)**2
03869 Fmmo(-(L-1):L-1, -(L-1):L-1) = Fmmo(-(L-1):L-1, -(L-1):L-1) &
03870 / (2d0*L-1d0)**2
03871
03872
03873
03874 Gmme(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03875 Gmmo(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
03876 do m = -(L-1), L-1
03877 do mm = -(L-1), L-1
03878 do k = -(L-1), L-1
03879 Gmme(m,mm) = Gmme(m,mm) + &
03880 Fmme(m,k) * ssht_sampling_weight_mw(k - mm) * 2d0 * PI
03881 Gmmo(m,mm) = Gmmo(m,mm) + &
03882 Fmmo(m,k) * ssht_sampling_weight_mw(k - mm) * 2d0 * PI
03883 end do
03884 end do
03885 end do
03886
03887
03888 flm(0::L**2-1) = cmplx(0d0, 0d0)
03889 do el = abs(spin), L-1
03890 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
03891 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
03892 do m = -el, el
03893 call ssht_sampling_elm2ind(ind, el, m)
03894 do mm = -el, el
03895 if (mod(m+spin,2) == 0) then
03896
03897 Gmm_term = Gmme(m,mm)
03898 else
03899
03900 Gmm_term = Gmmo(m,mm)
03901 end if
03902
03903 flm(ind) = flm(ind) + &
03904 (-1)**spin * elfactor &
03905 * exp(I*PION2*(m+spin)) &
03906 * dl(mm,m) * dl(mm,-spin) &
03907 * Gmm_term
03908
03909 end do
03910 end do
03911 end do
03912
03913
03914 if (present(verbosity)) then
03915 if (verbosity > 0) then
03916 write(*,'(a,a)') SSHT_PROMPT, &
03917 'Forward transform computed!'
03918 end if
03919 end if
03920
03921 end subroutine ssht_core_mweo_forward_sov
03922
03923
03924
03925
03926
03943
03944 subroutine ssht_core_mweo_forward_sov_conv(flm, f, L, spin, verbosity)
03945
03946 integer, intent(in) :: L
03947 integer, intent(in) :: spin
03948 integer, intent(in), optional :: verbosity
03949 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
03950 complex(dpc), intent(out) :: flm(0:L**2-1)
03951
03952 integer :: p, m, t, mm, el, ind, k
03953 real(dp) :: theta, phi
03954 real(dp) :: elfactor
03955
03956 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
03957 complex(dpc) :: fe(0:2*L-2 ,0:2*L-2)
03958 complex(dpc) :: fo(0:2*L-2 ,0:2*L-2)
03959 complex(dpc) :: Fmme(-(L-1):L-1, -(L-1):L-1)
03960 complex(dpc) :: Fmmo(-(L-1):L-1, -(L-1):L-1)
03961 complex(dpc) :: Gmme(-(L-1):L-1, -(L-1):L-1)
03962 complex(dpc) :: Gmmo(-(L-1):L-1, -(L-1):L-1)
03963 complex(dpc) :: Gmm_term
03964 integer*8 :: fftw_plan_fwd, fftw_plan_bwd
03965
03966 integer :: r
03967 complex(dpc) :: Fmme_pad(-2*(L-1):2*(L-1))
03968 complex(dpc) :: Fmmo_pad(-2*(L-1):2*(L-1))
03969 complex(dpc) :: w(-2*(L-1):2*(L-1))
03970 complex(dpc) :: wr(-2*(L-1):2*(L-1))
03971 character(len=STRING_LEN) :: format_spec
03972
03973
03974 if (present(verbosity)) then
03975 if (verbosity > 0) then
03976 write(*,'(a,a,a)') SSHT_PROMPT, &
03977 'Computing forward transform using McEwen and Wiaux', &
03978 ' even-odd sampling with'
03979 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
03980 digit(spin),',a)'
03981 write(*,trim(format_spec)) SSHT_PROMPT, &
03982 'parameters (L,spin,reality) = (', &
03983 L, ',', spin, ',FALSE)...'
03984 end if
03985 if (verbosity > 1) then
03986 write(*,'(a,a)') SSHT_PROMPT, &
03987 'Using routine ssht_core_mweo_forward_sov_conv...'
03988 end if
03989 end if
03990
03991
03992
03993 fe(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
03994 fe(L:2*L-2, 0:2*L-2) = f(L-2:0:-1, 0:2*L-2)
03995 fo(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
03996 fo(L:2*L-2, 0:2*L-2) = -f(L-2:0:-1, 0:2*L-2)
03997
03998
03999
04000
04001
04002
04003
04004
04005
04006
04007
04008
04009 call dfftw_plan_dft_2d(fftw_plan_fwd, 2*L-1, 2*L-1, fe(0:2*L-2,0:2*L-2), &
04010 fe(0:2*L-2,0:2*L-2), FFTW_FORWARD, FFTW_ESTIMATE)
04011 call dfftw_execute_dft(fftw_plan_fwd, fe(0:2*L-2,0:2*L-2), fe(0:2*L-2,0:2*L-2))
04012 call dfftw_execute_dft(fftw_plan_fwd, fo(0:2*L-2,0:2*L-2), fo(0:2*L-2,0:2*L-2))
04013 call dfftw_destroy_plan(fftw_plan_fwd)
04014
04015
04016
04017
04018
04019
04020 fe(0:2*L-2,0:2*L-2) = transpose(fe(0:2*L-2,0:2*L-2)) * exp(I*(L-1)*2d0*PI/(2d0*L-1d0))
04021 fo(0:2*L-2,0:2*L-2) = transpose(fo(0:2*L-2,0:2*L-2)) * exp(I*(L-1)*2d0*PI/(2d0*L-1d0))
04022 Fmme(0:L-1,0:L-1) = fe(0:L-1, 0:L-1)
04023 Fmme(-(L-1):-1,0:L-1) = fe(L:2*L-2, 0:L-1)
04024 Fmme(0:L-1,-(L-1):-1) = fe(0:L-1, L:2*L-2)
04025 Fmme(-(L-1):-1,-(L-1):-1) = fe(L:2*L-2, L:2*L-2)
04026 Fmmo(0:L-1,0:L-1) = fo(0:L-1, 0:L-1)
04027 Fmmo(-(L-1):-1,0:L-1) = fo(L:2*L-2, 0:L-1)
04028 Fmmo(0:L-1,-(L-1):-1) = fo(0:L-1, L:2*L-2)
04029 Fmmo(-(L-1):-1,-(L-1):-1) = fo(L:2*L-2, L:2*L-2)
04030
04031
04032 do m = 0, 2*L-2
04033 do mm = 0, 2*L-2
04034 Fmme(m-(L-1),mm-(L-1)) = Fmme(m-(L-1),mm-(L-1)) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
04035 Fmmo(m-(L-1),mm-(L-1)) = Fmmo(m-(L-1),mm-(L-1)) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
04036 end do
04037 end do
04038
04039 Fmme(-(L-1):L-1, -(L-1):L-1) = Fmme(-(L-1):L-1, -(L-1):L-1) &
04040 / (2d0*L-1d0)**2
04041 Fmmo(-(L-1):L-1, -(L-1):L-1) = Fmmo(-(L-1):L-1, -(L-1):L-1) &
04042 / (2d0*L-1d0)**2
04043
04044
04045 do mm = -2*(L-1), 2*(L-1)
04046 w(mm) = ssht_sampling_weight_mw(mm)
04047 end do
04048
04049
04050 wr(1:2*(L-1)) = w(-2*(L-1):-1)
04051 wr(-2*(L-1):0) = w(0:2*(L-1))
04052 w(-2*(L-1):2*(L-1)) = wr(-2*(L-1):2*(L-1))
04053 call dfftw_plan_dft_1d(fftw_plan_bwd, 4*L-3, wr(-2*(L-1):2*(L-1)), &
04054 wr(-2*(L-1):2*(L-1)), FFTW_BACKWARD, FFTW_MEASURE)
04055 call dfftw_execute_dft(fftw_plan_bwd, w(-2*(L-1):2*(L-1)), w(-2*(L-1):2*(L-1)))
04056 wr(0:2*(L-1)) = w(-2*(L-1):0)
04057 wr(-2*(L-1):-1) = w(1:2*(L-1))
04058
04059
04060 call dfftw_plan_dft_1d(fftw_plan_fwd, 4*L-3, w(-2*(L-1):2*(L-1)), &
04061 w(-2*(L-1):2*(L-1)), FFTW_FORWARD, FFTW_MEASURE)
04062
04063
04064
04065 do m = -(L-1), L-1
04066
04067
04068 Fmme_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
04069 Fmme_pad(-(L-1):L-1) = Fmme(m,-(L-1):L-1)
04070 Fmme_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
04071
04072
04073 Fmmo_pad(1:2*(L-1)) = Fmme_pad(-2*(L-1):-1)
04074 Fmmo_pad(-2*(L-1):0) = Fmme_pad(0:2*(L-1))
04075 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04076 call dfftw_execute_dft(fftw_plan_bwd, Fmme_pad(-2*(L-1):2*(L-1)), &
04077 Fmme_pad(-2*(L-1):2*(L-1)))
04078 Fmmo_pad(0:2*(L-1)) = Fmme_pad(-2*(L-1):0)
04079 Fmmo_pad(-2*(L-1):-1) = Fmme_pad(1:2*(L-1))
04080 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04081
04082
04083 do r = -2*(L-1), 2*(L-1)
04084 Fmme_pad(r) = Fmme_pad(r) * wr(-r)
04085 end do
04086
04087
04088 Fmmo_pad(1:2*(L-1)) = Fmme_pad(-2*(L-1):-1)
04089 Fmmo_pad(-2*(L-1):0) = Fmme_pad(0:2*(L-1))
04090 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04091 call dfftw_execute_dft(fftw_plan_fwd, Fmme_pad(-2*(L-1):2*(L-1)), &
04092 Fmme_pad(-2*(L-1):2*(L-1)))
04093 Fmmo_pad(0:2*(L-1)) = Fmme_pad(-2*(L-1):0)
04094 Fmmo_pad(-2*(L-1):-1) = Fmme_pad(1:2*(L-1))
04095 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04096
04097
04098 Gmme(m,-(L-1):(L-1)) = Fmme_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
04099
04100
04101
04102
04103 Fmmo_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
04104 Fmmo_pad(-(L-1):L-1) = Fmmo(m,-(L-1):L-1)
04105 Fmmo_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
04106
04107
04108 Fmme_pad(1:2*(L-1)) = Fmmo_pad(-2*(L-1):-1)
04109 Fmme_pad(-2*(L-1):0) = Fmmo_pad(0:2*(L-1))
04110 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04111 call dfftw_execute_dft(fftw_plan_bwd, Fmmo_pad(-2*(L-1):2*(L-1)), &
04112 Fmmo_pad(-2*(L-1):2*(L-1)))
04113 Fmme_pad(0:2*(L-1)) = Fmmo_pad(-2*(L-1):0)
04114 Fmme_pad(-2*(L-1):-1) = Fmmo_pad(1:2*(L-1))
04115 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04116
04117
04118 do r = -2*(L-1), 2*(L-1)
04119 Fmmo_pad(r) = Fmmo_pad(r) * wr(-r)
04120 end do
04121
04122
04123 Fmme_pad(1:2*(L-1)) = Fmmo_pad(-2*(L-1):-1)
04124 Fmme_pad(-2*(L-1):0) = Fmmo_pad(0:2*(L-1))
04125 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04126 call dfftw_execute_dft(fftw_plan_fwd, Fmmo_pad(-2*(L-1):2*(L-1)), &
04127 Fmmo_pad(-2*(L-1):2*(L-1)))
04128 Fmme_pad(0:2*(L-1)) = Fmmo_pad(-2*(L-1):0)
04129 Fmme_pad(-2*(L-1):-1) = Fmmo_pad(1:2*(L-1))
04130 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04131
04132
04133 Gmmo(m,-(L-1):(L-1)) = Fmmo_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
04134
04135 end do
04136 call dfftw_destroy_plan(fftw_plan_bwd)
04137 call dfftw_destroy_plan(fftw_plan_fwd)
04138
04139
04140 flm(0::L**2-1) = cmplx(0d0, 0d0)
04141 do el = abs(spin), L-1
04142 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
04143 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
04144 do m = -el, el
04145 call ssht_sampling_elm2ind(ind, el, m)
04146 do mm = -el, el
04147 if (mod(m+spin,2) == 0) then
04148
04149 Gmm_term = Gmme(m,mm)
04150 else
04151
04152 Gmm_term = Gmmo(m,mm)
04153 end if
04154
04155 flm(ind) = flm(ind) + &
04156 (-1)**spin * elfactor &
04157 * exp(I*PION2*(m+spin)) &
04158 * dl(mm,m) * dl(mm,-spin) &
04159 * Gmm_term
04160
04161 end do
04162 end do
04163 end do
04164
04165
04166 if (present(verbosity)) then
04167 if (verbosity > 0) then
04168 write(*,'(a,a)') SSHT_PROMPT, &
04169 'Forward transform computed!'
04170 end if
04171 end if
04172
04173 end subroutine ssht_core_mweo_forward_sov_conv
04174
04175
04176
04177
04178
04196
04197 subroutine ssht_core_mweo_forward_sov_conv_sym(flm, f, L, spin, verbosity)
04198
04199 integer, intent(in) :: L
04200 integer, intent(in) :: spin
04201 integer, intent(in), optional :: verbosity
04202 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
04203 complex(dpc), intent(out) :: flm(0:L**2-1)
04204
04205 integer :: p, m, t, mm, el, ind, k
04206 real(dp) :: theta, phi
04207 real(dp) :: elfactor
04208
04209 real(dp) :: dl(0:L-1, -(L-1):L-1)
04210 complex(dpc) :: fe(0:2*L-2 ,0:2*L-2)
04211 complex(dpc) :: fo(0:2*L-2 ,0:2*L-2)
04212 complex(dpc) :: Fmme(-(L-1):L-1, -(L-1):L-1)
04213 complex(dpc) :: Fmmo(-(L-1):L-1, -(L-1):L-1)
04214 complex(dpc) :: Gmme(-(L-1):L-1, -(L-1):L-1)
04215 complex(dpc) :: Gmmo(-(L-1):L-1, -(L-1):L-1)
04216 complex(dpc) :: Gmm_term
04217 integer*8 :: fftw_plan_fwd, fftw_plan_bwd
04218
04219 integer :: r
04220 complex(dpc) :: Fmme_pad(-2*(L-1):2*(L-1))
04221 complex(dpc) :: Fmmo_pad(-2*(L-1):2*(L-1))
04222 complex(dpc) :: w(-2*(L-1):2*(L-1))
04223 complex(dpc) :: wr(-2*(L-1):2*(L-1))
04224 character(len=STRING_LEN) :: format_spec
04225
04226 real(dp) :: signs(0:L), ssign
04227 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
04228 integer :: eltmp
04229
04230
04231 do el = 0, 2*(L-1) + 1
04232 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
04233 end do
04234 do m = 0, L-1, 2
04235 signs(m) = 1.0_dp
04236 signs(m+1) = -1.0_dp
04237 enddo
04238
04239
04240 ssign = signs(abs(spin))
04241
04242
04243 if (present(verbosity)) then
04244 if (verbosity > 0) then
04245 write(*,'(a,a,a)') SSHT_PROMPT, &
04246 'Computing forward transform using McEwen and Wiaux', &
04247 ' even-odd sampling with'
04248 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
04249 digit(spin),',a)'
04250 write(*,trim(format_spec)) SSHT_PROMPT, &
04251 'parameters (L,spin,reality) = (', &
04252 L, ',', spin, ',FALSE)...'
04253 end if
04254 if (verbosity > 1) then
04255 write(*,'(a,a)') SSHT_PROMPT, &
04256 'Using routine ssht_core_mweo_forward_sov_conv_sym...'
04257 end if
04258 end if
04259
04260
04261
04262 fe(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
04263 fe(L:2*L-2, 0:2*L-2) = f(L-2:0:-1, 0:2*L-2)
04264 fo(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
04265 fo(L:2*L-2, 0:2*L-2) = -f(L-2:0:-1, 0:2*L-2)
04266
04267
04268
04269
04270
04271
04272
04273
04274
04275
04276
04277
04278 call dfftw_plan_dft_2d(fftw_plan_fwd, 2*L-1, 2*L-1, fe(0:2*L-2,0:2*L-2), &
04279 fe(0:2*L-2,0:2*L-2), FFTW_FORWARD, FFTW_ESTIMATE)
04280 call dfftw_execute_dft(fftw_plan_fwd, fe(0:2*L-2,0:2*L-2), fe(0:2*L-2,0:2*L-2))
04281 call dfftw_execute_dft(fftw_plan_fwd, fo(0:2*L-2,0:2*L-2), fo(0:2*L-2,0:2*L-2))
04282 call dfftw_destroy_plan(fftw_plan_fwd)
04283
04284
04285
04286
04287
04288
04289 fe(0:2*L-2,0:2*L-2) = transpose(fe(0:2*L-2,0:2*L-2)) * exp(I*(L-1)*2d0*PI/(2d0*L-1d0))
04290 fo(0:2*L-2,0:2*L-2) = transpose(fo(0:2*L-2,0:2*L-2)) * exp(I*(L-1)*2d0*PI/(2d0*L-1d0))
04291 Fmme(0:L-1,0:L-1) = fe(0:L-1, 0:L-1)
04292 Fmme(-(L-1):-1,0:L-1) = fe(L:2*L-2, 0:L-1)
04293 Fmme(0:L-1,-(L-1):-1) = fe(0:L-1, L:2*L-2)
04294 Fmme(-(L-1):-1,-(L-1):-1) = fe(L:2*L-2, L:2*L-2)
04295 Fmmo(0:L-1,0:L-1) = fo(0:L-1, 0:L-1)
04296 Fmmo(-(L-1):-1,0:L-1) = fo(L:2*L-2, 0:L-1)
04297 Fmmo(0:L-1,-(L-1):-1) = fo(0:L-1, L:2*L-2)
04298 Fmmo(-(L-1):-1,-(L-1):-1) = fo(L:2*L-2, L:2*L-2)
04299
04300
04301 do mm = 0, 2*L-2
04302 do m = 0, 2*L-2
04303 Fmme(m-(L-1),mm-(L-1)) = Fmme(m-(L-1),mm-(L-1)) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
04304 Fmmo(m-(L-1),mm-(L-1)) = Fmmo(m-(L-1),mm-(L-1)) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
04305 end do
04306 end do
04307
04308 Fmme(-(L-1):L-1, -(L-1):L-1) = Fmme(-(L-1):L-1, -(L-1):L-1) &
04309 / (2d0*L-1d0)**2
04310 Fmmo(-(L-1):L-1, -(L-1):L-1) = Fmmo(-(L-1):L-1, -(L-1):L-1) &
04311 / (2d0*L-1d0)**2
04312
04313
04314 do mm = -2*(L-1), 2*(L-1)
04315 w(mm) = ssht_sampling_weight_mw(mm)
04316 end do
04317
04318
04319 wr(1:2*(L-1)) = w(-2*(L-1):-1)
04320 wr(-2*(L-1):0) = w(0:2*(L-1))
04321 w(-2*(L-1):2*(L-1)) = wr(-2*(L-1):2*(L-1))
04322 call dfftw_plan_dft_1d(fftw_plan_bwd, 4*L-3, wr(-2*(L-1):2*(L-1)), &
04323 wr(-2*(L-1):2*(L-1)), FFTW_BACKWARD, FFTW_MEASURE)
04324 call dfftw_execute_dft(fftw_plan_bwd, w(-2*(L-1):2*(L-1)), w(-2*(L-1):2*(L-1)))
04325 wr(0:2*(L-1)) = w(-2*(L-1):0)
04326 wr(-2*(L-1):-1) = w(1:2*(L-1))
04327
04328
04329 call dfftw_plan_dft_1d(fftw_plan_fwd, 4*L-3, w(-2*(L-1):2*(L-1)), &
04330 w(-2*(L-1):2*(L-1)), FFTW_FORWARD, FFTW_MEASURE)
04331
04332
04333
04334 do m = -(L-1), L-1
04335
04336
04337 Fmme_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
04338 Fmme_pad(-(L-1):L-1) = Fmme(m,-(L-1):L-1)
04339 Fmme_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
04340
04341
04342 Fmmo_pad(1:2*(L-1)) = Fmme_pad(-2*(L-1):-1)
04343 Fmmo_pad(-2*(L-1):0) = Fmme_pad(0:2*(L-1))
04344 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04345 call dfftw_execute_dft(fftw_plan_bwd, Fmme_pad(-2*(L-1):2*(L-1)), &
04346 Fmme_pad(-2*(L-1):2*(L-1)))
04347 Fmmo_pad(0:2*(L-1)) = Fmme_pad(-2*(L-1):0)
04348 Fmmo_pad(-2*(L-1):-1) = Fmme_pad(1:2*(L-1))
04349 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04350
04351
04352 do r = -2*(L-1), 2*(L-1)
04353 Fmme_pad(r) = Fmme_pad(r) * wr(-r)
04354 end do
04355
04356
04357 Fmmo_pad(1:2*(L-1)) = Fmme_pad(-2*(L-1):-1)
04358 Fmmo_pad(-2*(L-1):0) = Fmme_pad(0:2*(L-1))
04359 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04360 call dfftw_execute_dft(fftw_plan_fwd, Fmme_pad(-2*(L-1):2*(L-1)), &
04361 Fmme_pad(-2*(L-1):2*(L-1)))
04362 Fmmo_pad(0:2*(L-1)) = Fmme_pad(-2*(L-1):0)
04363 Fmmo_pad(-2*(L-1):-1) = Fmme_pad(1:2*(L-1))
04364 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04365
04366
04367 Gmme(m,-(L-1):(L-1)) = Fmme_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
04368
04369
04370
04371
04372 Fmmo_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
04373 Fmmo_pad(-(L-1):L-1) = Fmmo(m,-(L-1):L-1)
04374 Fmmo_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
04375
04376
04377 Fmme_pad(1:2*(L-1)) = Fmmo_pad(-2*(L-1):-1)
04378 Fmme_pad(-2*(L-1):0) = Fmmo_pad(0:2*(L-1))
04379 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04380 call dfftw_execute_dft(fftw_plan_bwd, Fmmo_pad(-2*(L-1):2*(L-1)), &
04381 Fmmo_pad(-2*(L-1):2*(L-1)))
04382 Fmme_pad(0:2*(L-1)) = Fmmo_pad(-2*(L-1):0)
04383 Fmme_pad(-2*(L-1):-1) = Fmmo_pad(1:2*(L-1))
04384 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04385
04386
04387 do r = -2*(L-1), 2*(L-1)
04388 Fmmo_pad(r) = Fmmo_pad(r) * wr(-r)
04389 end do
04390
04391
04392 Fmme_pad(1:2*(L-1)) = Fmmo_pad(-2*(L-1):-1)
04393 Fmme_pad(-2*(L-1):0) = Fmmo_pad(0:2*(L-1))
04394 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04395 call dfftw_execute_dft(fftw_plan_fwd, Fmmo_pad(-2*(L-1):2*(L-1)), &
04396 Fmmo_pad(-2*(L-1):2*(L-1)))
04397 Fmme_pad(0:2*(L-1)) = Fmmo_pad(-2*(L-1):0)
04398 Fmme_pad(-2*(L-1):-1) = Fmmo_pad(1:2*(L-1))
04399 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04400
04401
04402 Gmmo(m,-(L-1):(L-1)) = Fmmo_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
04403
04404 end do
04405 call dfftw_destroy_plan(fftw_plan_bwd)
04406 call dfftw_destroy_plan(fftw_plan_fwd)
04407
04408
04409 flm(0::L**2-1) = cmplx(0d0, 0d0)
04410 do el = abs(spin), L-1
04411 if (el /= 0 .and. el == abs(spin)) then
04412
04413 do eltmp = 0, abs(spin)
04414 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
04415 sqrt_tbl(0:2*eltmp+1))
04416 end do
04417 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
04418 el, signs(0:el))
04419 else
04420 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
04421 sqrt_tbl(0:2*el+1))
04422 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
04423 el, signs(0:el))
04424 end if
04425
04426 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
04427 do m = -el, el
04428 call ssht_sampling_elm2ind(ind, el, m)
04429
04430 flm(ind) = flm(ind) + &
04431 ssign * elfactor &
04432 * exp(I*PION2*(m+spin)) &
04433 * dl(0,m) * dl(0,-spin) &
04434 * Gmme(m,0)
04435
04436 do mm = 1, el
04437 if (mod(m+spin,2) == 0) then
04438
04439 Gmm_term = Gmme(m,mm) + signs(abs(m)) * ssign * Gmme(m,-mm)
04440 else
04441
04442 Gmm_term = Gmmo(m,mm) + signs(abs(m)) * ssign * Gmmo(m,-mm)
04443 end if
04444
04445 flm(ind) = flm(ind) + &
04446 ssign * elfactor &
04447 * exp(I*PION2*(m+spin)) &
04448 * dl(mm,m) * dl(mm,-spin) &
04449 * Gmm_term
04450
04451 end do
04452 end do
04453 end do
04454
04455
04456 if (present(verbosity)) then
04457 if (verbosity > 0) then
04458 write(*,'(a,a)') SSHT_PROMPT, &
04459 'Forward transform computed!'
04460 end if
04461 end if
04462
04463 end subroutine ssht_core_mweo_forward_sov_conv_sym
04464
04465
04466
04467
04468
04487
04488 subroutine ssht_core_mweo_forward_sov_conv_sym_real(flm, f, L, verbosity)
04489
04490 integer, intent(in) :: L
04491 integer, intent(in), optional :: verbosity
04492 real(dp), intent(in) :: f(0:L-1 ,0:2*L-2)
04493 complex(dpc), intent(out) :: flm(0:L**2-1)
04494
04495 integer :: p, m, t, mm, el, ind, k
04496 real(dp) :: theta, phi
04497 real(dp) :: elfactor
04498
04499 real(dp) :: dl(0:L-1, 0:L-1)
04500 real(dp) :: fe(0:2*L-2 ,0:2*L-2)
04501 real(dp) :: fo(0:2*L-2 ,0:2*L-2)
04502 complex(dpc) :: Fmme(0:L-1, -(L-1):L-1)
04503 complex(dpc) :: Fmmo(0:L-1, -(L-1):L-1)
04504 complex(dpc) :: Gmme(0:L-1, -(L-1):L-1)
04505 complex(dpc) :: Gmmo(0:L-1, -(L-1):L-1)
04506 complex(dpc) :: Gmm_term
04507 integer*8 :: fftw_plan_fwd, fftw_plan_bwd
04508
04509 integer :: r
04510 complex(dpc) :: Fmme_pad(-2*(L-1):2*(L-1))
04511 complex(dpc) :: Fmmo_pad(-2*(L-1):2*(L-1))
04512 complex(dpc) :: w(-2*(L-1):2*(L-1))
04513 complex(dpc) :: wr(-2*(L-1):2*(L-1))
04514
04515 integer :: ind_nm
04516 integer :: spin
04517 complex(dpc) :: tmp(0:L-1,0:2*L-2)
04518 character(len=STRING_LEN) :: format_spec
04519
04520 real(dp) :: signs(0:L), ssign
04521 real(dp) :: dl_mm_spin, dl_0_spin
04522 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
04523 integer :: eltmp
04524
04525
04526 do el = 0, 2*(L-1) + 1
04527 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
04528 end do
04529 do m = 0, L-1, 2
04530 signs(m) = 1.0_dp
04531 signs(m+1) = -1.0_dp
04532 enddo
04533
04534
04535 spin = 0
04536 ssign = signs(abs(spin))
04537
04538
04539 if (present(verbosity)) then
04540 if (verbosity > 0) then
04541 write(*,'(a,a,a)') SSHT_PROMPT, &
04542 'Computing forward transform using McEwen and Wiaux', &
04543 ' even-odd sampling with'
04544 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
04545 digit(spin),',a)'
04546 write(*,trim(format_spec)) SSHT_PROMPT, &
04547 'parameters (L,spin,reality) = (', &
04548 L, ',', spin, ',TRUE)...'
04549 end if
04550 if (verbosity > 1) then
04551 write(*,'(a,a)') SSHT_PROMPT, &
04552 'Using routine ssht_core_mweo_forward_sov_conv_sym_real...'
04553 end if
04554 end if
04555
04556
04557
04558
04559
04560 call dfftw_plan_dft_r2c_2d(fftw_plan_fwd, 2*L-1, 2*L-1, fe(0:2*L-2,0:2*L-2), &
04561 tmp(0:L-1,0:2*L-2), FFTW_ESTIMATE)
04562
04563 fe(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
04564 fe(L:2*L-2, 0:2*L-2) = f(L-2:0:-1, 0:2*L-2)
04565 call dfftw_execute_dft_r2c(fftw_plan_fwd, &
04566 transpose(fe(0:2*L-2,0:2*L-2)), tmp(0:L-1,0:2*L-2))
04567 Fmme(0:L-1,0:L-1) = tmp(0:L-1, 0:L-1)
04568 Fmme(0:L-1,-(L-1):-1) = tmp(0:L-1, L:2*L-2)
04569
04570 fo(0:L-1, 0:2*L-2) = f(0:L-1, 0:2*L-2)
04571 fo(L:2*L-2, 0:2*L-2) = -f(L-2:0:-1, 0:2*L-2)
04572 call dfftw_execute_dft_r2c(fftw_plan_fwd, &
04573 transpose(fo(0:2*L-2,0:2*L-2)), tmp(0:L-1,0:2*L-2))
04574 Fmmo(0:L-1,0:L-1) = tmp(0:L-1, 0:L-1)
04575 Fmmo(0:L-1,-(L-1):-1) = tmp(0:L-1, L:2*L-2)
04576
04577 call dfftw_destroy_plan(fftw_plan_fwd)
04578
04579 Fmme(0:L-1, -(L-1):L-1) = Fmme(0:L-1, -(L-1):L-1) &
04580 / (2d0*L-1d0)**2
04581 Fmmo(0:L-1, -(L-1):L-1) = Fmmo(0:L-1, -(L-1):L-1) &
04582 / (2d0*L-1d0)**2
04583
04584
04585
04586 do mm = -(L-1), L-1
04587 do m = 0, L-1
04588 Fmme(m,mm) = Fmme(m,mm) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
04589 Fmmo(m,mm) = Fmmo(m,mm) * exp(-I*(m+mm)*PI/(2d0*L-1d0))
04590 end do
04591 end do
04592
04593
04594 do mm = -2*(L-1), 2*(L-1)
04595 w(mm) = ssht_sampling_weight_mw(mm)
04596 end do
04597
04598
04599 wr(1:2*(L-1)) = w(-2*(L-1):-1)
04600 wr(-2*(L-1):0) = w(0:2*(L-1))
04601 w(-2*(L-1):2*(L-1)) = wr(-2*(L-1):2*(L-1))
04602 call dfftw_plan_dft_1d(fftw_plan_bwd, 4*L-3, wr(-2*(L-1):2*(L-1)), &
04603 wr(-2*(L-1):2*(L-1)), FFTW_BACKWARD, FFTW_MEASURE)
04604 call dfftw_execute_dft(fftw_plan_bwd, w(-2*(L-1):2*(L-1)), w(-2*(L-1):2*(L-1)))
04605 wr(0:2*(L-1)) = w(-2*(L-1):0)
04606 wr(-2*(L-1):-1) = w(1:2*(L-1))
04607
04608
04609 call dfftw_plan_dft_1d(fftw_plan_fwd, 4*L-3, w(-2*(L-1):2*(L-1)), &
04610 w(-2*(L-1):2*(L-1)), FFTW_FORWARD, FFTW_MEASURE)
04611
04612
04613
04614 do m = 0, L-1
04615
04616
04617 Fmme_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
04618 Fmme_pad(-(L-1):L-1) = Fmme(m,-(L-1):L-1)
04619 Fmme_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
04620
04621
04622 Fmmo_pad(1:2*(L-1)) = Fmme_pad(-2*(L-1):-1)
04623 Fmmo_pad(-2*(L-1):0) = Fmme_pad(0:2*(L-1))
04624 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04625 call dfftw_execute_dft(fftw_plan_bwd, Fmme_pad(-2*(L-1):2*(L-1)), &
04626 Fmme_pad(-2*(L-1):2*(L-1)))
04627 Fmmo_pad(0:2*(L-1)) = Fmme_pad(-2*(L-1):0)
04628 Fmmo_pad(-2*(L-1):-1) = Fmme_pad(1:2*(L-1))
04629 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04630
04631
04632 do r = -2*(L-1), 2*(L-1)
04633 Fmme_pad(r) = Fmme_pad(r) * wr(-r)
04634 end do
04635
04636
04637 Fmmo_pad(1:2*(L-1)) = Fmme_pad(-2*(L-1):-1)
04638 Fmmo_pad(-2*(L-1):0) = Fmme_pad(0:2*(L-1))
04639 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04640 call dfftw_execute_dft(fftw_plan_fwd, Fmme_pad(-2*(L-1):2*(L-1)), &
04641 Fmme_pad(-2*(L-1):2*(L-1)))
04642 Fmmo_pad(0:2*(L-1)) = Fmme_pad(-2*(L-1):0)
04643 Fmmo_pad(-2*(L-1):-1) = Fmme_pad(1:2*(L-1))
04644 Fmme_pad(-2*(L-1):2*(L-1)) = Fmmo_pad(-2*(L-1):2*(L-1))
04645
04646
04647 Gmme(m,-(L-1):(L-1)) = Fmme_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
04648
04649
04650
04651
04652 Fmmo_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
04653 Fmmo_pad(-(L-1):L-1) = Fmmo(m,-(L-1):L-1)
04654 Fmmo_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
04655
04656
04657 Fmme_pad(1:2*(L-1)) = Fmmo_pad(-2*(L-1):-1)
04658 Fmme_pad(-2*(L-1):0) = Fmmo_pad(0:2*(L-1))
04659 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04660 call dfftw_execute_dft(fftw_plan_bwd, Fmmo_pad(-2*(L-1):2*(L-1)), &
04661 Fmmo_pad(-2*(L-1):2*(L-1)))
04662 Fmme_pad(0:2*(L-1)) = Fmmo_pad(-2*(L-1):0)
04663 Fmme_pad(-2*(L-1):-1) = Fmmo_pad(1:2*(L-1))
04664 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04665
04666
04667 do r = -2*(L-1), 2*(L-1)
04668 Fmmo_pad(r) = Fmmo_pad(r) * wr(-r)
04669 end do
04670
04671
04672 Fmme_pad(1:2*(L-1)) = Fmmo_pad(-2*(L-1):-1)
04673 Fmme_pad(-2*(L-1):0) = Fmmo_pad(0:2*(L-1))
04674 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04675 call dfftw_execute_dft(fftw_plan_fwd, Fmmo_pad(-2*(L-1):2*(L-1)), &
04676 Fmmo_pad(-2*(L-1):2*(L-1)))
04677 Fmme_pad(0:2*(L-1)) = Fmmo_pad(-2*(L-1):0)
04678 Fmme_pad(-2*(L-1):-1) = Fmmo_pad(1:2*(L-1))
04679 Fmmo_pad(-2*(L-1):2*(L-1)) = Fmme_pad(-2*(L-1):2*(L-1))
04680
04681
04682 Gmmo(m,-(L-1):(L-1)) = Fmmo_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
04683
04684 end do
04685 call dfftw_destroy_plan(fftw_plan_bwd)
04686 call dfftw_destroy_plan(fftw_plan_fwd)
04687
04688
04689 flm(0::L**2-1) = cmplx(0d0, 0d0)
04690 do el = abs(spin), L-1
04691 if (el /= 0 .and. el == abs(spin)) then
04692
04693 do eltmp = 0, abs(spin)
04694 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
04695 sqrt_tbl(0:2*eltmp+1))
04696 end do
04697 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
04698 el, signs(0:el))
04699 else
04700 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
04701 sqrt_tbl(0:2*el+1))
04702 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
04703 el, signs(0:el))
04704 end if
04705
04706 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
04707 do m = 0, el
04708 call ssht_sampling_elm2ind(ind, el, m)
04709
04710 if (spin <= 0) then
04711 dl_0_spin = dl(0,-spin)
04712 else
04713 dl_0_spin = signs(el) * dl(0,spin)
04714 end if
04715
04716 flm(ind) = flm(ind) + &
04717 ssign * elfactor &
04718 * exp(I*PION2*(m+spin)) &
04719 * dl(0,m) * dl_0_spin &
04720 * Gmme(m,0)
04721
04722 do mm = 1, el
04723 if (mod(m+spin,2) == 0) then
04724
04725 Gmm_term = Gmme(m,mm) + signs(m) * ssign * Gmme(m,-mm)
04726 else
04727
04728 Gmm_term = Gmmo(m,mm) + signs(m) * ssign * Gmmo(m,-mm)
04729 end if
04730
04731 if (spin <= 0) then
04732 dl_mm_spin = dl(mm,-spin)
04733 else
04734 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
04735 end if
04736
04737 flm(ind) = flm(ind) + &
04738 ssign * elfactor &
04739 * exp(I*PION2*(m+spin)) &
04740 * dl(mm,m) * dl_mm_spin &
04741 * Gmm_term
04742
04743 end do
04744 end do
04745 end do
04746
04747
04748 do el = abs(spin), L-1
04749 do m = 1, el
04750 call ssht_sampling_elm2ind(ind, el, m)
04751 call ssht_sampling_elm2ind(ind_nm, el, -m)
04752 flm(ind_nm) = signs(m) * conjg(flm(ind))
04753 end do
04754 end do
04755
04756
04757 if (present(verbosity)) then
04758 if (verbosity > 0) then
04759 write(*,'(a,a)') SSHT_PROMPT, &
04760 'Forward transform computed!'
04761 end if
04762 end if
04763
04764 end subroutine ssht_core_mweo_forward_sov_conv_sym_real
04765
04766
04767
04768
04769
04770
04771
04772
04773
04774
04793
04794 subroutine ssht_core_mw_forward_sov_direct(flm, f, L, spin, verbosity)
04795
04796 integer, intent(in) :: L
04797 integer, intent(in) :: spin
04798 integer, intent(in), optional :: verbosity
04799 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
04800 complex(dpc), intent(out) :: flm(0:L**2-1)
04801
04802 integer :: p, m, t, mm, el, ind, k
04803 real(dp) :: theta, phi
04804 real(dp) :: elfactor
04805
04806 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
04807 complex(dpc) :: Fmt(-(L-1):L-1, 0:2*L-2)
04808 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
04809 complex(dpc) :: Gmm(-(L-1):L-1, -(L-1):L-1)
04810 character(len=STRING_LEN) :: format_spec
04811
04812
04813 if (present(verbosity)) then
04814 if (verbosity > 0) then
04815 write(*,'(a,a,a)') SSHT_PROMPT, &
04816 'Computing forward transform using McEwen and Wiaux', &
04817 ' sampling with'
04818 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
04819 digit(spin),',a)'
04820 write(*,trim(format_spec)) SSHT_PROMPT, &
04821 'parameters (L,spin,reality) = (', &
04822 L, ',', spin, ',FALSE)...'
04823 end if
04824 if (verbosity > 1) then
04825 write(*,'(a,a)') SSHT_PROMPT, &
04826 'Using routine ssht_core_mw_forward_sov_direct...'
04827 end if
04828 end if
04829
04830
04831 Fmt(-(L-1):L-1,0:2*L-2) = cmplx(0d0, 0d0)
04832 do p = 0, 2*L-2
04833 phi = ssht_sampling_mw_p2phi(p, L)
04834 do t = 0, L-1
04835 do m = -(L-1), L-1
04836 Fmt(m,t) = Fmt(m,t) + &
04837 f(t,p) * exp(-I*m*phi)
04838 end do
04839 end do
04840 end do
04841 Fmt(-(L-1):L-1,0:2*L-2) = Fmt(-(L-1):L-1,0:2*L-2) / (2d0*L-1d0)
04842
04843
04844 do m = -(L-1), L-1
04845 Fmt(m, L:2*L-2) = (-1)**(m+spin) * Fmt(m, L-2:0:-1)
04846 end do
04847
04848
04849 Fmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
04850 do t = 0, 2*L-2
04851 theta = ssht_sampling_mw_t2theta(t, L)
04852 do m = -(L-1), L-1
04853 do mm = -(L-1), L-1
04854 Fmm(m,mm) = Fmm(m,mm) + &
04855 Fmt(m,t) * exp(-I*mm*theta)
04856 end do
04857 end do
04858 end do
04859 Fmm(-(L-1):L-1, -(L-1):L-1) = Fmm(-(L-1):L-1, -(L-1):L-1) / (2d0*L-1d0)
04860
04861
04862 Gmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
04863 do m = -(L-1), L-1
04864 do mm = -(L-1), L-1
04865 do k = -(L-1), L-1
04866 Gmm(m,mm) = Gmm(m,mm) + &
04867 Fmm(m,k) * ssht_sampling_weight_mw(k - mm) * 2d0 * PI
04868 end do
04869 end do
04870 end do
04871
04872
04873 flm(0::L**2-1) = cmplx(0d0, 0d0)
04874 do el = abs(spin), L-1
04875 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
04876 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
04877 do m = -el, el
04878 call ssht_sampling_elm2ind(ind, el, m)
04879 do mm = -el, el
04880 flm(ind) = flm(ind) + &
04881 (-1)**spin * elfactor &
04882 * exp(I*PION2*(m+spin)) &
04883 * dl(mm,m) * dl(mm,-spin) &
04884 * Gmm(m,mm)
04885 end do
04886 end do
04887 end do
04888
04889
04890 if (present(verbosity)) then
04891 if (verbosity > 0) then
04892 write(*,'(a,a)') SSHT_PROMPT, &
04893 'Forward transform computed!'
04894 end if
04895 end if
04896
04897 end subroutine ssht_core_mw_forward_sov_direct
04898
04899
04900
04901
04902
04918
04919 subroutine ssht_core_mw_forward_sov(flm, f, L, spin, verbosity)
04920
04921 integer, intent(in) :: L
04922 integer, intent(in) :: spin
04923 integer, intent(in), optional :: verbosity
04924 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
04925 complex(dpc), intent(out) :: flm(0:L**2-1)
04926
04927 integer :: p, m, t, mm, el, ind, k
04928 real(dp) :: theta, phi
04929 real(dp) :: elfactor
04930
04931 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
04932 complex(dpc) :: Fmt(-(L-1):L-1, 0:2*L-2)
04933 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
04934 complex(dpc) :: Gmm(-(L-1):L-1, -(L-1):L-1)
04935 integer*8 :: fftw_plan
04936 complex(dpc) :: tmp(0:2*L-2)
04937 character(len=STRING_LEN) :: format_spec
04938
04939
04940 if (present(verbosity)) then
04941 if (verbosity > 0) then
04942 write(*,'(a,a,a)') SSHT_PROMPT, &
04943 'Computing forward transform using McEwen and Wiaux', &
04944 ' sampling with'
04945 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
04946 digit(spin),',a)'
04947 write(*,trim(format_spec)) SSHT_PROMPT, &
04948 'parameters (L,spin,reality) = (', &
04949 L, ',', spin, ',FALSE)...'
04950 end if
04951 if (verbosity > 1) then
04952 write(*,'(a,a)') SSHT_PROMPT, &
04953 'Using routine ssht_core_mw_forward_sov...'
04954 end if
04955 end if
04956
04957
04958 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, Fmt(-(L-1):L-1,0), &
04959 Fmt(-(L-1):L-1,0), FFTW_FORWARD, FFTW_MEASURE)
04960 do t = 0, L-1
04961 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), tmp(0:2*L-2))
04962 Fmt(0:L-1,t) = tmp(0:L-1)
04963 Fmt(-(L-1):-1,t) = tmp(L:2*L-2)
04964 end do
04965
04966 Fmt(-(L-1):L-1, 0:L-1) = Fmt(-(L-1):L-1, 0:L-1) / (2d0*L-1d0)
04967
04968
04969 do m = -(L-1), L-1
04970 Fmt(m, L:2*L-2) = (-1)**(m+spin) * Fmt(m, L-2:0:-1)
04971 end do
04972
04973
04974 do m = -(L-1), L-1
04975 call dfftw_execute_dft(fftw_plan, Fmt(m,0:2*L-2), tmp(0:2*L-2))
04976 Fmm(m,0:L-1) = tmp(0:L-1)
04977 Fmm(m,-(L-1):-1) = tmp(L:2*L-2)
04978 end do
04979 Fmm(-(L-1):L-1, -(L-1):L-1) = Fmm(-(L-1):L-1, -(L-1):L-1) / (2d0*L-1d0)
04980 call dfftw_destroy_plan(fftw_plan)
04981
04982
04983 do mm = -(L-1), L-1
04984 Fmm(-(L-1):L-1,mm) = Fmm(-(L-1):L-1, mm) * exp(-I*mm*PI/(2d0*L - 1d0))
04985 end do
04986
04987
04988 Gmm(-(L-1):L-1, -(L-1):L-1) = cmplx(0d0, 0d0)
04989 do m = -(L-1), L-1
04990 do mm = -(L-1), L-1
04991 do k = -(L-1), L-1
04992 Gmm(m,mm) = Gmm(m,mm) + &
04993 Fmm(m,k) * ssht_sampling_weight_mw(k - mm) * 2d0 * PI
04994 end do
04995 end do
04996 end do
04997
04998
04999 flm(0::L**2-1) = cmplx(0d0, 0d0)
05000 do el = abs(spin), L-1
05001 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
05002 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
05003 do m = -el, el
05004 call ssht_sampling_elm2ind(ind, el, m)
05005 do mm = -el, el
05006 flm(ind) = flm(ind) + &
05007 (-1)**spin * elfactor &
05008 * exp(I*PION2*(m+spin)) &
05009 * dl(mm,m) * dl(mm,-spin) &
05010 * Gmm(m,mm)
05011 end do
05012 end do
05013 end do
05014
05015
05016 if (present(verbosity)) then
05017 if (verbosity > 0) then
05018 write(*,'(a,a)') SSHT_PROMPT, &
05019 'Forward transform computed!'
05020 end if
05021 end if
05022
05023 end subroutine ssht_core_mw_forward_sov
05024
05025
05026
05027
05028
05045
05046 subroutine ssht_core_mw_forward_sov_conv(flm, f, L, spin, verbosity)
05047
05048 integer, intent(in) :: L
05049 integer, intent(in) :: spin
05050 integer, intent(in), optional :: verbosity
05051 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
05052 complex(dpc), intent(out) :: flm(0:L**2-1)
05053
05054 integer :: p, m, t, mm, el, ind, k
05055 real(dp) :: theta, phi
05056 real(dp) :: elfactor
05057
05058 real(dp) :: dl(-(L-1):L-1, -(L-1):L-1)
05059 complex(dpc) :: Fmt(-(L-1):L-1, 0:2*L-2)
05060 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
05061 complex(dpc) :: Gmm(-(L-1):L-1, -(L-1):L-1)
05062 integer*8 :: fftw_plan
05063 complex(dpc) :: tmp(0:2*L-2)
05064
05065 integer :: r
05066 complex(dpc) :: Fmm_pad(-2*(L-1):2*(L-1))
05067 complex(dpc) :: tmp_pad(-2*(L-1):2*(L-1))
05068 complex(dpc) :: w(-2*(L-1):2*(L-1))
05069 complex(dpc) :: wr(-2*(L-1):2*(L-1))
05070 integer*8 :: fftw_plan_fwd, fftw_plan_bwd
05071 character(len=STRING_LEN) :: format_spec
05072
05073
05074 if (present(verbosity)) then
05075 if (verbosity > 0) then
05076 write(*,'(a,a,a)') SSHT_PROMPT, &
05077 'Computing forward transform using McEwen and Wiaux', &
05078 ' sampling with'
05079 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
05080 digit(spin),',a)'
05081 write(*,trim(format_spec)) SSHT_PROMPT, &
05082 'parameters (L,spin,reality) = (', &
05083 L, ',', spin, ',FALSE)...'
05084 end if
05085 if (verbosity > 1) then
05086 write(*,'(a,a)') SSHT_PROMPT, &
05087 'Using routine ssht_core_mw_forward_sov_conv...'
05088 end if
05089 end if
05090
05091
05092 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, Fmt(-(L-1):L-1,0), &
05093 Fmt(-(L-1):L-1,0), FFTW_FORWARD, FFTW_MEASURE)
05094 do t = 0, L-1
05095 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), tmp(0:2*L-2))
05096 Fmt(0:L-1,t) = tmp(0:L-1)
05097 Fmt(-(L-1):-1,t) = tmp(L:2*L-2)
05098 end do
05099 Fmt(-(L-1):L-1, 0:L-1) = Fmt(-(L-1):L-1, 0:L-1) / (2d0*L-1d0)
05100
05101
05102 do m = -(L-1), L-1
05103 Fmt(m, L:2*L-2) = (-1)**(m+spin) * Fmt(m, L-2:0:-1)
05104 end do
05105
05106
05107 do m = -(L-1), L-1
05108 call dfftw_execute_dft(fftw_plan, Fmt(m,0:2*L-2), tmp(0:2*L-2))
05109 Fmm(m,0:L-1) = tmp(0:L-1)
05110 Fmm(m,-(L-1):-1) = tmp(L:2*L-2)
05111 end do
05112 Fmm(-(L-1):L-1, -(L-1):L-1) = Fmm(-(L-1):L-1, -(L-1):L-1) / (2d0*L-1d0)
05113 call dfftw_destroy_plan(fftw_plan)
05114
05115
05116 do mm = -(L-1), L-1
05117 Fmm(-(L-1):L-1,mm) = Fmm(-(L-1):L-1, mm) * exp(-I*mm*PI/(2d0*L - 1d0))
05118 end do
05119
05120
05121 do mm = -2*(L-1), 2*(L-1)
05122 w(mm) = ssht_sampling_weight_mw(mm)
05123 end do
05124
05125
05126 wr(1:2*(L-1)) = w(-2*(L-1):-1)
05127 wr(-2*(L-1):0) = w(0:2*(L-1))
05128 w(-2*(L-1):2*(L-1)) = wr(-2*(L-1):2*(L-1))
05129 call dfftw_plan_dft_1d(fftw_plan_bwd, 4*L-3, wr(-2*(L-1):2*(L-1)), &
05130 wr(-2*(L-1):2*(L-1)), FFTW_BACKWARD, FFTW_MEASURE)
05131 call dfftw_execute_dft(fftw_plan_bwd, w(-2*(L-1):2*(L-1)), w(-2*(L-1):2*(L-1)))
05132 wr(0:2*(L-1)) = w(-2*(L-1):0)
05133 wr(-2*(L-1):-1) = w(1:2*(L-1))
05134
05135
05136 call dfftw_plan_dft_1d(fftw_plan_fwd, 4*L-3, w(-2*(L-1):2*(L-1)), &
05137 w(-2*(L-1):2*(L-1)), FFTW_FORWARD, FFTW_MEASURE)
05138
05139
05140 do m = -(L-1), L-1
05141
05142
05143 Fmm_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
05144 Fmm_pad(-(L-1):L-1) = Fmm(m,-(L-1):L-1)
05145 Fmm_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
05146
05147
05148 tmp_pad(1:2*(L-1)) = Fmm_pad(-2*(L-1):-1)
05149 tmp_pad(-2*(L-1):0) = Fmm_pad(0:2*(L-1))
05150 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05151 call dfftw_execute_dft(fftw_plan_bwd, Fmm_pad(-2*(L-1):2*(L-1)), &
05152 Fmm_pad(-2*(L-1):2*(L-1)))
05153 tmp_pad(0:2*(L-1)) = Fmm_pad(-2*(L-1):0)
05154 tmp_pad(-2*(L-1):-1) = Fmm_pad(1:2*(L-1))
05155 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05156
05157
05158 do r = -2*(L-1), 2*(L-1)
05159 Fmm_pad(r) = Fmm_pad(r) * wr(-r)
05160 end do
05161
05162
05163 tmp_pad(1:2*(L-1)) = Fmm_pad(-2*(L-1):-1)
05164 tmp_pad(-2*(L-1):0) = Fmm_pad(0:2*(L-1))
05165 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05166 call dfftw_execute_dft(fftw_plan_fwd, Fmm_pad(-2*(L-1):2*(L-1)), &
05167 Fmm_pad(-2*(L-1):2*(L-1)))
05168 tmp_pad(0:2*(L-1)) = Fmm_pad(-2*(L-1):0)
05169 tmp_pad(-2*(L-1):-1) = Fmm_pad(1:2*(L-1))
05170 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05171
05172
05173 Gmm(m,-(L-1):(L-1)) = Fmm_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
05174
05175 end do
05176 call dfftw_destroy_plan(fftw_plan_bwd)
05177 call dfftw_destroy_plan(fftw_plan_fwd)
05178
05179
05180 flm(0::L**2-1) = cmplx(0d0, 0d0)
05181 do el = abs(spin), L-1
05182 call ssht_dl_beta_operator(dl(-el:el,-el:el), PION2, el)
05183 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
05184 do m = -el, el
05185 call ssht_sampling_elm2ind(ind, el, m)
05186 do mm = -el, el
05187 flm(ind) = flm(ind) + &
05188 (-1)**spin * elfactor &
05189 * exp(I*PION2*(m+spin)) &
05190 * dl(mm,m) * dl(mm,-spin) &
05191 * Gmm(m,mm)
05192 end do
05193 end do
05194 end do
05195
05196
05197 if (present(verbosity)) then
05198 if (verbosity > 0) then
05199 write(*,'(a,a)') SSHT_PROMPT, &
05200 'Forward transform computed!'
05201 end if
05202 end if
05203
05204 end subroutine ssht_core_mw_forward_sov_conv
05205
05206
05207
05208
05209
05227
05228 subroutine ssht_core_mw_forward_sov_conv_sym(flm, f, L, spin, verbosity)
05229
05230 integer, intent(in) :: L
05231 integer, intent(in) :: spin
05232 integer, intent(in), optional :: verbosity
05233 complex(dpc), intent(in) :: f(0:L-1 ,0:2*L-2)
05234 complex(dpc), intent(out) :: flm(0:L**2-1)
05235
05236 integer :: p, m, t, mm, el, ind, k
05237 real(dp) :: theta, phi
05238 real(dp) :: elfactor
05239
05240 real(dp) :: dl(0:L-1, -(L-1):L-1)
05241 complex(dpc) :: Fmt(-(L-1):L-1, 0:2*L-2)
05242 complex(dpc) :: Fmm(-(L-1):L-1, -(L-1):L-1)
05243 complex(dpc) :: Gmm(-(L-1):L-1, -(L-1):L-1)
05244 integer*8 :: fftw_plan
05245 complex(dpc) :: tmp(0:2*L-2)
05246
05247 integer :: r
05248 complex(dpc) :: Fmm_pad(-2*(L-1):2*(L-1))
05249 complex(dpc) :: tmp_pad(-2*(L-1):2*(L-1))
05250 complex(dpc) :: w(-2*(L-1):2*(L-1))
05251 complex(dpc) :: wr(-2*(L-1):2*(L-1))
05252 integer*8 :: fftw_plan_fwd, fftw_plan_bwd
05253 character(len=STRING_LEN) :: format_spec
05254
05255 real(dp) :: signs(0:L), ssign
05256 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
05257 integer :: eltmp
05258
05259
05260 do el = 0, 2*(L-1) + 1
05261 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
05262 end do
05263 do m = 0, L-1, 2
05264 signs(m) = 1.0_dp
05265 signs(m+1) = -1.0_dp
05266 enddo
05267
05268
05269 ssign = signs(abs(spin))
05270
05271
05272 if (present(verbosity)) then
05273 if (verbosity > 0) then
05274 write(*,'(a,a,a)') SSHT_PROMPT, &
05275 'Computing forward transform using McEwen and Wiaux', &
05276 ' sampling with'
05277 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
05278 digit(spin),',a)'
05279 write(*,trim(format_spec)) SSHT_PROMPT, &
05280 'parameters (L,spin,reality) = (', &
05281 L, ',', spin, ',FALSE)...'
05282 end if
05283 if (verbosity > 1) then
05284 write(*,'(a,a)') SSHT_PROMPT, &
05285 'Using routine ssht_core_mw_forward_sov_conv_sym...'
05286 end if
05287 end if
05288
05289
05290 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, Fmt(-(L-1):L-1,0), &
05291 Fmt(-(L-1):L-1,0), FFTW_FORWARD, FFTW_MEASURE)
05292 do t = 0, L-1
05293 call dfftw_execute_dft(fftw_plan, f(t,0:2*L-2), tmp(0:2*L-2))
05294 Fmt(0:L-1,t) = tmp(0:L-1)
05295 Fmt(-(L-1):-1,t) = tmp(L:2*L-2)
05296 end do
05297 Fmt(-(L-1):L-1, 0:L-1) = Fmt(-(L-1):L-1, 0:L-1) / (2d0*L-1d0)
05298
05299
05300 do m = -(L-1), L-1
05301 Fmt(m, L:2*L-2) = signs(abs(m)) * ssign * Fmt(m, L-2:0:-1)
05302 end do
05303
05304
05305 do m = -(L-1), L-1
05306 call dfftw_execute_dft(fftw_plan, Fmt(m,0:2*L-2), tmp(0:2*L-2))
05307 Fmm(m,0:L-1) = tmp(0:L-1)
05308 Fmm(m,-(L-1):-1) = tmp(L:2*L-2)
05309 end do
05310 Fmm(-(L-1):L-1, -(L-1):L-1) = Fmm(-(L-1):L-1, -(L-1):L-1) / (2d0*L-1d0)
05311 call dfftw_destroy_plan(fftw_plan)
05312
05313
05314 do mm = -(L-1), L-1
05315 Fmm(-(L-1):L-1,mm) = Fmm(-(L-1):L-1, mm) * exp(-I*mm*PI/(2d0*L - 1d0))
05316 end do
05317
05318
05319 do mm = -2*(L-1), 2*(L-1)
05320 w(mm) = ssht_sampling_weight_mw(mm)
05321 end do
05322
05323
05324 wr(1:2*(L-1)) = w(-2*(L-1):-1)
05325 wr(-2*(L-1):0) = w(0:2*(L-1))
05326 w(-2*(L-1):2*(L-1)) = wr(-2*(L-1):2*(L-1))
05327 call dfftw_plan_dft_1d(fftw_plan_bwd, 4*L-3, wr(-2*(L-1):2*(L-1)), &
05328 wr(-2*(L-1):2*(L-1)), FFTW_BACKWARD, FFTW_MEASURE)
05329 call dfftw_execute_dft(fftw_plan_bwd, w(-2*(L-1):2*(L-1)), w(-2*(L-1):2*(L-1)))
05330 wr(0:2*(L-1)) = w(-2*(L-1):0)
05331 wr(-2*(L-1):-1) = w(1:2*(L-1))
05332
05333
05334 call dfftw_plan_dft_1d(fftw_plan_fwd, 4*L-3, w(-2*(L-1):2*(L-1)), &
05335 w(-2*(L-1):2*(L-1)), FFTW_FORWARD, FFTW_MEASURE)
05336
05337
05338 do m = -(L-1), L-1
05339
05340
05341 Fmm_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
05342 Fmm_pad(-(L-1):L-1) = Fmm(m,-(L-1):L-1)
05343 Fmm_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
05344
05345
05346 tmp_pad(1:2*(L-1)) = Fmm_pad(-2*(L-1):-1)
05347 tmp_pad(-2*(L-1):0) = Fmm_pad(0:2*(L-1))
05348 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05349 call dfftw_execute_dft(fftw_plan_bwd, Fmm_pad(-2*(L-1):2*(L-1)), &
05350 Fmm_pad(-2*(L-1):2*(L-1)))
05351 tmp_pad(0:2*(L-1)) = Fmm_pad(-2*(L-1):0)
05352 tmp_pad(-2*(L-1):-1) = Fmm_pad(1:2*(L-1))
05353 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05354
05355
05356 do r = -2*(L-1), 2*(L-1)
05357 Fmm_pad(r) = Fmm_pad(r) * wr(-r)
05358 end do
05359
05360
05361 tmp_pad(1:2*(L-1)) = Fmm_pad(-2*(L-1):-1)
05362 tmp_pad(-2*(L-1):0) = Fmm_pad(0:2*(L-1))
05363 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05364 call dfftw_execute_dft(fftw_plan_fwd, Fmm_pad(-2*(L-1):2*(L-1)), &
05365 Fmm_pad(-2*(L-1):2*(L-1)))
05366 tmp_pad(0:2*(L-1)) = Fmm_pad(-2*(L-1):0)
05367 tmp_pad(-2*(L-1):-1) = Fmm_pad(1:2*(L-1))
05368 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05369
05370
05371 Gmm(m,-(L-1):(L-1)) = Fmm_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
05372
05373 end do
05374 call dfftw_destroy_plan(fftw_plan_bwd)
05375 call dfftw_destroy_plan(fftw_plan_fwd)
05376
05377
05378 flm(0::L**2-1) = cmplx(0d0, 0d0)
05379 do el = abs(spin), L-1
05380 if (el /= 0 .and. el == abs(spin)) then
05381
05382 do eltmp = 0, abs(spin)
05383 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
05384 sqrt_tbl(0:2*eltmp+1))
05385 end do
05386 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
05387 el, signs(0:el))
05388 else
05389 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
05390 sqrt_tbl(0:2*el+1))
05391 call ssht_dl_halfpi_trapani_fill_eighth2righthalf_table(dl(0:el,-el:el), &
05392 el, signs(0:el))
05393 end if
05394
05395 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
05396 do m = -el, el
05397 call ssht_sampling_elm2ind(ind, el, m)
05398
05399 flm(ind) = flm(ind) + &
05400 ssign * elfactor &
05401 * exp(I*PION2*(m+spin)) &
05402 * dl(0,m) * dl(0,-spin) &
05403 * Gmm(m,0)
05404
05405 do mm = 1, el
05406 flm(ind) = flm(ind) + &
05407 ssign * elfactor &
05408 * exp(I*PION2*(m+spin)) &
05409 * dl(mm,m) * dl(mm,-spin) &
05410 * (Gmm(m,mm) + signs(abs(m)) * ssign * Gmm(m,-mm))
05411 end do
05412 end do
05413 end do
05414
05415
05416 if (present(verbosity)) then
05417 if (verbosity > 0) then
05418 write(*,'(a,a)') SSHT_PROMPT, &
05419 'Forward transform computed!'
05420 end if
05421 end if
05422
05423 end subroutine ssht_core_mw_forward_sov_conv_sym
05424
05425
05426
05427
05428
05447
05448 subroutine ssht_core_mw_forward_sov_conv_sym_real(flm, f, L, verbosity)
05449
05450 integer, intent(in) :: L
05451 integer, intent(in), optional :: verbosity
05452 real(dp), intent(in) :: f(0:L-1 ,0:2*L-2)
05453 complex(dpc), intent(out) :: flm(0:L**2-1)
05454
05455 integer :: p, m, t, mm, el, ind, k
05456 real(dp) :: theta, phi
05457 real(dp) :: elfactor
05458
05459 real(dp) :: dl(0:L-1, 0:L-1)
05460 complex(dpc) :: Fmt(0:L-1, 0:2*L-2)
05461 complex(dpc) :: Fmm(0:L-1, -(L-1):L-1)
05462 complex(dpc) :: Gmm(0:L-1, -(L-1):L-1)
05463 integer*8 :: fftw_plan
05464 complex(dpc) :: tmp(0:2*L-2)
05465
05466 integer :: r
05467 complex(dpc) :: Fmm_pad(-2*(L-1):2*(L-1))
05468 complex(dpc) :: tmp_pad(-2*(L-1):2*(L-1))
05469 complex(dpc) :: w(-2*(L-1):2*(L-1))
05470 complex(dpc) :: wr(-2*(L-1):2*(L-1))
05471 integer*8 :: fftw_plan_fwd, fftw_plan_bwd
05472
05473 real(dp) :: tmpr(0:2*L-2)
05474 integer :: ind_nm
05475 integer :: spin
05476 character(len=STRING_LEN) :: format_spec
05477
05478 real(dp) :: signs(0:L), ssign
05479 real(dp) :: dl_mm_spin, dl_0_spin
05480 real(dp) :: sqrt_tbl(0:2*(L-1)+1)
05481 integer :: eltmp
05482
05483
05484 do el = 0, 2*(L-1) + 1
05485 sqrt_tbl(el) = dsqrt(real(el,kind=dp))
05486 end do
05487 do m = 0, L-1, 2
05488 signs(m) = 1.0_dp
05489 signs(m+1) = -1.0_dp
05490 enddo
05491
05492
05493 spin = 0
05494 ssign = signs(abs(spin))
05495
05496
05497 if (present(verbosity)) then
05498 if (verbosity > 0) then
05499 write(*,'(a,a,a)') SSHT_PROMPT, &
05500 'Computing forward transform using McEwen and Wiaux', &
05501 ' sampling with'
05502 write(format_spec,'(a,i20,a,i20,a)') '(a,a,i', digit(L),',a,i', &
05503 digit(spin),',a)'
05504 write(*,trim(format_spec)) SSHT_PROMPT, &
05505 'parameters (L,spin,reality) = (', &
05506 L, ',', spin, ',TRUE)...'
05507 end if
05508 if (verbosity > 1) then
05509 write(*,'(a,a)') SSHT_PROMPT, &
05510 'Using routine ssht_core_mw_forward_sov_conv_sym_real...'
05511 end if
05512 end if
05513
05514
05515 call dfftw_plan_dft_r2c_1d(fftw_plan, 2*L-1, tmpr(0:2*L-2), &
05516 Fmt(0:L-1,0), FFTW_MEASURE)
05517 do t = 0, L-1
05518 call dfftw_execute_dft_r2c(fftw_plan, f(t,0:2*L-2), tmp(0:L-1))
05519 Fmt(0:L-1,t) = tmp(0:L-1)
05520 end do
05521 call dfftw_destroy_plan(fftw_plan)
05522 Fmt(0:L-1, 0:L-1) = Fmt(0:L-1, 0:L-1) / (2d0*L-1d0)
05523
05524
05525
05526
05527
05528 do t = L, 2*L-2
05529 Fmt(0:L-1, t) = ssign * signs(0:L-1) * Fmt(0:L-1, 2*L-2-t)
05530 end do
05531
05532
05533 call dfftw_plan_dft_1d(fftw_plan, 2*L-1, tmp(0:2*L-2), &
05534 tmp(0:2*L-2), FFTW_FORWARD, FFTW_MEASURE)
05535 do m = 0, L-1
05536 call dfftw_execute_dft(fftw_plan, Fmt(m,0:2*L-2), tmp(0:2*L-2))
05537 Fmm(m,0:L-1) = tmp(0:L-1)
05538 Fmm(m,-(L-1):-1) = tmp(L:2*L-2)
05539 end do
05540 Fmm(0:L-1, -(L-1):L-1) = Fmm(0:L-1, -(L-1):L-1) / (2d0*L-1d0)
05541 call dfftw_destroy_plan(fftw_plan)
05542
05543
05544 do mm = -(L-1), L-1
05545 Fmm(0:L-1,mm) = Fmm(0:L-1, mm) * exp(-I*mm*PI/(2d0*L - 1d0))
05546 end do
05547
05548
05549 do mm = -2*(L-1), 2*(L-1)
05550 w(mm) = ssht_sampling_weight_mw(mm)
05551 end do
05552
05553
05554 wr(1:2*(L-1)) = w(-2*(L-1):-1)
05555 wr(-2*(L-1):0) = w(0:2*(L-1))
05556 w(-2*(L-1):2*(L-1)) = wr(-2*(L-1):2*(L-1))
05557 call dfftw_plan_dft_1d(fftw_plan_bwd, 4*L-3, wr(-2*(L-1):2*(L-1)), &
05558 wr(-2*(L-1):2*(L-1)), FFTW_BACKWARD, FFTW_MEASURE)
05559 call dfftw_execute_dft(fftw_plan_bwd, w(-2*(L-1):2*(L-1)), w(-2*(L-1):2*(L-1)))
05560 wr(0:2*(L-1)) = w(-2*(L-1):0)
05561 wr(-2*(L-1):-1) = w(1:2*(L-1))
05562
05563
05564 call dfftw_plan_dft_1d(fftw_plan_fwd, 4*L-3, w(-2*(L-1):2*(L-1)), &
05565 w(-2*(L-1):2*(L-1)), FFTW_FORWARD, FFTW_MEASURE)
05566
05567
05568 do m = 0, L-1
05569
05570
05571 Fmm_pad(-2*(L-1):-L) = cmplx(0d0, 0d0)
05572 Fmm_pad(-(L-1):L-1) = Fmm(m,-(L-1):L-1)
05573 Fmm_pad(L:2*(L-1)) = cmplx(0d0, 0d0)
05574
05575
05576 tmp_pad(1:2*(L-1)) = Fmm_pad(-2*(L-1):-1)
05577 tmp_pad(-2*(L-1):0) = Fmm_pad(0:2*(L-1))
05578 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05579 call dfftw_execute_dft(fftw_plan_bwd, Fmm_pad(-2*(L-1):2*(L-1)), &
05580 Fmm_pad(-2*(L-1):2*(L-1)))
05581 tmp_pad(0:2*(L-1)) = Fmm_pad(-2*(L-1):0)
05582 tmp_pad(-2*(L-1):-1) = Fmm_pad(1:2*(L-1))
05583 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05584
05585
05586
05587
05588
05589 Fmm_pad(-2*(L-1):2*(L-1)) = Fmm_pad(-2*(L-1):2*(L-1)) * wr(2*(L-1):-2*(L-1):-1)
05590
05591
05592 tmp_pad(1:2*(L-1)) = Fmm_pad(-2*(L-1):-1)
05593 tmp_pad(-2*(L-1):0) = Fmm_pad(0:2*(L-1))
05594 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05595 call dfftw_execute_dft(fftw_plan_fwd, Fmm_pad(-2*(L-1):2*(L-1)), &
05596 Fmm_pad(-2*(L-1):2*(L-1)))
05597 tmp_pad(0:2*(L-1)) = Fmm_pad(-2*(L-1):0)
05598 tmp_pad(-2*(L-1):-1) = Fmm_pad(1:2*(L-1))
05599 Fmm_pad(-2*(L-1):2*(L-1)) = tmp_pad(-2*(L-1):2*(L-1))
05600
05601
05602 Gmm(m,-(L-1):(L-1)) = Fmm_pad(-(L-1):(L-1)) * 2d0 * PI / (4d0*L-3d0)
05603
05604 end do
05605 call dfftw_destroy_plan(fftw_plan_bwd)
05606 call dfftw_destroy_plan(fftw_plan_fwd)
05607
05608
05609 flm(0::L**2-1) = cmplx(0d0, 0d0)
05610 do el = abs(spin), L-1
05611 if (el /= 0 .and. el == abs(spin)) then
05612
05613 do eltmp = 0, abs(spin)
05614 call ssht_dl_halfpi_trapani_eighth_table(dl(0:eltmp,0:eltmp), eltmp, &
05615 sqrt_tbl(0:2*eltmp+1))
05616 end do
05617 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
05618 el, signs(0:el))
05619 else
05620 call ssht_dl_halfpi_trapani_eighth_table(dl(0:el,0:el), el, &
05621 sqrt_tbl(0:2*el+1))
05622 call ssht_dl_halfpi_trapani_fill_eighth2quarter_table(dl(0:el,0:el), &
05623 el, signs(0:el))
05624 end if
05625
05626 elfactor = sqrt((2d0*el+1d0)/(4d0*PI))
05627 do m = 0, el
05628 call ssht_sampling_elm2ind(ind, el, m)
05629
05630 if (spin <= 0) then
05631 dl_0_spin = dl(0,-spin)
05632 else
05633 dl_0_spin = signs(el) * dl(0,spin)
05634 end if
05635
05636 flm(ind) = flm(ind) + &
05637 ssign * elfactor &
05638 * exp(I*PION2*(m+spin)) &
05639
05640 * dl(0,m) * dl_0_spin &
05641 * Gmm(m,0)
05642
05643 do mm = 1, el
05644
05645 if (spin <= 0) then
05646 dl_mm_spin = dl(mm,-spin)
05647 else
05648 dl_mm_spin = signs(el) * signs(mm) * dl(mm,spin)
05649 end if
05650
05651 flm(ind) = flm(ind) + &
05652 ssign * elfactor &
05653 * exp(I*PION2*(m+spin)) &
05654
05655 * dl(mm,m) * dl_mm_spin &
05656 * (Gmm(m,mm) + ssign * signs(m) * Gmm(m,-mm))
05657 end do
05658 end do
05659 end do
05660
05661
05662 do el = abs(spin), L-1
05663 do m = 1, el
05664 call ssht_sampling_elm2ind(ind, el, m)
05665 call ssht_sampling_elm2ind(ind_nm, el, -m)
05666 flm(ind_nm) = signs(m) * conjg(flm(ind))
05667 end do
05668 end do
05669
05670
05671 if (present(verbosity)) then
05672 if (verbosity > 0) then
05673 write(*,'(a,a)') SSHT_PROMPT, &
05674 'Forward transform computed!'
05675 end if
05676 end if
05677
05678 end subroutine ssht_core_mw_forward_sov_conv_sym_real
05679
05680
05681
05682
05683
05684
05685
05686
05687
05688
05689
05702
05703 function digit(L) result(d)
05704
05705 integer, intent(in) :: L
05706 integer :: d
05707
05708 if(L/10 < 1) then
05709 d = 1
05710 elseif(L/100 < 1) then
05711 d = 2
05712 elseif(L/1000 < 1) then
05713 d = 3
05714 elseif(L/10000 < 1) then
05715 d = 4
05716 elseif(L/100000 < 1) then
05717 d = 5
05718 else
05719 d = 25
05720 end if
05721
05722 end function digit
05723
05724
05725 end module ssht_core_mod