Skip to content

Commit 46ae141

Browse files
authored
ContinuumArray 0.19 (#93)
* ContinuumArray 0.19 * remove Abs/Laplacian * export Laplacian * tests pass * Add angularmomentum * Update Project.toml
1 parent 79edafa commit 46ae141

File tree

6 files changed

+83
-89
lines changed

6 files changed

+83
-89
lines changed

Project.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "HarmonicOrthogonalPolynomials"
22
uuid = "e416a80e-9640-42f3-8df8-80a93ca01ea5"
33
authors = ["Sheehan Olver <solver@mac.com>"]
4-
version = "0.6.3"
4+
version = "0.7"
55

66
[deps]
77
BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e"
@@ -20,13 +20,13 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
2020
[compat]
2121
BlockArrays = "1.0"
2222
BlockBandedMatrices = "0.13"
23-
ClassicalOrthogonalPolynomials = "0.13, 0.14"
24-
ContinuumArrays = "0.18"
23+
ClassicalOrthogonalPolynomials = "0.15"
24+
ContinuumArrays = "0.19"
2525
DomainSets = "0.7"
2626
FastTransforms = "0.15, 0.16, 0.17"
27-
InfiniteArrays = "0.14, 0.15"
27+
InfiniteArrays = "0.15"
2828
IntervalSets = "0.7"
29-
QuasiArrays = "0.11"
29+
QuasiArrays = "0.12"
3030
SpecialFunctions = "1, 2"
3131
StaticArrays = "1"
3232
julia = "1.10"

src/HarmonicOrthogonalPolynomials.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ import Base: OneTo, oneto, axes, getindex, convert, to_indices, tail, eltype, *,
55
import BlockArrays: block, blockindex, unblock, BlockSlice
66
import DomainSets: indomain, Sphere
77
import LinearAlgebra: norm, factorize
8-
import QuasiArrays: to_quasi_index, SubQuasiArray, *
9-
import ContinuumArrays: TransformFactorization, @simplify, ProjectionFactorization, plan_grid_transform, plan_transform, grid, grid_layout, plotgrid_layout, AbstractBasisLayout, MemoryLayout
8+
import QuasiArrays: to_quasi_index, SubQuasiArray, *, AbstractQuasiVecOrMat
9+
import ContinuumArrays: TransformFactorization, @simplify, ProjectionFactorization, plan_grid_transform, plan_transform, grid, grid_layout, plotgrid_layout,
10+
AbstractBasisLayout, MemoryLayout, abslaplacian, laplacian, AbstractDifferentialQuasiMatrix, operatorcall, similaroperator, SubBasisLayout,
11+
ApplyLayout, arguments, ExpansionLayout
1012
import ClassicalOrthogonalPolynomials: checkpoints, _sum, cardinality, increasingtruncations
1113
import BlockBandedMatrices: BlockRange1, _BandedBlockBandedMatrix
1214
import FastTransforms: Plan, interlace
1315
import QuasiArrays: LazyQuasiMatrix, LazyQuasiArrayStyle
1416
import InfiniteArrays: InfStepRange, RangeCumsum
1517

16-
export SphericalHarmonic, UnitSphere, SphericalCoordinate, RadialCoordinate, Block, associatedlegendre, RealSphericalHarmonic, sphericalharmonicy, Laplacian, AbsLaplacianPower, abs, -, ^, AngularMomentum
18+
export SphericalHarmonic, UnitSphere, SphericalCoordinate, RadialCoordinate, Block, associatedlegendre, RealSphericalHarmonic, sphericalharmonicy, abs, -, ^, AngularMomentum, Laplacian, AbsLaplacian
1719
cardinality(::Sphere) = ℵ₁
1820

1921
include("multivariateops.jl")

src/angularmomentum.jl

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,54 @@
1-
#########
2-
# AngularMomentum
3-
# Applies the partial derivative with respect to the last angular variable in the coordinate system.
4-
# For example, in polar coordinates (r, θ) in ℝ² or cylindrical coordinates (r, θ, z) in ℝ³, we apply ∂ / ∂θ = (x ∂ / ∂y - y ∂ / ∂x).
5-
# In spherical coordinates (ρ, θ, φ) in ℝ³, we apply ∂ / ∂φ = (x ∂ / ∂y - y ∂ / ∂x).
6-
#########
7-
8-
struct AngularMomentum{T,Ax<:Inclusion} <: LazyQuasiMatrix{T}
1+
"""
2+
AngularMomentum
3+
4+
Applies the partial derivative with respect to the last angular variable in the coordinate system.
5+
For example, in polar coordinates (r, θ) in ℝ² or cylindrical coordinates (r, θ, z) in ℝ³, we apply ∂ / ∂θ = (x ∂ / ∂y - y ∂ / ∂x).
6+
In spherical coordinates (ρ, θ, φ) in ℝ³, we apply ∂ / ∂φ = (x ∂ / ∂y - y ∂ / ∂x).
7+
"""
8+
struct AngularMomentum{T,Ax<:Inclusion,Order} <: AbstractDifferentialQuasiMatrix{T}
99
axis::Ax
10+
order::Order
1011
end
1112

12-
AngularMomentum{T}(axis::Inclusion) where T = AngularMomentum{T,typeof(axis)}(axis)
13-
AngularMomentum{T}(domain) where T = AngularMomentum{T}(Inclusion(domain))
14-
AngularMomentum(axis) = AngularMomentum{eltype(eltype(axis))}(axis)
13+
AngularMomentum{T, D}(axis::D, order) where {T,D<:Inclusion} = AngularMomentum{T,D,typeof(order)}(axis, order)
14+
AngularMomentum{T, D}(axis::D) where {T,D<:Inclusion} = AngularMomentum{T,D,Nothing}(axis, nothing)
15+
AngularMomentum{T}(axis::Inclusion, order...) where T = AngularMomentum{T,typeof(axis)}(axis, order...)
16+
AngularMomentum{T}(domain, order...) where T = AngularMomentum{T}(Inclusion(domain), order...)
17+
AngularMomentum(domain, order...) = AngularMomentum(Inclusion(domain), order...)
18+
AngularMomentum(ax::AbstractQuasiVector{T}, order...) where T = AngularMomentum{eltype(eltype(ax))}(ax, order...)
19+
AngularMomentum(L::AbstractQuasiMatrix, order...) = AngularMomentum(axes(L,1), order...)
1520

16-
axes(A::AngularMomentum) = (A.axis, A.axis)
17-
==(a::AngularMomentum, b::AngularMomentum) = a.axis == b.axis
18-
copy(A::AngularMomentum) = AngularMomentum(copy(A.axis))
1921

20-
^(A::AngularMomentum, k::Integer) = ApplyQuasiArray(^, A, k)
22+
operatorcall(::AngularMomentum) = angularmomentum
23+
similaroperator(D::AngularMomentum, ax, ord) = AngularMomentum{eltype(D)}(ax, ord)
2124

22-
@simplify function *(A::AngularMomentum, P::SphericalHarmonic)
25+
simplifiable(::typeof(*), A::AngularMomentum, B::AngularMomentum) = Val(true)
26+
*(D1::AngularMomentum, D2::AngularMomentum) = similaroperator(convert(AbstractQuasiMatrix{promote_type(eltype(D1),eltype(D2))}, D1), D1.axis, operatororder(D1)+operatororder(D2))
27+
28+
angularmomentum(A, order...; dims...) = angularmomentum_layout(MemoryLayout(A), A, order...; dims...)
29+
30+
angularmomentum_layout(::AbstractBasisLayout, Vm, order...; dims...) = error("Overload angularmomentum(::$(typeof(Vm)))")
31+
function angularmomentum_layout(::AbstractBasisLayout, a, order::Int; dims...)
32+
order < 0 && throw(ArgumentError("order must be non-negative"))
33+
order == 0 && return a
34+
isone(order) ? angularmomentum(a) : angularmomentum(angularmomentum(a), order-1)
35+
end
36+
37+
angularmomentum_layout(::ExpansionLayout, A, order...; dims...) = angularmomentum_layout(ApplyLayout{typeof(*)}(), A, order...; dims...)
38+
39+
40+
function angularmomentum_layout(::SubBasisLayout, Vm, order...; dims::Integer=1)
41+
dims == 1 || error("not implemented")
42+
angularmomentum(parent(Vm), order...)[:,parentindices(Vm)[2]]
43+
end
44+
45+
function angularmomentum_layout(LAY::ApplyLayout{typeof(*)}, V::AbstractQuasiVecOrMat, order...; dims=1)
46+
a = arguments(LAY, V)
47+
dims == 1 || throw(ArgumentError("cannot take angularmomentum a vector along dimension $dims"))
48+
*(angularmomentum(a[1], order...), tail(a)...)
49+
end
50+
51+
function angularmomentum(P::SphericalHarmonic)
2352
# Spherical harmonics are the eigenfunctions of the angular momentum operator on the unit sphere
2453
T = real(eltype(P))
2554
k = mortar(Base.OneTo.(1:2:∞))

src/laplace.jl

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,20 @@
1-
# Laplacian
2-
3-
struct Laplacian{T,D} <: LazyQuasiMatrix{T}
4-
axis::Inclusion{T,D}
5-
end
6-
7-
Laplacian{T}(axis::Inclusion{<:Any,D}) where {T,D} = Laplacian{T,D}(axis)
8-
# Laplacian{T}(domain) where T = Laplacian{T}(Inclusion(domain))
9-
# Laplacian(axis) = Laplacian{eltype(axis)}(axis)
10-
11-
axes(D::Laplacian) = (D.axis, D.axis)
12-
==(a::Laplacian, b::Laplacian) = a.axis == b.axis
13-
copy(D::Laplacian) = Laplacian(copy(D.axis))
14-
15-
@simplify function *::Laplacian, P::AbstractSphericalHarmonic)
1+
function abslaplacian(P::AbstractSphericalHarmonic; dims...)
162
# Spherical harmonics are the eigenfunctions of the Laplace operator on the unit sphere
17-
P * Diagonal(mortar(Fill.((-(0:∞)-(0:∞).^2), 1:2:∞)))
3+
P * Diagonal(mortar(Fill.((0:∞)+(0:∞).^2, 1:2:∞)))
184
end
195

