From 725c4b6a60b80d73250bec90e2dbff2355065df2 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 18 Dec 2024 13:26:27 +0900 Subject: [PATCH 1/6] simplify synonyms --- docs/src/resources/api.md | 6 +- src/qobj/arithmetic_and_attributes.jl | 9 +- src/qobj/boolean_functions.jl | 3 + src/qobj/functions.jl | 5 + src/qobj/operators.jl | 5 +- src/qobj/quantum_object.jl | 12 +- src/qobj/quantum_object_base.jl | 4 + src/qobj/quantum_object_evo.jl | 125 +++++++++++- src/qobj/synonyms.jl | 277 ++------------------------ 9 files changed, 172 insertions(+), 274 deletions(-) diff --git a/docs/src/resources/api.md b/docs/src/resources/api.md index b701d8e7..ff890fea 100644 --- a/docs/src/resources/api.md +++ b/docs/src/resources/api.md @@ -170,14 +170,14 @@ trans dag matrix_element unit +tensor +⊗ +qeye sqrtm logm expm sinm cosm -tensor -⊗ -qeye ``` ## [Time evolution](@id doc-API:Time-evolution) diff --git a/src/qobj/arithmetic_and_attributes.jl b/src/qobj/arithmetic_and_attributes.jl index a3baf214..92ad7494 100644 --- a/src/qobj/arithmetic_and_attributes.jl +++ b/src/qobj/arithmetic_and_attributes.jl @@ -130,12 +130,15 @@ end @doc raw""" dot(i::QuantumObject, A::AbstractQuantumObject j::QuantumObject) + matrix_element(i::QuantumObject, A::AbstractQuantumObject j::QuantumObject) Compute the generalized dot product `dot(i, A*j)` between a [`AbstractQuantumObject`](@ref) and two [`QuantumObject`](@ref) (`i` and `j`), namely ``\langle i | \hat{A} | j \rangle``. Supports the following inputs: - `A` is in the type of [`Operator`](@ref), with `i` and `j` are both [`Ket`](@ref). - `A` is in the type of [`SuperOperator`](@ref), with `i` and `j` are both [`OperatorKet`](@ref) + +Note that `matrix_element(i, A, j)` is a synonym of `dot(i, A, j)`. """ function LinearAlgebra.dot( i::QuantumObject{DT1,KetQuantumObject}, @@ -195,10 +198,11 @@ LinearAlgebra.transpose( @doc raw""" A' adjoint(A::AbstractQuantumObject) + dag(A::AbstractQuantumObject) Lazy adjoint (conjugate transposition) of the [`AbstractQuantumObject`](@ref) -Note that `A'` is a synonym for `adjoint(A)` +Note that `A'` and `dag(A)` are synonyms of `adjoint(A)`. """ LinearAlgebra.adjoint( A::AbstractQuantumObject{DT,OpType}, @@ -310,6 +314,7 @@ end @doc raw""" normalize(A::QuantumObject, p::Real) + unit(A::QuantumObject, p::Real) Return normalized [`QuantumObject`](@ref) so that its `p`-norm equals to unity, i.e. `norm(A, p) == 1`. @@ -317,6 +322,8 @@ Support for the following types of [`QuantumObject`](@ref): - If `A` is [`Ket`](@ref) or [`Bra`](@ref), default `p = 2` - If `A` is [`Operator`](@ref), default `p = 1` +Note that `unit` is a synonym of `normalize`. + Also, see [`norm`](@ref) about its definition for different types of [`QuantumObject`](@ref). """ LinearAlgebra.normalize( diff --git a/src/qobj/boolean_functions.jl b/src/qobj/boolean_functions.jl index 869d1464..1988342c 100644 --- a/src/qobj/boolean_functions.jl +++ b/src/qobj/boolean_functions.jl @@ -61,8 +61,11 @@ issuper(A) = false # default case @doc raw""" ishermitian(A::AbstractQuantumObject) + isherm(A::AbstractQuantumObject) Test whether the [`AbstractQuantumObject`](@ref) is Hermitian. + +Note that `isherm` is a synonym of `ishermitian`. """ LinearAlgebra.ishermitian(A::AbstractQuantumObject) = ishermitian(A.data) diff --git a/src/qobj/functions.jl b/src/qobj/functions.jl index 84631688..acc82700 100644 --- a/src/qobj/functions.jl +++ b/src/qobj/functions.jl @@ -148,9 +148,14 @@ end @doc raw""" kron(A::AbstractQuantumObject, B::AbstractQuantumObject, ...) + tensor(A::AbstractQuantumObject, B::AbstractQuantumObject, ...) + ⊗(A::AbstractQuantumObject, B::AbstractQuantumObject, ...) + A ⊗ B Returns the [Kronecker product](https://en.wikipedia.org/wiki/Kronecker_product) ``\hat{A} \otimes \hat{B} \otimes \cdots``. +Note that `tensor` and `⊗` are synonyms of `kron`. + # Examples ```jldoctest diff --git a/src/qobj/operators.jl b/src/qobj/operators.jl index ccb989de..ca8163ff 100644 --- a/src/qobj/operators.jl +++ b/src/qobj/operators.jl @@ -416,12 +416,15 @@ sigmaz() = rmul!(jmat(0.5, Val(:z)), 2) @doc raw""" eye(N::Int; type=Operator, dims=nothing) + qeye(N::Int; type=Operator, dims=nothing) Identity operator ``\hat{\mathbb{1}}`` with size `N`. It is also possible to specify the list of Hilbert dimensions `dims` if different subsystems are present. -Note that `type` can only be either [`Operator`](@ref) or [`SuperOperator`](@ref) +Note that +- `type` can only be either [`Operator`](@ref) or [`SuperOperator`](@ref) +- `qeye` is a synonym of `eye` """ eye( N::Int; diff --git a/src/qobj/quantum_object.jl b/src/qobj/quantum_object.jl index 46a38d7d..017ad35e 100644 --- a/src/qobj/quantum_object.jl +++ b/src/qobj/quantum_object.jl @@ -50,10 +50,16 @@ struct QuantumObject{MT<:AbstractArray,ObjType<:QuantumObjectType,N} <: Abstract end end -function QuantumObject(A::AbstractArray, type::ObjType, dims::Integer) where {ObjType<:QuantumObjectType} - return QuantumObject(A, type, SVector{1,Int}(dims)) -end +QuantumObject(A::AbstractArray, type::ObjType, dims::Integer) where {ObjType<:QuantumObjectType} = QuantumObject(A, type, SVector{1,Int}(dims)) + +@doc raw""" + Qobj(A::AbstractArray; type = nothing, dims = nothing) + QuantumObject(A::AbstractArray; type = nothing, dims = nothing) +Generate [`QuantumObject`](@ref) with a given `A::AbstractArray` and specified `type::QuantumObjectType` and `dims`. + +Note that `Qobj` is a synonym of `QuantumObject`. +""" function QuantumObject( A::AbstractMatrix{T}; type::ObjType = nothing, diff --git a/src/qobj/quantum_object_base.jl b/src/qobj/quantum_object_base.jl index e4cb9644..4ac18560 100644 --- a/src/qobj/quantum_object_base.jl +++ b/src/qobj/quantum_object_base.jl @@ -121,10 +121,14 @@ const OperatorKet = OperatorKetQuantumObject() @doc raw""" size(A::AbstractQuantumObject) size(A::AbstractQuantumObject, idx::Int) + shape(A::AbstractQuantumObject) + shape(A::AbstractQuantumObject, idx::Int) Returns a tuple containing each dimensions of the array in the [`AbstractQuantumObject`](@ref). Optionally, you can specify an index (`idx`) to just get the corresponding dimension of the array. + +Note that `shape` is a synonym of `size`. """ Base.size(A::AbstractQuantumObject) = size(A.data) Base.size(A::AbstractQuantumObject, idx::Int) = size(A.data, idx) diff --git a/src/qobj/quantum_object_evo.jl b/src/qobj/quantum_object_evo.jl index ddef7764..b586f42d 100644 --- a/src/qobj/quantum_object_evo.jl +++ b/src/qobj/quantum_object_evo.jl @@ -30,7 +30,7 @@ Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=fal julia> coef1(p, t) = exp(-1im * t) coef1 (generic function with 1 method) -julia> op = QuantumObjectEvolution(a, coef1) +julia> op = QobjEvo(a, coef1) Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) ``` @@ -50,7 +50,7 @@ Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=fal julia> coef2(p, t) = sin(t) coef2 (generic function with 1 method) -julia> op1 = QuantumObjectEvolution(((a, coef1), (σm, coef2))) +julia> op1 = QobjEvo(((a, coef1), (σm, coef2))) Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false (ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) + ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20)) ``` @@ -75,7 +75,7 @@ coef1 (generic function with 1 method) julia> coef2(p, t) = sin(p.ω2 * t) coef2 (generic function with 1 method) -julia> op1 = QuantumObjectEvolution(((a, coef1), (σm, coef2))) +julia> op1 = QobjEvo(((a, coef1), (σm, coef2))) Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false (ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) + ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20)) @@ -143,9 +143,12 @@ function QuantumObjectEvolution(data::AbstractSciMLOperator, type::QuantumObject end @doc raw""" + QobjEvo(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing) QuantumObjectEvolution(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing) Generate a [`QuantumObjectEvolution`](@ref) object from a [`SciMLOperator`](https://github.com/SciML/SciMLOperators.jl), in the same way as [`QuantumObject`](@ref) for `AbstractArray` inputs. + +Note that `QobjEvo` is a synonym of `QuantumObjectEvolution` """ function QuantumObjectEvolution(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing) _size = _get_size(data) @@ -161,7 +164,92 @@ function QuantumObjectEvolution(data::AbstractSciMLOperator; type::QuantumObject return QuantumObjectEvolution(data, type, dims) end -# Make the QuantumObjectEvolution, with the option to pre-multiply by a scalar +@doc raw""" + QobjEvo(op_func_list::Union{Tuple,AbstractQuantumObject}, α::Union{Nothing,Number}=nothing; type::Union{Nothing, QuantumObjectType}=nothing) + QuantumObjectEvolution(op_func_list::Union{Tuple,AbstractQuantumObject}, α::Union{Nothing,Number}=nothing; type::Union{Nothing, QuantumObjectType}=nothing) + +Generate [`QuantumObjectEvolution`](@ref). + +# Arguments +- `op_func_list::Union{Tuple,AbstractQuantumObject}`: A tuple of tuples or operators. +- `α::Union{Nothing,Number}=nothing`: A scalar to pre-multiply the operators. + +!!! warning "Beware of type-stability!" + Please note that, unlike QuTiP, this function doesn't support `op_func_list` as `Vector` type. This is related to the type-stability issue. See the Section [The Importance of Type-Stability](@ref doc:Type-Stability) for more details. + +# Notes +- If `α` is provided, all the operators in `op_func_list` will be pre-multiplied by `α`. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators. +- `QobjEvo` is a synonym of `QuantumObjectEvolution` + +# Examples +This operator can be initialized in the same way as the QuTiP `QobjEvo` object. For example +```jldoctest qobjevo +julia> a = tensor(destroy(10), qeye(2)) +Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false +20×20 SparseMatrixCSC{ComplexF64, Int64} with 18 stored entries: +⎡⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⎤ +⎢⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⎥ +⎣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⎦ + +julia> σm = tensor(qeye(10), sigmam()) +Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false +20×20 SparseMatrixCSC{ComplexF64, Int64} with 10 stored entries: +⎡⠂⡀⠀⠀⠀⠀⠀⠀⠀⠀⎤ +⎢⠀⠀⠂⡀⠀⠀⠀⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠂⡀⠀⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠀⠂⡀⠀⠀⎥ +⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡀⎦ + +julia> coef1(p, t) = exp(-1im * t) +coef1 (generic function with 1 method) + +julia> coef2(p, t) = sin(t) +coef2 (generic function with 1 method) + +julia> op1 = QobjEvo(((a, coef1), (σm, coef2))) +Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false +(ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) + ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20)) +``` + +We can also concretize the operator at a specific time `t` +```jldoctest qobjevo +julia> op1(0.1) +Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false +20×20 SparseMatrixCSC{ComplexF64, Int64} with 28 stored entries: +⎡⠂⡑⢄⠀⠀⠀⠀⠀⠀⠀⎤ +⎢⠀⠀⠂⡑⢄⠀⠀⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠂⡑⢄⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠀⠂⡑⢄⠀⎥ +⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡑⎦ +``` + +It also supports parameter-dependent time evolution +```jldoctest qobjevo +julia> coef1(p, t) = exp(-1im * p.ω1 * t) +coef1 (generic function with 1 method) + +julia> coef2(p, t) = sin(p.ω2 * t) +coef2 (generic function with 1 method) + +julia> op1 = QobjEvo(((a, coef1), (σm, coef2))) +Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false +(ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) + ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20)) + +julia> p = (ω1 = 1.0, ω2 = 0.5) +(ω1 = 1.0, ω2 = 0.5) + +julia> op1(p, 0.1) +Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false +20×20 SparseMatrixCSC{ComplexF64, Int64} with 28 stored entries: +⎡⠂⡑⢄⠀⠀⠀⠀⠀⠀⠀⎤ +⎢⠀⠀⠂⡑⢄⠀⠀⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠂⡑⢄⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠀⠂⡑⢄⠀⎥ +⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡑⎦ +``` +""" function QuantumObjectEvolution( op_func_list::Tuple, α::Union{Nothing,Number} = nothing; @@ -187,6 +275,35 @@ QuantumObjectEvolution( type::Union{Nothing,QuantumObjectType} = nothing, ) = QuantumObjectEvolution((op_func,), α; type = type) +@doc raw""" + QuantumObjectEvolution(op::QuantumObject, f::Function, α::Union{Nothing,Number}=nothing; type::Union{Nothing,QuantumObjectType} = nothing) + QobjEvo(op::QuantumObject, f::Function, α::Union{Nothing,Number}=nothing; type::Union{Nothing,QuantumObjectType} = nothing) + +Generate [`QuantumObjectEvolution`](@ref). + +# Notes +- The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. +- `QobjEvo` is a synonym of `QuantumObjectEvolution`. + +# Examples +```jldoctest +julia> a = tensor(destroy(10), qeye(2)) +Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false +20×20 SparseMatrixCSC{ComplexF64, Int64} with 18 stored entries: +⎡⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⎤ +⎢⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⎥ +⎢⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⎥ +⎣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⎦ + +julia> coef(p, t) = exp(-1im * t) +coef (generic function with 1 method) + +julia> op = QobjEvo(a, coef) +Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false +ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) +``` +""" QuantumObjectEvolution( op::QuantumObject, f::Function, diff --git a/src/qobj/synonyms.jl b/src/qobj/synonyms.jl index 6518d00a..6fc6ca60 100644 --- a/src/qobj/synonyms.jl +++ b/src/qobj/synonyms.jl @@ -4,184 +4,31 @@ Synonyms of the functions for QuantumObject export Qobj, QobjEvo, shape, isherm export trans, dag, matrix_element, unit -export sqrtm, logm, expm, sinm, cosm export tensor, ⊗ export qeye +export sqrtm, logm, expm, sinm, cosm @doc raw""" - Qobj(A::AbstractArray; type::QuantumObjectType, dims::Vector{Int}) + Qobj(A; kwargs...) -Generate [`QuantumObject`](@ref) - -Note that this functions is same as `QuantumObject(A; type=type, dims=dims)`. +`Qobj` is a synonym for generating [`QuantumObject`](@ref). See the docstring of [`QuantumObject`](@ref) for more details. """ Qobj(A; kwargs...) = QuantumObject(A; kwargs...) @doc raw""" - QobjEvo(op::QuantumObject, f::Function; type::Union{Nothing,QuantumObjectType} = nothing) - -Generate [`QuantumObjectEvolution`](@ref). - -Note that this functions is same as `QuantumObjectEvolution(op, f; type = type)`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. - -# Examples -```jldoctest -julia> a = tensor(destroy(10), qeye(2)) -Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false -20×20 SparseMatrixCSC{ComplexF64, Int64} with 18 stored entries: -⎡⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⎤ -⎢⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⎥ -⎣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⎦ - -julia> coef(p, t) = exp(-1im * t) -coef (generic function with 1 method) - -julia> op = QobjEvo(a, coef) -Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false -ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) -``` -""" -QobjEvo(op::QuantumObject, f::Function; type::Union{Nothing,QuantumObjectType} = nothing) = - QuantumObjectEvolution(op, f; type = type) - -@doc raw""" - QobjEvo(op_func_list::Union{Tuple,AbstractQuantumObject}, α::Union{Nothing,Number}=nothing; type::Union{Nothing, QuantumObjectType}=nothing) - -Generate [`QuantumObjectEvolution`](@ref). - -Note that this functions is same as `QuantumObjectEvolution(op_func_list)`. If `α` is provided, all the operators in `op_func_list` will be pre-multiplied by `α`. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators. - -# Arguments -- `op_func_list::Union{Tuple,AbstractQuantumObject}`: A tuple of tuples or operators. -- `α::Union{Nothing,Number}=nothing`: A scalar to pre-multiply the operators. - -!!! warning "Beware of type-stability!" - Please note that, unlike QuTiP, this function doesn't support `op_func_list` as `Vector` type. This is related to the type-stability issue. See the Section [The Importance of Type-Stability](@ref doc:Type-Stability) for more details. - -# Examples -This operator can be initialized in the same way as the QuTiP `QobjEvo` object. For example -```jldoctest qobjevo -julia> a = tensor(destroy(10), qeye(2)) -Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false -20×20 SparseMatrixCSC{ComplexF64, Int64} with 18 stored entries: -⎡⠀⠑⢄⠀⠀⠀⠀⠀⠀⠀⎤ -⎢⠀⠀⠀⠑⢄⠀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠑⢄⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠀⠀⠑⢄⠀⎥ -⎣⠀⠀⠀⠀⠀⠀⠀⠀⠀⠑⎦ - -julia> σm = tensor(qeye(10), sigmam()) -Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false -20×20 SparseMatrixCSC{ComplexF64, Int64} with 10 stored entries: -⎡⠂⡀⠀⠀⠀⠀⠀⠀⠀⠀⎤ -⎢⠀⠀⠂⡀⠀⠀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠂⡀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠀⠂⡀⠀⠀⎥ -⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡀⎦ - -julia> coef1(p, t) = exp(-1im * t) -coef1 (generic function with 1 method) - -julia> coef2(p, t) = sin(t) -coef2 (generic function with 1 method) - -julia> op1 = QobjEvo(((a, coef1), (σm, coef2))) -Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false -(ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) + ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20)) -``` - -We can also concretize the operator at a specific time `t` -```jldoctest qobjevo -julia> op1(0.1) -Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false -20×20 SparseMatrixCSC{ComplexF64, Int64} with 28 stored entries: -⎡⠂⡑⢄⠀⠀⠀⠀⠀⠀⠀⎤ -⎢⠀⠀⠂⡑⢄⠀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠂⡑⢄⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠀⠂⡑⢄⠀⎥ -⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡑⎦ -``` - -It also supports parameter-dependent time evolution -```jldoctest qobjevo -julia> coef1(p, t) = exp(-1im * p.ω1 * t) -coef1 (generic function with 1 method) - -julia> coef2(p, t) = sin(p.ω2 * t) -coef2 (generic function with 1 method) - -julia> op1 = QobjEvo(((a, coef1), (σm, coef2))) -Quantum Object Evo.: type=Operator dims=[10, 2] size=(20, 20) ishermitian=true isconstant=false -(ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20) + ScalarOperator(0.0 + 0.0im) * MatrixOperator(20 × 20)) - -julia> p = (ω1 = 1.0, ω2 = 0.5) -(ω1 = 1.0, ω2 = 0.5) - -julia> op1(p, 0.1) -Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=false -20×20 SparseMatrixCSC{ComplexF64, Int64} with 28 stored entries: -⎡⠂⡑⢄⠀⠀⠀⠀⠀⠀⠀⎤ -⎢⠀⠀⠂⡑⢄⠀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠂⡑⢄⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠀⠂⡑⢄⠀⎥ -⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡑⎦ -``` -""" -QobjEvo( - op_func_list::Union{Tuple,AbstractQuantumObject}, - α::Union{Nothing,Number} = nothing; - type::Union{Nothing,QuantumObjectType} = nothing, -) = QuantumObjectEvolution(op_func_list, α; type = type) - -QobjEvo(data::AbstractSciMLOperator, type::QuantumObjectType, dims::Integer) = - QuantumObjectEvolution(data, type, SVector{1,Int}(dims)) - -""" - QobjEvo(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing) - -Synonym of [`QuantumObjectEvolution`](@ref) object from a [`SciMLOperator`](https://github.com/SciML/SciMLOperators.jl). See the documentation for [`QuantumObjectEvolution`](@ref) for more information. -""" -QobjEvo(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing) = - QuantumObjectEvolution(data; type = type, dims = dims) - -@doc raw""" - shape(A::AbstractQuantumObject) + QobjEvo(args...; kwargs...) -Returns a tuple containing each dimensions of the array in the [`AbstractQuantumObject`](@ref). - -Note that this function is same as `size(A)`. +`QobjEvo` is a synonym for generating [`QuantumObjectEvolution`](@ref). See the docstrings of [`QuantumObjectEvolution`](@ref) for more details. """ -shape(A::AbstractQuantumObject) = size(A.data) - -@doc raw""" - isherm(A::AbstractQuantumObject) - -Test whether the [`AbstractQuantumObject`](@ref) is Hermitian. - -Note that this functions is same as `ishermitian(A)`. -""" -isherm(A::AbstractQuantumObject) = ishermitian(A) - -@doc raw""" - trans(A::AbstractQuantumObject) +QobjEvo(args...; kwargs...) = QuantumObjectEvolution(args...; kwargs...) -Lazy matrix transpose of the [`AbstractQuantumObject`](@ref). +const shape = size -Note that this function is same as `transpose(A)`. -""" -trans(A::AbstractQuantumObject{DT,OpType}) where {DT,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} = - transpose(A) +const isherm = ishermitian -@doc raw""" - dag(A::AbstractQuantumObject) +const trans = transpose -Lazy adjoint (conjugate transposition) of the [`AbstractQuantumObject`](@ref) - -Note that this function is same as `adjoint(A)`. -""" -dag(A::AbstractQuantumObject) = adjoint(A) +const dag = adjoint @doc raw""" matrix_element(i::QuantumObject, A::QuantumObject j::QuantumObject) @@ -194,35 +41,14 @@ Supports the following inputs: - `A` is in the type of [`Operator`](@ref), with `i` and `j` are both [`Ket`](@ref). - `A` is in the type of [`SuperOperator`](@ref), with `i` and `j` are both [`OperatorKet`](@ref) """ -matrix_element( - i::QuantumObject{<:AbstractArray{T1},KetQuantumObject}, - A::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject}, - j::QuantumObject{<:AbstractArray{T3},KetQuantumObject}, -) where {T1<:Number,T2<:Number,T3<:Number} = dot(i, A, j) -matrix_element( - i::QuantumObject{<:AbstractArray{T1},OperatorKetQuantumObject}, - A::QuantumObject{<:AbstractArray{T2},SuperOperatorQuantumObject}, - j::QuantumObject{<:AbstractArray{T3},OperatorKetQuantumObject}, -) where {T1<:Number,T2<:Number,T3<:Number} = dot(i, A, j) - -@doc raw""" - unit(A::QuantumObject, p::Real) +matrix_element(i, A, j) = dot(i, A, j) -Return normalized [`QuantumObject`](@ref) so that its `p`-norm equals to unity, i.e. `norm(A, p) == 1`. +const unit = normalize -Support for the following types of [`QuantumObject`](@ref): -- If `A` is [`Ket`](@ref) or [`Bra`](@ref), default `p = 2` -- If `A` is [`Operator`](@ref), default `p = 1` +const tensor = kron +const ⊗ = kron -Note that this function is same as `normalize(A, p)` - -Also, see [`norm`](@ref) about its definition for different types of [`QuantumObject`](@ref). -""" -unit( - A::QuantumObject{<:AbstractArray{T},ObjType}, - p::Real = 2, -) where {T,ObjType<:Union{KetQuantumObject,BraQuantumObject}} = normalize(A, p) -unit(A::QuantumObject{<:AbstractArray{T},OperatorQuantumObject}, p::Real = 1) where {T} = normalize(A, p) +const qeye = eye @doc raw""" sqrtm(A::QuantumObject) @@ -280,76 +106,3 @@ Note that this function is same as `cos(A)` and only supports for [`Operator`](@ cosm( A::QuantumObject{<:AbstractMatrix{T},ObjType}, ) where {T,ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} = cos(A) - -@doc raw""" - tensor(A::QuantumObject, B::QuantumObject, ...) - -Returns the [Kronecker product](https://en.wikipedia.org/wiki/Kronecker_product) ``\hat{A} \otimes \hat{B} \otimes \cdots``. - -Note that this function is same as `kron(A, B, ...)`. - -# Examples - -```jldoctest -julia> x = sigmax() -Quantum Object: type=Operator dims=[2] size=(2, 2) ishermitian=true -2×2 SparseMatrixCSC{ComplexF64, Int64} with 2 stored entries: - ⋅ 1.0+0.0im - 1.0+0.0im ⋅ - -julia> x_list = fill(x, 3); - -julia> tensor(x_list...).dims -3-element SVector{3, Int64} with indices SOneTo(3): - 2 - 2 - 2 -``` -""" -tensor(A...) = kron(A...) - -@doc raw""" - ⊗(A::QuantumObject, B::QuantumObject) - -Returns the [Kronecker product](https://en.wikipedia.org/wiki/Kronecker_product) ``\hat{A} \otimes \hat{B}``. - -Note that this function is same as `kron(A, B)`. - -# Examples - -```jldoctest -julia> a = destroy(20) -Quantum Object: type=Operator dims=[20] size=(20, 20) ishermitian=false -20×20 SparseMatrixCSC{ComplexF64, Int64} with 19 stored entries: -⎡⠈⠢⡀⠀⠀⠀⠀⠀⠀⠀⎤ -⎢⠀⠀⠈⠢⡀⠀⠀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠈⠢⡀⠀⠀⠀⎥ -⎢⠀⠀⠀⠀⠀⠀⠈⠢⡀⠀⎥ -⎣⠀⠀⠀⠀⠀⠀⠀⠀⠈⠢⎦ - -julia> O = a ⊗ a; - -julia> size(a), size(O) -((20, 20), (400, 400)) - -julia> a.dims, O.dims -([20], [20, 20]) -``` -""" -⊗(A::QuantumObject, B::QuantumObject) = kron(A, B) - -@doc raw""" - qeye(N::Int; type=Operator, dims=nothing) - -Identity operator ``\hat{\mathbb{1}}`` with size `N`. - -It is also possible to specify the list of Hilbert dimensions `dims` if different subsystems are present. - -Note that this function is same as `eye(N, type=type, dims=dims)`, and `type` can only be either [`Operator`](@ref) or [`SuperOperator`](@ref). -""" -qeye( - N::Int; - type::ObjType = Operator, - dims = nothing, -) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} = - QuantumObject(Diagonal(ones(ComplexF64, N)); type = type, dims = dims) From 11341bf00fe991b45cbcec9128615c156cc63eef Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 18 Dec 2024 13:30:02 +0900 Subject: [PATCH 2/6] format files --- src/qobj/quantum_object.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qobj/quantum_object.jl b/src/qobj/quantum_object.jl index 017ad35e..e7ffe450 100644 --- a/src/qobj/quantum_object.jl +++ b/src/qobj/quantum_object.jl @@ -50,7 +50,8 @@ struct QuantumObject{MT<:AbstractArray,ObjType<:QuantumObjectType,N} <: Abstract end end -QuantumObject(A::AbstractArray, type::ObjType, dims::Integer) where {ObjType<:QuantumObjectType} = QuantumObject(A, type, SVector{1,Int}(dims)) +QuantumObject(A::AbstractArray, type::ObjType, dims::Integer) where {ObjType<:QuantumObjectType} = + QuantumObject(A, type, SVector{1,Int}(dims)) @doc raw""" Qobj(A::AbstractArray; type = nothing, dims = nothing) From 314a611154e3a24b4b9896b49f1d957073d41d57 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Wed, 18 Dec 2024 14:14:29 +0900 Subject: [PATCH 3/6] fix docstring for `Qobj` and `QobjEvo` --- docs/make.jl | 4 ++-- src/qobj/quantum_object_evo.jl | 4 ++++ src/qobj/synonyms.jl | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index 56b374c4..e6467a74 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -13,8 +13,8 @@ using CairoMakie DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recursive = true) # some options for `makedocs` -const DRAFT = false # set `true` to disable cell evaluation -const DOCTEST = true # set `false` to skip doc tests +const DRAFT = true # set `true` to disable cell evaluation +const DOCTEST = false # set `false` to skip doc tests # generate bibliography bib = CitationBibliography( diff --git a/src/qobj/quantum_object_evo.jl b/src/qobj/quantum_object_evo.jl index b586f42d..5e8ca7a0 100644 --- a/src/qobj/quantum_object_evo.jl +++ b/src/qobj/quantum_object_evo.jl @@ -1,3 +1,7 @@ +#= +This file defines the QuantumObjectEvolution (QobjEvo) structure. +=# + export QuantumObjectEvolution @doc raw""" diff --git a/src/qobj/synonyms.jl b/src/qobj/synonyms.jl index 6fc6ca60..954d9076 100644 --- a/src/qobj/synonyms.jl +++ b/src/qobj/synonyms.jl @@ -13,14 +13,14 @@ export sqrtm, logm, expm, sinm, cosm `Qobj` is a synonym for generating [`QuantumObject`](@ref). See the docstring of [`QuantumObject`](@ref) for more details. """ -Qobj(A; kwargs...) = QuantumObject(A; kwargs...) +const Qobj = QuantumObject # we need the docstring here, otherwise the docstring won't be found because QuantumObject is not a public symbol @doc raw""" QobjEvo(args...; kwargs...) `QobjEvo` is a synonym for generating [`QuantumObjectEvolution`](@ref). See the docstrings of [`QuantumObjectEvolution`](@ref) for more details. """ -QobjEvo(args...; kwargs...) = QuantumObjectEvolution(args...; kwargs...) +const QobjEvo = QuantumObjectEvolution # we need the docstring here, otherwise the docstring won't be found because QuantumObjectEvolution is not a public symbol const shape = size From a276ad94efbc94769c771a6be2bc1c311886720f Mon Sep 17 00:00:00 2001 From: Yi-Te Huang <44385685+ytdHuang@users.noreply.github.com> Date: Wed, 18 Dec 2024 16:05:50 +0900 Subject: [PATCH 4/6] rebase incorrect modification --- docs/make.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/make.jl b/docs/make.jl index e6467a74..56b374c4 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -13,8 +13,8 @@ using CairoMakie DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recursive = true) # some options for `makedocs` -const DRAFT = true # set `true` to disable cell evaluation -const DOCTEST = false # set `false` to skip doc tests +const DRAFT = false # set `true` to disable cell evaluation +const DOCTEST = true # set `false` to skip doc tests # generate bibliography bib = CitationBibliography( From 62affab77ed240e33e39ad990e2935ffe6a17a02 Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 20 Dec 2024 21:46:36 +0900 Subject: [PATCH 5/6] improve docstring for synonyms --- src/qobj/arithmetic_and_attributes.jl | 16 +++++++++++----- src/qobj/boolean_functions.jl | 3 ++- src/qobj/functions.jl | 3 ++- src/qobj/operators.jl | 7 ++++--- src/qobj/quantum_object.jl | 3 ++- src/qobj/quantum_object_base.jl | 3 ++- src/qobj/quantum_object_evo.jl | 7 ++++--- src/qobj/synonyms.jl | 6 ++++-- 8 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/qobj/arithmetic_and_attributes.jl b/src/qobj/arithmetic_and_attributes.jl index 92ad7494..52e6859e 100644 --- a/src/qobj/arithmetic_and_attributes.jl +++ b/src/qobj/arithmetic_and_attributes.jl @@ -112,13 +112,15 @@ LinearAlgebra.:(/)(A::AbstractQuantumObject{DT}, n::T) where {DT,T<:Number} = get_typename_wrapper(A)(A.data / n, A.type, A.dims) @doc raw""" + A ⋅ B dot(A::QuantumObject, B::QuantumObject) Compute the dot product between two [`QuantumObject`](@ref): ``\langle A | B \rangle`` Note that `A` and `B` should be [`Ket`](@ref) or [`OperatorKet`](@ref) -`A ⋅ B` (where `⋅` can be typed by tab-completing `\cdot` in the REPL) is a synonym for `dot(A, B)` +!!! note + `A ⋅ B` (where `⋅` can be typed by tab-completing `\cdot` in the REPL) is a synonym of `dot(A, B)`. """ function LinearAlgebra.dot( A::QuantumObject{DT1,OpType}, @@ -138,7 +140,8 @@ Supports the following inputs: - `A` is in the type of [`Operator`](@ref), with `i` and `j` are both [`Ket`](@ref). - `A` is in the type of [`SuperOperator`](@ref), with `i` and `j` are both [`OperatorKet`](@ref) -Note that `matrix_element(i, A, j)` is a synonym of `dot(i, A, j)`. +!!! note + `matrix_element(i, A, j)` is a synonym of `dot(i, A, j)`. """ function LinearAlgebra.dot( i::QuantumObject{DT1,KetQuantumObject}, @@ -202,7 +205,8 @@ LinearAlgebra.transpose( Lazy adjoint (conjugate transposition) of the [`AbstractQuantumObject`](@ref) -Note that `A'` and `dag(A)` are synonyms of `adjoint(A)`. +!!! note + `A'` and `dag(A)` are synonyms of `adjoint(A)`. """ LinearAlgebra.adjoint( A::AbstractQuantumObject{DT,OpType}, @@ -322,7 +326,8 @@ Support for the following types of [`QuantumObject`](@ref): - If `A` is [`Ket`](@ref) or [`Bra`](@ref), default `p = 2` - If `A` is [`Operator`](@ref), default `p = 1` -Note that `unit` is a synonym of `normalize`. +!!! note + `unit` is a synonym of `normalize`. Also, see [`norm`](@ref) about its definition for different types of [`QuantumObject`](@ref). """ @@ -382,7 +387,8 @@ LinearAlgebra.rmul!(B::QuantumObject{<:AbstractArray}, a::Number) = (rmul!(B.dat Matrix square root of [`QuantumObject`](@ref) -Note that `√(A)` is a synonym for `sqrt(A)` +!!! note + `√(A)` (where `√` can be typed by tab-completing `\sqrt` in the REPL) is a synonym of `sqrt(A)`. """ LinearAlgebra.sqrt(A::QuantumObject{<:AbstractArray{T}}) where {T} = QuantumObject(sqrt(sparse_to_dense(A.data)), A.type, A.dims) diff --git a/src/qobj/boolean_functions.jl b/src/qobj/boolean_functions.jl index 1988342c..c67f8fe4 100644 --- a/src/qobj/boolean_functions.jl +++ b/src/qobj/boolean_functions.jl @@ -65,7 +65,8 @@ issuper(A) = false # default case Test whether the [`AbstractQuantumObject`](@ref) is Hermitian. -Note that `isherm` is a synonym of `ishermitian`. +!!! note + `isherm` is a synonym of `ishermitian`. """ LinearAlgebra.ishermitian(A::AbstractQuantumObject) = ishermitian(A.data) diff --git a/src/qobj/functions.jl b/src/qobj/functions.jl index acc82700..2731de8a 100644 --- a/src/qobj/functions.jl +++ b/src/qobj/functions.jl @@ -154,7 +154,8 @@ end Returns the [Kronecker product](https://en.wikipedia.org/wiki/Kronecker_product) ``\hat{A} \otimes \hat{B} \otimes \cdots``. -Note that `tensor` and `⊗` are synonyms of `kron`. +!!! note + `tensor` and `⊗` (where `⊗` can be typed by tab-completing `\otimes` in the REPL) are synonyms of `kron`. # Examples diff --git a/src/qobj/operators.jl b/src/qobj/operators.jl index ca8163ff..b65865d4 100644 --- a/src/qobj/operators.jl +++ b/src/qobj/operators.jl @@ -422,9 +422,10 @@ Identity operator ``\hat{\mathbb{1}}`` with size `N`. It is also possible to specify the list of Hilbert dimensions `dims` if different subsystems are present. -Note that -- `type` can only be either [`Operator`](@ref) or [`SuperOperator`](@ref) -- `qeye` is a synonym of `eye` +Note that `type` can only be either [`Operator`](@ref) or [`SuperOperator`](@ref) + +!!! note + `qeye` is a synonym of `eye`. """ eye( N::Int; diff --git a/src/qobj/quantum_object.jl b/src/qobj/quantum_object.jl index e7ffe450..c89826e7 100644 --- a/src/qobj/quantum_object.jl +++ b/src/qobj/quantum_object.jl @@ -59,7 +59,8 @@ QuantumObject(A::AbstractArray, type::ObjType, dims::Integer) where {ObjType<:Qu Generate [`QuantumObject`](@ref) with a given `A::AbstractArray` and specified `type::QuantumObjectType` and `dims`. -Note that `Qobj` is a synonym of `QuantumObject`. +!!! note + `Qobj` is a synonym of `QuantumObject`. """ function QuantumObject( A::AbstractMatrix{T}; diff --git a/src/qobj/quantum_object_base.jl b/src/qobj/quantum_object_base.jl index 4ac18560..df259307 100644 --- a/src/qobj/quantum_object_base.jl +++ b/src/qobj/quantum_object_base.jl @@ -128,7 +128,8 @@ Returns a tuple containing each dimensions of the array in the [`AbstractQuantum Optionally, you can specify an index (`idx`) to just get the corresponding dimension of the array. -Note that `shape` is a synonym of `size`. +!!! note + `shape` is a synonym of `size`. """ Base.size(A::AbstractQuantumObject) = size(A.data) Base.size(A::AbstractQuantumObject, idx::Int) = size(A.data, idx) diff --git a/src/qobj/quantum_object_evo.jl b/src/qobj/quantum_object_evo.jl index 5e8ca7a0..e9417b8f 100644 --- a/src/qobj/quantum_object_evo.jl +++ b/src/qobj/quantum_object_evo.jl @@ -181,9 +181,10 @@ Generate [`QuantumObjectEvolution`](@ref). !!! warning "Beware of type-stability!" Please note that, unlike QuTiP, this function doesn't support `op_func_list` as `Vector` type. This is related to the type-stability issue. See the Section [The Importance of Type-Stability](@ref doc:Type-Stability) for more details. -# Notes -- If `α` is provided, all the operators in `op_func_list` will be pre-multiplied by `α`. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators. -- `QobjEvo` is a synonym of `QuantumObjectEvolution` +Note that if `α` is provided, all the operators in `op_func_list` will be pre-multiplied by `α`. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators. + +!!! note + `QobjEvo` is a synonym of `QuantumObjectEvolution`. # Examples This operator can be initialized in the same way as the QuTiP `QobjEvo` object. For example diff --git a/src/qobj/synonyms.jl b/src/qobj/synonyms.jl index 954d9076..7f00dbc1 100644 --- a/src/qobj/synonyms.jl +++ b/src/qobj/synonyms.jl @@ -11,14 +11,16 @@ export sqrtm, logm, expm, sinm, cosm @doc raw""" Qobj(A; kwargs...) -`Qobj` is a synonym for generating [`QuantumObject`](@ref). See the docstring of [`QuantumObject`](@ref) for more details. +!!! note + `Qobj` is a synonym for generating [`QuantumObject`](@ref). See the docstring of [`QuantumObject`](@ref) for more details. """ const Qobj = QuantumObject # we need the docstring here, otherwise the docstring won't be found because QuantumObject is not a public symbol @doc raw""" QobjEvo(args...; kwargs...) -`QobjEvo` is a synonym for generating [`QuantumObjectEvolution`](@ref). See the docstrings of [`QuantumObjectEvolution`](@ref) for more details. +!!! note + `QobjEvo` is a synonym for generating [`QuantumObjectEvolution`](@ref). See the docstrings of [`QuantumObjectEvolution`](@ref) for more details. """ const QobjEvo = QuantumObjectEvolution # we need the docstring here, otherwise the docstring won't be found because QuantumObjectEvolution is not a public symbol From d31a4828ce5abfb6f9183b2be0bcdb8a36532c9f Mon Sep 17 00:00:00 2001 From: Yi-Te Huang Date: Fri, 20 Dec 2024 21:48:06 +0900 Subject: [PATCH 6/6] run code quality CI pipeline on `julia-lts` version --- .github/workflows/Code-Quality.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Code-Quality.yml b/.github/workflows/Code-Quality.yml index 29d56c44..b231d2b2 100644 --- a/.github/workflows/Code-Quality.yml +++ b/.github/workflows/Code-Quality.yml @@ -39,7 +39,7 @@ jobs: fail-fast: false matrix: version: - - '1' + - 'lts' os: - 'ubuntu-latest' arch: