Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 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

- Make CUDA conversion more general using Adapt.jl. ([#436], [#437])
- Make the generation of `fock` states non-mutating to support Zygote.jl. ([#438])
- Remove Reexport.jl from the dependencies. ([#443])

## [v0.29.1]
Release date: 2025-03-07
Expand Down Expand Up @@ -193,3 +194,4 @@ Release date: 2024-11-13
[#436]: https://github.com/qutip/QuantumToolbox.jl/issues/436
[#437]: https://github.com/qutip/QuantumToolbox.jl/issues/437
[#438]: https://github.com/qutip/QuantumToolbox.jl/issues/438
[#443]: https://github.com/qutip/QuantumToolbox.jl/issues/443
2 changes: 0 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ OrdinaryDiffEqCore = "bbf590c4-e513-4bbe-9b18-05decba2e5d8"
OrdinaryDiffEqTsit5 = "b1df2697-797e-41e3-8120-5422d3b24e4a"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
SciMLOperators = "c0aeaf25-5076-4817-a8d5-81caf7dfa961"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Expand Down Expand Up @@ -56,7 +55,6 @@ OrdinaryDiffEqCore = "1"
OrdinaryDiffEqTsit5 = "1"
Pkg = "1"
Random = "1"
Reexport = "1"
SciMLBase = "2"
SciMLOperators = "0.3"
SparseArrays = "1"
Expand Down
2 changes: 2 additions & 0 deletions benchmarks/runbenchmarks.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using BenchmarkTools
using LinearAlgebra
using SparseArrays
using QuantumToolbox
using OrdinaryDiffEq
using LinearSolve
Expand Down
7 changes: 6 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,12 @@ using Changelog
# Load of packages required to compile the extension documentation
using CairoMakie

DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recursive = true)
doctest_setup = quote
using LinearAlgebra
using SparseArrays
using QuantumToolbox
end
DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, doctest_setup; recursive = true)

# some options for `makedocs`
const DRAFT = false # set `true` to disable cell evaluation
Expand Down
6 changes: 4 additions & 2 deletions docs/src/getting_started/type_stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ Which returns a tensor of size `2x2x2x2x2x2`. Let's check the `@code_warntype`:
@code_warntype reshape_operator_data([2, 2, 2])
```

We got a `Any` type, because the compiler doesn't know the size of the `dims` vector. We can fix this by using a `Tuple` (or `SVector`):
We got a `Any` type, because the compiler doesn't know the size of the `dims` vector. We can fix this by using a `Tuple` (or `SVector` from [StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl)):

```@example type-stability
typeof(reshape_operator_data((2, 2, 2)))
Expand All @@ -219,13 +219,15 @@ Finally, let's look at the benchmarks
@benchmark reshape_operator_data($((2, 2, 2)))
```

Which is an innocuous but huge difference in terms of performance. Hence, we highly recommend using `Tuple` or `SVector` when defining the dimensions of a user-defined [`QuantumObject`](@ref).
Which is an innocuous but huge difference in terms of performance. Hence, we highly recommend using `Tuple` or `SVector` from [StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl) when defining the dimensions of a user-defined [`QuantumObject`](@ref).

## The use of `Val` in some `QuantumToolbox.jl` functions

In some functions of `QuantumToolbox.jl`, you may find the use of the [`Val`](https://docs.julialang.org/en/v1/base/base/#Base.Val) type in the arguments. This is a trick to pass a value at compile time, and it is very useful to avoid type instabilities. Let's make a very simple example, where we want to create a Fock state ``|j\rangle`` of a given dimension `N`, and we give the possibility to create it as a sparse or dense vector. At first, we can write the function without using `Val`:

```@example type-stability
using SparseArrays

function my_fock(N::Int, j::Int = 0; sparse::Bool = false)
if sparse
array = sparsevec([j + 1], [1.0 + 0im], N)
Expand Down
6 changes: 6 additions & 0 deletions docs/src/resources/api.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
```@meta
CurrentModule = QuantumToolbox

DocTestSetup = quote
using LinearAlgebra
using SparseArrays
using QuantumToolbox
end
```

# [API](@id doc-API)
Expand Down
4 changes: 4 additions & 0 deletions docs/src/users_guide/QuantumObject/QuantumObject.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ Qobj(rand(4, 4))
M = rand(ComplexF64, 4, 4)
Qobj(M, dims = [2, 2]) # dims as Vector
Qobj(M, dims = (2, 2)) # dims as Tuple (recommended)

import QuantumToolbox: SVector # or using StaticArrays
Qobj(M, dims = SVector(2, 2)) # dims as StaticArrays.SVector (recommended)
```

Expand Down Expand Up @@ -195,6 +197,8 @@ Vector{Int64}(v_d)
```

```@example Qobj
using SparseArrays

v_s = SparseVector(v_d)
```

Expand Down
2 changes: 0 additions & 2 deletions docs/src/users_guide/QuantumObject/QuantumObject_functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ Here is a table that summarizes all the supported linear algebra functions and a

- [`eigenenergies`](@ref): return eigenenergies (eigenvalues)
- [`eigenstates`](@ref): return [`EigsolveResult`](@ref) (contains eigenvalues and eigenvectors)
- [`eigvals`](@ref): return eigenvalues
- [`eigen`](@ref): using dense eigen solver and return [`EigsolveResult`](@ref) (contains eigenvalues and eigenvectors)
- [`eigsolve`](@ref): using sparse eigen solver and return [`EigsolveResult`](@ref) (contains eigenvalues and eigenvectors)
- [`eigsolve_al`](@ref): using the Arnoldi-Lindblad eigen solver and return [`EigsolveResult`](@ref) (contains eigenvalues and eigenvectors)

Expand Down
2 changes: 1 addition & 1 deletion docs/src/users_guide/tensor.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ H = 0.5 * ωa * σz + ωc * a' * a + g * (a' * σm + a * σm')

The partial trace is an operation that reduces the dimension of a Hilbert space by eliminating some degrees of freedom by averaging (tracing). In this sense it is therefore the converse of the tensor product. It is useful when one is interested in only a part of a coupled quantum system. For open quantum systems, this typically involves tracing over the environment leaving only the system of interest. In `QuantumToolbox` the function [`ptrace`](@ref) is used to take partial traces. [`ptrace`](@ref) takes one [`QuantumObject`](@ref) as an input, and also one argument `sel`, which marks the component systems that should be kept, and all the other components are traced out.

Remember that the index of `Julia` starts from `1`, and all the elements in `sel` should be positive `Integer`. Therefore, the type of `sel` can be either `Integer`, `Tuple`, `SVector`, or `Vector`.
Remember that the index of `Julia` starts from `1`, and all the elements in `sel` should be positive `Integer`. Therefore, the type of `sel` can be either `Integer`, `Tuple`, `SVector` ([StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl)), or `Vector`.

!!! warning "Beware of type-stability!"
Although it supports also `Vector` type, it is recommended to use `Tuple` or `SVector` from [`StaticArrays.jl`](https://github.com/JuliaArrays/StaticArrays.jl) to improve performance. For a brief explanation on the impact of the type of `sel`, see the section [The Importance of Type-Stability](@ref doc:Type-Stability).
Expand Down
2 changes: 1 addition & 1 deletion ext/QuantumToolboxCUDAExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using QuantumToolbox: makeVal, getVal
import QuantumToolbox: _sparse_similar, _convert_eltype_wordsize
import CUDA: cu, CuArray, allowscalar
import CUDA.CUSPARSE: CuSparseVector, CuSparseMatrixCSC, CuSparseMatrixCSR, AbstractCuSparseArray
import SparseArrays: SparseVector, SparseMatrixCSC
import SparseArrays: SparseVector, SparseMatrixCSC, sparse
import CUDA.Adapt: adapt

allowscalar(false)
Expand Down
26 changes: 14 additions & 12 deletions src/QuantumToolbox.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
module QuantumToolbox

# Re-export:
# 1. StaticArraysCore.SVector for the type of dims
# 2. basic functions in LinearAlgebra and SparseArrays
# 3. some functions in SciMLOperators
import Reexport: @reexport
@reexport import StaticArraysCore: SVector
@reexport using LinearAlgebra
@reexport using SparseArrays
@reexport import SciMLOperators: cache_operator, iscached, isconstant
using LinearAlgebra
using SparseArrays
import StaticArraysCore: SVector
import SciMLOperators: cache_operator, iscached, isconstant

# other functions in LinearAlgebra
import LinearAlgebra: BlasReal, BlasInt, BlasFloat, BlasComplex, checksquare
Expand Down Expand Up @@ -69,9 +64,16 @@ import Random: AbstractRNG, default_rng, seed!
import SpecialFunctions: loggamma
import StaticArraysCore: MVector

# Setting the number of threads to 1 allows
# to achieve better performances for more massive parallelizations
BLAS.set_num_threads(1)
# Export functions from the other modules

# LinearAlgebra
export ishermitian, issymmetric, isposdef, dot, tr, svdvals, norm, normalize, normalize!, diag, Hermitian, Symmetric

# SparseArrays
export permute

# SciMLOperators
export cache_operator, iscached, isconstant

# Utility
include("utilities.jl")
Expand Down
76 changes: 29 additions & 47 deletions src/qobj/arithmetic_and_attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ end

for op in (:(+), :(-), :(*))
@eval begin
function LinearAlgebra.$op(A::AbstractQuantumObject, B::AbstractQuantumObject)
function Base.$op(A::AbstractQuantumObject, B::AbstractQuantumObject)
check_dimensions(A, B)
QType = promote_op_type(A, B)
return QType($(op)(A.data, B.data), A.type, A.dimensions)
end
LinearAlgebra.$op(A::AbstractQuantumObject) = get_typename_wrapper(A)($(op)(A.data), A.type, A.dimensions)
Base.$op(A::AbstractQuantumObject) = get_typename_wrapper(A)($(op)(A.data), A.type, A.dimensions)

LinearAlgebra.$op(n::T, A::AbstractQuantumObject) where {T<:Number} =
Base.$op(n::T, A::AbstractQuantumObject) where {T<:Number} =
get_typename_wrapper(A)($(op)(n * I, A.data), A.type, A.dimensions)
LinearAlgebra.$op(A::AbstractQuantumObject, n::T) where {T<:Number} =
Base.$op(A::AbstractQuantumObject, n::T) where {T<:Number} =
get_typename_wrapper(A)($(op)(A.data, n * I), A.type, A.dimensions)
end
end
Expand All @@ -63,7 +63,7 @@ for ADimType in (:Dimensions, :GeneralDimensions)
for BDimType in (:Dimensions, :GeneralDimensions)
if ADimType == BDimType == :Dimensions
@eval begin
function LinearAlgebra.:(*)(
function Base.:(*)(
A::AbstractQuantumObject{OperatorQuantumObject,<:$ADimType},
B::AbstractQuantumObject{OperatorQuantumObject,<:$BDimType},
)
Expand All @@ -74,7 +74,7 @@ for ADimType in (:Dimensions, :GeneralDimensions)
end
else
@eval begin
function LinearAlgebra.:(*)(
function Base.:(*)(
A::AbstractQuantumObject{OperatorQuantumObject,<:$ADimType},
B::AbstractQuantumObject{OperatorQuantumObject,<:$BDimType},
)
Expand All @@ -91,57 +91,41 @@ for ADimType in (:Dimensions, :GeneralDimensions)
end
end

function LinearAlgebra.:(*)(
A::AbstractQuantumObject{OperatorQuantumObject},
B::QuantumObject{KetQuantumObject,<:Dimensions},
)
function Base.:(*)(A::AbstractQuantumObject{OperatorQuantumObject}, B::QuantumObject{KetQuantumObject,<:Dimensions})
check_mul_dimensions(get_dimensions_from(A), get_dimensions_to(B))
return QuantumObject(A.data * B.data, Ket, Dimensions(get_dimensions_to(A)))
end
function LinearAlgebra.:(*)(
A::QuantumObject{BraQuantumObject,<:Dimensions},
B::AbstractQuantumObject{OperatorQuantumObject},
)
function Base.:(*)(A::QuantumObject{BraQuantumObject,<:Dimensions}, B::AbstractQuantumObject{OperatorQuantumObject})
check_mul_dimensions(get_dimensions_from(A), get_dimensions_to(B))
return QuantumObject(A.data * B.data, Bra, Dimensions(get_dimensions_from(B)))
end
function LinearAlgebra.:(*)(A::QuantumObject{KetQuantumObject}, B::QuantumObject{BraQuantumObject})
function Base.:(*)(A::QuantumObject{KetQuantumObject}, B::QuantumObject{BraQuantumObject})
check_dimensions(A, B)
return QuantumObject(A.data * B.data, Operator, A.dimensions) # to align with QuTiP, don't use kron(A, B) to do it.
end
function LinearAlgebra.:(*)(A::QuantumObject{BraQuantumObject}, B::QuantumObject{KetQuantumObject})
function Base.:(*)(A::QuantumObject{BraQuantumObject}, B::QuantumObject{KetQuantumObject})
check_dimensions(A, B)
return A.data * B.data
end
function LinearAlgebra.:(*)(
A::AbstractQuantumObject{SuperOperatorQuantumObject},
B::QuantumObject{OperatorQuantumObject},
)
function Base.:(*)(A::AbstractQuantumObject{SuperOperatorQuantumObject}, B::QuantumObject{OperatorQuantumObject})
check_dimensions(A, B)
return QuantumObject(vec2mat(A.data * mat2vec(B.data)), Operator, A.dimensions)
end
function LinearAlgebra.:(*)(A::QuantumObject{OperatorBraQuantumObject}, B::QuantumObject{OperatorKetQuantumObject})
function Base.:(*)(A::QuantumObject{OperatorBraQuantumObject}, B::QuantumObject{OperatorKetQuantumObject})
check_dimensions(A, B)
return A.data * B.data
end
function LinearAlgebra.:(*)(
A::AbstractQuantumObject{SuperOperatorQuantumObject},
B::QuantumObject{OperatorKetQuantumObject},
)
function Base.:(*)(A::AbstractQuantumObject{SuperOperatorQuantumObject}, B::QuantumObject{OperatorKetQuantumObject})
check_dimensions(A, B)
return QuantumObject(A.data * B.data, OperatorKet, A.dimensions)
end
function LinearAlgebra.:(*)(
A::QuantumObject{OperatorBraQuantumObject},
B::AbstractQuantumObject{SuperOperatorQuantumObject},
)
function Base.:(*)(A::QuantumObject{OperatorBraQuantumObject}, B::AbstractQuantumObject{SuperOperatorQuantumObject})
check_dimensions(A, B)
return QuantumObject(A.data * B.data, OperatorBra, A.dimensions)
end

LinearAlgebra.:(^)(A::QuantumObject, n::T) where {T<:Number} = QuantumObject(^(A.data, n), A.type, A.dimensions)
LinearAlgebra.:(/)(A::AbstractQuantumObject, n::T) where {T<:Number} =
get_typename_wrapper(A)(A.data / n, A.type, A.dimensions)
Base.:(^)(A::QuantumObject, n::T) where {T<:Number} = QuantumObject(^(A.data, n), A.type, A.dimensions)
Base.:(/)(A::AbstractQuantumObject, n::T) where {T<:Number} = get_typename_wrapper(A)(A.data / n, A.type, A.dimensions)

@doc raw"""
A ⋅ B
Expand Down Expand Up @@ -221,7 +205,7 @@ Base.conj(A::AbstractQuantumObject) = get_typename_wrapper(A)(conj(A.data), A.ty

Lazy matrix transpose of the [`AbstractQuantumObject`](@ref).
"""
LinearAlgebra.transpose(
Base.transpose(
A::AbstractQuantumObject{OpType},
) where {OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
get_typename_wrapper(A)(transpose(A.data), A.type, transpose(A.dimensions))
Expand All @@ -236,15 +220,13 @@ Lazy adjoint (conjugate transposition) of the [`AbstractQuantumObject`](@ref)
!!! note
`A'` and `dag(A)` are synonyms of `adjoint(A)`.
"""
LinearAlgebra.adjoint(
A::AbstractQuantumObject{OpType},
) where {OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
Base.adjoint(A::AbstractQuantumObject{OpType}) where {OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
get_typename_wrapper(A)(adjoint(A.data), A.type, adjoint(A.dimensions))
LinearAlgebra.adjoint(A::QuantumObject{KetQuantumObject}) = QuantumObject(adjoint(A.data), Bra, adjoint(A.dimensions))
LinearAlgebra.adjoint(A::QuantumObject{BraQuantumObject}) = QuantumObject(adjoint(A.data), Ket, adjoint(A.dimensions))
LinearAlgebra.adjoint(A::QuantumObject{OperatorKetQuantumObject}) =
Base.adjoint(A::QuantumObject{KetQuantumObject}) = QuantumObject(adjoint(A.data), Bra, adjoint(A.dimensions))
Base.adjoint(A::QuantumObject{BraQuantumObject}) = QuantumObject(adjoint(A.data), Ket, adjoint(A.dimensions))
Base.adjoint(A::QuantumObject{OperatorKetQuantumObject}) =
QuantumObject(adjoint(A.data), OperatorBra, adjoint(A.dimensions))
LinearAlgebra.adjoint(A::QuantumObject{OperatorBraQuantumObject}) =
Base.adjoint(A::QuantumObject{OperatorBraQuantumObject}) =
QuantumObject(adjoint(A.data), OperatorKet, adjoint(A.dimensions))

@doc raw"""
Expand Down Expand Up @@ -415,7 +397,7 @@ Matrix square root of [`QuantumObject`](@ref)
!!! note
`√(A)` (where `√` can be typed by tab-completing `\sqrt` in the REPL) is a synonym of `sqrt(A)`.
"""
LinearAlgebra.sqrt(A::QuantumObject) = QuantumObject(sqrt(to_dense(A.data)), A.type, A.dimensions)
Base.sqrt(A::QuantumObject) = QuantumObject(sqrt(to_dense(A.data)), A.type, A.dimensions)

@doc raw"""
log(A::QuantumObject)
Expand All @@ -424,7 +406,7 @@ Matrix logarithm of [`QuantumObject`](@ref)

Note that this function only supports for [`Operator`](@ref) and [`SuperOperator`](@ref)
"""
LinearAlgebra.log(A::QuantumObject{ObjType}) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
Base.log(A::QuantumObject{ObjType}) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
QuantumObject(log(to_dense(A.data)), A.type, A.dimensions)

@doc raw"""
Expand All @@ -434,11 +416,11 @@ Matrix exponential of [`QuantumObject`](@ref)

Note that this function only supports for [`Operator`](@ref) and [`SuperOperator`](@ref)
"""
LinearAlgebra.exp(
Base.exp(
A::QuantumObject{ObjType,DimsType,<:AbstractMatrix},
) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},DimsType} =
QuantumObject(to_sparse(exp(A.data)), A.type, A.dimensions)
LinearAlgebra.exp(
Base.exp(
A::QuantumObject{ObjType,DimsType,<:AbstractSparseMatrix},
) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},DimsType} =
QuantumObject(_spexp(A.data), A.type, A.dimensions)
Expand Down Expand Up @@ -483,7 +465,7 @@ Matrix sine of [`QuantumObject`](@ref), defined as

Note that this function only supports for [`Operator`](@ref) and [`SuperOperator`](@ref)
"""
LinearAlgebra.sin(A::QuantumObject{ObjType}) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
Base.sin(A::QuantumObject{ObjType}) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
(exp(1im * A) - exp(-1im * A)) / 2im

@doc raw"""
Expand All @@ -495,7 +477,7 @@ Matrix cosine of [`QuantumObject`](@ref), defined as

Note that this function only supports for [`Operator`](@ref) and [`SuperOperator`](@ref)
"""
LinearAlgebra.cos(A::QuantumObject{ObjType}) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
Base.cos(A::QuantumObject{ObjType}) where {ObjType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
(exp(1im * A) + exp(-1im * A)) / 2

@doc raw"""
Expand Down Expand Up @@ -768,7 +750,7 @@ true
```

!!! warning "Beware of type-stability!"
It is highly recommended to use `permute(A, order)` with `order` as `Tuple` or `SVector` to keep type stability. See the [related Section](@ref doc:Type-Stability) about type stability for more details.
It is highly recommended to use `permute(A, order)` with `order` as `Tuple` or `SVector` from [StaticArrays.jl](https://github.com/JuliaArrays/StaticArrays.jl) to keep type stability. See the [related Section](@ref doc:Type-Stability) about type stability for more details.
"""
function SparseArrays.permute(
A::QuantumObject{ObjType},
Expand Down
6 changes: 3 additions & 3 deletions src/qobj/dimensions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@
Base.prod(dims::Dimensions) = prod(dims.to)
Base.prod(spaces::NTuple{N,AbstractSpace}) where {N} = prod(_get_space_size, spaces)

LinearAlgebra.transpose(dimensions::Dimensions) = dimensions
LinearAlgebra.transpose(dimensions::GeneralDimensions) = GeneralDimensions(dimensions.from, dimensions.to) # switch `to` and `from`
LinearAlgebra.adjoint(dimensions::AbstractDimensions) = transpose(dimensions)
Base.transpose(dimensions::Dimensions) = dimensions
Base.transpose(dimensions::GeneralDimensions) = GeneralDimensions(dimensions.from, dimensions.to) # switch `to` and `from`

Check warning on line 95 in src/qobj/dimensions.jl

View check run for this annotation

Codecov / codecov/patch

src/qobj/dimensions.jl#L95

Added line #L95 was not covered by tests
Base.adjoint(dimensions::AbstractDimensions) = transpose(dimensions)

# this is used to show `dims` for Qobj and QobjEvo
_get_dims_string(dimensions::Dimensions) = string(dimensions_to_dims(dimensions))
Expand Down
2 changes: 2 additions & 0 deletions src/qobj/eigsolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,8 @@ julia> a = destroy(5);

julia> H = a + a';

julia> using LinearAlgebra;

julia> E, ψ, U = eigen(H)
EigsolveResult: type=Operator dims=[5]
values:
Expand Down
Loading
Loading