|
144 | 144 | SPINSPHERESYNTHESIS
|
145 | 145 | SPINSPHEREANALYSIS
|
146 | 146 | SPHERICALISOMETRY
|
| 147 | + FMMLEG2CHEB |
147 | 148 | end
|
148 | 149 |
|
149 | 150 | Transforms(t::Transforms) = t
|
@@ -187,7 +188,8 @@ let k2s = Dict(LEG2CHEB => "Legendre--Chebyshev",
|
187 | 188 | TETRAHEDRONANALYSIS => "FFTW Chebyshev analysis on the tetrahedron",
|
188 | 189 | SPINSPHERESYNTHESIS => "FFTW Fourier synthesis on the sphere (spin-weighted)",
|
189 | 190 | SPINSPHEREANALYSIS => "FFTW Fourier analysis on the sphere (spin-weighted)",
|
190 |
| - SPHERICALISOMETRY => "Spherical isometry") |
| 191 | + SPHERICALISOMETRY => "Spherical isometry", |
| 192 | + FMMLEG2CHEB => "FMM Legendre--Chebyshev") |
191 | 193 | global kind2string
|
192 | 194 | kind2string(k::Union{Integer, Transforms}) = k2s[Transforms(k)]
|
193 | 195 | end
|
@@ -314,6 +316,50 @@ destroy_plan(p::FTPlan{Complex{Float64}, 2, SPINSPHERESYNTHESIS}) = ccall((:ft_d
|
314 | 316 | destroy_plan(p::FTPlan{Complex{Float64}, 2, SPINSPHEREANALYSIS}) = ccall((:ft_destroy_spinsphere_fftw_plan, libfasttransforms), Cvoid, (Ptr{ft_plan_struct}, ), p)
|
315 | 317 | destroy_plan(p::FTPlan{Float64, 2, SPHERICALISOMETRY}) = ccall((:ft_destroy_sph_isometry_plan, libfasttransforms), Cvoid, (Ptr{ft_plan_struct}, ), p)
|
316 | 318 |
|
| 319 | +destroy_plan(p::FTPlan{Float32, 1, FMMLEG2CHEB}) = ccall((:ft_free_fmmf, libfasttransforms), Cvoid, (Ptr{ft_plan_struct}, ), p) |
| 320 | +destroy_plan(p::FTPlan{Float64, 1, FMMLEG2CHEB}) = ccall((:ft_free_fmm, libfasttransforms), Cvoid, (Ptr{ft_plan_struct}, ), p) |
| 321 | + |
| 322 | +function plan_fmm_leg2cheb(::Type{Float64}, n::Integer) |
| 323 | + maxs = 64 |
| 324 | + M = 18 |
| 325 | + BOTH = 2 |
| 326 | + lagrange = 0 |
| 327 | + verbose = 2 |
| 328 | + plan = ccall((:ft_create_fmm, libfasttransforms), Ptr{ft_plan_struct}, (Cint, Cint, Cint, Cint, Cint, Cint), n, maxs, M, BOTH, lagrange, verbose) |
| 329 | + return FTPlan{Float64, 1, FMMLEG2CHEB}(plan, n) |
| 330 | +end |
| 331 | + |
| 332 | +function mul!(y::StridedVector{Float64}, p::FTPlan{Float64, 1, FMMLEG2CHEB}, x::StridedVector{Float64}) |
| 333 | + checksize(p, x) |
| 334 | + checksize(p, y) |
| 335 | + checkstride(p, x) |
| 336 | + checkstride(p, y) |
| 337 | + L2C = 0 |
| 338 | + flops = ccall((:ft_execute, libfasttransforms), Cint, (Ptr{Float64}, Ptr{Float64}, Ptr{ft_plan_struct}, Cint, Cint), x, y, p, L2C, 1) |
| 339 | + return y |
| 340 | +end |
| 341 | +function div!(y::StridedVector{Float64}, p::FTPlan{Float64, 1, FMMLEG2CHEB}, x::StridedVector{Float64}) |
| 342 | + checksize(p, x) |
| 343 | + checksize(p, y) |
| 344 | + checkstride(p, x) |
| 345 | + checkstride(p, y) |
| 346 | + C2L = 1 |
| 347 | + flops = ccall((:ft_execute, libfasttransforms), Cint, (Ptr{Float64}, Ptr{Float64}, Ptr{ft_plan_struct}, Cint, Cint), x, y, p, C2L, 1) |
| 348 | + return y |
| 349 | +end |
| 350 | + |
| 351 | +function *(p::FTPlan{T, 1, FMMLEG2CHEB}, x::AbstractArray{T}) where T |
| 352 | + Ax = Array(x) |
| 353 | + y = zero(Ax) |
| 354 | + mul!(y, p, Ax) |
| 355 | +end |
| 356 | +function \(p::FTPlan{T, 1, FMMLEG2CHEB}, x::AbstractArray{T}) where T |
| 357 | + Ax = Array(x) |
| 358 | + y = zero(Ax) |
| 359 | + div!(y, p, Ax) |
| 360 | +end |
| 361 | + |
| 362 | + |
317 | 363 | struct AdjointFTPlan{T, S, R}
|
318 | 364 | parent::S
|
319 | 365 | adjoint::R
|
@@ -433,7 +479,7 @@ for f in (:leg2cheb, :cheb2leg, :ultra2ultra, :jac2jac,
|
433 | 479 | :cheb2jac, :ultra2cheb, :cheb2ultra, :associatedjac2jac,
|
434 | 480 | :modifiedjac2jac, :modifiedlag2lag, :modifiedherm2herm,
|
435 | 481 | :sph2fourier, :sphv2fourier, :disk2cxf, :ann2cxf,
|
436 |
| - :rectdisk2cheb, :tri2cheb, :tet2cheb) |
| 482 | + :rectdisk2cheb, :tri2cheb, :tet2cheb, :fmm_leg2cheb) |
437 | 483 | plan_f = Symbol("plan_", f)
|
438 | 484 | lib_f = Symbol("lib_", f)
|
439 | 485 | @eval begin
|
|
0 commit comments