Skip to content

Commit

Permalink
Introduce Space, Dimensions, and GeneralDimensions (#360)
Browse files Browse the repository at this point in the history
  • Loading branch information
ytdHuang authored Jan 13, 2025
1 parent 6716a52 commit 4f81980
Show file tree
Hide file tree
Showing 33 changed files with 779 additions and 334 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Change the structure of block diagonalization functions, using `BlockDiagonalForm` struct and changing the function name from `bdf` to `block_diagonal_form`. ([#349])
- Add **GPUArrays** compatibility for `ptrace` function, by using **KernelAbstractions.jl**. ([#350])
- Introduce `Space`, `Dimensions`, `GeneralDimensions` structures to support wider definitions and operations of `Qobj/QobjEvo`, and potential functionalities in the future. ([#271], [#353], [#360])

## [v0.24.0]
Release date: 2024-12-13
Expand Down Expand Up @@ -55,6 +56,7 @@ Release date: 2024-11-13
[v0.24.0]: https://github.com/qutip/QuantumToolbox.jl/releases/tag/v0.24.0
[#86]: https://github.com/qutip/QuantumToolbox.jl/issues/86
[#139]: https://github.com/qutip/QuantumToolbox.jl/issues/139
[#271]: https://github.com/qutip/QuantumToolbox.jl/issues/271
[#292]: https://github.com/qutip/QuantumToolbox.jl/issues/292
[#306]: https://github.com/qutip/QuantumToolbox.jl/issues/306
[#309]: https://github.com/qutip/QuantumToolbox.jl/issues/309
Expand All @@ -71,3 +73,5 @@ Release date: 2024-11-13
[#347]: https://github.com/qutip/QuantumToolbox.jl/issues/347
[#349]: https://github.com/qutip/QuantumToolbox.jl/issues/349
[#350]: https://github.com/qutip/QuantumToolbox.jl/issues/350
[#353]: https://github.com/qutip/QuantumToolbox.jl/issues/353
[#360]: https://github.com/qutip/QuantumToolbox.jl/issues/360
5 changes: 4 additions & 1 deletion docs/src/resources/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ CurrentModule = QuantumToolbox
## [Quantum object (Qobj) and type](@id doc-API:Quantum-object-and-type)

```@docs
Space
Dimensions
GeneralDimensions
AbstractQuantumObject
BraQuantumObject
Bra
Expand Down Expand Up @@ -73,7 +76,7 @@ LinearAlgebra.diag
proj
ptrace
purity
permute
SparseArrays.permute
tidyup
tidyup!
get_data
Expand Down
18 changes: 10 additions & 8 deletions ext/QuantumToolboxCUDAExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,58 +10,60 @@ import SparseArrays: SparseVector, SparseMatrixCSC
If `A.data` is a dense array, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CuArray` for gpu calculations.
"""
CuArray(A::QuantumObject{Tq}) where {Tq<:Union{Vector,Matrix}} = QuantumObject(CuArray(A.data), A.type, A.dims)
CuArray(A::QuantumObject{Tq}) where {Tq<:Union{Vector,Matrix}} = QuantumObject(CuArray(A.data), A.type, A.dimensions)

@doc raw"""
CuArray{T}(A::QuantumObject)
If `A.data` is a dense array, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CuArray` with element type `T` for gpu calculations.
"""
CuArray{T}(A::QuantumObject{Tq}) where {T,Tq<:Union{Vector,Matrix}} = QuantumObject(CuArray{T}(A.data), A.type, A.dims)
CuArray{T}(A::QuantumObject{Tq}) where {T,Tq<:Union{Vector,Matrix}} =
QuantumObject(CuArray{T}(A.data), A.type, A.dimensions)

@doc raw"""
CuSparseVector(A::QuantumObject)
If `A.data` is a sparse vector, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CUSPARSE.CuSparseVector` for gpu calculations.
"""
CuSparseVector(A::QuantumObject{<:SparseVector}) = QuantumObject(CuSparseVector(A.data), A.type, A.dims)
CuSparseVector(A::QuantumObject{<:SparseVector}) = QuantumObject(CuSparseVector(A.data), A.type, A.dimensions)

@doc raw"""
CuSparseVector{T}(A::QuantumObject)
If `A.data` is a sparse vector, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CUSPARSE.CuSparseVector` with element type `T` for gpu calculations.
"""
CuSparseVector{T}(A::QuantumObject{<:SparseVector}) where {T} = QuantumObject(CuSparseVector{T}(A.data), A.type, A.dims)
CuSparseVector{T}(A::QuantumObject{<:SparseVector}) where {T} =
QuantumObject(CuSparseVector{T}(A.data), A.type, A.dimensions)

@doc raw"""
CuSparseMatrixCSC(A::QuantumObject)
If `A.data` is in the type of `SparseMatrixCSC`, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CUSPARSE.CuSparseMatrixCSC` for gpu calculations.
"""
CuSparseMatrixCSC(A::QuantumObject{<:SparseMatrixCSC}) = QuantumObject(CuSparseMatrixCSC(A.data), A.type, A.dims)
CuSparseMatrixCSC(A::QuantumObject{<:SparseMatrixCSC}) = QuantumObject(CuSparseMatrixCSC(A.data), A.type, A.dimensions)

@doc raw"""
CuSparseMatrixCSC{T}(A::QuantumObject)
If `A.data` is in the type of `SparseMatrixCSC`, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CUSPARSE.CuSparseMatrixCSC` with element type `T` for gpu calculations.
"""
CuSparseMatrixCSC{T}(A::QuantumObject{<:SparseMatrixCSC}) where {T} =
QuantumObject(CuSparseMatrixCSC{T}(A.data), A.type, A.dims)
QuantumObject(CuSparseMatrixCSC{T}(A.data), A.type, A.dimensions)

@doc raw"""
CuSparseMatrixCSR(A::QuantumObject)
If `A.data` is in the type of `SparseMatrixCSC`, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CUSPARSE.CuSparseMatrixCSR` for gpu calculations.
"""
CuSparseMatrixCSR(A::QuantumObject{<:SparseMatrixCSC}) = QuantumObject(CuSparseMatrixCSR(A.data), A.type, A.dims)
CuSparseMatrixCSR(A::QuantumObject{<:SparseMatrixCSC}) = QuantumObject(CuSparseMatrixCSR(A.data), A.type, A.dimensions)

@doc raw"""
CuSparseMatrixCSR(A::QuantumObject)
If `A.data` is in the type of `SparseMatrixCSC`, return a new [`QuantumObject`](@ref) where `A.data` is in the type of `CUDA.CUSPARSE.CuSparseMatrixCSR` with element type `T` for gpu calculations.
"""
CuSparseMatrixCSR{T}(A::QuantumObject{<:SparseMatrixCSC}) where {T} =
QuantumObject(CuSparseMatrixCSR{T}(A.data), A.type, A.dims)
QuantumObject(CuSparseMatrixCSR{T}(A.data), A.type, A.dimensions)

@doc raw"""
cu(A::QuantumObject; word_size::Int=64)
Expand Down
2 changes: 2 additions & 0 deletions src/QuantumToolbox.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ include("progress_bar.jl")
include("linear_maps.jl")

# Quantum Object
include("qobj/space.jl")
include("qobj/dimensions.jl")
include("qobj/quantum_object_base.jl")
include("qobj/quantum_object.jl")
include("qobj/quantum_object_evo.jl")
Expand Down
5 changes: 2 additions & 3 deletions src/correlations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ function correlation_3op_2t(
ψ0 = steadystate(L)
end

allequal((L.dims, ψ0.dims, A.dims, B.dims, C.dims)) ||
throw(DimensionMismatch("The quantum objects are not of the same Hilbert dimension."))
check_dimensions(L, ψ0, A, B, C)

kwargs2 = merge((saveat = collect(tlist),), (; kwargs...))
ρt_list = mesolve(L, ψ0, tlist; kwargs2...).states
Expand Down Expand Up @@ -137,7 +136,7 @@ function correlation_2op_2t(
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
}
C = eye(prod(H.dims), dims = H.dims)
C = eye(prod(H.dimensions), dims = H.dimensions)
if reverse
corr = correlation_3op_2t(H, ψ0, tlist, τlist, c_ops, A, B, C; kwargs...)
else
Expand Down
29 changes: 19 additions & 10 deletions src/negativity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ julia> round(negativity(ρ, 2), digits=2)
```
"""
function negativity::QuantumObject, subsys::Int; logarithmic::Bool = false)
mask = fill(false, length.dims))
mask = fill(false, length.dimensions))
try
mask[subsys] = true
catch
Expand Down Expand Up @@ -70,37 +70,46 @@ Return the partial transpose of a density matrix ``\rho``, where `mask` is an ar
# Returns
- `ρ_pt::QuantumObject`: The density matrix with the selected subsystems transposed.
"""
function partial_transpose::QuantumObject{T,OperatorQuantumObject}, mask::Vector{Bool}) where {T}
if length(mask) != length.dims)
function partial_transpose::QuantumObject{DT,OperatorQuantumObject}, mask::Vector{Bool}) where {DT}
if length(mask) != length.dimensions)
throw(ArgumentError("The length of \`mask\` should be equal to the length of \`ρ.dims\`."))
end
return _partial_transpose(ρ, mask)
end

# for dense matrices
function _partial_transpose::QuantumObject{<:AbstractArray,OperatorQuantumObject}, mask::Vector{Bool})
function _partial_transpose::QuantumObject{DT,OperatorQuantumObject}, mask::Vector{Bool}) where {DT<:AbstractArray}
isa.dimensions, GeneralDimensions) &&
(get_dimensions_to(ρ) != get_dimensions_from(ρ)) &&
throw(ArgumentError("Invalid partial transpose for dims = $(_get_dims_string.dimensions))"))

mask2 = [1 + Int(i) for i in mask]
# mask2 has elements with values equal to 1 or 2
# 1 - the subsystem don't need to be transposed
# 2 - the subsystem need be transposed

nsys = length(mask2)
dims = dimensions_to_dims(get_dimensions_to(ρ))
pt_dims = reshape(Vector(1:(2*nsys)), (nsys, 2))
pt_idx = [
[pt_dims[n, mask2[n]] for n in 1:nsys] # origin value in mask2
[pt_dims[n, 3-mask2[n]] for n in 1:nsys] # opposite value in mask2 (1 -> 2, and 2 -> 1)
[pt_dims[n, mask2[n]] for n in 1:nsys] # origin value in mask2
[pt_dims[n, 3-mask2[n]] for n in 1:nsys] # opposite value in mask2 (1 -> 2, and 2 -> 1)
]
return QuantumObject(
reshape(permutedims(reshape.data, (ρ.dims..., ρ.dims...)), pt_idx), size(ρ)),
reshape(permutedims(reshape.data, (dims..., dims...)), pt_idx), size(ρ)),
Operator,
ρ.dims,
Dimensions.dimensions.to),
)
end

# for sparse matrices
function _partial_transpose::QuantumObject{<:AbstractSparseArray,OperatorQuantumObject}, mask::Vector{Bool})
isa.dimensions, GeneralDimensions) &&
(get_dimensions_to(ρ) != get_dimensions_from(ρ)) &&
throw(ArgumentError("Invalid partial transpose for dims = $(_get_dims_string.dimensions))"))

M, N = size(ρ)
dimsTuple = Tuple(ρ.dims)
dimsTuple = Tuple(dimensions_to_dims(get_dimensions_to(ρ)))
colptr = ρ.data.colptr
rowval = ρ.data.rowval
nzval = ρ.data.nzval
Expand Down Expand Up @@ -132,5 +141,5 @@ function _partial_transpose(ρ::QuantumObject{<:AbstractSparseArray,OperatorQuan
end
end

return QuantumObject(sparse(I_pt, J_pt, V_pt, M, N), Operator, ρ.dims)
return QuantumObject(sparse(I_pt, J_pt, V_pt, M, N), Operator, ρ.dimensions)
end
Loading

0 comments on commit 4f81980

Please sign in to comment.