Skip to content

Commit c14f5e0

Browse files
authored
Propagate Tuples in InterlaceOperator (#259)
* propagate tuples in InterlateOperator * Add vector parameter to ArraySpace * Bugfix to Fun MatrixSppace constructor * relax MatrixSpace sig in ProductSpaceOperators
1 parent e8fb103 commit c14f5e0

File tree

5 files changed

+38
-36
lines changed

5 files changed

+38
-36
lines changed

src/Operators/Operator.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Abstract type to represent linear operators between spaces.
1414
"""
1515
abstract type Operator{T} end #T is the entry type, Float64 or Complex{Float64}
1616

17+
const VectorOrTupleOfOp{O<:Operator} = Union{AbstractVector{O}, Tuple{O, Vararg{O}}}
18+
1719
eltype(::Operator{T}) where {T} = T
1820
eltype(::Type{<:Operator{T}}) where {T} = T
1921
eltype(::Type{OT}) where {OT<:Operator} = eltype(supertype(OT))

src/Operators/general/InterlaceOperator.jl

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function spacescompatible(A::AbstractMatrix{T}) where T<:Operator
3131
true
3232
end
3333

34-
spacescompatible(A::AbstractVector{T}) where {T<:Operator} = spacescompatible(map(domainspace,A))
34+
spacescompatible(A::VectorOrTupleOfOp) = spacescompatible(map(domainspace,A))
3535

3636
function domainspace(A::AbstractMatrix{T}) where T<:Operator
3737
if !spacescompatible(A)
@@ -42,13 +42,12 @@ function domainspace(A::AbstractMatrix{T}) where T<:Operator
4242
Space(spl)
4343
end
4444

45-
function rangespace(A::AbstractVector{T}) where T<:Operator
45+
function rangespace(A::VectorOrTupleOfOp)
4646
if !spacescompatible(A)
4747
error("Cannot construct rangespace for $A as domain spaces are not compatible")
4848
end
49-
50-
spl=map(rangespace,A)
51-
Space(spl)
49+
spl=map(rangespace, A)
50+
ArraySpace(_convert_vector_or_svector(spl), first(spl))
5251
end
5352

5453
promotespaces(A::AbstractMatrix{<:Operator}) = promotespaces(Matrix(A))
@@ -110,15 +109,16 @@ function InterlaceOperator(ops::AbstractMatrix{<:Operator},ds::Space,rs::Space)
110109
l,u = (1-dimension(rs),dimension(ds)-1) # not banded
111110
end
112111

113-
opsm = convert(Matrix{Operator{mapreduce(eltype, promote_type, ops)}}, ops)
112+
MT = Matrix{Operator{mapreduce(eltype, promote_type, ops)}}
113+
opsm = strictconvert(MT, ops)
114114
InterlaceOperator(opsm,ds,rs,
115115
cache(dsi),
116116
cache(rsi),
117117
(l,u))
118118
end
119119

120120

121-
function InterlaceOperator(ops::Vector{<:Operator},ds::Space,rs::Space)
121+
function InterlaceOperator(ops::VectorOrTupleOfOp, ds::Space, rs::Space)
122122
# calculate bandwidths
123123
p=size(ops,1)
124124
if all(isbanded,ops)
@@ -134,7 +134,8 @@ function InterlaceOperator(ops::Vector{<:Operator},ds::Space,rs::Space)
134134
l,u = (1-dimension(rs),dimension(ds)-1) # not banded
135135
end
136136

137-
opsv = convert(Vector{Operator{mapreduce(eltype, promote_type, ops)}}, ops)
137+
VT = Vector{Operator{mapreduce(eltype, promote_type, ops)}}
138+
opsv = strictconvert(VT, _convert_vector(ops))
138139
InterlaceOperator(opsv,ds,rs,
139140
cache(BlockInterlacer(tuple(blocklengths(ds)))),
140141
cache(interlacer(rs)),
@@ -176,18 +177,18 @@ InterlaceOperator(opsin::AbstractMatrix{<:Operator},::Type{DS}) where {DS<:Space
176177
InterlaceOperator(opsin::AbstractMatrix,S...) =
177178
InterlaceOperator(Matrix{Operator{mapreduce(eltype,promote_type,opsin)}}(promotespaces(opsin)),S...)
178179

179-
_convertVector(v::AbstractVector) = convert(Vector, v)
180-
_convertVector(t::Tuple) = [t...]
180+
_convert_vector(v::AbstractVector) = convert(Vector, v)
181+
_convert_vector_or_svector(v::AbstractVector) = _convert_vector(v)
182+
_convert_vector(t::Tuple) = [t...]
183+
_convert_vector_or_svector(t::Tuple) = SVector{length(t), mapreduce(typeof, typejoin, t)}(t)
181184

182185
function InterlaceOperator(opsin::AbstractVector{<:Operator})
183-
ops = promotedomainspace(opsin)
184-
opsv = _convertVector(ops)
185-
InterlaceOperator(opsv, domainspace(first(ops)), rangespace(opsv))
186+
ops = _convert_vector(promotedomainspace(opsin))
187+
InterlaceOperator(ops, domainspace(first(ops)), rangespace(ops))
186188
end
187189
function InterlaceOperator(opsin::Tuple{Operator, Vararg{Operator}})
188190
ops = promotedomainspace(opsin)
189-
opsv = _convertVector(ops)
190-
InterlaceOperator(opsv, domainspace(first(ops)), rangespace(opsv))
191+
InterlaceOperator(ops, domainspace(first(ops)), rangespace(ops))
191192
end
192193

193194
InterlaceOperator(ops::AbstractArray) =

src/Operators/spacepromotion.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ promotedomainspace(P::Operator,sp::Space,cursp::Space) =
8686

8787

8888

89-
const VectorOrTupleOfOp{O<:Operator} = Union{AbstractVector{O}, Tuple{O, Vararg{O}}}
90-
9189
__maybetypedmap(f, k, ops) = map(op->f(op,k), ops)
9290
_maybetypedmap(f, k, O, ops::AbstractVector) =
9391
strictconvert(Vector{O}, __maybetypedmap(f, k, ops))

src/Spaces/ArraySpace.jl

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,26 @@ f = Fun(x->[exp(x),sin(x)],-1..1)
1010
space(f) == ArraySpace(Chebyshev(),2)
1111
```
1212
"""
13-
struct ArraySpace{S,n,DD,RR} <: DirectSumSpace{NTuple{n,S},DD,Array{RR,n}}
14-
spaces::Array{S,n}
13+
struct ArraySpace{S,n,DD,RR,A<:AbstractArray{S,n}} <: DirectSumSpace{NTuple{n,S},DD,Array{RR,n}}
14+
spaces::A
1515
end
1616

17-
const VectorSpace{S,DD,RR} = ArraySpace{S,1,DD,RR}
18-
const MatrixSpace{S,DD,RR} = ArraySpace{S,2,DD,RR}
17+
const VectorSpace{S,DD,RR,A<:AbstractVector{S}} = ArraySpace{S,1,DD,RR,A}
18+
const MatrixSpace{S,DD,RR,A<:AbstractMatrix{S}} = ArraySpace{S,2,DD,RR,A}
1919

2020
#TODO: Think through domain/domaindominsion
21-
ArraySpace(sp::AbstractArray{SS,N}) where {SS<:Space,N} =
22-
ArraySpace{SS,N,domaintype(first(sp)),mapreduce(rangetype,promote_type,sp)}(sp)
21+
ArraySpace(sp::AbstractArray{SS,N}, f = first(sp)) where {SS<:Space,N} =
22+
ArraySpace{SS,N,domaintype(f),mapreduce(rangetype,promote_type,sp),typeof(sp)}(sp)
2323
ArraySpace(S::Space,n::NTuple{N,Int}) where {N} = ArraySpace(fill(S,n))
2424
ArraySpace(S::Space,n::Integer) = ArraySpace(S,(n,))
2525
ArraySpace(S::Space,n,m) = ArraySpace(fill(S,(n,m)))
2626
ArraySpace(d::Domain,n...) = ArraySpace(Space(d),n...)
2727

2828
Space(sp::AbstractArray{<:Space}) = ArraySpace(sp)
29-
convert(::Type{Array}, sp::ArraySpace) = sp.spaces
30-
convert(::Type{Vector}, sp::VectorSpace) = sp.spaces
31-
convert(::Type{Matrix}, sp::MatrixSpace) = sp.spaces
32-
Array(sp::ArraySpace) = sp.spaces
33-
Vector(sp::VectorSpace) = sp.spaces
34-
Matrix(sp::MatrixSpace) = sp.spaces
29+
convert(::Type{A}, sp::ArraySpace) where {A<:Array} = A(sp.spaces)::A
30+
Array(sp::ArraySpace) = convert(Array, sp.spaces)
31+
Vector(sp::VectorSpace) = convert(Vector, sp.spaces)
32+
Matrix(sp::MatrixSpace) = convert(Matrix, sp.spaces)
3533

3634

3735
BlockInterlacer(sp::ArraySpace) = BlockInterlacer(blocklengths.(tuple(sp.spaces...)))
@@ -107,8 +105,7 @@ end
107105

108106

109107
Base.vec(AS::ArraySpace) = ArraySpace(vec(AS.spaces))
110-
Base.vec(f::Fun{ArraySpace{S,n,DD,RR}}) where {S,n,DD,RR} =
111-
[f[j] for j=1:length(f.space)]
108+
Base.vec(f::Fun{<:ArraySpace}) = [f[j] for j=1:length(f.space)]
112109

113110
repeat(A::ArraySpace,n,m) = ArraySpace(repeat(A.spaces,n,m))
114111

@@ -117,14 +114,14 @@ component(A::MatrixSpace,k::Integer,j::Integer) = A.spaces[k,j]
117114
Base.getindex(f::Fun{DSS},k::Integer) where {DSS<:ArraySpace} = component(f,k)
118115

119116

120-
Base.getindex(f::Fun{MatrixSpace{S,DD,RR}},k::Integer,j::Integer) where {S,DD,RR} =
117+
Base.getindex(f::Fun{<:MatrixSpace},k::Integer,j::Integer) =
121118
f[k+stride(f,2)*(j-1)]
122119

123120
Base.getindex(f::Fun{DSS},kj::CartesianIndex{1}) where {DSS<:ArraySpace} = f[kj[1]]
124121
Base.getindex(f::Fun{DSS},kj::CartesianIndex{2}) where {DSS<:ArraySpace} = f[kj[1],kj[2]]
125122

126123

127-
function Fun(A::AbstractArray{Fun{VectorSpace{S,DD,RR},V,VV},2}) where {S,V,VV,DD,RR}
124+
function Fun(A::AbstractMatrix{<:Fun{<:VectorSpace{S},V,VV}}) where {S,V,VV}
128125
@assert size(A,1)==1
129126

130127
M = Matrix{Fun{S,V,VV}}(undef, length(space(A[1])),size(A,2))

src/Spaces/ProductSpaceOperators.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Evaluation(S::SumSpace,x,order) =
6565
InterlaceOperator(RowVector(vnocat(map(s->Evaluation(s,x,order),components(S))...)),SumSpace))
6666

