Skip to content

Commit f5201b8

Browse files
authored
Add flags to PlusOperator and TimesOperator (#338)
* isbandedblockbanded in Plus and TimesOperator * israggedbelow in Plus and TimesOperator * version bump to v0.7.57
1 parent 6353b9c commit f5201b8

File tree

4 files changed

+63
-38
lines changed

4 files changed

+63
-38
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "ApproxFunBase"
22
uuid = "fbd15aa5-315a-5a7d-a8a4-24992e37be05"
3-
version = "0.7.56"
3+
version = "0.7.57"
44

55
[deps]
66
AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c"

src/Multivariate/Multivariate.jl

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,12 @@ points(f::BivariateFun,k...)=points(space(f),size(f,1),size(f,2),k...)
5757

5858

5959
function *(vx::LowRankFun, u0::ProductFun)
60-
sum(zip(vx.A, vx.B)) do (a,b)
61-
transpose(b*(transpose(a*u0)))
60+
A, B = vx.A, vx.B
61+
ret = transpose(B[begin]*(transpose(A[begin]*u0)))
62+
for i in eachindex(A, B)[begin+1:end]
63+
ret += transpose(B[i]*(transpose(A[i]*u0)))
6264
end
65+
ret
6366
end
6467

6568
*(a::ProductFun,b::LowRankFun)=b*a

src/Operators/general/algebra.jl

Lines changed: 55 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,33 @@ struct PlusOperator{T,BW,SZ,O<:Operator{T},BBW,SBBW} <: Operator{T}
1010
sz::SZ
1111
blockbandwidths::BBW
1212
subblockbandwidths::SBBW
13+
isbandedblockbanded::Bool
14+
israggedbelow::Bool
1315

1416
function PlusOperator{T,BW,SZ,O,BBW,SBBW}(opsin::Vector{O}, bw::BW,
15-
sz::SZ, bbw::BBW, sbbw::SBBW) where {T,O<:Operator{T},BW,SZ,BBW,SBBW}
17+
sz::SZ, bbw::BBW, sbbw::SBBW,
18+
ibbb::Bool, irb::Bool) where {T,O<:Operator{T},BW,SZ,BBW,SBBW}
1619
all(x -> size(x) == sz, opsin) || throw("sizes of operators are incompatible")
17-
new{T,BW,SZ,O,BBW,SBBW}(opsin, bw, sz, bbw,sbbw)
20+
new{T,BW,SZ,O,BBW,SBBW}(opsin, bw, sz, bbw,sbbw, ibbb, irb)
1821
end
1922
end
2023

2124
bandwidthsmax(ops, f=bandwidths) = mapreduce(f, (t1, t2) -> max.(t1, t2), ops, init=(-720, -720)) #= approximate (-∞,-∞) =#
2225

23-
function PlusOperator(opsin::Vector{O}, args...) where {O<:Operator}
24-
PlusOperator{eltype(O)}(opsin, args...)
26+
function PlusOperator(ops::Vector{O}, args...) where {O<:Operator}
27+
PlusOperator{eltype(O)}(ops, args...)
2528
end
26-
function PlusOperator{ET}(opsin::Vector{O},
27-
bw::Tuple{Any,Any}=bandwidthsmax(opsin),
28-
sz::Tuple{Any,Any}=size(first(opsin)),
29-
bbw::Tuple{Any,Any}=bandwidthsmax(opsin, blockbandwidths),
30-
sbbw::Tuple{Any,Any}=bandwidthsmax(opsin, subblockbandwidths),
29+
function PlusOperator{ET}(ops::Vector{O},
30+
bw::Tuple{Any,Any}=bandwidthsmax(ops),
31+
sz::Tuple{Any,Any}=size(first(ops)),
32+
bbw::Tuple{Any,Any}=bandwidthsmax(ops, blockbandwidths),
33+
sbbw::Tuple{Any,Any}=bandwidthsmax(ops, subblockbandwidths),
34+
ibbb::Bool=all(isbandedblockbanded, ops),
35+
irb::Bool=all(israggedbelow, ops),
3136
) where {ET,O<:Operator{ET}}
3237

33-
PlusOperator{ET,typeof(bw),typeof(sz),O,typeof(bbw),typeof(sbbw)}(opsin, bw, sz, bbw, sbbw)
38+
PlusOperator{ET,typeof(bw),typeof(sz),O,typeof(bbw),typeof(sbbw)}(
39+
ops, bw, sz, bbw, sbbw, ibbb, irb)
3440
end
3541

3642
for (OP, mn) in ((:colstart, :min), (:colstop, :max), (:rowstart, :min), (:rowstop, :max))
@@ -57,7 +63,9 @@ function convert(::Type{Operator{T}}, P::PlusOperator) where {T}
5763
ops = P.ops
5864
PlusOperator(eltype(ops) <: Operator{T} ? ops :
5965
_convertops(Operator{T}, ops),
60-
bandwidths(P), size(P), blockbandwidths(P), subblockbandwidths(P))::Operator{T}
66+
bandwidths(P), size(P), blockbandwidths(P),
67+
subblockbandwidths(P), isbandedblockbanded(P),
68+
israggedbelow(P))::Operator{T}
6169
end
6270
end
6371

