Skip to content

Commit 88a3793

Browse files
committed
Merge branch 'main' into dl/basissingularities
2 parents 5788c9f + 8462dd4 commit 88a3793

25 files changed

+622
-391
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
- uses: julia-actions/julia-buildpkg@v1
4848
- uses: julia-actions/julia-runtest@v1
4949
- uses: julia-actions/julia-processcoverage@v1
50-
- uses: codecov/codecov-action@v4
50+
- uses: codecov/codecov-action@v5
5151
with:
5252
token: ${{ secrets.CODECOV_TOKEN }}
5353
file: lcov.info

.github/workflows/downstream.yml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: IntegrationTest
2+
on:
3+
push:
4+
branches: [main]
5+
tags: [v*]
6+
pull_request:
7+
paths-ignore:
8+
- 'LICENSE'
9+
- 'README.md'
10+
- '.github/workflows/TagBot.yml'
11+
12+
jobs:
13+
pre_job:
14+
# continue-on-error: true # Uncomment once integration is finished
15+
runs-on: ubuntu-latest
16+
# Map a step output to a job output
17+
outputs:
18+
should_skip: ${{ steps.skip_check.outputs.should_skip }}
19+
steps:
20+
- id: skip_check
21+
uses: fkirc/skip-duplicate-actions@v5
22+
test:
23+
needs: pre_job
24+
if: needs.pre_job.outputs.should_skip != 'true'
25+
name: ${{ matrix.package.group }}/${{ matrix.package.repo }}/${{ matrix.julia-version }}
26+
runs-on: ${{ matrix.os }}
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
julia-version: ['1']
31+
os: [ubuntu-latest]
32+
package:
33+
- {repo: HarmonicOrthogonalPolynomials.jl, group: JuliaApproximation}
34+
- {repo: MultivariateOrthogonalPolynomials.jl, group: JuliaApproximation}
35+
- {repo: SemiclassicalOrthogonalPolynomials.jl, group: JuliaApproximation}
36+
- {repo: PiecewiseOrthogonalPolynomials.jl, group: JuliaApproximation}
37+
- {repo: SingularIntegrals.jl, group: JuliaApproximation}
38+
steps:
39+
- uses: actions/checkout@v4
40+
- uses: julia-actions/setup-julia@v2
41+
with:
42+
version: ${{ matrix.julia-version }}
43+
arch: x64
44+
- uses: julia-actions/julia-buildpkg@latest
45+
- name: Clone Downstream
46+
uses: actions/checkout@v4
47+
with:
48+
repository: ${{ matrix.package.group }}/${{ matrix.package.repo }}
49+
path: downstream
50+
- name: Load this and run the downstream tests
51+
shell: julia --color=yes --project=downstream {0}
52+
run: |
53+
using Pkg
54+
try
55+
# force it to use this PR's version of the package
56+
Pkg.develop(PackageSpec(path=".")) # resolver may fail with main deps
57+
Pkg.update()
58+
Pkg.test(; coverage = true) # resolver may fail with test time deps
59+
catch err
60+
err isa Pkg.Resolve.ResolverError || rethrow()
61+
# If we can't resolve that means this is incompatible by SemVer and this is fine
62+
# It means we marked this as a breaking change, so we don't need to worry about
63+
# Mistakenly introducing a breaking change, as we have intentionally made one
64+
@info "Not compatible with this release. No problem." exception=err
65+
exit(0) # Exit immediately, as a success
66+
end
67+
- uses: julia-actions/julia-processcoverage@v1
68+
- uses: codecov/codecov-action@v5
69+
with:
70+
token: ${{ secrets.CODECOV_TOKEN }}
71+
files: lcov.info

Project.toml

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
name = "ClassicalOrthogonalPolynomials"
22
uuid = "b30e2e7b-c4ee-47da-9d5f-2c5c27239acd"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.13.7"
4+
version = "0.15.1"
5+
56

