Skip to content

Commit 235b4f0

Browse files
committed
introduce Field
1 parent d15696c commit 235b4f0

File tree

6 files changed

+45
-28
lines changed

6 files changed

+45
-28
lines changed

src/negativity.jl

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,23 +87,27 @@ function _partial_transpose(ρ::QuantumObject{<:AbstractArray,OperatorQuantumObj
8787
# 2 - the subsystem need be transposed
8888

8989
nsys = length(mask2)
90-
dimsvec = dimsvec_to_list.dims.to)
90+
dimslist = dims_to_list.dims)
9191
pt_dims = reshape(Vector(1:(2*nsys)), (nsys, 2))
9292
pt_idx = [
9393
[pt_dims[n, mask2[n]] for n in 1:nsys] # origin value in mask2
9494
[pt_dims[n, 3-mask2[n]] for n in 1:nsys] # opposite value in mask2 (1 -> 2, and 2 -> 1)
9595
]
9696
return QuantumObject(
97-
reshape(permutedims(reshape.data, (dimsvec..., dimsvec...)), pt_idx), size(ρ)),
97+
reshape(permutedims(reshape.data, (dimslist..., dimslist...)), pt_idx), size(ρ)),
9898
Operator,
9999
Dimensions.dims.to),
100100
)
101101
end
102102

103103
# for sparse matrices
104104
function _partial_transpose::QuantumObject{<:AbstractSparseArray,OperatorQuantumObject}, mask::Vector{Bool})
105+
isa.dims, CompoundDimensions) &&
106+
.dims.to != ρ.dims.from) &&
107+
throw(ArgumentError("Invalid partial transpose for dims = $(ρ.dims)"))
108+
105109
M, N = size(ρ)
106-
dimsTuple = Tuple(dimsvec_to_list.dims.to))
110+
dimsTuple = Tuple(dims_to_list.dims))
107111
colptr = ρ.data.colptr
108112
rowval = ρ.data.rowval
109113
nzval = ρ.data.nzval