@@ -221,9 +229,12 @@ struct TimesOperator{T,BW,SZ,O<:Operator{T},BBW,SBBW} <: Operator{T}
221229
sz::SZ
222230
blockbandwidths::BBW
223231
subblockbandwidths::SBBW
232+
isbandedblockbanded::Bool
233+
israggedbelow::Bool
224234

225235
function TimesOperator{T,BW,SZ,O,BBW,SBBW}(ops::Vector{O}, bw::BW,
226-
sz::SZ, bbw::BBW, sbbw::SBBW) where {T,O<:Operator{T},BW,SZ,BBW,SBBW}
236+
sz::SZ, bbw::BBW, sbbw::SBBW,
237+
ibbb::Bool, irb::Bool) where {T,O<:Operator{T},BW,SZ,BBW,SBBW}
227238
# check compatible
228239
for k = 1:length(ops)-1
229240
size(ops[k], 2) == size(ops[k+1], 1) || throw(ArgumentError("incompatible operator sizes"))
@@ -241,7 +252,7 @@ struct TimesOperator{T,BW,SZ,O<:Operator{T},BBW,SBBW} <: Operator{T}
241252
newops = ops
242253
end
243254

244-
new{T,BW,SZ,O,BBW,SBBW}(newops, bw, sz, bbw, sbbw)
255+
new{T,BW,SZ,O,BBW,SBBW}(newops, bw, sz, bbw, sbbw, ibbb, irb)
245256
end
246257
end
247258

@@ -260,18 +271,22 @@ function TimesOperator(ops::AbstractVector{O},
260271
sz::Tuple{Any,Any}=_timessize(ops),
261272
bbw::Tuple{Any,Any}=bandwidthssum(ops, blockbandwidths),
262273
sbbw::Tuple{Any,Any}=bandwidthssum(ops, subblockbandwidths),
263-
) where {T,O<:Operator{T}}
264-
TimesOperator{T,typeof(bw),typeof(sz),O,typeof(bbw),typeof(sbbw)}(convert_vector(ops),
265-
bw, sz, bbw, sbbw)
274+
ibbb::Bool=all(isbandedblockbanded, ops),
275+
irb::Bool=all(israggedbelow, ops),
276+
) where {O<:Operator}
277+
TimesOperator{eltype(O),typeof(bw),typeof(sz),O,typeof(bbw),typeof(sbbw)}(
278+
convert_vector(ops), bw, sz, bbw, sbbw, ibbb, irb)
266279
end
267280

268281
_extractops(A::TimesOperator, ::typeof(*)) = A.ops
269282

270283
function TimesOperator(A::Operator, B::Operator)
271284
v = collateops(*, A, B)
285+
ibbb = all(isbandedblockbanded, (A, B))
286+
irb = all(israggedbelow, (A, B))
272287
TimesOperator(convert_vector(v), _bandwidthssum(A, B), _timessize((A, B)),
273288
_bandwidthssum(A, B, blockbandwidths),
274-
_bandwidthssum(A, B, subblockbandwidths))
289+
_bandwidthssum(A, B, subblockbandwidths), ibbb, irb)
275290
end
276291

277292

@@ -285,7 +300,8 @@ function convert(::Type{Operator{T}}, P::TimesOperator) where {T}
285300
TimesOperator(eltype(ops) <: Operator{T} ? ops :
286301
_convertops(Operator{T}, ops),
287302
bandwidths(P), size(P), blockbandwidths(P),
288-
subblockbandwidths(P))::Operator{T}
303+
subblockbandwidths(P), isbandedblockbanded(P),
304+
israggedbelow(P))::Operator{T}
289305
end
290306
end
291307

@@ -298,14 +314,13 @@ end
298314
@inline function _promotetimes(opsin,
299315
dsp=domainspace(last(opsin)),
300316
sz=_timessize(opsin),
301-
anytimesop=true,
302-
)
317+
anytimesop=true)
303318

