Skip to content

Commit

Permalink
1) Interchange the first and second type parameters of InternalPattern
Browse files Browse the repository at this point in the history
2) Add `parameternames` to `InternalPattern` so that its type parameters can be accessed by the name.
  • Loading branch information
waltergu committed Dec 4, 2024
1 parent 09fb4bb commit 20da05b
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 27 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "QuantumLattices"
uuid = "78ae1a1f-1d5d-5174-b61c-66e31b2346dc"
authors = ["waltergu <[email protected]>"]
version = "0.10.2"
version = "0.10.3"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Expand Down
43 changes: 22 additions & 21 deletions src/DegreesOfFreedom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -332,23 +332,24 @@ Judge whether the direct product of a set of homogenous simple internal indexes
end

"""
InternalPattern{P, I<:Tuple{Vararg{SimpleInternalIndex}}, N, C<:NTuple{N, Function}} <: QuantumOperator
InternalPattern{I, P, N, C<:NTuple{N, Function}} <: QuantumOperator
Internal pattern for the direct product of a set of simple internal indexes with extra constraints.
"""
struct InternalPattern{P, I<:Tuple{Vararg{SimpleInternalIndex}}, N, C<:NTuple{N, Function}} <: QuantumOperator
struct InternalPattern{I, P, N, C<:NTuple{N, Function}} <: QuantumOperator
index::InternalIndexProd{I}
constraints::C
representations::NTuple{N, String}
function InternalPattern{P}(index::InternalIndexProd{I}, constraints::NTuple{N, Function}, representations::NTuple{N, String}=map(string, constraints)) where {P, I<:Tuple{Vararg{SimpleInternalIndex}}, N}
@assert isa(P, NTuple{N, Int}) "InternalPattern error: partition ($P) is not $N-tuple of integers."
@assert sum(P)==rank(index) "InternalPattern error: sum of partition ($(sum(P))) is not equal to the rank ($(rank(index))) of the direct product of simple internal indexes."
new{P, I, N, typeof(constraints)}(index, constraints, representations)
new{I, P, N, typeof(constraints)}(index, constraints, representations)
end
end
@inline Base.:(==)(pattern₁::InternalPattern{P₁}, pattern₂::InternalPattern{P₂}) where {P₁, P₂} = P₁==P₂ && pattern₁.index==pattern₂.index && pattern₁.representations==pattern₂.representations
@inline Base.:isequal(pattern₁::InternalPattern{P₁}, pattern₂::InternalPattern{P₂}) where {P₁, P₂} = isequal(P₁, P₂) && isequal(pattern₁.index, pattern₂.index) && isequal(pattern₁.representations, pattern₂.representations)
@inline Base.hash(pattern::InternalPattern{P}, h::UInt) where P = hash((P..., pattern.index.contents..., pattern.representations...), h)
@inline parameternames(::Type{<:InternalPattern}) = (:index, :partition, :npartition, :constraints)
@inline Base.:(==)(pattern₁::InternalPattern, pattern₂::InternalPattern) = partition(pattern₁)==partition(pattern₂) && pattern₁.index==pattern₂.index && pattern₁.representations==pattern₂.representations
@inline Base.:isequal(pattern₁::InternalPattern, pattern₂::InternalPattern) = isequal(partition(pattern₁), partition(pattern₂)) && isequal(pattern₁.index, pattern₂.index) && isequal(pattern₁.representations, pattern₂.representations)
@inline Base.hash(pattern::InternalPattern, h::UInt) = hash((partition(pattern)..., pattern.index.contents..., pattern.representations...), h)
function Base.show(io::IO, pattern::InternalPattern)
len, count = length(pattern.representations), 1
for i = 1:len
Expand Down Expand Up @@ -388,40 +389,40 @@ Construct an internal pattern whose constraint is an [`AllEqual`](@ref) function

"""
partition(pattern::InternalPattern) -> Tuple{Vararg{Int}}
partition(::Type{<:InternalPattern{P}}) where P -> P
partition(::Type{<:InternalPattern{I, P} where I}) where P -> P
Get the partition of the direct product of a set of simple internal indexes on which the extra constraints operate independently.
"""
@inline partition(pattern::InternalPattern) = partition(typeof(pattern))
@inline partition(::Type{<:InternalPattern{P}}) where P = P
@inline partition(::Type{<:InternalPattern{I, P} where I}) where P = P

"""
rank(pattern::InternalPattern) -> Int
rank(::Type{<:InternalPattern{P}}) where P -> Int
rank(::Type{P}) where {P<:InternalPattern} -> Int
Get the rank of the direct product of the simple internal indexes that an internal pattern can apply.
"""
@inline rank(pattern::InternalPattern) = rank(typeof(pattern))
@inline @generated rank(::Type{<:InternalPattern{P}}) where P = sum(P)
@inline @generated rank(::Type{P}) where {P<:InternalPattern} = sum(partition(P))

