Skip to content

Commit e2b7c59

Browse files
Merge pull request #15 from MikaelSlevinsky/start-hierarchical
Support Spherical Harmonics
2 parents c8899f5 + 2a85d5c commit e2b7c59

20 files changed

+1923
-29
lines changed

README.md

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,56 @@
22

33
[![Build Status](https://travis-ci.org/MikaelSlevinsky/FastTransforms.jl.svg?branch=master)](https://travis-ci.org/MikaelSlevinsky/FastTransforms.jl) [![](https://img.shields.io/badge/docs-stable-blue.svg)](https://MikaelSlevinsky.github.io/FastTransforms.jl/stable) [![](https://img.shields.io/badge/docs-latest-blue.svg)](https://MikaelSlevinsky.github.io/FastTransforms.jl/latest)
44

5-
The aim of this package is to provide new classes of fast transforms with low
6-
pre-computation. One approach is based on the use of asymptotic formulae to
7-
relate the transforms to a small number of fast Fourier transforms. Another
8-
approach is based on a Toeplitz-dot-Hankel decomposition of the matrix of
9-
connection coefficients. Both new classes of fast transforms do not
10-
require large pre-computation for fast execution and they are designed
11-
to work on expansions of functions with any degree of regularity.
12-
13-
The Chebyshev—Jacobi transform and its inverse are implemented. This
14-
allows the fast conversion of Chebyshev expansion coefficients to Jacobi expansion
15-
coefficients and back.
5+
The aim of this package is to provide fast orthogonal polynomial transforms that are designed for expansions of functions with any degree of regularity. There are multiple approaches to the classical connection problem, though the user does not need to know the specifics.
6+
7+
One approach is based on the use of asymptotic formulae to relate the transforms to a small number of fast Fourier transforms. Another approach is based on a Toeplitz-dot-Hankel decomposition of the matrix of connection coefficients. Alternatively, the matrix of connection coefficients may be decomposed hierarchically à la Fast Multipole Method.
8+
9+
## The Chebyshev—Legendre Transform
10+
11+
The Chebyshev—Legendre transform allows the fast conversion of Chebyshev expansion coefficients to Legendre expansion coefficients and back.
12+
1613
```julia
1714
julia> Pkg.add("FastTransforms")
1815

1916
julia> using FastTransforms
2017

2118
julia> c = rand(10001);
2219

20+
julia> leg2cheb(c);
21+
22+
julia> cheb2leg(c);
23+
24+
julia> norm(cheb2leg(leg2cheb(c))-c)
25+
5.564168202018823e-13
26+
```
27+
28+
The implementation separates pre-computation into a type of plan. This type is constructed with either `plan_leg2cheb` or `plan_cheb2leg`. Let's see how much faster it is if we pre-compute.
29+
30+
```julia
31+
julia> p1 = plan_leg2cheb(c);
32+
33+
julia> p2 = plan_cheb2leg(c);
34+
35+
julia> @time leg2cheb(c);
36+
0.082615 seconds (11.94 k allocations: 31.214 MiB, 6.75% gc time)
37+
38+
julia> @time p1*c;
39+
0.004297 seconds (6 allocations: 78.422 KiB)
40+
41+
julia> @time cheb2leg(c);
42+
0.110388 seconds (11.94 k allocations: 31.214 MiB, 8.16% gc time)
43+
44+
julia> @time p2*c;
45+
0.004500 seconds (6 allocations: 78.422 KiB)
46+
```
47+
48+
## The Chebyshev—Jacobi Transform
49+
50+
The Chebyshev—Jacobi transform allows the fast conversion of Chebyshev expansion coefficients to Jacobi expansion coefficients and back.
51+
52+
```julia
53+
julia> c = rand(10001);
54+
2355
julia> @time norm(icjt(cjt(c,0.1,-0.2),0.1,-0.2)-c,Inf)
2456
0.258390 seconds (431 allocations: 6.278 MB)
2557
1.4830359162942841e-12
@@ -43,15 +75,61 @@ is valid for the half-open square `(α,β) ∈ (-1/2,1/2]^2`. Therefore, the fas
4375
when the parameters are inside. If the parameters `(α,β)` are not exceptionally beyond the square,
4476
then increment/decrement operators are used with linear complexity (and linear conditioning) in the degree.
4577

46-
The Padua transform and its inverse are also implemented thanks to
47-
[Michael Clarke](https://github.com/MikeAClarke). These are optimized methods
48-
designed for computing the bivariate Chebyshev coefficients by interpolating a
49-
bivariate function at the Padua points on `[-1,1]^2`.
78+
## The Padua Transform
79+
80+
The Padua transform and its inverse are implemented thanks to [Michael Clarke](https://github.com/MikeAClarke). These are optimized methods designed for computing the bivariate Chebyshev coefficients by interpolating a bivariate function at the Padua points on `[-1,1]^2`.
81+
82+
```julia
83+
julia> n = 200;
84+
85+
julia> N = div((n+1)*(n+2),2);
86+
87+
julia> v = rand(N); # The length of v is the number of Padua points
88+
89+
julia> @time norm(ipaduatransform(paduatransform(v))-v)
90+
0.006571 seconds (846 allocations: 1.746 MiB)
91+
3.123637691861415e-14
92+
93+
```
94+
95+
## The Spherical Harmonic Transform
96+
97+
Let `F` be a matrix of spherical harmonic expansion coefficients arranged by increasing order in absolute value, alternating between negative and positive orders. Then `sph2fourier` converts the representation into a bivariate Fourier series, and `fourier2sph` converts it back.
98+
```julia
99+
julia> F = sphrandn(Float64, 256, 256);
100+
101+
julia> G = sph2fourier(F);
102+
103+
julia> H = fourier2sph(G);
104+
105+
julia> norm(F-H)
106+
4.950645831278297e-14
107+
108+
julia> F = sphrandn(Float64, 1024, 1024);
109+
110+
julia> G = sph2fourier(F; sketch = :none);
111+
Pre-computing...100%|███████████████████████████████████████████| Time: 0:00:04
112+
113+
julia> H = fourier2sph(G; sketch = :none);
114+
Pre-computing...100%|███████████████████████████████████████████| Time: 0:00:04
115+
116+
julia> norm(F-H)
117+
1.1510623098225283e-12
118+
119+
```
120+
121+
As with other fast transforms, `plan_sph2fourier` saves effort by caching the pre-computation. Be warned that for dimensions larger than `1,000`, this is no small feat!
50122

51123
# References:
52124

53-
1. N. Hale and A. Townsend. <a href="http://dx.doi.org/10.1137/130932223">A fast, simple, and stable Chebyshev—Legendre transform using and asymptotic formula</a>, SIAM J. Sci. Comput., 36:A148—A167, 2014.
125+
[1] B. Alpert and V. Rokhlin. <a href="http://dx.doi.org/10.1137/0912009">A fast algorithm for the evaluation of Legendre expansions</a>, *SIAM J. Sci. Stat. Comput.*, **12**:158—179, 1991.
126+
127+
[2] N. Hale and A. Townsend. <a href="http://dx.doi.org/10.1137/130932223">A fast, simple, and stable Chebyshev—Legendre transform using and asymptotic formula</a>, *SIAM J. Sci. Comput.*, **36**:A148—A167, 2014.
128+
129+
[3] J. Keiner. <a href="http://dx.doi.org/10.1137/070703065">Computing with expansions in Gegenbauer polynomials</a>, *SIAM J. Sci. Comput.*, **31**:2151—2171, 2009.
130+
131+
[4] R. M. Slevinsky. <a href="https://doi.org/10.1093/imanum/drw070">On the use of Hahn's asymptotic formula and stabilized recurrence for a fast, simple, and stable Chebyshev—Jacobi transform</a>, in press at *IMA J. Numer. Anal.*, 2017.
54132

55-
2. R. M. Slevinsky. <a href="http://arxiv.org/abs/1602.02618">On the use of Hahn's asymptotic formula and stabilized recurrence for a fast, simple, and stable Chebyshev—Jacobi transform</a>, arXiv:1602.02618, 2016.
133+
[5] R. M. Slevinsky. <a href="https://arxiv.org/abs/1705.05448">Fast and backward stable transforms between spherical harmonic expansions and bivariate Fourier series</a>, arXiv:1705.05448, 2017.
56134

57-
3. A. Townsend, M. Webb, and S. Olver. <a href="http://arxiv.org/abs/1604.07486">Fast polynomial transforms based on Toeplitz and Hankel matrices</a>, arXiv:1604.07486, 2016.
135+
[6] A. Townsend, M. Webb, and S. Olver. <a href="https://doi.org/10.1090/mcom/3277">Fast polynomial transforms based on Toeplitz and Hankel matrices</a>, in press at *Math. Comp.*, 2017.

REQUIRE

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
julia 0.5
22
ToeplitzMatrices 0.2
3-
Compat 0.17
3+
HierarchicalMatrices 0.0.1
4+
LowRankApprox 0.0.2
5+
ProgressMeter 0.3.4
6+
Compat 0.17

docs/make.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ deploydocs(
1818
julia = "0.5",
1919
osname = "linux",
2020
target = "build",
21-
deps = nothing,
21+
deps = Deps.pip("pygments", "mkdocs", "python-markdown-math"),
2222
make = nothing
2323
)

docs/src/index.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,37 @@
11
# FastTransforms.jl Documentation
22

3+
## Introduction
4+
5+
In numerical analysis, it is customary to expand a function in a basis:
6+
```math
7+
f(x) \sim \sum_{\ell=0}^{\infty} f_{\ell} \phi_{\ell}(x).
8+
```
9+
It may be necessary to transform our representation to one in a new basis, say, ``\{\psi_m(x)\}_{m\ge0}``:
10+
```math
11+
f(x) \sim \sum_{m=0}^{\infty} g_m \psi_m(x).
12+
```
13+
In many cases of interest, both representations are of finite length ``n`` and we seek a fast method (faster than ``\mathcal{O}(n^2)``) to transform the original coefficients ``f_{\ell}`` to the new coefficients ``g_m``.
14+
15+
A similar problem arises when we wish to evaluate ``f`` at a set of points ``\{x_m\}_{m=0}^n``. We wish to transform coefficients of ``f`` to values at the set of points in fewer than ``\mathcal{O}(n^2)`` operations.
316

417
## Fast Transforms
518

19+
```@docs
20+
leg2cheb
21+
```
22+
23+
```@docs
24+
cheb2leg
25+
```
26+
27+
```@docs
28+
plan_leg2cheb
29+
```
30+
31+
```@docs
32+
plan_cheb2leg
33+
```
34+
635
```@docs
736
cjt
837
```
@@ -39,6 +68,18 @@ plan_paduatransform!
3968
plan_ipaduatransform!
4069
```
4170

71+
```@docs
72+
sph2fourier
73+
```
74+
75+
```@docs
76+
fourier2sph
77+
```
78+
79+
```@docs
80+
plan_sph2fourier
81+
```
82+
4283
## Other Exported Methods
4384

4485
```@docs
@@ -49,6 +90,10 @@ gaunt
4990
paduapoints
5091
```
5192

93+
```@docs
94+
sphevaluate
95+
```
96+
5297
## Internal Methods
5398

5499
```@docs

src/FastTransforms.jl

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
__precompile__()
22
module FastTransforms
33

4-
using Base, ToeplitzMatrices, Compat
4+
using Base, ToeplitzMatrices, HierarchicalMatrices, LowRankApprox, ProgressMeter, Compat
55

6-
import Base: *
7-
import Base: view
6+
import Base: *, \, size, view
7+
import Base: getindex, setindex!, Factorization, length
8+
import Base.LinAlg: BlasFloat, BlasInt
9+
import HierarchicalMatrices: HierarchicalMatrix, unsafe_broadcasttimes!
10+
import HierarchicalMatrices: A_mul_B!, At_mul_B!, Ac_mul_B!
11+
import LowRankApprox: ColPerm
812

913
export cjt, icjt, jjt, plan_cjt, plan_icjt
1014
export leg2cheb, cheb2leg, leg2chebu, ultra2ultra, jac2jac
15+
export normleg2cheb, cheb2normleg, normleg12cheb2, cheb22normleg1
16+
export plan_leg2cheb, plan_cheb2leg
17+
export plan_normleg2cheb, plan_cheb2normleg
18+
export plan_normleg12cheb2, plan_cheb22normleg1
1119
export gaunt
1220
export paduatransform, ipaduatransform, paduatransform!, ipaduatransform!, paduapoints
1321
export plan_paduatransform!, plan_ipaduatransform!
1422

23+
export SlowSphericalHarmonicPlan, FastSphericalHarmonicPlan, ThinSphericalHarmonicPlan
24+
export sph2fourier, fourier2sph, plan_sph2fourier
25+
export sphones, sphzeros, sphrand, sphrandn, sphevaluate
26+
1527
# Other module methods and constants:
1628
#export ChebyshevJacobiPlan, jac2cheb, cheb2jac
1729
#export sqrtpi, pochhammer, stirlingseries, stirlingremainder, Aratio, Cratio, Anαβ
@@ -42,12 +54,15 @@ include("cjt.jl")
4254

4355
include("toeplitzhankel.jl")
4456

45-
leg2cheb(x...)=th_leg2cheb(x...)
46-
cheb2leg(x...)=th_cheb2leg(x...)
57+
#leg2cheb(x...)=th_leg2cheb(x...)
58+
#cheb2leg(x...)=th_cheb2leg(x...)
4759
leg2chebu(x...)=th_leg2chebu(x...)
4860
ultra2ultra(x...)=th_ultra2ultra(x...)
4961
jac2jac(x...)=th_jac2jac(x...)
5062

63+
include("hierarchical.jl")
64+
include("SphericalHarmonics/SphericalHarmonics.jl")
65+
5166
include("gaunt.jl")
5267

5368

0 commit comments

Comments
 (0)