From c0a2e51a78e16f2b0d32f132a56318a3f72eb7fc Mon Sep 17 00:00:00 2001 From: Joachim Brand Date: Sun, 2 Feb 2025 02:02:08 +1300 Subject: [PATCH] sparse constructors --- src/BitStringAddresses/bosefs.jl | 1 + src/BitStringAddresses/fermifs.jl | 6 ++++-- src/BitStringAddresses/occupationnumberfs.jl | 18 ++++++++++++++++-- test/BitStringAddresses.jl | 9 ++++++++- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/BitStringAddresses/bosefs.jl b/src/BitStringAddresses/bosefs.jl index 0d0433c89..8ac94c04e 100644 --- a/src/BitStringAddresses/bosefs.jl +++ b/src/BitStringAddresses/bosefs.jl @@ -107,6 +107,7 @@ BoseFS(vals::Integer...) = BoseFS(vals) # specify occupation numbers BoseFS(val::Integer) = BoseFS((val,)) # single mode address BoseFS{N,M}(vals::Integer...) where {N,M} = BoseFS{N,M}(vals) +# Sparse constructors BoseFS(M::Integer, pairs::Pair...) = BoseFS(M, pairs) BoseFS(M::Integer, pairs) = BoseFS(sparse_to_onr(M, pairs)) BoseFS{N,M}(pairs::Pair...) where {N,M} = BoseFS{N,M}(pairs) diff --git a/src/BitStringAddresses/fermifs.jl b/src/BitStringAddresses/fermifs.jl index 43f9dc3a6..94a548292 100644 --- a/src/BitStringAddresses/fermifs.jl +++ b/src/BitStringAddresses/fermifs.jl @@ -24,7 +24,7 @@ chosen automatically based on the properties of the address. particles in `bs` is equal to `N`, or whether each mode only contains one particle. * [`@fs_str`](@ref): Addresses are sometimes printed in a compact manner. This - representation can also be used as a constructor. See the last example below. + representation can also be used as a constructor. See the examples below. # Examples @@ -95,7 +95,8 @@ function FermiFS{N,M}(onr::Union{AbstractArray{<:Integer},NTuple{M,<:Integer}}) end return FermiFS{N,M,S}(from_fermi_onr(S, onr)) end -function FermiFS(onr::Union{AbstractArray,Tuple}) +function FermiFS(onr) + onr = Tuple(onr) M = length(onr) N = sum(onr) return FermiFS{N,M}(onr) @@ -109,6 +110,7 @@ FermiFS(M::Integer, pairs::Pair...) = FermiFS(M, pairs) FermiFS(M::Integer, pairs) = FermiFS(sparse_to_onr(M, pairs)) FermiFS{N,M}(pairs::Vararg{Pair,N}) where {N,M} = FermiFS{N,M}(pairs) FermiFS{N,M}(pairs) where {N,M} = FermiFS{N,M}(sparse_to_onr(M, pairs)) +FermiFS(pairs::Pair...) = throw(ArgumentError("number of modes must be provided")) function print_address(io::IO, f::FermiFS{N,M}; compact=false) where {N,M} if compact && f.bs isa SortedParticleList diff --git a/src/BitStringAddresses/occupationnumberfs.jl b/src/BitStringAddresses/occupationnumberfs.jl index d3ce4089f..f2cf880f9 100644 --- a/src/BitStringAddresses/occupationnumberfs.jl +++ b/src/BitStringAddresses/occupationnumberfs.jl @@ -32,6 +32,9 @@ OccupationNumberFS{5, UInt8}(0, 0, 0, 0, 0) julia> OccupationNumberFS(i for i in 1:3) # use list comprehension OccupationNumberFS{3, UInt8}(1, 2, 3) + +julia> OccupationNumberFS(4, 1=>2, 3=>4) # sparse constructor +OccupationNumberFS{4, UInt8}(2, 0, 4, 0) ``` """ struct OccupationNumberFS{M,T<:Unsigned} <: SingleComponentFockAddress{missing,M} @@ -51,9 +54,10 @@ function OccupationNumberFS(arg) return OccupationNumberFS{length(t)}(t) end -function OccupationNumberFS(args...) +function OccupationNumberFS(args::Integer...) return OccupationNumberFS{length(args)}(args) end +OccupationNumberFS(arg::Integer) = OccupationNumberFS{1}(arg) # to resolve ambiguity function OccupationNumberFS{M}(args...) where M sv = SVector{M}(args...) @@ -71,9 +75,19 @@ end function OccupationNumberFS{M,T}() where {M,T<:Unsigned} return OccupationNumberFS(SVector{M,T}(zero(T) for _ in 1:M)) end - OccupationNumberFS{M}() where {M} = OccupationNumberFS{M,UInt8}() +# Sparse constructors +OccupationNumberFS(M::Integer, pairs::Pair...) = OccupationNumberFS(M, pairs) +OccupationNumberFS(M::Integer, pairs) = OccupationNumberFS(sparse_to_onr(M, pairs)) +OccupationNumberFS{M}(pairs::Pair...) where {M} = OccupationNumberFS{M}(pairs) + +function OccupationNumberFS{M}(pairs::NTuple{<:Any,Pair}) where {M} + OccupationNumberFS{M}(sparse_to_onr(M, pairs)) +end + +OccupationNumberFS(pairs::Pair...) = throw(ArgumentError("number of modes must be provided")) + function print_address(io::IO, ofs::OccupationNumberFS{M,T}; compact=false) where {M,T} if compact BITS = sizeof(T) * 8 diff --git a/test/BitStringAddresses.jl b/test/BitStringAddresses.jl index cc4e29da2..8dde7aaaf 100644 --- a/test/BitStringAddresses.jl +++ b/test/BitStringAddresses.jl @@ -464,7 +464,7 @@ end @test OccupationNumberFS(i for i in 1:3) == OccupationNumberFS(1, 2, 3) @test isa(OccupationNumberFS{3,UInt32}(i for i in 1:3), OccupationNumberFS{3,UInt32}) @test isa(OccupationNumberFS(1, 2, 3), OccupationNumberFS{3,UInt8}) - @test_throws ArgumentError OccupationNumberFS(1.1, 2, 3) + @test_throws MethodError OccupationNumberFS(1.1, 2, 3) @test_throws ArgumentError OccupationNumberFS(-1, 2, 3) @test_throws ArgumentError OccupationNumberFS(1, 2, 300) end @@ -485,6 +485,13 @@ end @test isa(OccupationNumberFS(fs), OccupationNumberFS{2,UInt8}) end + @testset "OccupationNumberFS with sparse constructor" begin + @test OccupationNumberFS(2, 2=>4) == OccupationNumberFS(0, 4) + @test OccupationNumberFS{2}(2 => 4) == OccupationNumberFS(2, 2 => 4) + @test OccupationNumberFS(5, i => i + 1 for i in 1:3) == + OccupationNumberFS{5}(Tuple(i => i + 1 for i in 1:3)) + end + @testset "Printing and parsing OccupationNumberFS" begin fs = OccupationNumberFS(1, 2, 3, 0, 1, 20, 3, 2, 5, 0, 1) @test eval(Meta.parse(repr(fs))) == fs