Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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)

- Introduce `QuantumToolbox.settings` and `auto_tidyup`. ([#460])

## [v0.31.0]
Release date: 2025-05-03

Expand Down Expand Up @@ -221,3 +223,4 @@ Release date: 2024-11-13
[#453]: https://github.com/qutip/QuantumToolbox.jl/issues/453
[#455]: https://github.com/qutip/QuantumToolbox.jl/issues/455
[#456]: https://github.com/qutip/QuantumToolbox.jl/issues/456
[#460]: https://github.com/qutip/QuantumToolbox.jl/issues/460
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const PAGES = [
"Hierarchical Equations of Motion" => "users_guide/HEOM.md",
"Solving for Steady-State Solutions" => "users_guide/steadystate.md",
"Two-time correlation functions" => "users_guide/two_time_corr_func.md",
"QuantumToolbox Settings" => "users_guide/settings.md",
"Extensions" => [
"users_guide/extensions/cuda.md",
"users_guide/extensions/cairomakie.md",
Expand Down
1 change: 1 addition & 0 deletions docs/src/resources/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ AbstractLinearMap
## [Utility functions](@id doc-API:Utility-functions)

```@docs
QuantumToolbox.settings
QuantumToolbox.versioninfo
QuantumToolbox.about
gaussian
Expand Down
36 changes: 36 additions & 0 deletions docs/src/users_guide/settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# [QuantumToolbox Settings](@id doc:QuantumToolbox-Settings)

In this section, we introduce the default global settings used throughout the package and show how to modify them.

All settings are stored in [`QuantumToolbox.settings`](@ref).

!!! warning "Differences from QuTiP"
Due to the differences in programming languages, solving algorithms, and many other reasons, these global settings (including their default values and usage) may be very different from those in `Python QuTiP`.

## List of settings

Here, we list out each setting along with the specific functions that will use it.

- `tidyup_tol::Real = 1e-14` : tolerance for [`tidyup`](@ref) and [`tidyup!`](@ref).
- `auto_tidyup::Bool = true` : Automatically tidyup during the following situations:
* Solving for eigenstates, including [`eigenstates`](@ref), [`eigsolve`](@ref), and [`eigsolve_al`](@ref).
- (to be announced)

## Change default settings

First, we can check the current [`QuantumToolbox.settings`](@ref):

```@example settings
using QuantumToolbox

QuantumToolbox.settings
```

Next, one can overwrite the default settings by

```@example settings
QuantumToolbox.settings.tidyup_tol[] = 1e-10
QuantumToolbox.settings.auto_tidyup[] = false

QuantumToolbox.settings
```
1 change: 1 addition & 0 deletions src/QuantumToolbox.jl
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export permute
export cache_operator, iscached, isconstant

# Utility
include("settings.jl")
include("utilities.jl")
include("versioninfo.jl")
include("progress_bar.jl")
Expand Down
17 changes: 9 additions & 8 deletions src/qobj/arithmetic_and_attributes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -629,27 +629,28 @@ purity(ρ::QuantumObject{ObjType}) where {ObjType<:Union{Ket,Bra}} = sum(abs2,
purity(ρ::QuantumObject{Operator}) = real(tr(ρ.data^2))

@doc raw"""
tidyup(A::QuantumObject, tol::Real=1e-14)
tidyup(A::QuantumObject, tol::Real=settings.tidyup_tol[])

Given a [`QuantumObject`](@ref) `A`, check the real and imaginary parts of each element separately. Remove the real or imaginary value if its absolute value is less than `tol`.
"""
tidyup(A::QuantumObject, tol::T = 1e-14) where {T<:Real} = QuantumObject(tidyup(A.data, tol), A.type, A.dimensions)
tidyup(A::AbstractArray, tol::T2 = 1e-14) where {T2<:Real} = tidyup!(copy(A), tol)
tidyup(A::QuantumObject, tol::T = settings.tidyup_tol[]) where {T<:Real} =
QuantumObject(tidyup(A.data, tol), A.type, A.dimensions)
tidyup(A::AbstractArray, tol::T2 = settings.tidyup_tol[]) where {T2<:Real} = tidyup!(copy(A), tol)

@doc raw"""
tidyup!(A::QuantumObject, tol::Real=1e-14)
tidyup!(A::QuantumObject, tol::Real=settings.tidyup_tol[])

Given a [`QuantumObject`](@ref) `A`, check the real and imaginary parts of each element separately. Remove the real or imaginary value if its absolute value is less than `tol`.

Note that this function is an in-place version of [`tidyup`](@ref).
"""
tidyup!(A::QuantumObject, tol::T = 1e-14) where {T<:Real} = (tidyup!(A.data, tol); A)
function tidyup!(A::AbstractSparseArray, tol::T2 = 1e-14) where {T2<:Real}
tidyup!(A::QuantumObject, tol::T = settings.tidyup_tol[]) where {T<:Real} = (tidyup!(A.data, tol); A)
function tidyup!(A::AbstractSparseArray, tol::T2 = settings.tidyup_tol[]) where {T2<:Real}
tidyup!(nonzeros(A), tol) # tidyup A.nzval in-place (also support for CUDA sparse arrays)
return dropzeros!(A)
end
tidyup!(A::AbstractArray{T}, tol::T2 = 1e-14) where {T<:Real,T2<:Real} = @. A = T(abs(A) > tol) * A
tidyup!(A::AbstractArray{T}, tol::T2 = 1e-14) where {T,T2<:Real} =
tidyup!(A::AbstractArray{T}, tol::T2 = settings.tidyup_tol[]) where {T<:Real,T2<:Real} = @. A = T(abs(A) > tol) * A
tidyup!(A::AbstractArray{T}, tol::T2 = settings.tidyup_tol[]) where {T,T2<:Real} =
@. A = T(abs(real(A)) > tol) * real(A) + 1im * T(abs(imag(A)) > tol) * imag(A)

@doc raw"""
Expand Down
9 changes: 8 additions & 1 deletion src/qobj/eigsolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@
end
mul!(cache1, Vₘ, M(Uₘ * VR))
vecs = cache1[:, 1:k]
settings.auto_tidyup[] && tidyup!(vecs)

return EigsolveResult(vals, vecs, type, dimensions, iter, numops, (iter < maxiter))
end
Expand Down Expand Up @@ -349,7 +350,10 @@
vals = @. (1 + sigma * res.values) / res.values
end

return EigsolveResult(vals, res.vectors, res.type, res.dimensions, res.iter, res.numops, res.converged)
vecs = res.vectors
settings.auto_tidyup[] && tidyup!(vecs)

return EigsolveResult(vals, vecs, res.type, res.dimensions, res.iter, res.numops, res.converged)
end

@doc raw"""
Expand Down Expand Up @@ -430,6 +434,8 @@
@. vecs[:, i] = vec * exp(-1im * angle(vec[1]))
end

settings.auto_tidyup[] && tidyup!(vecs)

return EigsolveResult(vals, vecs, res.type, res.dimensions, res.iter, res.numops, res.converged)
end

Expand All @@ -439,7 +445,7 @@
Calculates the eigenvalues and eigenvectors of the [`QuantumObject`](@ref) `A` using
the Julia [LinearAlgebra](https://docs.julialang.org/en/v1/stdlib/LinearAlgebra/) package.

```jldoctest

Check failure on line 448 in src/qobj/eigsolve.jl

View workflow job for this annotation

GitHub Actions / build

doctest failure in src/qobj/eigsolve.jl:448-474 ```jldoctest julia> a = destroy(5); julia> H = a + a'; julia> using LinearAlgebra; julia> E, ψ, U = eigen(H) EigsolveResult: type=Operator() dims=[5] values: 5-element Vector{ComplexF64}: -2.8569700138728 + 0.0im -1.3556261799742608 + 0.0im 1.3322676295501878e-15 + 0.0im 1.3556261799742677 + 0.0im 2.8569700138728056 + 0.0im vectors: 5×5 Matrix{ComplexF64}: 0.106101+0.0im -0.471249-0.0im … 0.471249-0.0im 0.106101-0.0im -0.303127-0.0im 0.638838+0.0im 0.638838+0.0im 0.303127-0.0im 0.537348+0.0im -0.279149-0.0im 0.279149-0.0im 0.537348-0.0im -0.638838-0.0im -0.303127-0.0im -0.303127-0.0im 0.638838+0.0im 0.447214+0.0im 0.447214+0.0im -0.447214-0.0im 0.447214-0.0im julia> expect(H, ψ[1]) ≈ E[1] true ``` Subexpression: E, ψ, U = eigen(H) Evaluated output: EigsolveResult: type=Operator() dims=[5] values: 5-element Vector{ComplexF64}: -2.8569700138728 + 0.0im -1.3556261799742608 + 0.0im 1.3322676295501878e-15 + 0.0im 1.3556261799742677 + 0.0im 2.8569700138728056 + 0.0im vectors: 5×5 Matrix{ComplexF64}: 0.106101+0.0im -0.471249-0.0im … 0.471249+0.0im 0.106101+0.0im -0.303127-0.0im 0.638838+0.0im 0.638838+0.0im 0.303127+0.0im 0.537348+0.0im -0.279149-0.0im 0.279149+0.0im 0.537348+0.0im -0.638838-0.0im -0.303127-0.0im -0.303127-0.0im 0.638838+0.0im 0.447214+0.0im 0.447214+0.0im -0.447214-0.0im 0.447214+0.0im Expected output: EigsolveResult: type=Operator() dims=[5] values: 5-element Vector{ComplexF64}: -2.8569700138728 + 0.0im -1.3556261799742608 + 0.0im 1.3322676295501878e-15 + 0.0im 1.3556261799742677 + 0.0im 2.8569700138728056 + 0.0im vectors: 5×5 Matrix{ComplexF64}: 0.106101+0.0im -0.471249-0.0im … 0.471249-0.0im 0.106101-0.0im -0.303127-0.0im 0.638838+0.0im 0.638838+0.0im 0.303127-0.0im 0.537348+0.0im -0.279149-0.0im 0.279149-0.0im 0.537348-0.0im -0.638838-0.0im -0.303127-0.0im -0.303127-0.0im 0.638838+0.0im 0.447214+0.0im 0.447214+0.0im -0.447214-0.0im 0.447214-0.0im diff = Warning: Diff output requires color. EigsolveResult: type=Operator() dims=[5] values: 5-element Vector{ComplexF64}: -2.8569700138728 + 0.0im -1.3556261799742608 + 0.0im 1.3322676295501878e-15 + 0.0im 1.3556261799742677 + 0.0im 2.8569700138728056 + 0.0im vectors: 5×5 Matrix{ComplexF64}: 0.106101+0.0im -0.471249-0.0im … 0.471249-0.0im 0.106101-0.0im 0.471249+0.0im 0.106101+0.0im -0.303127-0.0im 0.638838+0.0im 0.638838+0.0im 0.303127-0.0im 0.303127+0.0im 0.537348+0.0im -0.279149-0.0im 0.279149-0.0im 0.537348-0.0im 0.279149+0.0im 0.537348+0.0im -0.638838-0.0im -0.303127-0.0im -0.303127-0.0im 0.638838+0.0im 0.447214+0.0im 0.447214+0.0im -0.447214-0.0im 0.447214-0.0im0.447214+0.0im
julia> a = destroy(5);

julia> H = a + a';
Expand Down Expand Up @@ -473,6 +479,7 @@
# This fixes a type inference issue. But doesn't work for GPU arrays
E::mat2vec(to_dense(MT)) = F.values
U::to_dense(MT) = F.vectors
settings.auto_tidyup[] && tidyup!(U)

return EigsolveResult(E, U, A.type, A.dimensions, 0, 0, true)
end
Expand Down
36 changes: 36 additions & 0 deletions src/settings.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Base.@kwdef struct Settings
tidyup_tol::Ref{Real} = 1e-14
auto_tidyup::Ref{Bool} = true
end

function Base.show(io::IO, s::Settings)
println(io, "QuantumToolbox.jl Settings")
println(io, "--------------------------")
map(x -> println(io, "$x[] = ", getfield(s, x)[]), fieldnames(Settings))
return nothing
end

@doc raw"""
QuantumToolbox.settings

Contains all the default global settings of QuantumToolbox.jl.

# List of settings

- `tidyup_tol::Real = 1e-14` : tolerance for [`tidyup`](@ref) and [`tidyup!`](@ref).
- `auto_tidyup::Bool = true` : Automatically tidyup.

For detailed explanation of each settings, see our documentation [here](https://qutip.org/QuantumToolbox.jl/stable/users_guide/settings).

# Change default settings

One can overwrite the default global settings by

```julia
using QuantumToolbox

QuantumToolbox.settings.tidyup_tol[] = 1e-10
QuantumToolbox.settings.auto_tidyup[] = false
```
"""
const settings = Settings()
Loading