67
[deps]
78
ArrayLayouts = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
@@ -22,40 +23,49 @@ LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02"
2223
LazyBandedMatrices = "d7e5e226-e90b-4449-9968-0f923699bf6f"
2324
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
2425
QuasiArrays = "c4ea9172-b204-11e9-377d-29865faadc5c"
25-
RecurrenceRelationships = "807425ed-42ea-44d6-a357-6771516d7b2c"
2626
RecurrenceRelationshipArrays = "b889d2dc-af3c-4820-88a8-238fa91d3518"
27+
RecurrenceRelationships = "807425ed-42ea-44d6-a357-6771516d7b2c"
2728
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
2829

30+
[weakdeps]
31+
MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
32+
33+
[extensions]
34+
ClassicalOrthogonalPolynomialsMutableArithmeticsExt = "MutableArithmetics"
35+
2936
[compat]
3037
ArrayLayouts = "1.3.1"
3138
BandedMatrices = "1"
3239
BlockArrays = "1"
3340
BlockBandedMatrices = "0.13"
34-
ContinuumArrays = "0.18.3"
41+
ContinuumArrays = "0.19"
3542
DomainSets = "0.6, 0.7"
43+
DynamicPolynomials = "0.6"
3644
FFTW = "1.1"
3745
FastGaussQuadrature = "1"
38-
FastTransforms = "0.16.6"
46+
FastTransforms = "0.16.6, 0.17"
3947
FillArrays = "1"
4048
HypergeometricFunctions = "0.3.4"
41-
InfiniteArrays = " 0.14"
42-
InfiniteLinearAlgebra = "0.8"
49+
InfiniteArrays = " 0.15"
50+
InfiniteLinearAlgebra = "0.10"
4351
IntervalSets = "0.7"
44-
LazyArrays = "2.2"
45-
LazyBandedMatrices = "0.10"
46-
QuasiArrays = "0.11"
47-
RecurrenceRelationships = "0.1"
48-
RecurrenceRelationshipArrays = "0.1"
52+
LazyArrays = "2.5.1"
53+
LazyBandedMatrices = "0.11"
54+
MutableArithmetics = "1"
55+
QuasiArrays = "0.12"
56+
RecurrenceRelationshipArrays = "0.1.2"
57+
RecurrenceRelationships = "0.2"
4958
SpecialFunctions = "1.0, 2"
5059
julia = "1.10"
5160

5261
[extras]
5362
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
63+
DynamicPolynomials = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
5464
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
5565
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
5666
SemiseparableMatrices = "f8ebbe35-cbfb-4060-bf7f-b10e4670cf57"
5767
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
5868
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
5969

6070
[targets]
61-
test = ["Base64", "Test", "ForwardDiff", "SemiseparableMatrices", "StaticArrays", "Random"]
71+
test = ["Base64", "Test", "ForwardDiff", "SemiseparableMatrices", "StaticArrays", "Random", "DynamicPolynomials"]

docs/make.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
using Documenter, ClassicalOrthogonalPolynomials
22