20-
# Negative fractional Laplacian (-Δ)^α or equiv. abs(Δ)^α
21-
22-
struct AbsLaplacianPower{T,D,A} <: LazyQuasiMatrix{T}
23-
axis::Inclusion{T,D}
24-
α::A
6+
function abslaplacian(P::AbstractSphericalHarmonic, order; dims...)
7+
# Spherical harmonics are the eigenfunctions of the Laplace operator on the unit sphere
8+
P * Diagonal(mortar(Fill.(((0:∞)+(0:∞).^2) .^ order, 1:2:∞)))
259
end
2610

27-
AbsLaplacianPower{T}(axis::Inclusion{<:Any,D},α) where {T,D} = AbsLaplacianPower{T,D,typeof(α)}(axis,α)
28-
29-
axes(D:: AbsLaplacianPower) = (D.axis, D.axis)
30-
==(a:: AbsLaplacianPower, b:: AbsLaplacianPower) = a.axis == b.axis && a.α == b.α
31-
copy(D:: AbsLaplacianPower) = AbsLaplacianPower(copy(D.axis), D.α)
3211

33-
abs::Laplacian) = AbsLaplacianPower(axes(Δ,1),1)
34-
-::Laplacian) = abs(Δ)
12+
function laplacian(P::AbstractSphericalHarmonic; dims...)
13+
# Spherical harmonics are the eigenfunctions of the Laplace operator on the unit sphere
14+
P * Diagonal(mortar(Fill.(-(0:∞)-(0:∞).^2, 1:2:∞)))
15+
end
3516