"""
rank(pattern::InternalPattern, i::Integer) -> Int
rank(::Type{<:InternalPattern{P}}, i::Integer) where P -> Int
rank(::Type{P}, i::Integer) where {P<:InternalPattern} -> Int
Get the rank of the direct product of the simple internal indexes that the ith constraint in an internal pattern can apply.
"""
@inline rank(pattern::InternalPattern, i::Integer) = rank(typeof(pattern), i)
@inline rank(::Type{<:InternalPattern{P}}, i::Integer) where P = P[i]
@inline rank(::Type{P}, i::Integer) where {P<:InternalPattern} = partition(P)[i]

"""
match(pattern::InternalPattern, index::InternalIndexProd) -> Bool
Judge whether the direct product of a set of simple internal indexes satisfies an internal pattern.
"""
@generated function Base.match(pattern::InternalPattern{P}, index::InternalIndexProd) where P
@generated function Base.match(pattern::InternalPattern, index::InternalIndexProd)
@assert rank(pattern)==rank(index) "match error: mismatched ranks of the direct product of simple internal indexes and internal pattern."
exprs, count = [], 1
for (i, r) in enumerate(P)
for (i, r) in enumerate(partition(pattern))
start, stop = count, count+r-1
segment = Expr(:call, :InternalIndexProd, Expr(:tuple, [:(index[$pos]) for pos=start:stop]...))
push!(exprs, :(pattern.constraints[$i]($segment)::Bool))
Expand All @@ -435,8 +436,8 @@ end
Get the combination of two internal patterns.
"""
@inline function (pattern₁::InternalPattern{P₁}, pattern₂::InternalPattern{P₂}) where {P₁, P₂}
return InternalPattern{(P₁..., P₂...)}(pattern₁.indexpattern₂.index, (pattern₁.constraints..., pattern₂.constraints...), (pattern₁.representations..., pattern₂.representations...))
@inline function (pattern₁::InternalPattern, pattern₂::InternalPattern)
return InternalPattern{(partition(pattern₁)..., partition(pattern₂)...)}(pattern₁.indexpattern₂.index, (pattern₁.constraints..., pattern₂.constraints...), (pattern₁.representations..., pattern₂.representations...))
end

"""
Expand Down Expand Up @@ -1225,7 +1226,7 @@ end
V = Expr(:call, :promote_type, [:(parametertype($C, 2)) for C in types]...)
S = parametertype(MC, 2)
I = Expr(:call, :indextype, parametertype(MC, 1), [:(parametertype($C, 1)) for C in types]...)
C = :(InternalPattern{(2,), Tuple{$I, $I}, 1, Tuple{typeof(AllEqual($I))}})
C = :(InternalPattern{Tuple{$I, $I}, (2,), 1, Tuple{typeof(AllEqual($I))}})
return :(Coupling{$V, Pattern{Tuple{$S, $S}, $C}})
end
@inline VectorSpaceStyle(::Type{<:MatrixCoupling}) = VectorSpaceDirectProducted(:forward)
Expand Down Expand Up @@ -1260,11 +1261,11 @@ end
types = fieldtypes(TS)
MV = promote_type(V, map(valtype, types)...)
SS = Tuple{concatenate(map(C->fieldtypes(parametertype(idtype(C), :sites)), types)...)...}
IS = Tuple{concatenate(map(C->fieldtypes(parametertype(parametertype(idtype(C), :internal), 2)), types)...)...}
FS = Tuple{concatenate(map(C->fieldtypes(parametertype(parametertype(idtype(C), :internal), 4)), types)...)...}
IS = Tuple{concatenate(map(C->fieldtypes(parametertype(parametertype(idtype(C), :internal), :index)), types)...)...}
FS = Tuple{concatenate(map(C->fieldtypes(parametertype(parametertype(idtype(C), :internal), :constraints)), types)...)...}
N = length(types)
RS = ntuple(i->2, Val(N))
P = InternalPattern{RS, IS, N, FS}
P = InternalPattern{IS, RS, N, FS}
return Coupling{MV, Pattern{SS, P}}
end
@inline VectorSpaceStyle(::Type{<:MatrixCouplingProd}) = VectorSpaceDirectProducted(:forward)
Expand Down Expand Up @@ -1547,7 +1548,7 @@ Get the compatible `Operator` type from the type of a term, a Hilbert space and
V, V′, V′′ = valtype(T), valtype(C), valtype(fieldtype(T, :amplitude), B)
isconcretetype(V′) && (V = promote_type(V, V′))
isconcretetype(V′′) && (V = promote_type(V, V′′))
indextypes = ntuple(i->indextype(filter(fieldtype(parametertype(parametertype(idtype(C), :internal), 2), i), valtype(H)), eltype(B)), Val(rank(C)))
indextypes = ntuple(i->indextype(filter(fieldtype(parametertype(parametertype(idtype(C), :internal), :index), i), valtype(H)), eltype(B)), Val(rank(C)))
return fulltype(Operator, NamedTuple{(:value, :id), Tuple{V, Tuple{indextypes...}}})
end

Expand Down
4 changes: 2 additions & 2 deletions src/QuantumSystems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1299,11 +1299,11 @@ Construct a set of `Coupling`s corresponding to the dynamical matrix of phonons.