304319
@assert length(opsin) > 1 "need at least 2 operators"
305-
ops, bw, bbw, sbbw = __promotetimes(opsin, dsp, anytimesop)
306-
TimesOperator(ops, bw, sz, bbw, sbbw)
320+
ops, bw, bbw, sbbw, ibbb, irb = __promotetimes(opsin, dsp, anytimesop)
321+
TimesOperator(ops, bw, sz, bbw, sbbw, ibbb, irb)
307322
end
308-
@inline function __promotetimes(opsin, dsp, anytimesop)
323+
function __promotetimes(opsin, dsp, anytimesop)
309324
ops = Vector{Operator{promote_eltypeof(opsin)}}(undef, 0)
310325
sizehint!(ops, length(opsin))
311326

@@ -322,9 +337,14 @@ end
322337
end
323338
end
324339
reverse!(ops), bandwidthssum(ops), bandwidthssum(ops, blockbandwidths),
325-
bandwidthssum(ops, subblockbandwidths)
340+
bandwidthssum(ops, subblockbandwidths), all(isbandedblockbanded, ops),
341+
all(israggedbelow, ops)
342+
end
343+
@inline function _op_bws(op)
344+
[op], bandwidths(op), blockbandwidths(op),
345+
subblockbandwidths(op), isbandedblockbanded(op),
346+
israggedbelow(op)
326347
end
327-
_op_bws(op) = [op], bandwidths(op), blockbandwidths(op), subblockbandwidths(op)
328348
@inline function __promotetimes(opsin::Tuple{Operator,Operator}, dsp, anytimesop)
329349
@assert !any(Base.Fix2(isa, TimesOperator), opsin) "TimesOperator should have been extracted already"
330350

@@ -343,9 +363,12 @@ _op_bws(op) = [op], bandwidths(op), blockbandwidths(op), subblockbandwidths(op)
343363
else
344364
op2_dsp = op2:dsp
345365
op1_dsp = op1:rangespace(op2_dsp)
346-
return [op1_dsp, op2_dsp], bandwidthssum((op1_dsp, op2_dsp)),
347-
bandwidthssum((op1_dsp, op2_dsp), blockbandwidths),
348-
bandwidthssum((op1_dsp, op2_dsp), subblockbandwidths)
366+
ops = (op1_dsp, op2_dsp)
367+
return [ops...], bandwidthssum(ops),
368+
bandwidthssum(ops, blockbandwidths),
369+
bandwidthssum(ops, subblockbandwidths),
370+
all(isbandedblockbanded, ops),
371+
all(israggedbelow, ops)
349372
end
350373
end
351374

@@ -361,9 +384,9 @@ bandwidths(P::PlusOrTimesOp) = P.bandwidths
361384
blockbandwidths(P::PlusOrTimesOp) = P.blockbandwidths
362385
subblockbandwidths(P::PlusOrTimesOp) = P.subblockbandwidths
363386

364-
isbandedblockbanded(P::PlusOrTimesOp) = all(isbandedblockbanded, P.ops)
387+
isbandedblockbanded(P::PlusOrTimesOp) = P.isbandedblockbanded
365388

366-
israggedbelow(P::PlusOrTimesOp) = isbandedbelow(P) || all(israggedbelow, P.ops)
389+
israggedbelow(P::PlusOrTimesOp) = P.israggedbelow
367390

368391
Base.stride(P::TimesOperator) = mapreduce(stride, gcd, P.ops)
369392

@@ -552,7 +575,8 @@ for OP in (:(adjoint), :(transpose))
552575
strictconvert(Vector, reverse!(map($OP, A.ops))),
553576
reverse(bandwidths(A)), reverse(size(A)),
554577
reverse(blockbandwidths(A)),
555-
reverse(subblockbandwidths(A))
578+
reverse(subblockbandwidths(A)),
579+
isbandedblockbanded(A),
556580
)
557581
end
558582

src/Space.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,10 +133,8 @@ Implement a [`Conversion`](@ref) operator or override [`coefficients`](@ref) to
133133
134134
# Examples
135135
```jldoctest
136-
julia> f = Fun(x->x^2, NormalizedLegendre());
137-
138-
julia> ApproxFunBase.canonicalspace(f)
139-
Legendre()
136+
julia> ApproxFunBase.canonicalspace(NormalizedChebyshev())
137+
Chebyshev()
140138
```
141139
"""
142140
canonicalspace(T) = T

0 commit comments

Comments
 (0)