Skip to content

Commit c3bdcab

Browse files
authored
Add Fixed basis (#52)
* Add Fixed basis * Fixes * Fix format * Add doc * Clean up badges * Fix format * Fix
1 parent 37d9cf3 commit c3bdcab

File tree

8 files changed

+147
-19
lines changed

8 files changed

+147
-19
lines changed

README.md

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
# Multivariate Bases
22

3-
| **Documentation** | **Build Status** | **Social** |
4-
|:-----------------:|:----------------:|:----------:|
5-
| [![][docs-stable-img]][docs-stable-url] | [![Build Status][build-img]][build-url] | [![Gitter][gitter-img]][gitter-url] |
6-
| [![][docs-latest-img]][docs-latest-url] | [![Codecov branch][codecov-img]][codecov-url] | [<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/a/af/Discourse_logo.png/799px-Discourse_logo.png" width="64">][discourse-url] |
3+
[![][docs-stable-img]][docs-stable-url] [![][docs-latest-img]][docs-latest-url] [![Build Status][build-img]][build-url] [![Codecov branch][codecov-img]][codecov-url]
74

85
This package provides a standardized API for multivariate polynomial bases
96
based on the [MultivariatePolynomials](https://github.com/JuliaAlgebra/MultivariatePolynomials.jl) API.
107

118
It defines the following basis:
12-
* `FixedPolynomialBasis`: A polynomial basis described by a list of polynomials.
9+
* `FixedBasis`: A polynomial basis described by a list of polynomials.
1310
* Monomial bases: `MonomialBasis` and `ScaledMonomialBasis`.
1411
* Orthogonal bases:
1512
- Hermite bases: `ProbabilistsHermiteBasis` and `PhysicistsHermiteBasis`.
@@ -34,7 +31,3 @@ See the documentation for more details.
3431
[build-url]: https://github.com/JuliaAlgebra/MultivariateBases.jl/actions?query=workflow%3ACI
3532
[codecov-img]: http://codecov.io/github/JuliaAlgebra/MultivariateBases.jl/coverage.svg?branch=master
3633
[codecov-url]: http://codecov.io/github/JuliaAlgebra/MultivariateBases.jl?branch=master
37-
38-
[gitter-url]: https://gitter.im/JuliaAlgebra/Lobby?utm_source=share-link&utm_medium=link&utm_campaign=share-link
39-
[gitter-img]: https://badges.gitter.im/JuliaAlgebra/Lobby.svg
40-
[discourse-url]: https://discourse.julialang.org/c/domain/opt

docs/src/index.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ maxdegree_basis
1515
explicit_basis_covering
1616
```
1717

18+
## Basis elements
19+
20+
```@docs
21+
Polynomial
22+
SemisimpleElement
23+
```
24+
1825
## Monomial basis
1926

2027
```@docs
@@ -40,3 +47,10 @@ ChebyshevFirstKind
4047
ChebyshevSecondKind
4148
Trigonometric
4249
```
50+
51+
## Additional basis
52+
53+
```@docs
54+
FixedBasis
55+
SemisimpleBasis
56+
```

src/MultivariateBases.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,5 +82,6 @@ function MA.promote_operation(
8282
end
8383

8484
include("arithmetic.jl")
85+
include("fixed.jl")
8586

8687
end # module

src/arithmetic.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,18 @@ for op in [:+, :-]
7676
end
7777
end
7878

79+
function term_element(α, p::Polynomial{B,M}) where {B,M}
80+
return algebra_element(
81+
sparse_coefficients(MP.term(α, p.monomial)),
82+
FullBasis{B,M}(),
83+
)
84+
end
85+
86+
# Needed by `SymbolicWedderburn` which multiplies elements of the basis by `Int`
87+
# We'll see if `::Number` is too restrictive
88+
# Should be able to remove once https://github.com/kalmarek/SymbolicWedderburn.jl/issues/88 is closed
89+
Base.:*::Number, p::Polynomial) = term_element(α, p)
90+
7991
function MA.operate!(op::Union{typeof(+),typeof(-),typeof(*)}, p::_APL, q::_AE)
8092
return MA.operate!(op, p, MP.polynomial(q))
8193
end

src/fixed.jl

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
struct FixedBasis{B,M,T,V} <:
3+
SA.ExplicitBasis{SA.AlgebraElement{Algebra{FullBasis{B,M},B,M},T,V},Int}
4+
elements::Vector{SA.AlgebraElement{Algebra{FullBasis{B,M},B,M},T,V}}
5+
end
6+
7+
Fixed basis with polynomials `elements`.
8+
"""
9+
struct FixedBasis{B,M,T,V} <:
10+
SA.ExplicitBasis{SA.AlgebraElement{Algebra{FullBasis{B,M},B,M},T,V},Int}
11+
elements::Vector{SA.AlgebraElement{Algebra{FullBasis{B,M},B,M},T,V}}
12+
end
13+
14+
Base.length(b::FixedBasis) = length(b.elements)
15+
Base.getindex(b::FixedBasis, i::Integer) = b.elements[i]
16+
17+
function Base.show(io::IO, b::FixedBasis)
18+
print(io, "FixedBasis(")
19+
_show_vector(io, MIME"text/plain"(), b.elements)
20+
print(io, ")")
21+
return
22+
end
23+
24+
"""
25+
struct SemisimpleBasis{T,I,B<:SA.ExplicitBasis{T,I}} <: SA.ExplicitBasis{T,I}
26+
bases::Vector{B}
27+
end
28+
29+
Semisimple basis for use with [SymbolicWedderburn](https://github.com/kalmarek/SymbolicWedderburn.jl/).
30+
Its elements are of [`SemisimpleElement`](@ref)s.
31+
"""
32+
struct SemisimpleBasis{T,I,B<:SA.ExplicitBasis{T,I}} <: SA.ExplicitBasis{T,I}
33+
bases::Vector{B}
34+
end
35+
36+
Base.length(b::SemisimpleBasis) = length(first(b.bases))
37+
38+
"""
39+
struct SemisimpleElement{P}
40+
polynomials::Vector{P}
41+
end
42+
43+
Elements of [`SemisimpleBasis`](@ref).
44+
"""
45+
struct SemisimpleElement{P}
46+
elements::Vector{P}
47+
end
48+
SA.star(p::SemisimpleElement) = SemisimpleElement(SA.star.(p.elements))
49+
50+
function Base.getindex(b::SemisimpleBasis, i::Integer)
51+
return SemisimpleElement(getindex.(b.bases, i))
52+
end
53+
54+
function Base.show(io::IO, b::SemisimpleBasis)
55+
if length(b.bases) == 1
56+
print(io, "Simple basis:")
57+
else
58+
print(io, "Semisimple basis with $(length(b.bases)) simple sub-bases:")
59+
end
60+
for basis in b.bases
61+
println(io)
62+
print(io, " ")
63+
print(io, basis)
64+
end
65+
end

src/monomial.jl

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,20 +258,26 @@ function constant_algebra_element(::Type{<:SubBasis{B,M}}, α) where {B,M}
258258
)
259259
end
260260

261-
function _show(io::IO, mime::MIME, basis::SubBasis{B}) where {B}
262-
print(io, "SubBasis{$(nameof(B))}")
263-
print(io, "([")
261+
# TODO use Base.show_vector here, maybe by wrapping the `generator` vector
262+
# into something that spits objects wrapped with the `mime` type
263+
function _show_vector(io::IO, mime::MIME, v)
264+
print(io, '[')
264265
first = true
265-
# TODO use Base.show_vector here, maybe by wrapping the `generator` vector
266-
# into something that spits objects wrapped with the `mime` type
267-
for mono in basis.monomials
266+
for el in v
268267
if !first
269268
print(io, ", ")
270269
end
271270
first = false
272-
show(io, mime, mono)
271+
show(io, mime, el)
273272
end
274-
return print(io, "])")
273+
return print(io, ']')
274+
end
275+
276+
function _show(io::IO, mime::MIME, basis::SubBasis{B}) where {B}
277+
print(io, "SubBasis{$(nameof(B))}(")
278+
_show_vector(io, mime, basis.monomials)
279+
print(io, ')')
280+
return
275281
end
276282

277283
function Base.show(io::IO, mime::MIME"text/plain", basis::SubBasis)
@@ -449,7 +455,7 @@ function SA.coeffs(
449455
return SA.SparseCoefficients(_vec(source.monomials), _vec(cfs))
450456
else
451457
res = SA.zero_coeffs(
452-
_promote_coef(_promote_coef(valtype(cfs), B1), B2),
458+
_promote_coef(_promote_coef(SA.value_type(cfs), B1), B2),
453459
target,
454460
)
455461
return SA.coeffs!(res, cfs, source, target)

src/polynomial.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# TODO Add to MultivariatePolynomials
22
MP.variables(p::SA.AlgebraElement) = MP.variables(explicit_basis(p))
33
Base.keytype(p::MP.AbstractPolynomialLike) = MP.monomial_type(p)
4-
Base.valtype(p::MP.AbstractPolynomialLike) = MP.coefficient_type(p)
4+
SA.value_type(p::MP.AbstractPolynomialLike) = MP.coefficient_type(p)
55
#Base.keys(p::MP.AbstractPolynomial) = MP.monomials(p)
66
SA.nonzero_pairs(p::MP.AbstractPolynomialLike) = MP.terms(p)
77
function Base.similar(p::PT, ::Type{T}) where {PT<:MP.AbstractPolynomial,T}
@@ -41,6 +41,16 @@ end
4141

4242
abstract type AbstractMonomialIndexed end
4343

44+
"""
45+
struct Polynomial{B<:AbstractMonomialIndexed,M<:MP.AbstractMonomial}
46+
monomial::M
47+
function Polynomial{B}(mono::MP.AbstractMonomial) where {B}
48+
return new{B,typeof(mono)}(mono)
49+
end
50+
end
51+
52+
Polynomial of basis `FullBasis{B,M}()` at index `monomial`.
53+
"""
4454
struct Polynomial{B<:AbstractMonomialIndexed,M<:MP.AbstractMonomial}
4555
monomial::M
4656
function Polynomial{B}(mono::MP.AbstractMonomial) where {B}

test/fixed.jl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using Test
2+
import StarAlgebras as SA
3+
using MultivariateBases
4+
const MB = MultivariateBases
5+
using DynamicPolynomials
6+
7+
@testset "FixedBasis" begin
8+
@polyvar x y
9+
x_term = MB.term_element(1, MB.Polynomial{MB.Monomial}(x))
10+
y_term = MB.term_element(1, MB.Polynomial{MB.Monomial}(y))
11+
p1 = x_term + im * y_term
12+
p2 = x_term - im * y_term
13+
fixed = MB.FixedBasis([p1, p2])
14+
@test length(fixed) == 2
15+
@test fixed[1] p1
16+
@test fixed[2] p2
17+
@test sprint(show, fixed) == "FixedBasis([$p1, $p2])"
18+
19+
semi = MB.SemisimpleBasis([MB.FixedBasis([p1]), MB.FixedBasis([p2])])
20+
@test length(semi) == 1
21+
@test sprint(show, semi) ==
22+
"Semisimple basis with 2 simple sub-bases:\n FixedBasis([$p1])\n FixedBasis([$p2])"
23+
mult = semi[1]
24+
@test all(mult.elements .≈ [p1, p2])
25+
smult = SA.star(mult)
26+
@test all(smult.elements .≈ [p2, p1])
27+
end

0 commit comments

Comments
 (0)