### expand
"""
expand(pnc::Coupling{<:Number, <:Pattern{<:NTuple{2, Colon}, <:InternalPattern{(2,), <:NTuple{2, PhononIndex{:u}}}}}, ::Val{:Hooke}, bond::Bond, hilbert::Hilbert) -> VectorSpace
expand(pnc::Coupling{<:Number, <:Pattern{<:NTuple{2, Colon}, <:InternalPattern{<:NTuple{2, PhononIndex{:u}}}}}, ::Val{:Hooke}, bond::Bond, hilbert::Hilbert) -> VectorSpace
Expand the default phonon potential coupling on a given bond.
"""
function expand(pnc::Coupling{<:Number, <:Pattern{<:NTuple{2, Colon}, <:InternalPattern{(2,), <:NTuple{2, PhononIndex{:u}}}}}, ::Val{:Hooke}, bond::Bond, hilbert::Hilbert)
function expand(pnc::Coupling{<:Number, <:Pattern{<:NTuple{2, Colon}, <:InternalPattern{<:NTuple{2, PhononIndex{:u}}}}}, ::Val{:Hooke}, bond::Bond, hilbert::Hilbert)
= rcoordinate(bond)/norm(rcoordinate(bond))
@assert isapprox(pnc.value, 1, atol=atol, rtol=rtol) "expand error: wrong coefficient of Hooke coupling."
pn₁ = filter(pnc.pattern.internal.index[1], hilbert[bond[1].site])
Expand Down
7 changes: 4 additions & 3 deletions test/DegreesOfFreedom.jl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ end
@test allequal(𝕕(1) 𝕕(1)) && !allequal(𝕕(1) 𝕕(2))

pattern = InternalPattern(𝕕(:)𝕕(:), allequal, "AllEqual(:nambu)")
@test parameternames(typeof(pattern)) == (:index, :partition, :npartition, :constraints)
@test pattern == InternalPattern(𝕕(:)𝕕(:))
@test isequal(pattern, InternalPattern(𝕕(:)𝕕(:)))
@test hash(pattern, UInt(8)) == hash((2, 𝕕(:), 𝕕(:), "AllEqual(:nambu)"), UInt(8))
Expand Down Expand Up @@ -336,7 +337,7 @@ end
@test component[2] == (2, 1, +1)

mc = MatrixCoupling(:, DID, component)
@test eltype(typeof(mc)) == Coupling{Int64, Pattern{Tuple{Colon, Colon}, InternalPattern{(2,), Tuple{DID{Int}, DID{Int}}, 1, Tuple{AllEqual{()}}}}}
@test eltype(typeof(mc)) == Coupling{Int64, Pattern{Tuple{Colon, Colon}, InternalPattern{Tuple{DID{Int}, DID{Int}}, (2,), 1, Tuple{AllEqual{()}}}}}
@test mc[1] == Coupling(-1, 𝕕(:, 1), 𝕕(:, 2))
@test mc[2] == Coupling(+1, 𝕕(:, 2), 𝕕(:, 1))
@test mc^2 == mc*mc
Expand All @@ -349,7 +350,7 @@ end

mcp = 2 * mc * another
@test mcp == MatrixCouplingProd(mc, another) * 2
@test eltype(mcp) == Coupling{Float64, Pattern{Tuple{Colon, Colon, Ordinal, Ordinal}, InternalPattern{(2, 2), Tuple{DID{Int}, DID{Int}, DID{Colon}, DID{Colon}}, 2, Tuple{AllEqual{()}, AllEqual{(:nambu,)}}}}}
@test eltype(mcp) == Coupling{Float64, Pattern{Tuple{Colon, Colon, Ordinal, Ordinal}, InternalPattern{Tuple{DID{Int}, DID{Int}, DID{Colon}, DID{Colon}}, (2, 2), 2, Tuple{AllEqual{()}, AllEqual{(:nambu,)}}}}}
@test mcp[1] == 2 * mc[1] * another[1]
@test mcp[2] == 2 * mc[2] * another[1]
@test mc*2 == 2*mc == MatrixCouplingProd(2, mc)
Expand All @@ -366,7 +367,7 @@ end
mc₂ = MatrixCoupling((2ⁿᵈ, 1ˢᵗ), DID, Component([1, 2], [2, 1], [0 1im; -1im 0]))
mcs = mc₁ + mc₂
@test mcs == MatrixCouplingSum(mc₁, mc₂)
@test eltype(mcs) == Coupling{Complex{Int64}, Pattern{Tuple{Ordinal, Ordinal}, InternalPattern{(2,), Tuple{DID{Int}, DID{Int}}, 1, Tuple{AllEqual{()}}}}}
@test eltype(mcs) == Coupling{Complex{Int64}, Pattern{Tuple{Ordinal, Ordinal}, InternalPattern{Tuple{DID{Int}, DID{Int}}, (2,), 1, Tuple{AllEqual{()}}}}}
@test collect(mcs) == [
Coupling(𝕕(1ˢᵗ, 2), 𝕕(2ⁿᵈ, 2)),
Coupling(𝕕(1ˢᵗ, 1), 𝕕(2ⁿᵈ, 1)),
Expand Down

0 comments on commit 20da05b

Please sign in to comment.