Skip to content

Commit 9b89bb3

Browse files
committed
Implement Limber approximation
1 parent 20a5e5e commit 9b89bb3

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

docs/src/comparison.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,14 @@ plot_compare(l, l, Dl1[:, 2], Dl2[:, 2], "l", "Dₗ(TE)"; tol = 3e-14)
417417
plot_compare(l, l, Dl1[:, 3], Dl2[:, 3], "l", "Dₗ(EE)"; tol = 6e-15)
418418
```
419419
```@example class
420-
Dl2 = Dl_symboltz([:ψψ], l, pars; Nlos = 8196)
420+
Dl2 = Dl_symboltz([:ψψ], l, pars; Nlos = 8196) # do not use Limber approximation
421421
plot_compare(l, l, Dl1[:, 4], Dl2[:, 1], "l", "Dₗ(ψψ)"; lgx = true, lgy = true, tol = 2e-12)
422422
```
423423
```@example class
424+
Dl2 = Dl_symboltz([:ψψ], l, pars; l_limber = 0) # use Limber approximation for all l
425+
plot_compare(l, l, Dl1[:, 4], Dl2[:, 1], "l", "Dₗ(ψψ)"; lgx = true, lgy = true, tol = 9e-11)
426+
```
427+
```@example class
424428
diffpars = [M.c.Ω₀, M.b.Ω₀, M.g.h]
425429
θ = [pars[par] for par in diffpars]
426430
modes = [:TT, :TE, :EE]

src/observables/angular.jl

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ ChainRulesCore.frule((_, _, Δx), ::typeof(jl_x2), l, x) = jl_x2(l, x), jl_x2′
5555
# TODO: use u = k*χ as integration variable, so oscillations of Bessel functions are the same for every k?
5656
# TODO: define and document symbolic dispatch!
5757
"""
58-
los_integrate(Ss::AbstractMatrix{T}, ls::AbstractVector, τs::AbstractVector, ks::AbstractVector, Rl::Function; integrator = TrapezoidalRule(), verbose = false) where {T <: Real}
58+
los_integrate(Ss::AbstractMatrix{T}, ls::AbstractVector, τs::AbstractVector, ks::AbstractVector, Rl::Function; l_limber = typemax(Int), integrator = TrapezoidalRule(), verbose = false) where {T <: Real}
5959
6060
For the given `ls` and `ks`, compute the line-of-sight-integrals
6161
```math
@@ -64,7 +64,7 @@ Iₗ(k) = ∫dτ S(k,τ) Rₗ(k(τ₀-τ))
6464
over the source function values `Ss` against the radial functions `Rl` (e.g. the spherical Bessel functions ``jₗ(x)``).
6565
The element `Ss[i,j]` holds the source function value ``S(kᵢ, τⱼ)``.
6666
"""
67-
function los_integrate(Ss::AbstractMatrix{T}, ls::AbstractVector, τs::AbstractVector, ks::AbstractVector, Rl::Function = jl; integrator = TrapezoidalRule(), verbose = false) where {T <: Real}
67+
function los_integrate(Ss::AbstractMatrix{T}, ls::AbstractVector, τs::AbstractVector, ks::AbstractVector, Rl::Function = jl; l_limber = typemax(Int), integrator = TrapezoidalRule(), verbose = false) where {T <: Real}
6868
# Julia is column-major; make sure innermost loop indices appear first in slice expressions (https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-column-major)
6969
@assert size(Ss) == (length(τs), length(ks)) "size(Ss) = $(size(Ss))$((length(τs), length(ks)))"
7070
τs = collect(τs) # force array to avoid floating point errors with ranges in following χs due to (e.g. tiny negative χ)
@@ -80,13 +80,30 @@ function los_integrate(Ss::AbstractMatrix{T}, ls::AbstractVector, τs::AbstractV
8080
verbose && print("\rLOS integrating with l = $l")
8181
for ik in eachindex(ks)
8282
k = ks[ik]
83-
forin eachindex(τs)
84-
S = Ss[iτ,ik]
85-
χ = χs[iτ]
86-
= k * χ
87-
∂I_∂τ[iτ] = S * Rl(l, kχ) # TODO: rewrite LOS integral to avoid evaluating Rl with dual numbers? # TODO: rewrite LOS integral with y = kτ0 and x=τ/τ0 to cache jls independent of cosmology
83+
if l l_limber
84+
χ = (l+1/2) / k
85+
if χ > χs[1]
86+
# χ > χini > χrec, so source function is definitely zero
87+
S = 0.0
88+
else
89+
# interpolate between two closest points in saved array
90+
iχ₋ = searchsortedfirst(χs, χ; rev = true)
91+
iχ₊ = iχ₋ - 1
92+
χ₋, χ₊ = χs[iχ₋], χs[iχ₊] # now χ₋ < χ < χ₊
93+
S₋, S₊ = Ss[iχ₋,ik], Ss[iχ₊,ik]
94+
S = S₋ + (S₊-S₋) *-χ₋) / (χ₊-χ₋)
95+
end
96+
I = /(2l+1)) * S / k
97+
else
98+
forin eachindex(τs)
99+
S = Ss[iτ,ik]
100+
χ = χs[iτ]
101+
= k * χ
102+
∂I_∂τ[iτ] = S * Rl(l, kχ) # TODO: rewrite LOS integral to avoid evaluating Rl with dual numbers? # TODO: rewrite LOS integral with y = kτ0 and x=τ/τ0 to cache jls independent of cosmology
103+
end
104+
I = integrate(τs, ∂I_∂τ; integrator) # integrate over τ # TODO: add starting I(τini) to fix small l?
88105
end
89-
Is[ik,il] = integrate(τs, ∂I_∂τ; integrator) # integrate over τ # TODO: add starting I(τini) to fix small l?
106+
Is[ik,il] = I
90107
end
91108
end
92109
verbose && println()

0 commit comments

Comments
 (0)