Skip to content

Commit d844ef4

Browse files
authored
sampling, extrema (#242) and preliminary support orthogonalising quasimatrices (#246)
* sampling and orthogonalising quasimatrices * Fix #242 * Update Project.toml * Fixlegendre transform on matrices
1 parent ec0ed94 commit d844ef4

File tree

7 files changed

+58
-10
lines changed

7 files changed

+58
-10
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ FastTransforms = "0.16.6, 0.17"
4747
FillArrays = "1"
4848
HypergeometricFunctions = "0.3.4"
4949
InfiniteArrays = " 0.15"
50-
InfiniteLinearAlgebra = "0.10"
50+
InfiniteLinearAlgebra = "0.10.1"
5151
IntervalSets = "0.7"
52-
LazyArrays = "2.5.1"
52+
LazyArrays = "2.7"
5353
LazyBandedMatrices = "0.11"
5454
MutableArithmetics = "1"
5555
QuasiArrays = "0.12"

src/ClassicalOrthogonalPolynomials.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import Base: @_inline_meta, axes, getindex, unsafe_getindex, convert, prod, *, /
1111
IndexStyle, IndexLinear, ==, OneTo, tail, similar, copyto!, copy, setindex,
1212
first, last, Slice, size, length, axes, IdentityUnitRange, sum, _sum, cumsum,
1313
to_indices, tail, getproperty, inv, show, isapprox, summary,
14-
findall, searchsortedfirst, diff
14+
findall, searchsortedfirst, diff, minimum, maximum, extrema
1515
import Base.Broadcast: materialize, BroadcastStyle, broadcasted, Broadcasted
1616
import LazyArrays: MemoryLayout, Applied, ApplyStyle, flatten, _flatten, adjointlayout,
1717
sub_materialize, arguments, sub_paddeddata, paddeddata, AbstractPaddedLayout, PaddedColumns, resizedata!, LazyVector, ApplyLayout, call,

src/adaptivetransform.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ ContinuumArrays.transform_ldiv_size(::Tuple{<:Any,InfiniteCardinal{0}}, A::Abstr
77
padchop!(cfs, tol, ax...) = pad(chop!(cfs, tol), ax...)
88
padchop(cfs, tol, ax...) = pad(chop(cfs, tol), ax...)
99

10+
padrows(a::AbstractVector, ax) = pad(a, ax)
11+
padrows(a::AbstractMatrix, ax) = pad(a, ax, :)
12+
1013
# ax will impose block structure for us
1114
padchop!(cfs::BlockedVector, tol, ax...) = padchop!(cfs.blocks, tol, ax...)
1215

@@ -56,7 +59,6 @@ end
5659
function adaptivetransform_ldiv(A::AbstractQuasiArray{U}, f::AbstractQuasiMatrix{V}) where {U,V}
5760
T = promote_type(eltype(U),eltype(V))
5861

59-
bx = axes(f,2)
6062
r = checkpoints(A)
6163
fr = f[r,:]
6264
maxabsfr = norm(fr,Inf)
@@ -69,12 +71,12 @@ function adaptivetransform_ldiv(A::AbstractQuasiArray{U}, f::AbstractQuasiMatrix
6971
cfs = An \ f
7072
maxabsc = maximum(abs, cfs)
7173
if maxabsc == 0 && maxabsfr == 0
72-
return pad(similar(cfs,0,size(cfs,2)), ax, bx)
74+
return pad(similar(cfs,0,size(cfs,2)), ax, :)
7375
end
7476

7577
if maximum(abs,@views(cfs[end-2:end,:])) < 10tol*maxabsc
7678
n = size(cfs,1)
77-
c = padchop(cfs, tol, ax, bx)
79+
c = padchop(cfs, tol, ax, :)
7880
un = A * c # expansion
7981
# we allow for transformed coefficients being a different size
8082
##TODO: how to do scaling for unnormalized bases like Jacobi?

src/classical/jacobi.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ ldiv(P::Jacobi{V}, f::Inclusion{T}) where {T,V} = _op_ldiv(P, f)
288288
ldiv(P::Jacobi{V}, f::AbstractQuasiFill{T,1}) where {T,V} = _op_ldiv(P, f)
289289
function transform_ldiv(P::Jacobi{V}, f::AbstractQuasiArray) where V
290290
T = ChebyshevT{V}()
291-
pad(FastTransforms.th_cheb2jac(paddeddata(T \ f), P.a, P.b, 1), axes(P,2), tail(axes(f))...)
291+
padrows(FastTransforms.th_cheb2jac(paddeddata(T \ f), P.a, P.b, 1), axes(P,2))
292292
end
293293

294294

src/classical/legendre.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ ldiv(P::Legendre{V}, f::AbstractQuasiFill{T,1}) where {T,V} = _op_ldiv(P, f)
189189
function transform_ldiv(::Legendre{V}, f::Union{AbstractQuasiVector,AbstractQuasiMatrix}) where V
190190
T = ChebyshevT{V}()
191191
dat = transform_ldiv(T, f)
192-
pad(th_cheb2leg(paddeddata(dat)), axes(dat)...)
192+
padrows(th_cheb2leg(paddeddata(dat), 1), axes(dat,1))
193193
end
194194

195195
plan_transform(::Legendre{T}, szs::NTuple{N,Int}, dims...) where {T,N} = JacobiTransformPlan(FastTransforms.plan_th_cheb2leg!(T, szs, dims...), plan_chebyshevtransform(T, szs, dims...))

src/roots.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,27 @@ function _searchsortedfirst(::ExpansionLayout{<:AbstractOPLayout}, f, x; iterati
4949
end
5050
(a+b)/2
5151
end
52-
searchsortedfirst(f::AbstractQuasiVector, x; kwds...) = _searchsortedfirst(MemoryLayout(f), f, x; kwds...)
52+
searchsortedfirst(f::AbstractQuasiVector, x; kwds...) = _searchsortedfirst(MemoryLayout(f), f, x; kwds...)
53+
54+
function sample(f::AbstractQuasiVector, n...)
55+
g = cumsum(f)
56+
searchsortedfirst.(Ref(g/last(g)), rand(n...))
57+
end
58+
59+
####
60+
# min/max/extrema
61+
####
62+
function minimum(f::AbstractQuasiVector)
63+
r = findall(iszero, diff(f))
64+
min(first(f), minimum(f[r]), last(f))
65+
end
66+
67+
function maximum(f::AbstractQuasiVector)
68+
r = findall(iszero, diff(f))
69+
max(first(f), maximum(f[r]), last(f))
70+
end
71+
72+
function extrema(f::AbstractQuasiVector)
73+
r = findall(iszero, diff(f))
74+
extrema([first(f); f[r]; last(f)])
75+
end

test/test_roots.jl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using ClassicalOrthogonalPolynomials, Test
1+
using ClassicalOrthogonalPolynomials, Random, Test
2+
using ClassicalOrthogonalPolynomials: sample
3+
4+
Random.seed!(5)
25

36
@testset "roots" begin
47
T = Chebyshev()
@@ -8,4 +11,24 @@ using ClassicalOrthogonalPolynomials, Test
811

912
g = x -> x + 0.001cos(x)
1013
@test searchsortedfirst(expand(T, g), 0.1) searchsortedfirst(expand(P, g), 0.1) findall(iszero, expand(T, x -> g(x)-0.1))[1]
14+
end
15+
16+
@testset "sample" begin
17+
f = expand(Chebyshev(), exp)
18+
@test sum(sample(f, 100_000))/100_000 0.31 atol=1E-2
19+
end
20+
21+
@testset "det point sampling" begin
22+
P = Normalized(Legendre()); x = axes(P,1)
23+
A = cos.((0:5)' .* x)
24+
@test (Legendre() \ A)[1:5,1] [1; zeros(4)] # test transform bug
25+
@test (P \ A)[1:5,1] [sqrt(2); zeros(4)]
26+
Q,R = qr(P \ A)
27+
end
28+
29+
@testset "minimum/maximum/extrema (#242)" begin
30+
f = expand(ChebyshevT(), x -> exp(x) * cos(100x.^2))
31+
@test minimum(f) -2.682833127491678
32+
@test maximum(f) 2.6401248792053362
33+
@test extrema(f) == (minimum(f), maximum(f))
1134
end

0 commit comments

Comments
 (0)