diff --git a/Project.toml b/Project.toml index da7b104..dfd57c7 100644 --- a/Project.toml +++ b/Project.toml @@ -18,11 +18,13 @@ ConstructionBaseStaticArraysExt = "StaticArrays" IntervalSets = "0.5, 0.6, 0.7" StaticArrays = "1" julia = "1" +LinearAlgebra = "<0.0.1,1" [extras] IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [targets] -test = ["IntervalSets","StaticArrays","Test"] +test = ["IntervalSets","LinearAlgebra","StaticArrays","Test"] diff --git a/ext/ConstructionBaseLinearAlgebraExt.jl b/ext/ConstructionBaseLinearAlgebraExt.jl new file mode 100644 index 0000000..9a06bf1 --- /dev/null +++ b/ext/ConstructionBaseLinearAlgebraExt.jl @@ -0,0 +1,46 @@ +module ConstructionBaseLinearAlgebraExt + +import ConstructionBase +import LinearAlgebra + +### Tridiagonal + +function tridiagonal_constructor(dl::V, d::V, du::V) where {V<:AbstractVector{T}} where T + LinearAlgebra.Tridiagonal{T,V}(dl, d, du) +end +function tridiagonal_constructor(dl::V, d::V, du::V, du2::V) where {V<:AbstractVector{T}} where T + LinearAlgebra.Tridiagonal{T,V}(dl, d, du, du2) +end + +# `du2` may be undefined, so we need a custom `getfields` that checks `isdefined` +function ConstructionBase.getfields(o::LinearAlgebra.Tridiagonal) + if isdefined(o, :du2) + (dl=o.dl, d=o.d, du=o.du, du2=o.du2) + else + (dl=o.dl, d=o.d, du=o.du) + end +end + +ConstructionBase.constructorof(::Type{<:LinearAlgebra.Tridiagonal}) = tridiagonal_constructor + +### Cholesky + +ConstructionBase.setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple{()}) = C + +function ConstructionBase.setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple{(:L,),<:Tuple{<:LinearAlgebra.LowerTriangular}}) + return LinearAlgebra.Cholesky(C.uplo === 'U' ? copy(patch.L.data') : patch.L.data, C.uplo, C.info) +end +function ConstructionBase.setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple{(:U,),<:Tuple{<:LinearAlgebra.UpperTriangular}}) + return LinearAlgebra.Cholesky(C.uplo === 'L' ? copy(patch.U.data') : patch.U.data, C.uplo, C.info) +end +function ConstructionBase.setproperties( + C::LinearAlgebra.Cholesky, + patch::NamedTuple{(:UL,),<:Tuple{<:Union{LinearAlgebra.LowerTriangular,LinearAlgebra.UpperTriangular}}} +) + return LinearAlgebra.Cholesky(patch.UL.data, C.uplo, C.info) +end +function ConstructionBase.setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple) + throw(ArgumentError("Invalid patch for `Cholesky`: $(patch)")) +end + +end #module \ No newline at end of file diff --git a/src/ConstructionBase.jl b/src/ConstructionBase.jl index c0d1236..d29c18f 100644 --- a/src/ConstructionBase.jl +++ b/src/ConstructionBase.jl @@ -211,4 +211,7 @@ end include("nonstandard.jl") include("functions.jl") +#unconditionally include the extension for now +include("../ext/ConstructionBaseLinearAlgebraExt.jl") + end # module diff --git a/src/nonstandard.jl b/src/nonstandard.jl index 4b114a7..e1b839b 100644 --- a/src/nonstandard.jl +++ b/src/nonstandard.jl @@ -1,4 +1,3 @@ -using LinearAlgebra ### SubArray # `offset1` and `stride1` fields are calculated from parent indices. @@ -28,24 +27,7 @@ end constructorof(::Type{<:PermutedDimsArray{<:Any,N,perm,iperm,<:Any}}) where {N,perm,iperm} = PermutedDimsArrayConstructor{N,perm,iperm}() -### Tridiagonal -function tridiagonal_constructor(dl::V, d::V, du::V) where {V<:AbstractVector{T}} where T - Tridiagonal{T,V}(dl, d, du) -end -function tridiagonal_constructor(dl::V, d::V, du::V, du2::V) where {V<:AbstractVector{T}} where T - Tridiagonal{T,V}(dl, d, du, du2) -end -# `du2` may be undefined, so we need a custom `getfields` that checks `isdefined` -function getfields(o::Tridiagonal) - if isdefined(o, :du2) - (dl=o.dl, d=o.d, du=o.du, du2=o.du2) - else - (dl=o.dl, d=o.d, du=o.du) - end -end - -constructorof(::Type{<:LinearAlgebra.Tridiagonal}) = tridiagonal_constructor ### LinRange # `lendiv` is a calculated field @@ -56,21 +38,3 @@ constructorof(::Type{<:LinRange}) = linrange_constructor ### Expr: args get splatted # ::Expr annotation is to make it type-stable on Julia 1.3- constructorof(::Type{<:Expr}) = (head, args) -> Expr(head, args...)::Expr - -### Cholesky -setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple{()}) = C -function setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple{(:L,),<:Tuple{<:LinearAlgebra.LowerTriangular}}) - return LinearAlgebra.Cholesky(C.uplo === 'U' ? copy(patch.L.data') : patch.L.data, C.uplo, C.info) -end -function setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple{(:U,),<:Tuple{<:LinearAlgebra.UpperTriangular}}) - return LinearAlgebra.Cholesky(C.uplo === 'L' ? copy(patch.U.data') : patch.U.data, C.uplo, C.info) -end -function setproperties( - C::LinearAlgebra.Cholesky, - patch::NamedTuple{(:UL,),<:Tuple{<:Union{LinearAlgebra.LowerTriangular,LinearAlgebra.UpperTriangular}}} -) - return LinearAlgebra.Cholesky(patch.UL.data, C.uplo, C.info) -end -function setproperties(C::LinearAlgebra.Cholesky, patch::NamedTuple) - throw(ArgumentError("Invalid patch for `Cholesky`: $(patch)")) -end