Skip to content

Commit

Permalink
Document all keywords to minimize
Browse files Browse the repository at this point in the history
- JuMP interface support
  • Loading branch information
iagoleal committed Jan 22, 2025
1 parent 4c0cefa commit fb69d5a
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 21 deletions.
35 changes: 21 additions & 14 deletions src/TenSolver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,21 @@ QUBODrivers.@setup Optimizer begin
# JuMP-specific
NumberOfReads["num_reads"]::Integer = 1_000
# Solver keywords
"cutoff" :: Float64 = 1e-8
"atol" :: Float64 = 1e-8
"rtol" :: Float64 = 1e-8
"vtol" :: Float64 = 0.0
"iterations" :: Int = 10
"time_limit" :: Float64 = +Inf
"maxdim" :: Union{Int, Vector{Int}} = [10, 20, 50, 100, 100, 200]
"noise" :: Union{Float64, Vector{Float64}} = [1e-5, 1e-6, 1e-7, 1e-8, 1e-10, 1e-12, 0.0]
"device" :: Function = cpu
"preprocess" :: Bool = false
# ITensor keywords
"outputlevel" :: Int = 1
"cutoff" :: Float64 = 1e-8
"atol" :: Float64 = 1e-8
"rtol" :: Float64 = 1e-8
"vtol" :: Float64 = 0.0
"iterations" :: Int = 10
"time_limit" :: Float64 = +Inf
"maxdim" :: Union{Int, Vector{Int}} = [10, 20, 50, 100, 100, 200]
"mindim" :: Union{Int, Vector{Int}} = 1
"noise" :: Union{Float64, Vector{Float64}} = [1e-5, 1e-6, 1e-7, 1e-8, 1e-10, 1e-12, 0.0]
"device" :: Function = cpu
"eigsolve_krylovdim" :: Int = 3
"eigsolve_maxiter" :: Int = 1
"eigsolve_tol" :: Float64 = 1e-14
"preprocess" :: Bool = false
"verbosity" :: Int = 1
end
end

Expand All @@ -49,7 +52,7 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
end

if MOI.get(sampler, MOI.Silent())
MOI.set(sampler, MOI.RawOptimizerAttribute("outputlevel"), 0)
MOI.set(sampler, MOI.RawOptimizerAttribute("verbosity"), 0)
end

num_reads = MOI.get(sampler, NumberOfReads())
Expand All @@ -66,9 +69,13 @@ function QUBODrivers.sample(sampler::Optimizer{T}) where {T}
iterations = get("iterations"),
time_limit = get("time_limit"),
maxdim = get("maxdim"),
mindim = get("mindim"),
noise = get("noise"),
device = get("device"),
outputlevel = get("outputlevel"),
verbosity = get("verbosity"),
eigsolve_krylovdim = get("eigsolve_krylovdim"),
eigsolve_tol = get("eigsolve_tol"),
eigsolve_maxiter = get("eigsolve_maxiter"),
)
energy, psi = results.value
obj = a * energy
Expand Down
54 changes: 47 additions & 7 deletions src/solver.jl
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Solve the Quadratic Unconstrained Binary Optimization (QUBO) problem
s.t. b_i in {0, 1}
Return the optimal value `E` and a probability distribution `ψ` over optimal solutions.
You can use [`sample`](@ref) to get an actual bitstring solving the QUBO.
You can use [`sample`](@ref) to get an actual bitstring from `ψ`.
This function uses DMRG with tensor networks to calculate the optimal solution,
by finding the ground state (least eigenspace) of the Hamiltonian
Expand All @@ -136,6 +136,31 @@ by finding the ground state (least eigenspace) of the Hamiltonian
where D_i acts locally on the i-th qubit as [0 0; 0 1], i.e, the projection on |1>.
Keyword arguments:
- `iterations :: Int` - Maximum iterations the solver should run. Defaults to `10`.
- `cutoff :: Float64` - Any absolute value below this threshold is considered zero. Defaults to `1e-8`.
You can use this keyword to control the solver's accuracy vs resources trade-off.
- `maxdim` - The maximum allowed bond dimension.
Integer or array of integer specifying the bond dimension per iteration.
You can use this keyword to control the solver's accuracy vs resources trade-off.
- `mindim` - The minimum allowed bond dimension, if possible.
Integer or array of integer specifying the bond dimension per iteration.
- `time_limit :: Float64` - If specified, determines the maximum running time in seconds.
It only determines whether a new iteration should start or not, thus the solver may run for longer if the threshold happens during an iteration.
- `device = cpu` - Accelerator device used during computation.
See the section below for how to run on GPUs.
- `vtol :: Float64` - If specified, determines the variance tolerance before the algorithm stops.
The variance test determines whether DMRG converged to an eigenstate (not necessarily the ground state),
but is expensive to calculate.
- `noise` - A float or array of floats (per iteration) specifying the noise term added to the system to help with convergence.
It is recommended to use a large noise (~ 1e-5) on the initial iterations and let it go to zero on later iterations.
- `eigsolve_krylovdim :: Int = 3` - Maximum Krylov space dimension used in the local eigensolver.
- `eigsolve_tol :: Float64 = 1e-14` - Eigensolver tolerance.
- `eigsolve_maxiter :: Int = 1` - Maximum iterations for eigensolver.
Running on GPU:
The optional keyword `device` controls whether the solver should run on CPU or GPU.
For using a GPU, you can import the respective package, e.g. CUDA.jl,
and pass its accelerator as argument.
Expand All @@ -148,22 +173,29 @@ import Metal
minimize(Q; device = Metal.mtl)
```
See also [`maximize`](@ref).
"""
function minimize( Q :: AbstractMatrix{T}
, l :: Union{AbstractVector{T}, Nothing} = nothing
, c :: T = zero(T)
; cutoff :: Float64 = 1e-8 # a cutoff of 1E-5 gives sensible accuracy; a cutoff of 1E-8 is high accuracy; and a cutoff of 1E-12 is near exact accuracy. (https://itensor.org/docs.cgi?page=tutorials/dmrg_params)
, iterations :: Int = 10
, device :: Function = cpu
, time_limit :: Float64 = +Inf
, atol :: Float64 = cutoff
, rtol :: Float64 = atol
, vtol :: Float64 = 0.0
, iterations :: Int = 10
, time_limit :: Float64 = +Inf
, verbosity = 1
# DMRG keywords
, maxdim = [10, 20, 50, 100, 100, 200]
, mindim = 1
, noise = [1e-5, 1e-6, 1e-7, 1e-8, 1e-10, 1e-12, 0.0] # 1E-5 is a lot of noise and 1E-12 is a minimal amount of noise that can still be considered non-zero.
, device :: Function = cpu
, eigsolve_krylovdim :: Int = 3
, eigsolve_maxiter :: Int = 1
, eigsolve_tol :: Float64 = 1e-14
# Work in progress
, preprocess :: Bool = false
, kwargs...
) where {T}
particles = size(Q)[1]

Expand All @@ -189,8 +221,16 @@ function minimize( Q :: AbstractMatrix{T}
; nsweeps = iterations
, observer = observer
, ishermitian = true
, maxdim, cutoff, kwargs...)

, outputlevel = verbosity
, cutoff
, maxdim
, mindim
, noise
, eigsolve_krylovdim
, eigsolve_tol
, eigsolve_maxiter
, eigsolve_verbosity = 0
)
# The calculated energy has approximation errors compared to the true solution.
# It makes more sense to sample a solution and calculate the true objective function applied to it.
psi = Distribution(tn)
Expand Down

0 comments on commit fb69d5a

Please sign in to comment.