From 71425d916228c91ac5c87f7d313567180be47668 Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 00:18:25 -0400 Subject: [PATCH 1/9] add LinearAlgebraExt --- Project.toml | 6 ++- ext/ConstructionBaseLinearAlgebraExt.jl | 51 +++++++++++++++++++++++++ src/nonstandard.jl | 37 ++---------------- 3 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 ext/ConstructionBaseLinearAlgebraExt.jl diff --git a/Project.toml b/Project.toml index 6a9b1f6..a5d92e2 100644 --- a/Project.toml +++ b/Project.toml @@ -9,20 +9,24 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [weakdeps] IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" ConstructionBaseStaticArraysExt = "StaticArrays" +ConstructionBaseLinearAlgebraExt = "LinearAlgebra" [compat] IntervalSets = "0.5, 0.6, 0.7" StaticArrays = "1" julia = "1" +LinearAlgebra = "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..ceb25dd --- /dev/null +++ b/ext/ConstructionBaseLinearAlgebraExt.jl @@ -0,0 +1,51 @@ +module ConstructionBaseLinearAlgebraExt + +if !isdefined(Base, :get_extension) + import ConstructionBase + import LinearAlgebra +else + import ..ConstructionBase + import ..LinearAlgebra +end + +### 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/nonstandard.jl b/src/nonstandard.jl index 4b114a7..e1c0ad8 100644 --- a/src/nonstandard.jl +++ b/src/nonstandard.jl @@ -28,24 +28,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 @@ -57,20 +40,6 @@ constructorof(::Type{<:LinRange}) = linrange_constructor # ::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 +if !isdefined(Base,:get_extension) + include("ext/ConstructionBaseLinearAlgebraExt.jl") +end \ No newline at end of file From 3b4bf8f6c81d20c078e41059e0d905f44ea4460c Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 00:25:09 -0400 Subject: [PATCH 2/9] move usage of LinearAlgebra into conditional loading --- src/nonstandard.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nonstandard.jl b/src/nonstandard.jl index e1c0ad8..cb45c5d 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. @@ -41,5 +40,6 @@ constructorof(::Type{<:LinRange}) = linrange_constructor constructorof(::Type{<:Expr}) = (head, args) -> Expr(head, args...)::Expr if !isdefined(Base,:get_extension) + using LinearAlgebra include("ext/ConstructionBaseLinearAlgebraExt.jl") end \ No newline at end of file From 1c4a4929d2febfee1cfa11b04cad2d54568742d2 Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 00:31:46 -0400 Subject: [PATCH 3/9] add `<0.0.1` in compat, typo in ext --- Project.toml | 2 +- ext/ConstructionBaseLinearAlgebraExt.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index a5d92e2..00036c6 100644 --- a/Project.toml +++ b/Project.toml @@ -20,7 +20,7 @@ ConstructionBaseLinearAlgebraExt = "LinearAlgebra" IntervalSets = "0.5, 0.6, 0.7" StaticArrays = "1" julia = "1" -LinearAlgebra = "1" +LinearAlgebra = "<0.0.1,1" [extras] IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" diff --git a/ext/ConstructionBaseLinearAlgebraExt.jl b/ext/ConstructionBaseLinearAlgebraExt.jl index ceb25dd..3f03078 100644 --- a/ext/ConstructionBaseLinearAlgebraExt.jl +++ b/ext/ConstructionBaseLinearAlgebraExt.jl @@ -1,6 +1,6 @@ module ConstructionBaseLinearAlgebraExt -if !isdefined(Base, :get_extension) +if isdefined(Base, :get_extension) import ConstructionBase import LinearAlgebra else From 01e17398d766adb3099eef1fed08bbb7ece71721 Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 00:49:01 -0400 Subject: [PATCH 4/9] typo in extension include --- src/nonstandard.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nonstandard.jl b/src/nonstandard.jl index cb45c5d..380f764 100644 --- a/src/nonstandard.jl +++ b/src/nonstandard.jl @@ -41,5 +41,5 @@ constructorof(::Type{<:Expr}) = (head, args) -> Expr(head, args...)::Expr if !isdefined(Base,:get_extension) using LinearAlgebra - include("ext/ConstructionBaseLinearAlgebraExt.jl") + include("..ext/ConstructionBaseLinearAlgebraExt.jl") end \ No newline at end of file From ad3df5224e42393421f188d28260b993b0b4f012 Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 00:52:57 -0400 Subject: [PATCH 5/9] another typo in ext include --- src/nonstandard.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nonstandard.jl b/src/nonstandard.jl index 380f764..9f4bc10 100644 --- a/src/nonstandard.jl +++ b/src/nonstandard.jl @@ -41,5 +41,5 @@ constructorof(::Type{<:Expr}) = (head, args) -> Expr(head, args...)::Expr if !isdefined(Base,:get_extension) using LinearAlgebra - include("..ext/ConstructionBaseLinearAlgebraExt.jl") + include("../ext/ConstructionBaseLinearAlgebraExt.jl") end \ No newline at end of file From 6988031e955e25f503f8ab1951958c41ae095736 Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 01:04:28 -0400 Subject: [PATCH 6/9] add conditional test on getfields([]) --- test/runtests.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 7cee50d..7ac0ccb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -21,7 +21,15 @@ end @testset "getfields" begin @test getfields(()) === () - @test getfields([]) === NamedTuple() + + #on julia 1.10 onwards, Array has fields :ref and :size. the :ref field is a memory field + #with non-constant value (the pointer location in memory). The only constant field in [] + #is it's size, (0,) + if !isdefined(Base,:Memory) + @test getfields([]) === NamedTuple() + else + @test getfields([]).size === (0,) + end @test getfields(Empty()) === NamedTuple() @test getfields(NamedTuple()) === NamedTuple() @test getfields((10,20,30)) === (10,20,30) From 2596c4b4a7134e0900cca93356df058d4ba78d02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Tue, 16 Jul 2024 02:23:47 -0400 Subject: [PATCH 7/9] Update test/runtests.jl Co-authored-by: Jan Weidner --- test/runtests.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 7ac0ccb..a93b678 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -28,7 +28,8 @@ end if !isdefined(Base,:Memory) @test getfields([]) === NamedTuple() else - @test getfields([]).size === (0,) + arr = [] + @test getfields(arr) === (;arr.ref, arr.size) end @test getfields(Empty()) === NamedTuple() @test getfields(NamedTuple()) === NamedTuple() From 7d953c654ef4b14ccc5ead56af0d11580b2a9177 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Riedemann?= <38795484+longemen3000@users.noreply.github.com> Date: Tue, 16 Jul 2024 02:26:13 -0400 Subject: [PATCH 8/9] Update runtests.jl --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index a93b678..d7a75b7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -29,7 +29,7 @@ end @test getfields([]) === NamedTuple() else arr = [] - @test getfields(arr) === (;arr.ref, arr.size) + @test getfields(arr) === (ref = arr.ref, size = arr.size) end @test getfields(Empty()) === NamedTuple() @test getfields(NamedTuple()) === NamedTuple() From b7ee255db41cbcaa55f4e76dc1f5160e5ad50436 Mon Sep 17 00:00:00 2001 From: longemen3000 Date: Tue, 16 Jul 2024 19:02:26 -0400 Subject: [PATCH 9/9] use LinearAlgebra unconditionally --- Project.toml | 2 -- ext/ConstructionBaseLinearAlgebraExt.jl | 9 ++------- src/ConstructionBase.jl | 3 +++ src/nonstandard.jl | 5 ----- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/Project.toml b/Project.toml index 00036c6..edba197 100644 --- a/Project.toml +++ b/Project.toml @@ -9,12 +9,10 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [weakdeps] IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" ConstructionBaseStaticArraysExt = "StaticArrays" -ConstructionBaseLinearAlgebraExt = "LinearAlgebra" [compat] IntervalSets = "0.5, 0.6, 0.7" diff --git a/ext/ConstructionBaseLinearAlgebraExt.jl b/ext/ConstructionBaseLinearAlgebraExt.jl index 3f03078..9a06bf1 100644 --- a/ext/ConstructionBaseLinearAlgebraExt.jl +++ b/ext/ConstructionBaseLinearAlgebraExt.jl @@ -1,12 +1,7 @@ module ConstructionBaseLinearAlgebraExt -if isdefined(Base, :get_extension) - import ConstructionBase - import LinearAlgebra -else - import ..ConstructionBase - import ..LinearAlgebra -end +import ConstructionBase +import LinearAlgebra ### Tridiagonal diff --git a/src/ConstructionBase.jl b/src/ConstructionBase.jl index ba31236..8853af6 100644 --- a/src/ConstructionBase.jl +++ b/src/ConstructionBase.jl @@ -222,4 +222,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 9f4bc10..e1b839b 100644 --- a/src/nonstandard.jl +++ b/src/nonstandard.jl @@ -38,8 +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 - -if !isdefined(Base,:get_extension) - using LinearAlgebra - include("../ext/ConstructionBaseLinearAlgebraExt.jl") -end \ No newline at end of file