36-
^(D::AbsLaplacianPower, k) = AbsLaplacianPower(D.axis, D.α*k)
17+
function laplacian(P::AbstractSphericalHarmonic, order::Int; dims...)
18+
# Spherical harmonics are the eigenfunctions of the Laplace operator on the unit sphere
19+
P * Diagonal(mortar(Fill.((-(0:∞)-(0:∞).^2) .^ order, 1:2:∞)))
20+
end

src/multivariateops.jl

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,3 @@
1-
2-
#########
3-
# PartialDerivative{k}
4-
# takes a partial derivative in the k-th index.
5-
#########
6-
7-
8-
struct PartialDerivative{k,T,Ax<:Inclusion} <: LazyQuasiMatrix{T}
9-
axis::Ax
10-
end
11-
12-
PartialDerivative{k,T}(axis::Inclusion) where {k,T} = PartialDerivative{k,T,typeof(axis)}(axis)
13-
PartialDerivative{k,T}(domain) where {k,T} = PartialDerivative{k,T}(Inclusion(domain))
14-
PartialDerivative{k}(axis) where k = PartialDerivative{k,eltype(eltype(axis))}(axis)
15-
16-
axes(D::PartialDerivative) = (D.axis, D.axis)
17-
==(a::PartialDerivative{k}, b::PartialDerivative{k}) where k = a.axis == b.axis
18-
copy(D::PartialDerivative{k}) where k = PartialDerivative{k}(copy(D.axis))
19-
20-
^(D::PartialDerivative, k::Integer) = ApplyQuasiArray(^, D, k)
21-
221
abstract type MultivariateOrthogonalPolynomial{d,T} <: Basis{T} end
232
const BivariateOrthogonalPolynomial{T} = MultivariateOrthogonalPolynomial{2,T}
243