6767

68-
ToeplitzOperator(G::Fun{MatrixSpace{S,DD,RR},V}) where {S,RR,V,DD} = interlace(map(ToeplitzOperator,Array(G)))
68+
ToeplitzOperator(G::Fun{<:MatrixSpace}) = interlace(map(ToeplitzOperator,Array(G)))
6969

7070
## Sum Space
7171

@@ -253,10 +253,14 @@ choosedomainspace(M::CalculusOperator{UnsetSpace},sp::SumSpace)=mapreduce(s->cho
253253

254254
## Multiplcation for Array*Vector
255255

256-
function Multiplication(f::Fun{MatrixSpace{S,DD,RR}},sp::VectorSpace{S2,DD2,RR2}) where {S,DD,RR,S2,DD2,RR2}
256+
function Multiplication(f::Fun{<:MatrixSpace}, sp::VectorSpace)
257257
@assert size(space(f),2)==length(sp)
258258
m=Array(f)
259-
MultiplicationWrapper(f,interlace(Operator{promote_type(cfstype(f),prectype(sp))}[Multiplication(m[k,j],sp[j]) for k=1:size(m,1),j=1:size(m,2)]))
259+
MultiplicationWrapper(f, interlace(
260+
Operator{promote_type(cfstype(f),prectype(sp))}[
261+
Multiplication(m[k,j],sp[j]) for k=1:size(m,1),j=1:size(m,2)]
262+
)
263+
)
260264
end
261265

262266

0 commit comments

Comments
 (0)