Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased](https://github.com/qutip/QuantumToolbox.jl/tree/main)

- Support different length for to and from on GeneralDimensions. ([#448])

## [v0.30.0]
Release date: 2025-04-12

Expand Down Expand Up @@ -201,3 +203,4 @@ Release date: 2024-11-13
[#438]: https://github.com/qutip/QuantumToolbox.jl/issues/438
[#440]: https://github.com/qutip/QuantumToolbox.jl/issues/440
[#443]: https://github.com/qutip/QuantumToolbox.jl/issues/443
[#448]: https://github.com/qutip/QuantumToolbox.jl/issues/448
6 changes: 3 additions & 3 deletions src/entropy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ Here, ``S`` is the [Von Neumann entropy](https://en.wikipedia.org/wiki/Von_Neuma
- `kwargs` are the keyword arguments for calculating Von Neumann entropy. See also [`entropy_vn`](@ref).
"""
function entropy_mutual(
ρAB::QuantumObject{ObjType,<:AbstractDimensions{N}},
ρAB::QuantumObject{ObjType,<:AbstractDimensions{N,M}},
selA::Union{Int,AbstractVector{Int},Tuple},
selB::Union{Int,AbstractVector{Int},Tuple};
kwargs...,
) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject},N}
) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject},N,M}
# check if selA and selB matches the dimensions of ρAB
sel_A_B = (selA..., selB...)
(length(sel_A_B) != N) && throw(
Expand Down Expand Up @@ -182,7 +182,7 @@ Here, ``S`` is the [Von Neumann entropy](https://en.wikipedia.org/wiki/Von_Neuma
- `kwargs` are the keyword arguments for calculating Von Neumann entropy. See also [`entropy_vn`](@ref).
"""
entropy_conditional(
ρAB::QuantumObject{ObjType,<:AbstractDimensions{N}},
ρAB::QuantumObject{ObjType,<:AbstractDimensions{N,N}},
selB::Union{Int,AbstractVector{Int},Tuple};
kwargs...,
) where {ObjType<:Union{KetQuantumObject,OperatorQuantumObject},N} =
Expand Down
23 changes: 10 additions & 13 deletions src/qobj/dimensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ This file defines the Dimensions structures, which can describe composite Hilber

export AbstractDimensions, Dimensions, GeneralDimensions

abstract type AbstractDimensions{N} end
abstract type AbstractDimensions{N,M} end

@doc raw"""
struct Dimensions{N,T<:Tuple} <: AbstractDimensions{N}
struct Dimensions{N,T<:Tuple} <: AbstractDimensions{N, N}
to::T
end

A structure that describes the Hilbert [`Space`](@ref) of each subsystems.
"""
struct Dimensions{N,T<:Tuple} <: AbstractDimensions{N}
struct Dimensions{N,T<:Tuple} <: AbstractDimensions{N,N}
to::T

# make sure the elements in the tuple are all AbstractSpace
Expand All @@ -24,7 +24,7 @@ function Dimensions(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<:Intege
L = length(dims)
(L > 0) || throw(DomainError(dims, "The argument dims must be of non-zero length"))

return Dimensions(NTuple{L,Space}(Space.(dims)))
return Dimensions(Tuple(Space.(dims)))
end
Dimensions(dims::Int) = Dimensions(Space(dims))
Dimensions(dims::DimType) where {DimType<:AbstractSpace} = Dimensions((dims,))
Expand All @@ -42,14 +42,14 @@ Dimensions(dims::Any) = throw(

A structure that describes the left-hand side (`to`) and right-hand side (`from`) Hilbert [`Space`](@ref) of an [`Operator`](@ref).
"""
struct GeneralDimensions{N,T1<:Tuple,T2<:Tuple} <: AbstractDimensions{N}
struct GeneralDimensions{N,M,T1<:Tuple,T2<:Tuple} <: AbstractDimensions{N,M}
# note that the number `N` should be the same for both `to` and `from`
to::T1 # space acting on the left
from::T2 # space acting on the right

# make sure the elements in the tuple are all AbstractSpace
GeneralDimensions(to::NTuple{N,T1}, from::NTuple{N,T2}) where {N,T1<:AbstractSpace,T2<:AbstractSpace} =
new{N,typeof(to),typeof(from)}(to, from)
GeneralDimensions(to::NTuple{N,T1}, from::NTuple{M,T2}) where {N,M,T1<:AbstractSpace,T2<:AbstractSpace} =
new{N,M,typeof(to),typeof(from)}(to, from)
end
function GeneralDimensions(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<:Union{AbstractVector,NTuple},N}
(length(dims) != 2) && throw(ArgumentError("Invalid dims = $dims"))
Expand All @@ -59,14 +59,11 @@ function GeneralDimensions(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<

L1 = length(dims[1])
L2 = length(dims[2])
((L1 > 0) && (L1 == L2)) || throw(
DomainError(
(L1, L2),
"The length of the arguments `dims[1]` and `dims[2]` must be in the same length and have at least one element.",
),
((L1 > 0) && (L2 > 0)) || throw(
DomainError((L1, L2), "The length of the arguments `dims[1]` and `dims[2]` must have at least one element."),
)

return GeneralDimensions(NTuple{L1,Space}(Space.(dims[1])), NTuple{L1,Space}(Space.(dims[2])))
return GeneralDimensions(Tuple(Space.(dims[1])), Tuple(Space.(dims[2])))
end

_gen_dimensions(dims::AbstractDimensions) = dims
Expand Down
2 changes: 1 addition & 1 deletion src/qobj/quantum_object_base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ get_dimensions_to(
get_dimensions_from(A::AbstractQuantumObject{KetQuantumObject,<:Dimensions{N}}) where {N} = space_one_list(N)
get_dimensions_from(A::AbstractQuantumObject{BraQuantumObject,<:Dimensions{N}}) where {N} = A.dimensions.to
get_dimensions_from(A::AbstractQuantumObject{OperatorQuantumObject,<:Dimensions{N}}) where {N} = A.dimensions.to
get_dimensions_from(A::AbstractQuantumObject{OperatorQuantumObject,<:GeneralDimensions{N}}) where {N} =
get_dimensions_from(A::AbstractQuantumObject{OperatorQuantumObject,<:GeneralDimensions{N,M}}) where {N,M} =
A.dimensions.from
get_dimensions_from(
A::AbstractQuantumObject{ObjType,<:Dimensions{N}},
Expand Down
7 changes: 5 additions & 2 deletions test/core-test/quantum_objects.jl
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
a2 = Qobj(a)
a3 = Qobj(a, type = SuperOperator)
a4 = Qobj(sprand(ComplexF64, 100, 10, 0.1)) # GeneralDimensions
a5 = QuantumObject(rand(ComplexF64, 2*3*4, 5), dims = ((2, 3, 4), (5,)))
@test isket(a2) == false
@test isbra(a2) == false
@test isoper(a2) == true
Expand Down Expand Up @@ -116,6 +117,8 @@
@test isconstant(a4) == true
@test isunitary(a4) == false
@test a4.dims == [[100], [10]]
@test isoper(a5) == true
@test a5.dims == [[2, 3, 4], [5]]
@test_throws DimensionMismatch Qobj(a, dims = 2)
@test_throws DimensionMismatch Qobj(a4.data, dims = 2)
@test_throws DimensionMismatch Qobj(a4.data, dims = ((100,), (2,)))
Expand Down Expand Up @@ -351,7 +354,7 @@
for T in [ComplexF32, ComplexF64]
N = 4
a = rand(T, N)
@inferred QuantumObject{KetQuantumObject,Dimensions{1},typeof(a)} Qobj(a)
@inferred Qobj(a)
for type in [Ket, OperatorKet]
@inferred Qobj(a, type = type)
end
Expand All @@ -367,7 +370,7 @@
end

UnionType2 = Union{
QuantumObject{OperatorQuantumObject,GeneralDimensions{1,Tuple{Space},Tuple{Space}},Matrix{T}},
QuantumObject{OperatorQuantumObject,GeneralDimensions{1,1,Tuple{Space},Tuple{Space}},Matrix{T}},
QuantumObject{OperatorQuantumObject,Dimensions{1,Tuple{Space}},Matrix{T}},
}
a = rand(T, N, N)
Expand Down
Loading