test/runtests.jl

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ end
229229
= Laplacian(Rxyz)
230230
@testisa Laplacian
231231
@testisa Laplacian
232-
@test *(SΔ,S) isa ApplyQuasiArray
232+
@test *S isa ApplyQuasiArray
233233
@test *(RΔ,R) isa ApplyQuasiArray
234234
@test copy(SΔ) ====== copy(RΔ)
235235
@test axes(SΔ) == axes(RΔ) == (axes(S,1),axes(S,1)) == (axes(R,1),axes(R,1))
@@ -323,8 +323,8 @@ end
323323
S = SphericalHarmonic()
324324
xyz = axes(S,1)
325325
@test Laplacian(xyz) isa Laplacian
326-
@test Laplacian(xyz)^2 isa QuasiArrays.ApplyQuasiArray
327-
@test Laplacian(xyz)^3 isa QuasiArrays.ApplyQuasiArray
326+
@test Laplacian(xyz)^2 isa Laplacian
327+
@test Laplacian(xyz)^3 isa Laplacian
328328
f1 = c -> cos(c.θ)^2
329329
Δ_f1 = c -> -1-3*cos(2*c.θ)
330330
Δ2_f1 = c -> 6+18*cos(2*c.θ)
@@ -342,8 +342,8 @@ end
342342
S = SphericalHarmonic()[:,Block.(Base.OneTo(10))]
343343
xyz = axes(S,1)
344344
@test Laplacian(xyz) isa Laplacian
345-
@test Laplacian(xyz)^2 isa QuasiArrays.ApplyQuasiArray
346-
@test Laplacian(xyz)^3 isa QuasiArrays.ApplyQuasiArray
345+
@test Laplacian(xyz)^2 isa Laplacian
346+
@test Laplacian(xyz)^3 isa Laplacian
347347
f1 = c -> cos(c.θ)^2
348348
Δ_f1 = c -> -1-3*cos(2*c.θ)
349349
Δ2_f1 = c -> 6+18*cos(2*c.θ)
@@ -361,8 +361,8 @@ end
361361
S = RealSphericalHarmonic()[:,Block.(Base.OneTo(10))]
362362
xyz = axes(S,1)
363363
@test Laplacian(xyz) isa Laplacian
364-
@test Laplacian(xyz)^2 isa QuasiArrays.ApplyQuasiArray
365-
@test Laplacian(xyz)^3 isa QuasiArrays.ApplyQuasiArray
364+
@test Laplacian(xyz)^2 isa Laplacian
365+
@test Laplacian(xyz)^3 isa Laplacian
366366
f1 = c -> cos(c.θ)^2
367367
Δ_f1 = c -> -1-3*cos(2*c.θ)
368368
Δ2_f1 = c -> 6+18*cos(2*c.θ)
@@ -381,25 +381,25 @@ end
381381
α = 1/3
382382
S = SphericalHarmonic()
383383
Sxyz = axes(S,1)
384-
SΔα = AbsLaplacianPower(Sxyz,α)
384+
SΔα = AbsLaplacian(Sxyz,α)
385385
Δ = Laplacian(Sxyz)
386386
@test copy(SΔα) == SΔα
387-
@test SΔα isa AbsLaplacianPower
387+
@test SΔα isa AbsLaplacian
388388
@test SΔα isa QuasiArrays.LazyQuasiMatrix
389389
@test axes(SΔα) == (axes(S,1),axes(S,1))
390-
@test abs(Δ) == -Δ == AbsLaplacianPower(axes(Δ,1),1)
390+
@test abs(Δ) == -Δ == AbsLaplacian(axes(Δ,1),1)
391391
@test abs(Δ)^α == SΔα
392392
# Set 2
393393
α = 7/13
394394
S = SphericalHarmonic()
395395
Sxyz = axes(S,1)
396-
SΔα = AbsLaplacianPower(Sxyz,α)
396+
SΔα = AbsLaplacian(Sxyz,α)
397397
Δ = Laplacian(Sxyz)
398398
@test copy(SΔα) == SΔα
399-
@test SΔα isa AbsLaplacianPower
399+
@test SΔα isa AbsLaplacian
400400
@test SΔα isa QuasiArrays.LazyQuasiMatrix
401401
@test axes(SΔα) == (axes(S,1),axes(S,1))
402-
@test abs(Δ) == -Δ == AbsLaplacianPower(axes(Δ,1),1)
402+
@test abs(Δ) == -Δ == AbsLaplacian(axes(Δ,1),1)
403403
@test abs(Δ)^α == SΔα
404404
end
405405

@@ -417,9 +417,9 @@ end
417417
@testset "Angular momentum" begin
418418
S = SphericalHarmonic()
419419
R = RealSphericalHarmonic()
420-
∂θ = AngularMomentum(axes(S, 1))
420+
∂θ = AngularMomentum(S)
421421
@test axes(∂θ) == (axes(S, 1), axes(S, 1))
422-
@test ∂θ == AngularMomentum(axes(R, 1)) == AngularMomentum(axes(S, 1).domain)
422+
@test ∂θ == AngularMomentum(R) == AngularMomentum(axes(S, 1).domain)
423423
@test copy(∂θ) ∂θ
424424
A = S \ (∂θ * S)
425425
A2 = S \ (∂θ^2 * S)

0 commit comments

Comments
 (0)