3+
DocMeta.setdocmeta!(ClassicalOrthogonalPolynomials,
4+
:DocTestSetup,
5+
:(using ClassicalOrthogonalPolynomials))
6+
37
makedocs(
48
modules = [ClassicalOrthogonalPolynomials],
59
sitename="ClassicalOrthogonalPolynomials.jl",

docs/src/index.md

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,23 @@ CurrentModule = ClassicalOrthogonalPolynomials
1010
We follow the [Digital Library of Mathematical Functions](https://dlmf.nist.gov/18.3),
1111
which defines the following classical orthogonal polynomials:
1212

13-
1. Legendre: `P_n(x)`
14-
2. Chebyshev (1st kind, 2nd kind): `T_n(x)`, `U_n(x)`
15-
3. Ultraspherical: `C_n^{(λ)}(x)`
16-
4. Jacobi: `P_n^{(a,b)}(x)`
17-
5. Laguerre: `L_n^{(α)}(x)`
18-
6. Hermite: `H_n(x)`
13+
1. Legendre: $P_n(x)$, defined over $[-1, 1]$ with weight $w(x) = 1$.
14+
2. Chebyshev (1st kind, 2nd kind): $T_n(x)$ and $U_n(x)$, defined over $[-1, 1]$ with weights $w(x) = 1/\sqrt{1-x^2}$ and $w(x) = \sqrt{1-x^2}$, respectively.
15+
3. Ultraspherical: $C_n^{(\lambda)}(x)$, defined over $[-1, 1]$ with weight $w(x) = (1-x^2)^{\lambda-1/2}$.
16+
4. Jacobi: $P_n^{(a,b)}(x)$, defined over $[-1, 1]$ with weight $w(x) = (1-x)^a(1+x)^b$.
17+
5. Laguerre: $L_n^{(\alpha)}(x)$, defined over $[0, ∞)$ with weight $w(x) = x^\alpha \mathrm{e}^{-x}$.
18+
6. Hermite: $H_n(x)$, defined over $(-∞, ∞)$ with weight $w(x) = \mathrm{e}^{-x^2}$.
19+
20+
These special polynomials have many applications and can be used as a basis for any function given their domain conditions are met, however these polynomials have some advantages due to their formulation:
21+
22+
- Because of their relation to Laplace’s equation, **Legendre polynomials** can be useful as a basis for functions with spherical symmetry.
23+
- **Chebyshev polynomials** are generally effective in reducing errors from numerical methods such as quadrature, interpolation, and approximation.
24+
- Due to the flexibility of its parameters, **Jacobi polynomials** are capable of tailoring the behavior of an approximation around its endpoints, making these polynomials particularly useful in boundary value problems.
25+
- **Ultraspherical polynomials** are advantageous in spectral methods for solving differential equations.
26+
- **Laguerre polynomials** have a semi-infinite domain, therefore they are beneficial for problems involving exponential decay.
27+
- Because of its weight function, **Hermite polynomials** can be useful in situations where functions display a Gaussian-like distribution.
28+
29+
These are just a few applications of these polynomials. They have many more uses across mathematics, physics, and engineering.
1930

2031
## Evaluation
2132

@@ -126,17 +137,15 @@ U\T
126137

127138
```@docs
128139
ClassicalOrthogonalPolynomials.Chebyshev
129-
```
130-
```@docs
131140
ClassicalOrthogonalPolynomials.chebyshevt
132-
```
133-
```@docs
134141
ClassicalOrthogonalPolynomials.chebyshevu
135142
```
136143
```@docs
144+
ClassicalOrthogonalPolynomials.Legendre
137145
ClassicalOrthogonalPolynomials.legendrep
138146
```
139147
```@docs
148+
ClassicalOrthogonalPolynomials.Jacobi
140149
ClassicalOrthogonalPolynomials.jacobip
141150
```
142151
```@docs
@@ -147,8 +156,6 @@ ClassicalOrthogonalPolynomials.hermiteh
147156
```
148157

149158

150-
151-
152159
### Weights
153160

154161
```@docs
@@ -161,7 +168,9 @@ ClassicalOrthogonalPolynomials.HermiteWeight
161168
ClassicalOrthogonalPolynomials.Weighted
162169
```
163170
```@docs
171+
ClassicalOrthogonalPolynomials.LegendreWeight
164172
ClassicalOrthogonalPolynomials.ChebyshevWeight
173+
ClassicalOrthogonalPolynomials.JacobiWeight
165174
```
166175
```@docs
167176
ClassicalOrthogonalPolynomials.LaguerreWeight
@@ -170,6 +179,13 @@ ClassicalOrthogonalPolynomials.LaguerreWeight
170179
ClassicalOrthogonalPolynomials.HalfWeighted
171180
```
172181

182+
### Affine-mapped
183+
```@docs
184+
ClassicalOrthogonalPolynomials.legendre
185+
ClassicalOrthogonalPolynomials.jacobi
186+
ClassicalOrthogonalPolynomials.legendreweight
187+
ClassicalOrthogonalPolynomials.jacobiweight
188+
```
173189

174190
### Recurrences
175191

@@ -190,32 +206,22 @@ ClassicalOrthogonalPolynomials.recurrencecoefficients
190206
```
191207

192208

193-
194209
### Internal
195210

196211
```@docs
197-
ClassicalOrthogonalPolynomials.ShuffledIR2HC
198-
```
199-
```@docs
200-
ClassicalOrthogonalPolynomials.ShuffledR2HC
201-
```
202-
```@docs
212+
ClassicalOrthogonalPolynomials.ShuffledFFT
203213
ClassicalOrthogonalPolynomials.ShuffledIFFT
214+
ClassicalOrthogonalPolynomials.ShuffledR2HC
215+
ClassicalOrthogonalPolynomials.ShuffledIR2HC
204216
```
205217
```@docs
206218
ClassicalOrthogonalPolynomials.qr_jacobimatrix
207-
```
208-
```@docs
209-
ClassicalOrthogonalPolynomials.MappedOPLayout
210-
```
211-
```@docs
212219
ClassicalOrthogonalPolynomials.cholesky_jacobimatrix
213220
```
214221
```@docs
215222
ClassicalOrthogonalPolynomials.AbstractNormalizedOPLayout
216-
```
217-
```@docs
218-
ClassicalOrthogonalPolynomials.ShuffledFFT
223+
ClassicalOrthogonalPolynomials.MappedOPLayout
224+
ClassicalOrthogonalPolynomials.WeightedOPLayout
219225
```
220226
```@docs
221227
ClassicalOrthogonalPolynomials.legendre_grammatrix
@@ -224,9 +230,6 @@ ClassicalOrthogonalPolynomials.legendre_grammatrix
224230
ClassicalOrthogonalPolynomials.weightedgrammatrix
225231
```
226232
```@docs
227-
ClassicalOrthogonalPolynomials.WeightedOPLayout
228-
```
229-
```@docs
230233
ClassicalOrthogonalPolynomials.interlace!
231234
```
232235
```@docs
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module ClassicalOrthogonalPolynomialsMutableArithmeticsExt
2+
using ClassicalOrthogonalPolynomials, MutableArithmetics
3+
import ClassicalOrthogonalPolynomials: initiateforwardrecurrence, recurrencecoefficients, _p0
4+
5+
Base.unsafe_getindex(P::OrthogonalPolynomial, x::AbstractMutable, n::Number) = initiateforwardrecurrence(n-1, recurrencecoefficients(P)..., x, _p0(P))[end]
6+
7+
recurrencecoefficients(::Legendre{T}) where T<:AbstractMutable = recurrencecoefficients(Legendre())
8+
end

src/ClassicalOrthogonalPolynomials.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@ import QuasiArrays: cardinality, checkindex, QuasiAdjoint, QuasiTranspose, Inclu
2929
QuasiDiagonal, MulQuasiArray, MulQuasiMatrix, MulQuasiVector, QuasiMatMulMat,
3030
ApplyQuasiArray, ApplyQuasiMatrix, LazyQuasiArrayApplyStyle, AbstractQuasiArrayApplyStyle,
3131
LazyQuasiArray, LazyQuasiVector, LazyQuasiMatrix, LazyLayout, LazyQuasiArrayStyle,
32-
_getindex, layout_getindex, _factorize, AbstractQuasiArray, AbstractQuasiMatrix, AbstractQuasiVector,
32+
_getindex, layout_getindex, AbstractQuasiArray, AbstractQuasiMatrix, AbstractQuasiVector,
3333
AbstractQuasiFill, equals_layout, QuasiArrayLayout, PolynomialLayout, diff_layout
3434

3535
import InfiniteArrays: OneToInf, InfAxes, Infinity, AbstractInfUnitRange, InfiniteCardinal, InfRanges
36-
import InfiniteLinearAlgebra: chop!, chop, pad, choplength, compatible_resize!, partialcholesky!
37-
import ContinuumArrays: Basis, Weight, basis_axes, @simplify, Identity, AbstractAffineQuasiVector, ProjectionFactorization,
36+
import InfiniteLinearAlgebra: chop!, chop, pad, choplength, compatible_resize!, partialcholesky!, SymTridiagonalConjugation, TridiagonalConjugation
37+
import ContinuumArrays: Basis, Weight, basis_axes, @simplify, AbstractAffineQuasiVector, ProjectionFactorization,
3838
grid, plotgrid, plotgrid_layout, plotvalues_layout, grid_layout, transform_ldiv, TransformFactorization, QInfAxes, broadcastbasis, ExpansionLayout, basismap,
3939
AffineQuasiVector, AffineMap, AbstractWeightLayout, AbstractWeightedBasisLayout, WeightedBasisLayout, WeightedBasisLayouts, demap, AbstractBasisLayout, BasisLayout,
4040
checkpoints, weight, unweighted, MappedBasisLayouts, sum_layout, invmap, plan_ldiv, layout_broadcasted, MappedBasisLayout, SubBasisLayout, broadcastbasis_layout,
4141
plan_grid_transform, plan_transform, MAX_PLOT_POINTS, MulPlan, grammatrix, AdjointBasisLayout, grammatrix_layout, plan_transform_layout, _cumsum
42-
import FastTransforms: Λ, ChebyshevGrid, chebyshevpoints, Plan, ScaledPlan, th_cheb2leg
42+
import FastTransforms: Λ, ChebyshevGrid, chebyshevpoints, Plan, ScaledPlan, th_cheb2leg, pochhammer
4343
import RecurrenceRelationships: forwardrecurrence, forwardrecurrence!, clenshaw, clenshaw!,
44-
check_clenshaw_recurrences
44+
check_clenshaw_recurrences, polynomialtype
4545
import RecurrenceRelationshipArrays: initiateforwardrecurrence, Clenshaw
4646
import FastGaussQuadrature: jacobimoment
4747

@@ -90,6 +90,8 @@ represents an OP multiplied by its orthogonality weight.
9090
"""
9191
struct WeightedOPLayout{Lay<:AbstractOPLayout} <: AbstractWeightedBasisLayout end
9292

93+
grid_layout(::WeightedOPLayout, P, n) = grid(unweighted(P), n)
94+
9395
isorthogonalityweighted(::WeightedOPLayout, _) = true
9496
function isorthogonalityweighted(::AbstractWeightedBasisLayout, wS)
9597
w,S = arguments(wS)
@@ -247,15 +249,14 @@ grammatrix_layout(::WeightedOPLayout{MappedOPLayout}, P) = grammatrix_layout(Map
247249

248250
OrthogonalPolynomial(w::Weight) =error("Override for $(typeof(w))")
249251

250-
@simplify *(B::Identity, C::OrthogonalPolynomial) = ApplyQuasiMatrix(*, C, jacobimatrix(C))
252+
@simplify *(B::QuasiDiagonal{<:Any,<:Inclusion}, C::OrthogonalPolynomial) = ApplyQuasiMatrix(*, C, jacobimatrix(C))
251253

252254
function layout_broadcasted(::Tuple{PolynomialLayout,AbstractOPLayout}, ::typeof(*), x::Inclusion, C)
253255
x == axes(C,1) || throw(DimensionMismatch())
254256
C*jacobimatrix(C)
255257
end
256258

257259

258-
259260
# function broadcasted(::LazyQuasiArrayStyle{2}, ::typeof(*), a::BroadcastQuasiVector, C::OrthogonalPolynomial)
260261
# axes(a,1) == axes(C,1) || throw(DimensionMismatch())
261262
# # re-expand in OP basis

0 commit comments

Comments
 (0)