Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Operator constructor instead of convert #399

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions src/Operators/Operator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -900,3 +900,5 @@ diagindrow(S::SubOperator) = diagindrow(S,parentindices(S)[1],parentindices(S)[2

# Conversion between operator types
convert(::Type{O}, c::Operator) where {O<:Operator} = c isa O ? c : O(c)::O
convert(::Type{Operator{T}}, c::Operator{S}) where {S,T} = c isa Operator{T} ? c : Operator{T}(c)::Operator{T}
Operator(A::Operator) = A
10 changes: 9 additions & 1 deletion src/Operators/SubOperator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,16 @@ SubOperator(A,inds,dims) = SubOperator(A,inds,dims,(dims[1]-1,dims[2]-1))
SubOperator(A,inds) = SubOperator(A,inds,map(length,inds))


convert(::Type{Operator{T}},SO::SubOperator) where {T} =
Operator{T}(SO::SubOperator) where {T} =
SubOperator(Operator{T}(SO.parent),SO.indexes,SO.dims,SO.bandwidths)::Operator{T}
function SubOperator{T,B,I,DI,BI}(S::SubOperator) where {T,B,I,DI,BI}
SubOperator{T,B,I,DI,BI}(
strictconvert(B, S.parent),
strictconvert(I, S.indexes),
strictconvert(DI, S.dims),
strictconvert(BI, S.bandwidths),
)
end

function view(A::Operator,kr::InfRanges,jr::InfRanges)
@assert isinf(size(A,1)) && isinf(size(A,2))
Expand Down
7 changes: 5 additions & 2 deletions src/Operators/almostbanded/LowRankOperator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct LowRankOperator{S<:Space,T} <: AbstractLowRankOperator{T}
U::Vector{VFun{S,T}}
V::Vector{Operator{T}}

function LowRankOperator{S,T}(U::Vector{VFun{S,T}},V::Vector{Operator{T}}) where {S,T}
function LowRankOperator{S,T}(U::Vector{VFun{S,T}},V::Vector{Operator{T}}) where {S<:Space,T}
@assert all(isafunctional,V)

@assert length(U) == length(V)
Expand Down Expand Up @@ -39,9 +39,12 @@ LowRankOperator(B::AbstractVector,S...) = LowRankOperator(strictconvert(Vector{O
LowRankOperator(A::Fun,B::Operator) = LowRankOperator([A],[B])


convert(::Type{Operator{T}},L::LowRankOperator{S}) where {S,T} =
function LowRankOperator{S,T}(L::LowRankOperator) where {S<:Space,T}
LowRankOperator{S,T}(strictconvert(Vector{VFun{S,T}},L.U),
strictconvert(Vector{Operator{T}},L.V))
end

Operator{T}(L::LowRankOperator{S}) where {S,T} = LowRankOperator{S,T}(L)


datasize(L::LowRankOperator,k) =
Expand Down
9 changes: 6 additions & 3 deletions src/Operators/almostbanded/LowRankPertOperator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ function LowRankPertOperator(Bin::Operator,Lin::LowRankOperator)
end



convert(::Type{Operator{T}},L::LowRankPertOperator) where {T} =
LowRankPertOperator(Operator{T}(L.op),Operator{T}(L.pert))::Operator{T}
function LowRankPertOperator{OO,LR,T}(L::LowRankPertOperator) where {OO,LR,T}
LowRankPertOperator{OO,LR,T}(strictconvert(OO, L.op), strictconvert(LR, L.pert))
end
function Operator{T}(L::LowRankPertOperator) where {T}
LowRankPertOperator(Operator{T}(L.op),Operator{T}(L.pert))
end
convert(::Type{Operator},V::AbstractVector{OT}) where {OT<:Operator}=LowRankPertOperator(V)


Expand Down
33 changes: 18 additions & 15 deletions src/Operators/banded/CalculusOperator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,23 @@ macro calculus_operator(Op)
space::S # the domain space
order::OT
end
function $ConcOp{S,OT,T}(C::$ConcOp) where {S<:Space,OT,T}
$ConcOp{S,OT,T}(strictconvert(S, C.space), strictconvert(OT, C.order))
end
struct $WrappOp{BT<:Operator,S<:Space,R<:Space,OT,T} <: $Op{S,OT,T}
op::BT
order::OT
domainspace::S
rangespace::R
end
function $WrappOp{BT,S,R,OT,T}(C::$WrappOp) where {BT<:Operator,S<:Space,R<:Space,OT,T}
$WrappOp{BT,S,R,OT,T}(
strictconvert(BT, C.op),
strictconvert(OT, C.order),
strictconvert(S, C.domainspace),
strictconvert(R, C.rangespace),
)
end

ApproxFunBase.@wrapper $WrappOp false false
ApproxFunBase.domainspace(A::$WrappOp) = A.domainspace
Expand Down Expand Up @@ -58,26 +69,18 @@ macro calculus_operator(Op)
$Op(x...) = $DefaultOp(x...)
$ConcOp(S::Space) = $ConcOp(S,1)

function Base.convert(::Type{Operator{T}},D::$ConcOp) where T
if T==eltype(D)
D
else
$ConcOp{typeof(D.space),typeof(D.order),T}(D.space, D.order)
end
function Operator{T}(D::$ConcOp) where {T}
$ConcOp{typeof(D.space),typeof(D.order),T}(D)::Operator{T}
end

$WrappOp(op::Operator, order = 1, d = domainspace(op), r = rangespace(op)) =
$WrappOp{typeof(op),typeof(d),typeof(r),typeof(order),eltype(op)}(op,order,d,r)

function Base.convert(::Type{Operator{T}},D::$WrappOp) where T
if T==eltype(D)
D
else
op=ApproxFunBase.strictconvert(Operator{T},D.op)
S = domainspace(D)
R = rangespace(D)
$WrappOp(op,D.order,S,R)::Operator{T}
end
function Operator{T}(D::$WrappOp) where {T}
op=ApproxFunBase.strictconvert(Operator{T},D.op)
S = domainspace(D)
R = rangespace(D)
$WrappOp{typeof(op),typeof(S),typeof(R),typeof(D.order),T}(op,D.order,S,R)::Operator{T}
end

## Routines
Expand Down
13 changes: 6 additions & 7 deletions src/Operators/banded/ConstantOperator.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export ConstantOperator, IdentityOperator, BasisFunctional

struct ConstantOperator{T,DS} <: Operator{T}
struct ConstantOperator{T,DS<:Space} <: Operator{T}
λ::T
space::DS
ConstantOperator{T,DS}(c::Number,sp::DS) where {T,DS} = new{T,DS}(strictconvert(T,c),sp)
Expand Down Expand Up @@ -36,12 +36,11 @@ getindex(C::ConstantOperator,k::Integer,j::Integer) =

==(C1::ConstantOperator, C2::ConstantOperator) = C1.λ==C2.λ

function convert(::Type{Operator{T}}, C::ConstantOperator) where T
if T == eltype(C)
C
else
ConstantOperator{T,typeof(C.space)}(C.λ,C.space)
end
function ConstantOperator{T,DS}(C::ConstantOperator) where {T,DS}
ConstantOperator{T,DS}(strictconvert(T, C.λ), strictconvert(DS, C.space))
end
function Operator{T}(C::ConstantOperator) where T
ConstantOperator{T,typeof(C.space)}(C.λ,C.space)
end

# zero needs to be different since it can take a space to
Expand Down
32 changes: 17 additions & 15 deletions src/Operators/banded/Conversion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ function ConcreteConversion(a::Space,b::Space)
ConcreteConversion(T, a, b)
end

function convert(::Type{Operator{T}}, C::ConcreteConversion) where {T}
if T==eltype(C)
C
else
ConcreteConversion(T, C.domainspace,C.rangespace)::Operator{T}
end
function ConcreteConversion{D,R,T}(C::ConcreteConversion) where {D<:Space,R<:Space,T}
ConcreteConversion{D,R,T}(strictconvert(D,C.domainspace), strictconvert(R, C.rangespace))
end

function Operator{T}(C::ConcreteConversion) where {T}
ConcreteConversion(T, C.domainspace,C.rangespace)::Operator{T}
end

domainspace(C::ConcreteConversion)=C.domainspace
Expand Down Expand Up @@ -126,15 +126,17 @@ Conversion(A::Space,B::Space,C::Space,D::Space...) =

==(A::ConversionWrapper,B::ConversionWrapper) = A.op==B.op


function convert(::Type{Operator{T}},D::ConversionWrapper) where T
if T==eltype(D)
D
else
BO=strictconvert(Operator{T},D.op)
d, r = domainspace(D), rangespace(D)
ConversionWrapper(d, r, BO)::Operator{T}
end
function ConversionWrapper{D,R,T,O}(C::ConversionWrapper) where {D<:Space,R<:Space,T,O<:Operator{T}}
ConversionWrapper{D,R,T,O}(
strictconvert(D,C.domainspace),
strictconvert(R,C.rangespace),
strictconvert(O, C.op)
)
end
function Operator{T}(D::ConversionWrapper) where T
BO=strictconvert(Operator{T},D.op)
d, r = domainspace(D), rangespace(D)
ConversionWrapper(d, r, BO)::Operator{T}
end

convert(::Type{T}, C::ConversionWrapper) where {T<:Number} = strictconvert(T, C.op)
Expand Down
23 changes: 10 additions & 13 deletions src/Operators/banded/Multiplication.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,11 @@ Multiplication(c::Number) = Multiplication(Fun(c) )
# This covers right multiplication unless otherwise specified.
Multiplication(S::Space,f::Fun) = Multiplication(f,S)


function convert(::Type{Operator{T}},C::ConcreteMultiplication{S,V}) where {S,V,T}
if T==eltype(C)
C
else
ConcreteMultiplication{S,V,T}(Fun{S,T}(C.f),C.space)
end
function ConcreteMultiplication{D,S,T}(C::ConcreteMultiplication) where {D<:Space,S<:Space,T}
ConcreteMultiplication{D,S,T}(strictconvert(VFun{D,T}, C.f), strictconvert(S, C.space))
end
function Operator{T}(C::ConcreteMultiplication{S,V}) where {S,V,T}
ConcreteMultiplication{S,V,T}(Fun{S,T}(C.f),C.space)
end

domainspace(M::ConcreteMultiplication{D,S,T}) where {D,S,T} = M.space
Expand Down Expand Up @@ -113,12 +111,11 @@ domainspace(M::MultiplicationWrapper) = M.space

@wrapper MultiplicationWrapper false

function convert(::Type{Operator{TT}},C::MultiplicationWrapper{S,V,O,T}) where {TT,S,V,O,T}
if TT==T
C
else
MultiplicationWrapper(Fun{S,TT}(C.f),Operator{TT}(C.op), C.space)::Operator{TT}
end
function MultiplicationWrapper{D,S,T,O}(M::MultiplicationWrapper) where {D<:Space,S<:Space,T,O<:Operator{T}}
MultiplicationWrapper{D,S,T,O}(strictconvert(VFun{D,T}, M.f), strictconvert(O, M.op), strictconvert(S, M.space))
end
function Operator{TT}(C::MultiplicationWrapper{S}) where {TT,S}
MultiplicationWrapper(Fun{S,TT}(C.f),Operator{TT}(C.op), C.space)::Operator{TT}
end


Expand Down
15 changes: 10 additions & 5 deletions src/Operators/banded/PermutationOperator.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Creates a operator that permutes rows, in blocks of size
# length(perm)
struct PermutationOperator{T,DS,RS} <: Operator{T}
struct PermutationOperator{T,DS<:Space,RS<:Space} <: Operator{T}
perm::Vector{Int}
domainspace::DS
rangespace::RS
Expand All @@ -13,8 +13,10 @@ PermutationOperator(prm) = PermutationOperator(prm, ℓ⁰, ℓ⁰)
domainspace(P::PermutationOperator) = P.domainspace
rangespace(P::PermutationOperator) = P.rangespace


convert(::Type{Operator{T}},P::PermutationOperator) where {T} =
function PermutationOperator{T,DS,RS}(P::PermutationOperator) where {T,DS<:Space,RS<:Space}
PermutationOperator{T,DS,RS}(P.perm, strictconvert(DS, P.domainspace), strictconvert(RS, P.rangespace))
end
Operator{T}(P::PermutationOperator) where {T} =
PermutationOperator{T}(P.perm, P.domainspace, P.rangespace)

function bandwidths(P::PermutationOperator)
Expand All @@ -39,7 +41,7 @@ perm(a::Vector,b::Vector) = multiplyperm(invperm(sortperm(b)),sortperm(a))
perm(a::Tuple,b::Tuple) = perm(collect(a),collect(b))


struct NegateEven{T,DS,RS} <: Operator{T}
struct NegateEven{T,DS<:Space,RS<:Space} <: Operator{T}
domainspace::DS
rangespace::RS
end
Expand All @@ -52,7 +54,10 @@ NegateEven() = NegateEven(ℓ⁰,ℓ⁰)
domainspace(P::NegateEven) = P.domainspace
rangespace(P::NegateEven) = P.rangespace

convert(::Type{Operator{T}},P::NegateEven) where {T} =
function NegateEven{T,DS,RS}(N::NegateEven) where {T,DS<:Space,RS<:Space}
NegateEven{T,DS,RS}(strictconvert(DS, N.domainspace), strictconvert(RS, N.rangespace))
end
Operator{T}(P::NegateEven) where {T} =
NegateEven{T}(P.domainspace, P.rangespace)

bandwidths(P::NegateEven) = (0,0)
Expand Down
6 changes: 4 additions & 2 deletions src/Operators/banded/Reverse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ for TYP in (:ReverseOrientation,:Reverse)
end

$WRAP(op::Operator) = $WRAP{typeof(op),eltype(op)}(op)
convert(::Type{Operator{T}},op::$TYP) where {T} = $TYP{T}()
convert(::Type{Operator{T}},op::$WRAP) where {T} = $WRAP(Operator{T}(op.op))::Operator{T}
$TYP{T}(op::$TYP) where {T} = $TYP{T}()
Operator{T}(op::$TYP) where {T} = $TYP{T}()
$WRAP{OS,T}(op::$WRAP) where {OS,T} = $WRAP{OS,T}(strictconvert(OS,op))
Operator{T}(op::$WRAP) where {T} = $WRAP(Operator{T}(op.op))::Operator{T}

@wrapper $WRAP
end
Expand Down
9 changes: 6 additions & 3 deletions src/Operators/banded/ToeplitzOperator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ ToeplitzOperator(V::Vector{T},W::Vector{Q}) where {T<:Number,Q<:Number} =
ToeplitzOperator(V::AbstractVector,W::AbstractVector) =
ToeplitzOperator(collect(V),collect(W))

convert(::Type{Operator{TT}},T::ToeplitzOperator) where {TT} =
function ToeplitzOperator{T}(x::ToeplitzOperator) where {T<:Number}
ToeplitzOperator{T}(strictconvert(Vector{T}, x.negative), strictconvert(Vector{T}, x.nonnegative))
end
Operator{TT}(T::ToeplitzOperator) where {TT<:Number} =
ToeplitzOperator(strictconvert(Vector{TT},T.negative),strictconvert(Vector{TT},T.nonnegative))

for op in (:(Base.real), :(Base.imag))
Expand Down Expand Up @@ -106,8 +109,8 @@ HankelOperator(V::AbstractVector)=HankelOperator(collect(V))
HankelOperator(f::Fun)=HankelOperator(f.coefficients)



@eval convert(::Type{Operator{TT}},T::HankelOperator) where {TT}=HankelOperator(strictconvert(Vector{TT},T.coefficients))
HankelOperator{T}(H::HankelOperator) where {T<:Number} = HankelOperator{T}(strictconvert(Vector{T}, H.coefficients))
Operator{TT}(H::HankelOperator) where {TT<:Number} = HankelOperator(strictconvert(Vector{TT},H.coefficients))

function hankel_getindex(v::AbstractVector,k::Integer,j::Integer)
if k+j-1 ≤ length(v)
Expand Down
18 changes: 11 additions & 7 deletions src/Operators/functionals/CalculusFunctional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ macro calculus_functional(Op)
WrappOp = Symbol(Op, :Wrapper)
return esc(quote
abstract type $Op{SSS,TTT} <: ApproxFunBase.CalculusFunctional{SSS,TTT} end
struct $ConcOp{S,T} <: $Op{S,T}
struct $ConcOp{S<:Space,T} <: $Op{S,T}
domainspace::S
end
struct $WrappOp{BT<:Operator,S<:Space,T} <: $Op{S,T}
Expand All @@ -30,9 +30,11 @@ macro calculus_functional(Op)

ApproxFunBase.promotedomainspace(::$Op,sp::Space) = $Op(sp)


Base.convert(::Type{Operator{T}},Σ::$ConcOp) where {T} =
(T==eltype(Σ) ? Σ : $ConcOp{typeof(Σ.domainspace),T}(Σ.domainspace))::Operator{T}
function $ConcOp{S,T}(C::$ConcOp) where {S<:Space,T}
$ConcOp{S,T}(strictconvert(S, C.domainspace))
end
Operator{T}(Σ::$ConcOp) where {T} =
$ConcOp{typeof(Σ.domainspace),T}(Σ.domainspace)::Operator{T}

ApproxFunBase.domain(Σ::$ConcOp) = domain(Σ.domainspace)
ApproxFunBase.domainspace(Σ::$ConcOp) = Σ.domainspace
Expand All @@ -43,9 +45,11 @@ macro calculus_functional(Op)
$WrappOp(op::Operator) =
$WrappOp{typeof(op),typeof(domainspace(op)),eltype(op)}(op)


Base.convert(::Type{Operator{T}},Σ::$WrappOp) where {T} =
(T==eltype(Σ) ? Σ : $WrappOp(strictconvert(Operator{T},Σ.op)))::Operator{T}
function $WrappOp{BT,S,T}(W::$WrappOp) where {BT<:Operator,S<:Space,T}
$WrappOp{BT,S,T}(strictconvert(BT, W.op))
end
Operator{T}(Σ::$WrappOp) where {T} =
$WrappOp(strictconvert(Operator{T},Σ.op))::Operator{T}
end)
end

Expand Down
Loading