Skip to content

Commit 8223d9d

Browse files
authored
Merge pull request #2 from JuliaAlgebra/bl/orthogonal
Add classical multiple orthogonal basis
2 parents 6e62d70 + 9d10007 commit 8223d9d

File tree

16 files changed

+454
-44
lines changed

16 files changed

+454
-44
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818
julia: 1.0
1919
os: linux
2020
script:
21-
- julia --project=docs/ -e 'import Pkg; Pkg.instantiate(); Pkg.develop(Pkg.PackageSpec(path=pwd()))'
21+
- julia --project=docs/ -e 'import Pkg; Pkg.instantiate();
22+
Pkg.add("DynamicPolynomials");
23+
Pkg.develop(Pkg.PackageSpec(path=pwd()))'
2224
- julia --project=docs/ docs/make.jl
2325
after_success: skip

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
[deps]
22
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3+
MultivariateBases = "be282fd4-ad43-11e9-1d11-8bd9d7e43378"
34

45
[compat]
56
Documenter = "~0.21"

docs/src/index.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,42 @@
1+
```@meta
2+
DocTestSetup = quote
3+
using MultivariateBases
4+
end
5+
```
6+
17
# MultivariateBases
28

39
[MultivariateBases.jl](https://github.com/JuliaAlgebra/MultivariateBases.jl) is a standardized API for multivariate polynomial bases
410
based on the [MultivariatePolynomials](https://github.com/JuliaAlgebra/MultivariatePolynomials.jl) API.
511

612
```@docs
713
AbstractPolynomialBasis
14+
maxdegree_basis
15+
basis_covering_monomials
816
FixedPolynomialBasis
17+
```
18+
19+
## Monomial basis
20+
21+
```@docs
922
MonomialBasis
1023
ScaledMonomialBasis
1124
```
25+
26+
## Orthogonal basis
27+
28+
```@docs
29+
AbstractMultipleOrthogonalBasis
30+
univariate_orthogonal_basis
31+
reccurence_first_coef
32+
reccurence_second_coef
33+
reccurence_third_coef
34+
reccurence_deno_coef
35+
ProbabilistsHermiteBasis
36+
PhysicistsHermiteBasis
37+
LaguerreBasis
38+
AbstractGegenbauerBasis
39+
LegendreBasis
40+
ChebyshevBasisFirstKind
41+
ChebyshevBasisSecondKind
42+
```

src/MultivariateBases.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,21 @@ using MultivariatePolynomials
77
const MP = MultivariatePolynomials
88

99
export AbstractPolynomialBasis
10-
export maxdegree_basis, empty_basis
10+
export maxdegree_basis, basis_covering_monomials, empty_basis
1111
include("interface.jl")
1212

1313
export AbstractMonomialBasis, MonomialBasis, ScaledMonomialBasis
1414
include("monomial.jl")
1515
include("scaled.jl")
1616

17-
export FixedPolynomialBasis, ChebyshevBasis
17+
export FixedPolynomialBasis, AbstractMultipleOrthogonalBasis, ProbabilistsHermiteBasis, PhysicistsHermiteBasis, LaguerreBasis
18+
export AbstractGegenbauerBasis, LegendreBasis, ChebyshevBasis, ChebyshevBasisFirstKind, ChebyshevBasisSecondKind
19+
export univariate_orthogonal_basis, reccurence_first_coef, reccurence_second_coef, reccurence_third_coef, reccurence_deno_coef
1820
include("fixed.jl")
21+
include("orthogonal.jl")
22+
include("hermite.jl")
23+
include("laguerre.jl")
24+
include("legendre.jl")
1925
include("chebyshev.jl")
2026

2127
end # module

src/chebyshev.jl

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
1-
struct ChebyshevBasis{P} <: AbstractPolynomialVectorBasis{P, Vector{P}}
1+
abstract type AbstractChebyshevBasis{P} <: AbstractGegenbauerBasis{P} end
2+
3+
polynomial_type(::Type{<:AbstractChebyshevBasis}, V::Type) = MP.polynomialtype(V, Float64)
4+
5+
reccurence_first_coef(::Type{<:AbstractChebyshevBasis}, degree) = 2
6+
reccurence_third_coef(::Type{<:AbstractChebyshevBasis}, degree) = -1
7+
reccurence_deno_coef(::Type{<:AbstractChebyshevBasis}, degree) = 1
8+
9+
"""
10+
struct ChebyshevBasisFirstKind{P} <: AbstractChebyshevBasis{P}
11+
polynomials::Vector{P}
12+
end
13+
14+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = \\frac{1}{\\sqrt{1 - x^2}}`` over the interval ``[-1, 1]``.
15+
"""
16+
struct ChebyshevBasisFirstKind{P} <: AbstractChebyshevBasis{P}
217
polynomials::Vector{P}
318
end
419

5-
function chebyshev_polynomial_first_kind(variable::MP.AbstractVariable, degree::Integer)
6-
@assert degree >= 0
7-
if degree == 0
8-
return [MA.@rewrite(0 * variable + 1)]
9-
elseif degree == 1
10-
return push!(chebyshev_polynomial_first_kind(variable, 0),
11-
MA.@rewrite(1 * variable + 0))
12-
else
13-
previous = chebyshev_polynomial_first_kind(variable, degree - 1)
14-
next = MA.@rewrite(2variable * previous[degree] - previous[degree - 1])
15-
push!(previous, next)
16-
return previous
20+
const ChebyshevBasis{P} = ChebyshevBasisFirstKind{P}
21+
22+
degree_one_univariate_polynomial(::Type{<:ChebyshevBasisFirstKind}, variable::MP.AbstractVariable) = MA.@rewrite(variable + 0)
23+
24+
"""
25+
struct ChebyshevBasisSecondKind{P} <: AbstractChebyshevBasis{P}
26+
polynomials::Vector{P}
1727
end
18-
end
1928
20-
function maxdegree_basis(B::Type{ChebyshevBasis}, variables, maxdegree::Int)
21-
univariate = [chebyshev_polynomial_first_kind(variable, maxdegree) for variable in variables]
22-
return ChebyshevBasis([
23-
prod(i -> univariate[i][degree(mono, variables[i]) + 1],
24-
eachindex(variables))
25-
for mono in MP.monomials(variables, 0:maxdegree)])
29+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = \\sqrt{1 - x^2}`` over the interval ``[-1, 1]``.
30+
"""
31+
struct ChebyshevBasisSecondKind{P} <: AbstractChebyshevBasis{P}
32+
polynomials::Vector{P}
2633
end
34+
35+
degree_one_univariate_polynomial(::Type{<:ChebyshevBasisSecondKind}, variable::MP.AbstractVariable) = MA.@rewrite(2variable + 0)

src/hermite.jl

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
abstract type AbstractHermiteBasis{P} <: AbstractMultipleOrthogonalBasis{P} end
2+
3+
polynomial_type(::Type{<:AbstractHermiteBasis}, V::Type) = MP.polynomialtype(V, Int)
4+
5+
even_odd_separated(::Type{<:AbstractHermiteBasis}) = true
6+
7+
reccurence_second_coef(::Type{<:AbstractHermiteBasis}, degree) = 0
8+
reccurence_deno_coef(::Type{<:AbstractHermiteBasis}, degree) = 1
9+
10+
"""
11+
struct ProbabilistsHermiteBasis{P} <: AbstractHermiteBasis{P}
12+
polynomials::Vector{P}
13+
end
14+
15+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = \\exp(-x^2/2)`` over the interval ``[-\\infty, \\infty]``.
16+
"""
17+
struct ProbabilistsHermiteBasis{P} <: AbstractHermiteBasis{P}
18+
polynomials::Vector{P}
19+
end
20+
reccurence_first_coef(::Type{<:ProbabilistsHermiteBasis}, degree) = 1
21+
reccurence_third_coef(::Type{<:ProbabilistsHermiteBasis}, degree) = -(degree - 1)
22+
degree_one_univariate_polynomial(::Type{<:ProbabilistsHermiteBasis}, variable::MP.AbstractVariable) = MA.@rewrite(1variable)
23+
24+
"""
25+
struct PhysicistsHermiteBasis{P} <: AbstractHermiteBasis{P}
26+
polynomials::Vector{P}
27+
end
28+
29+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = \\exp(-x^2)`` over the interval ``[-\\infty, \\infty]``.
30+
"""
31+
struct PhysicistsHermiteBasis{P} <: AbstractHermiteBasis{P}
32+
polynomials::Vector{P}
33+
end
34+
reccurence_first_coef(::Type{<:PhysicistsHermiteBasis}, degree) = 2
35+
reccurence_third_coef(::Type{<:PhysicistsHermiteBasis}, degree) = -2(degree - 1)
36+
degree_one_univariate_polynomial(::Type{<:PhysicistsHermiteBasis}, variable::MP.AbstractVariable) = MA.@rewrite(2variable)

src/interface.jl

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,34 @@ abstract type AbstractPolynomialBasis end
1212
function MP.polynomial(coefs::Vector, basis::AbstractPolynomialBasis)
1313
return MP.polynomial(i -> coefs[i], basis)
1414
end
15+
16+
"""
17+
maxdegree_basis(B::Type{<:AbstractPolynomialBasis}, variables, maxdegree::Int)
18+
19+
Return the basis of type `B` generating all polynomials of degree up to
20+
`maxdegree` with variables `variables`.
21+
"""
22+
function maxdegree_basis end
23+
24+
"""
25+
basis_covering_monomials(B::Type{<:AbstractPolynomialBasis}, monos::AbstractVector{<:AbstractMonomial})
26+
27+
Return the minimal basis of type `B` that can generate all polynomials of the
28+
monomial basis generated by `monos`.
29+
30+
## Examples
31+
32+
For example, to generate all the polynomials with nonzero coefficients for the
33+
monomials `x^4` and `x^2`, we need three polynomials as otherwise, we generate
34+
polynomials with nonzero constant term.
35+
```jldoctest
36+
julia> using DynamicPolynomials
37+
38+
julia> @polyvar x
39+
(x,)
40+
41+
julia> basis_covering_monomials(ChebyshevBasis, [x^4, x^2])
42+
ChebyshevBasisFirstKind{Polynomial{true,Float64}}(DynamicPolynomials.Polynomial{true,Float64}[8.0x⁴ - 8.0x² + 1.0, 2.0x² - 1.0, 1.0])
43+
```
44+
"""
45+
function basis_covering_monomials end

src/laguerre.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"""
2+
struct LaguerreBasis{P} <: AbstractMultipleOrthogonalBasis{P}
3+
polynomials::Vector{P}
4+
end
5+
6+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = \\exp(-x)`` over the interval ``[0, \\infty]``.
7+
"""
8+
struct LaguerreBasis{P} <: AbstractMultipleOrthogonalBasis{P}
9+
polynomials::Vector{P}
10+
end
11+
12+
polynomial_type(::Type{<:LaguerreBasis}, V::Type) = MP.polynomialtype(V, Float64)
13+
14+
even_odd_separated(::Type{<:LaguerreBasis}) = false
15+
16+
reccurence_first_coef(::Type{<:LaguerreBasis}, degree) = -1
17+
reccurence_second_coef(::Type{<:LaguerreBasis}, degree) = (2degree - 1)
18+
reccurence_third_coef(::Type{<:LaguerreBasis}, degree) = -(degree - 1)
19+
reccurence_deno_coef(::Type{<:LaguerreBasis}, degree) = degree
20+
21+
degree_one_univariate_polynomial(::Type{<:LaguerreBasis}, variable::MP.AbstractVariable) = MA.@rewrite(1 - variable)

src/legendre.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
struct AbstractGegenbauerBasis{P} <: AbstractMultipleOrthogonalBasis{P}
3+
polynomials::Vector{P}
4+
end
5+
6+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = (1 - x^2)^{\\alpha - 1/2}`` over the interval ``[-1, 1]``.
7+
"""
8+
abstract type AbstractGegenbauerBasis{P} <: AbstractMultipleOrthogonalBasis{P} end
9+
10+
even_odd_separated(::Type{<:AbstractGegenbauerBasis}) = true
11+
reccurence_second_coef(::Type{<:AbstractGegenbauerBasis}, degree) = 0
12+
13+
"""
14+
struct LegendreBasis{P} <: AbstractGegenbauerBasis{P}
15+
polynomials::Vector{P}
16+
end
17+
18+
Orthogonal polynomial with respect to the univariate weight function ``w(x) = 1`` over the interval ``[-1, 1]``.
19+
"""
20+
struct LegendreBasis{P} <: AbstractGegenbauerBasis{P}
21+
polynomials::Vector{P}
22+
end
23+
24+
polynomial_type(::Type{<:LegendreBasis}, V::Type) = MP.polynomialtype(V, Float64)
25+
26+
reccurence_first_coef(::Type{<:LegendreBasis}, degree) = (2degree - 1)
27+
reccurence_third_coef(::Type{<:LegendreBasis}, degree) = -(degree - 1)
28+
reccurence_deno_coef(::Type{<:LegendreBasis}, degree) = degree
29+
30+
degree_one_univariate_polynomial(::Type{<:LegendreBasis}, variable::MP.AbstractVariable) = MA.@rewrite(variable + 0)

src/monomial.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ empty_basis(MB::Type{<:AbstractMonomialBasis{MT}}) where {MT} = MB(MP.emptymonov
1111
function maxdegree_basis(B::Type{<:AbstractMonomialBasis}, variables, maxdegree::Int)
1212
return B(MP.monomials(variables, 0:maxdegree))
1313
end
14+
function basis_covering_monomials(B::Type{<:AbstractMonomialBasis}, monos::AbstractVector{<:AbstractMonomial})
15+
return B(monos)
16+
end
1417

1518
# The `i`th index of output is the index of occurence of `x[i]` in `y`,
1619
# or `0` if it does not occur.

0 commit comments

Comments
 (0)