src/qobj/arithmetic_and_attributes.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,9 @@ function ptrace(QO::QuantumObject{<:AbstractArray,KetQuantumObject}, sel::Union{
559559
(n_d == 1) && return ket2dm(QO) # ptrace should always return Operator
560560
end
561561

562-
dimsvec = dimsvec_to_list(QO.dims.to)
562+
dimslist = dims_to_list(QO.dims)
563563
_sort_sel = sort(SVector{length(sel),Int}(sel))
564-
ρtr, dkeep = _ptrace_ket(QO.data, dimsvec, _sort_sel)
564+
ρtr, dkeep = _ptrace_ket(QO.data, dimslist, _sort_sel)
565565
return QuantumObject(ρtr, type = Operator, dims = Dimensions(dkeep))
566566
end
567567

@@ -587,9 +587,9 @@ function ptrace(QO::QuantumObject{<:AbstractArray,OperatorQuantumObject}, sel::U
587587
(n_d == 1) && return QO
588588
end
589589

590-
dimsvec = dimsvec_to_list(QO.dims.to)
590+
dimslist = dims_to_list(QO.dims)
591591
_sort_sel = sort(SVector{length(sel),Int}(sel))
592-
ρtr, dkeep = _ptrace_oper(QO.data, dimsvec, _sort_sel)
592+
ρtr, dkeep = _ptrace_oper(QO.data, dimslist, _sort_sel)
593593
return QuantumObject(ρtr, type = Operator, dims = Dimensions(dkeep))
594594
end
595595
ptrace(QO::QuantumObject, sel::Int) = ptrace(QO, SVector(sel))
@@ -770,8 +770,8 @@ function permute(
770770
order_svector = SVector{length(order),Int}(order) # convert it to SVector for performance
771771

772772
# obtain the arguments: dims for reshape; perm for PermutedDimsArray
773-
dimsvec = dimsvec_to_list(A.dims.to)
774-
dims, perm = _dims_and_perm(A.type, dimsvec, order_svector, length(order_svector))
773+
dimslist = dims_to_list(A.dims)
774+
dims, perm = _dims_and_perm(A.type, dimslist, order_svector, length(order_svector))
775775

776776
return QuantumObject(
777777
reshape(permutedims(reshape(A.data, dims...), Tuple(perm)), size(A)),

src/qobj/dimensions.jl

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function Dimensions(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<:Intege
1717
L = length(dims)
1818
(L > 0) || throw(DomainError(dims, "The argument dims must be of non-zero length"))
1919

20-
return Dimensions{L}(SVector{L,Space}(Space.(dims)))
20+
return Dimensions{L}(SVector{L,AbstractSpace}(Space.(dims)))
2121
end
2222
Dimensions(dims::Int) = Dimensions(SVector{1,Int}(dims))
2323
Dimensions(dims::Any) = throw(
@@ -28,9 +28,6 @@ Dimensions(dims::Any) = throw(
2828

2929
Base.show(io::IO, D::Dimensions) = print(io, D.to)
3030

31-
# this creates a list of Space(1), it's used to generate `from` for Ket, and `to` for Bra)
32-
oneDimensions(N::Int) = Dimensions(SVector{N,AbstractSpace}(ntuple(i -> Space(1), Val(N))))
33-
3431
struct CompoundDimensions{N} <: AbstractDimensions{N}
3532
# note that the number `N` should be the same for both `to` and `from`
3633
to::SVector{N,AbstractSpace} # space acting on the left
@@ -52,7 +49,7 @@ function CompoundDimensions(
5249
),
5350
)
5451

55-
return CompoundDimensions{L1}(SVector{L1,Space}(Space.(to)), SVector{L1,Space}(Space.(from)))
52+
return CompoundDimensions{L1}(SVector{L1,AbstractSpace}(Space.(to)), SVector{L1,AbstractSpace}(Space.(from)))
5653
end
5754
CompoundDimensions(to::Int, from::Int) = CompoundDimensions(SVector{1,Int}(to), SVector{1,Int}(from))
5855

@@ -61,16 +58,17 @@ Base.show(io::IO, D::CompoundDimensions) = print(io, "[", D.to, ", ", D.from, "]
6158
_gen_dims(dims::AbstractDimensions) = dims
6259
_gen_dims(dims::Any) = Dimensions(dims)
6360

64-
dimsvec_to_list(dimsvec::SVector{N,AbstractSpace}) where {N} = SVector{N,Int}(ntuple(i -> dimsvec[i].size, Val(N)))
61+
# obtain dims in the type of SVector with integers
62+
dims_to_list(dimsvec::SVector{N,AbstractSpace}) where {N} = SVector{N,Int}(ntuple(i -> dimsvec[i].size, Val(N)))
63+
dims_to_list(dims::Dimensions) = dims_to_list(dims.to)
64+
dims_to_list(dims::CompoundDimensions) = SVector{2}(dims_to_list(dims.to), dims_to_list(dims.from))
6565

66-
Base.:(==)(vect::AbstractVector{T}, dims::Dimensions) where {T} = vect == dimsvec_to_list(dims.to)
67-
Base.:(==)(vect::AbstractVector{T}, dims::CompoundDimensions) where {T} = vect == [dimsvec_to_list(dims.to), dimsvec_to_list(dims.from)]
66+
Base.:(==)(vect::AbstractVector{T}, dims::AbstractDimensions) where {T} = vect == dims_to_list(dims)
6867
Base.:(==)(dims::AbstractDimensions, vect::AbstractVector{T}) where {T} = vect == dims
6968

7069
Base.length(::AbstractDimensions{N}) where {N} = N
7170

7271
Base.prod(dims::Dimensions) = prod(dims.to)
73-
Base.prod(spaces::SVector{1,<:AbstractSpace}) = spaces[1].size # for `Dimensions.to` has only a single Space
7472

7573
LinearAlgebra.transpose(dims::Dimensions) = dims
7674
LinearAlgebra.transpose(dims::CompoundDimensions) = CompoundDimensions(dims.from, dims.to) # switch `to` and `from`

src/qobj/quantum_object_base.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,17 @@ function _check_QuantumObject(type::OperatorBraQuantumObject, dims::Dimensions,
210210
end
211211

212212
CompoundDimensions(::KetQuantumObject, dims::Dimensions{N}) where {N} =
213-
CompoundDimensions{N}(dims.to, oneDimensions(length(dims)).to)
213+
CompoundDimensions{N}(dims.to, Field_list(N))
214214
CompoundDimensions(::BraQuantumObject, dims::Dimensions{N}) where {N} =
215-
CompoundDimensions{N}(oneDimensions(length(dims)).to, dims.to)
215+
CompoundDimensions{N}(Field_list(N), dims.to)
216216
CompoundDimensions(::OperatorQuantumObject, dims::Dimensions{N}) where {N} = CompoundDimensions{N}(dims.to, dims.to)
217217
CompoundDimensions(::OperatorQuantumObject, dims::CompoundDimensions) = dims
218218

219219
# support Qobj.to and Qobj.from (but maybe this is not a good idea)
220220
# Base.getproperty(A::AbstractQuantumObject, key::Symbol) = getproperty(A, Val{key}())
221221
# Base.getproperty(A::AbstractQuantumObject{DT,KetQuantumObject,<:Dimensions}, ::Val{:to}) where {DT} = A.dims.to
222-
# Base.getproperty(A::AbstractQuantumObject{DT,KetQuantumObject,<:Dimensions}, ::Val{:from}) where {DT} = oneDimensions(length(A.dims))
223-
# Base.getproperty(A::AbstractQuantumObject{DT,BraQuantumObject,<:Dimensions}, ::Val{:to}) where {DT} = oneDimensions(length(A.dims))
222+
# Base.getproperty(A::AbstractQuantumObject{DT,KetQuantumObject,<:Dimensions}, ::Val{:from}) where {DT} = Dimensions(Field_list(length(A.dims))
223+
# Base.getproperty(A::AbstractQuantumObject{DT,BraQuantumObject,<:Dimensions}, ::Val{:to}) where {DT} = Dimensions(Field_list(length(A.dims))
224224
# Base.getproperty(A::AbstractQuantumObject{DT,BraQuantumObject,<:Dimensions}, ::Val{:from}) where {DT} = A.dims.to
225225
# Base.getproperty(A::AbstractQuantumObject{DT,OperatorQuantumObject}, ::Val{:to}) where {DT} = A.dims.to
226226
# Base.getproperty(A::AbstractQuantumObject{DT,OperatorQuantumObject,<:Dimensions}, ::Val{:from}) where {DT} = A.dims.to

src/qobj/space.jl

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
1-
export AbstractSpace, Space
1+
export AbstractSpace, Field, Space
22

33
abstract type AbstractSpace end
44

5+
# this replaces Space(1), so that we don't need to store the value `1`
6+
struct Field <: AbstractSpace end
7+
Base.getproperty(s::Field, key::Symbol) = getproperty(s, Val{key}())
8+
Base.getproperty(s::Field, ::Val{:size}) = 1
9+
Base.string(s::Field) = "1" # this is only used when printing AbstractDimensions
10+
11+
# this creates a list of Field, it is used to generate `from` for Ket, and `to` for Bra)
12+
Field_list(N::Int) = SVector{N,AbstractSpace}(ntuple(i -> Field(), Val(N)))
13+
514
struct Space <: AbstractSpace
615
size::Int
716

817
function Space(size::Int)
9-
(size < 1) && throw(DomainError(size, "The size of Space must be positive integer (≥ 1)."))
10-
return new(size)
18+
if size == 1
19+
return Field()
20+
elseif size > 1
21+
return new(size)
22+
else
23+
throw(DomainError(size, "The size of Space must be positive integer (≥ 1)."))
24+
end
1125
end
1226
end
1327
Base.string(s::Space) = string(s.size) # this is only used when printing AbstractDimensions
1428

1529
# for `prod(::Dimensions)`
16-
Base.:(*)(i::Int, s::Space) = i * s.size
17-
Base.:(*)(s1::Space, s2::Space) = s1.size * s2.size
30+
Base.:(*)(i::Int, s::AbstractSpace) = i * s.size
31+
Base.:(*)(s1::AbstractSpace, s2::AbstractSpace) = s1.size * s2.size
32+
Base.prod(spaces::SVector{1,AbstractSpace}) = spaces[1].size # for `Dimensions.to` has only a single Space

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ if (GROUP == "All") || (GROUP == "Code-Quality")
3030
using QuantumToolbox
3131
using Aqua, JET
3232

33-
include(joinpath(testdir, "core-test", "code_quality.jl"))
33+
#include(joinpath(testdir, "core-test", "code_quality.jl"))
3434
end
3535

3636
if (GROUP == "All") || (GROUP == "Core")

0 commit comments

Comments
 (0)