API Reference
Fallback dispatch
When extending QUBOTools, one might want to implement a method for QUBOTools.backend.
For MathOptInterface/JuMP integrations, including ToQUBO workflows that expose an MOI.ModelLike object, the supported public materialization path is:
qt_model = QUBOTools.Model(moi_model)Use backend for wrapper types that already own or can return a QUBOTools.AbstractModel; use QUBOTools.Model(moi_model) when the source is an MOI model that needs to be converted into QUBOTools' sparse in-memory representation.
QUBOTools.backend — Function
backend(model)::AbstractModel
backend(model::AbstractModel)::AbstractModelAccesses the model's backend. Implementing this function allows one to profit from fallback implementations of other methods.
Variable System
QUBOTools.index — Function
index(model::AbstractModel{V}, v::V) where {V}Given a variable, returns the corresponding index.
QUBOTools.indices — Function
indices(model)Returns a sorted vector $[1, \dots, n]$ that matches the variable indices, where $n$ is the model's dimension.
QUBOTools.hasindex — Function
hasindex(model::AbstractModel, i::Integer)::BoolGiven an index, returns whether it is valid for rhe model.
QUBOTools.variable — Function
variable(model::AbstractModel, i::Integer)Given an index, returns the corresponding variable.
QUBOTools.variables — Function
variables(model)Returns a vector containing the model's variables in index order.
QUBOTools.hasvariable — Function
hasvariable(model::AbstractModel{V}, v::V)::Bool where {V}Given a variable, tells if it belongs to the model.
QUBOTools.VariableMap — Type
VariableMap{V}Establishes a bijection between variables and their indices. The interface for accessing this mapping relies on QUBOTools.index and QUBOTools.variable.
PseudoBooleanOptimization.varlt — Function
varlt(x, y)Return true when variable x should sort before variable y in QUBOTools' canonical variable ordering.
Objective & Domain Frames
QUBOTools.Domain — Type
DomainEnum representing binary variable domains, BoolDomain and SpinDomain.
QUBOTools.BoolDomain — Constant
BoolDomainRepresents the boolean domain $\mathbb{B} = \lbrace{0, 1}\rbrace$.
Properties
\[x \in \mathbb{B}, n \in \mathbb{N} \implies x^{n} = x\]
QUBOTools.SpinDomain — Constant
SpinDomainRepresents the spin domain $\mathbb{S} = \lbrace{-1, 1}\rbrace$.
Properties
\[s \in \mathbb{S}, n \in \mathbb{Z} \implies s^{2n} = 1, s^{2n + 1} = s\]
QUBOTools.domain — Function
domain(model::AbstractModel)Returns the variable domain of a given model.
QUBOTools.Sense — Type
SenseEnum representing the minimization and maximization objective senses, Min and Max.
QUBOTools.sense — Function
sense(model)Returns the objective sense of a model.
QUBOTools.Frame — Type
Frame(sense::Sense, domain::Domain)QUBOTools.frame — Function
frame(model)QUBOTools.cast — Function
Recasting the sense of a model preserves its meaning but the linear terms, quadratic terms and constant offset of a model will have its signs reversed, so does the overall objective function.
\[\begin{array}{ll} \min_{s} \alpha [f(s) + \beta] &\equiv \max_{s} -\alpha [f(s) + \beta] \\ &\equiv \max_{s} \alpha [-f(s) - \beta] \\ \end{array}\]
Errors
QUBOTools.CastingError — Type
CastingErrorError while casting data between domains or senses.
Models
QUBOTools.AbstractModel — Type
AbstractModel{V,T,U}Represents an abstract QUBO Model.
As shown in the example above, implementing a method for the QUBOTools.backend function gives access to most fallback implementations.
QUBOTools.Model — Type
Model{V,T,U,F<:AbstractForm{T}} <: AbstractModel{V,T,U}Reference AbstractModel implementation. It is intended to be the stardard in-memory representation for QUBO models.
Sparse Constructors
Model{V,T,U}(variables, L::SparseVector, Q::SparseMatrixCSC; kws...)
Model{V,T,U}(
variables,
linear_indices,
linear_values,
quadratic_rows,
quadratic_cols,
quadratic_values;
kws...,
)These constructors build the model's sparse normal form directly. The vector variables defines the public variable-index mapping: variables[i] maps to index i, and all variables must be unique. COO indices are 1-based positions in that vector. Unlike dictionary and set constructors, which sort variables with varlt, sparse constructors preserve the caller-supplied variable order.
Quadratic inputs are normalized to strict upper-triangular storage. Entries with i > j are stored as (j, i), diagonal entries are accumulated into the linear form, duplicate coordinates are summed by Julia's sparse constructors, and resulting explicit zeros are removed with dropzeros!. Pass upper-triangular quadratic data, or pre-halve mirrored off-diagonal entries; a full symmetric matrix contributes both (i, j) and (j, i) and therefore doubles each off-diagonal coefficient in the stored normal form.
scale and offset are stored as the model's normal-form scale and offset; the coefficient inputs are not pre-scaled. Objective evaluation uses scale * (linear + quadratic + offset).
MathOptInterface/JuMP Integration
Both V and T parameters exist to support MathOptInterface/JuMP integration. This is made possible by choosing V to match MOI.VariableIndex and T as in Optimizer{T}.
Model Forms
QUBOTools.AbstractForm — Type
AbstractForm{T}A form is a $7$-tuple $(n, \ell, Q, \alpha, \beta) \times (\textrm{sense}, \textrm{domain})$ representing a QUBO / Ising model.
- $n$, the dimension, is the number of variables.
- $\mathbf{\ell}$, the linear form, represents a vector storing the linear terms.
- $\mathbf{Q}$, the quadratic form, represents an upper triangular matrix containing the quadratic interactions.
- $\alpha$ is the scale factor, defaults to $1$.
- $\beta$ is the offset factor, defaults to $0$.
The inner data structures used to represent each of these elements may vary.
QUBOTools.AbstractLinearForm — Type
AbstractLinearForm{T}Linear form subtypes will create a wrapper around data structures for representing the linear terms $\mathbf{\ell}'\mathbf{x}$ of the QUBO model.
QUBOTools.AbstractQuadraticForm — Type
AbstractQuadraticForm{T}Quadratic form subtypes will create a wrapper around data structures for representing the quadratic terms $\mathbf{x}'\mathbf{Q}\,\mathbf{x}$ of the QUBO model.
QUBOTools.form — Function
form(src [, formtype::Type{<:AbstractForm{T}}]; sense, domain) where {T}
form(src [, formtype::Union{Symbol,Type}, T::Type = Float64]; sense, domain)Returns the QUBO form stored within src, casting it to the corresponding (sense, domain) frame and, if necessary, converting the coefficients to type T.
The underlying data structure is given by formtype. Current options include :dict, :dense and :sparse.
For more informaion, see QUBOTools.Form and QUBOTools.AbstractForm.
QUBOTools.linear_form — Function
linear_form(Φ::F) where {T,F<:AbstractForm{T}}Returns the linear part of the QUBO form.
QUBOTools.quadratic_form — Function
quadratic_form(Φ::F) where {T,F<:AbstractForm{T}}Returns the quadratic part of the QUBO form.
QUBOTools.qubo — Function
qubo(args; kws...)This function is a shorthand for form(args...; kws..., domain = :bool).
For more informaion, see QUBOTools.form.
QUBOTools.ising — Function
ising(args; kws...)This function is a shorthand for form(args...; kws..., domain = :spin).
For more informaion, see QUBOTools.form.
QUBOTools.fix_variables — Function
fix_variables(Φ::AbstractForm, fix::AbstractDict{<:Integer})Fixes variables in Φ to the values supplied by fix.
For boolean forms, fixed values must belong to $\mathbb{B} = \{0, 1\}$. For spin forms, fixed values must belong to $\mathbb{S} = \{-1, 1\}$.
Returns (Φ_reduced, offset_delta, index_map), where offset_delta is the unscaled amount added to offset(Φ) and index_map maps each surviving original variable index to its dense index in Φ_reduced.
QUBOTools.lift_state — Function
lift_state(state_reduced, fix, index_map, n)Reconstructs a full length-n state from a reduced state, fixed variable values, and the index_map returned by QUBOTools.fix_variables.
Underlying Data Structures
QUBOTools.Form — Type
Form{T,LF,LQ}QUBOTools.formtype — Function
formtype(spec::Type)
formtype(spec::Symbol)Returns a form type according to the given specification.
formtype(src)Returns the form type of a form or model.
QUBOTools.DictForm — Type
DictForm{T}This QUBO form is built using dictionaries for both the linear and quadratic terms.
QUBOTools.DictLinearForm — Type
DictLinearForm{T}QUBOTools.DictQuadraticForm — Type
DictQuadraticForm{T}QUBOTools.DenseForm — Type
DenseForm{T}This QUBO form is built using a vector for the linear terms and a matrix for storing the quadratic terms.
QUBOTools.DenseLinearForm — Type
DenseLinearForm{T}QUBOTools.DenseQuadraticForm — Type
DenseQuadraticForm{T}QUBOTools.SparseForm — Type
SparseForm{T}This QUBO form is built using a sparse vector for the linear terms and a sparse matrix for the quadratic ones.
QUBOTools.SparseLinearForm — Type
SparseLinearForm{T}QUBOTools.SparseQuadraticForm — Type
SparseQuadraticForm{T}Solutions
QUBOTools.State — Type
StateQUBOTools.AbstractSample — Type
AbstractSampleA sample is a triple $(\psi, \lambda, r)$ where $\psi \in \mathbb{U}^{n} \sim \mathbb{B}^{n}$ is the sampled vector, $\lambda \in \mathbb{R}$ is the associated energy value and $r \in \mathbb{N}$ is the number of reads, i. e., the multiplicity of the sample.
QUBOTools.Sample — Type
Sample{T,U}(state::Vector{U}, value::T, reads::Integer = 1) where{T,U}This is the reference implementation for QUBOTools.AbstractSample.
QUBOTools.sample — Function
sample(model, i::Integer)Returns the $i$-th sample on the model's current solution, if available.
QUBOTools.hassample — Function
hassample(solution::AbstractSolution, i::Integer)Tells if the $i$-th sample is available on the solution.
QUBOTools.AbstractSolution — Type
AbstractSolutionBy definitioon, a solution is an ordered set of samples.
QUBOTools.SampleSet — Type
SampleSet{T,U}(
data::Vector{Sample{T,U}},
metadata::Union{Dict{String,Any},Nothing} = nothing;
sense::Union{Sense,Symbol} = :min,
domain::Union{Domain,Symbol} = :bool,
) where {T,U}Reference implementation of QUBOTools.AbstractSolution.
It was inspired by D-Wave's SampleSet[dwave], with a few tweaks. For example, samples are automatically sorted upon instantiation and repeated samples are merged by adding up their reads field. Also, the solution frame is stored, allowing for queries and cast operations.
QUBOTools.solution — Function
solution(model) where {T,U<:Integer}Returns the model's current solution.
QUBOTools.sampleset_table — Function
sampleset_table(sampleset::AbstractSolution; bit_order = :native, include_probability = true)Return a row table for sampleset as a Vector{NamedTuple} with stable columns. The default columns are rank, state, reads, value, and probability; probability is omitted when include_probability = false.
The returned vector is compatible with the Tables.jl row-table convention without making Tables.jl a package dependency.
QUBOTools.state — Function
state(sample::AbstractSample{T,U}) where {T,U<:Integer}Returns a vector containing the assingment of each variable in a sample.
state(model, i::Integer) where {U<:Integer}Returns a vector corresponding to the bitstring of the $i$-th sample on the model's current solution, if available.
QUBOTools.value — Function
value(model)::T where {T}
value(model, i::Integer)::T where {T}
value(solution::AbstractSolution{T,U}, i::Integer)::T where {T,U}
value(model, state::AbstractVector{U}) where {U<:Integer}
value(solution::AbstractSolution{T,U}, state::AbstractVector{U})::T where {T,U<:Integer}
value(Q::Dict{Tuple{Int,Int},T}, ψ::Vector{U}, α::T = one(T), β::T = zero(T)) where {T}
value(h::Dict{Int,T}, J::Dict{Tuple{Int,Int},T}, ψ::Vector{U}, α::T = one(T), β::T = zero(T)) where {T}QUBOTools.energy — Function
energyAn alias for value.
QUBOTools.reads — Function
reads(model)
reads(solution::AbstractSolution)Returns the total amount of reads from each sample, combined.
reads(model, i::Integer)
reads(solution::AbstractSolution, i::Integer)Returns the sampling frequency of the $i$-th sample on the model's current solution, if available.
QUBOTools.ObjectiveBreakdown — Type
ObjectiveBreakdownStructured objective evaluation for a state.
Fields:
state: state vector in the evaluated model or form domain;raw_value: linear plus quadratic value before scale and offset;scaled_value:scale * raw_value;offset_adjusted_value:scale * (raw_value + offset), matchingvalue;scale,offset,sense, anddomain: frame data used for evaluation.
QUBOTools.ObjectiveMismatch — Type
ObjectiveMismatchDetailed record for one stored sample value that does not match model evaluation.
QUBOTools.objective_breakdown — Function
objective_breakdown(model_or_form, state; variables = nothing)
objective_breakdown(model, sample)
objective_breakdown(model, i::Integer)Return a structured objective-value breakdown for state.
The breakdown separates the raw quadratic value, the scaled value, and the offset-adjusted value used by value. When variables is provided for a model and vector state, the vector is interpreted in that variable order and projected to the model's variable order before evaluation. The sample and integer overloads evaluate state data without a surrounding solution frame, so the state is assumed to already be in the model domain; use annotate_objectives! or verify_objective_values when evaluating samples from a SampleSet whose frame may differ from the model. The integer overload interprets i as the index of a sample in solution(model).
QUBOTools.annotate_objectives! — Function
annotate_objectives!(sampleset, model; label = :objective, variables = nothing)Compute objective breakdown rows for each sample and store them under metadata(sampleset)["objectives"][label]. Stored rows record the evaluated state, after any solution-domain cast or variable projection needed to evaluate against model.
QUBOTools.objective_value_mismatches — Function
objective_value_mismatches(model, sampleset; atol = 0, rtol = sqrt(eps(Float64)))Return detailed records for samples whose stored values do not match model evaluation within tolerance.
QUBOTools.verify_objective_values — Function
verify_objective_values(model, sampleset; kws...)Return true when every stored sample value matches model evaluation within the given tolerance.
Solution Errors
QUBOTools.SolutionError — Type
SolutionErrorError occurred while gathering solutions.
Data Access
QUBOTools.linear_terms — Function
linear_terms(model::AbstractModel{V,T,U}) where {V,T,U}Returns an iterator for the linear nonzero terms of a model as Int => T pairs.
QUBOTools.quadratic_terms — Function
quadratic_terms(model::AbstractModel{V,T,U}) where {V,T,U}Returns an iterator for the quadratic nonzero terms of a model as Tuple{Int,Int} => T pairs.
QUBOTools.scale — Function
scale(model::AbstractModel)
scale(model::AbstractForm)Returns the scaling factor of a model.
QUBOTools.offset — Function
offset(model::AbstractModel)
offset(model::AbstractForm)Returns the constant offset factor of a model.
QUBOTools.data — Function
data(form)
data(sol::AbstractSolution)Retrieves the raw data behind solution and form wrappers.
QUBOTools.metadata — Function
metadata(model::AbstractModel)
metadata(sol::AbstractSolution)Retrieves metadata from a model or solution as a JSON-compatible Dict{String,Any}.
QUBOTools.id — Function
id(model)Returns a model identifier as an Int or nothing.
QUBOTools.description — Function
description(model)Returns the model description as a String or nothing.
QUBOTools.start — Function
start(model::AbstractModel{V,T,U}; domain = domain(model))::Dict{Int,U} where {V,T,U}Returns a dictionary containing a warm-start value for each variable index.
QUBOTools.attach! — Function
attach!(model::AbstractModel{V,T,U}, sol::AbstractSolution{T,U}) where {V,T,U}Attaches solution to model, replacing existing data and solution metadata. It automatically casts the solution to the model frame upon attachment.
File Formats & I/O
QUBOTools.AbstractFormat — Type
AbstractFormatSupertype for QUBOTools file-format descriptors used by model and solution I/O.
QUBOTools.Format — Type
Format{F}Concrete format descriptor for format F, storing validated format-specific settings.
QUBOTools.format — Function
format(::AbstractString)::AbstractFormat
format(::Symbol)::AbstractFormat
format(::Symbol, ::Symbol)::AbstractFormatGiven the file path, tries to infer the type associated to a QUBO model format.
QUBOTools.version — Function
version(fmt::AbstractFormat)Returns the version of a format protocol as a VersionNumber or nothing.
QUBOTools.infer_format — Function
infer_format(hints::Vector{Symbol})::Format
infer_format(; path::AbstractString)Infer a QUBOTools file format from ordered hint symbols or from the suffixes of path.
QUBOTools.read_model — Function
read_model(::AbstractString)
read_model(::AbstractString, ::AbstractFormat)
read_model(::IO, ::AbstractFormat)QUBOTools.write_model — Function
write_model(::AbstractString, ::AbstractModel)
write_model(::AbstractString, ::AbstractModel, ::AbstractFormat)
write_model(::IO, ::AbstractModel, ::AbstractFormat)QUBOTools.read_solution — Function
read_solution(::AbstractString)
read_solution(::AbstractString, ::AbstractFormat)
read_solution(::IO, ::AbstractFormat)QUBOTools.write_solution — Function
write_solution(::AbstractString, ::AbstractSolution)
write_solution(::AbstractString, ::AbstractSolution, ::AbstractFormat)
write_solution(::IO, ::AbstractSolution, ::AbstractFormat)QUBOTools.read_samples — Function
read_samples(path::AbstractString; metadata_path = nothing, bit_order = :native)Read a CSV distribution written by write_samples and return a SampleSet. Duplicate states with matching values are merged by the SampleSet constructor. The probability column, when present, is treated as derived data; reads remains authoritative. Imported values use Float64 and reads use Int.
When embedded or sidecar metadata records bit_order, that recorded order is used to recover the native state order; the bit_order keyword is used only for metadata-less input. Sidecar metadata written by write_samples must be supplied with metadata_path to recover the recorded frame and solution metadata. read_samples returns a SampleSet and does not reconstruct model context from the optional metadata model block.
QUBOTools.write_samples — Function
write_samples(path::AbstractString, sampleset::AbstractSolution; format = :csv,
metadata_path = nothing, bit_order = :native, include_probability = true)Write a SampleSet-like solution as a stable tabular distribution file.
Only format = :csv is currently supported. By default, JSON metadata is embedded in a leading CSV comment so read_samples can recover the solution frame and metadata. If metadata_path is provided, the JSON metadata is written to that sidecar path instead and must be passed to read_samples to recover the recorded frame and metadata. When model context is provided, model scale, offset, and variable names are recorded in the JSON metadata.
Format & I/O Errors
QUBOTools.FormatError — Type
FormatErrorError related to the format specification.
QUBOTools.FormatInferenceError — Type
FormatInferenceErrorThrown when QUBOTools cannot infer a supported format from a path or hint sequence.
QUBOTools.SyntaxError — Type
SyntaxErrorSyntax error while parsing file.
Model Metrics
QUBOTools.dimension — Function
dimension(model)::IntegerCounts the total number of variables in the model.
QUBOTools.linear_size — Function
linear_size(model)Counts the number of non-zero linear terms in the model.
QUBOTools.quadratic_size — Function
quadratic_size(model)Counts the number of non-zero quadratic terms in the model.
QUBOTools.density — Function
density(model)::Float64Computes the density $\rho$ of non-zero terms in a model, according to the expression[qplib]
\[\rho = \frac{n_{\ell} + 2 n_{q}}{n^{2}}\]
where $n_{\ell}$ is the number of non-zero linear terms, $n_{q}$ the number of quadratic ones and $n$ the number of variables.
If the model is empty, returns NaN.
QUBOTools.linear_density — Function
linear_density(model)::Float64Computes the linear density $\rho_{\ell}$, given by
\[\rho_{\ell} = \frac{n_{\ell}}{n}\]
where $n_{\ell}$ is the number of non-zero linear terms and $n$ the number of variables.
QUBOTools.quadratic_density — Function
quadratic_density(model)::Float64Computes the quadratic density $\rho_{q}$, given by
\[\rho_{q} = \frac{2 n_{q}}{n (n - 1)}\]
where $n_{q}$ is the number of non-zero quadratic terms and $n$ the number of variables.
QUBOTools.topology — Function
topology(model)Returns a Graphs.jl-compatible graph representing the quadratic interactions between variables in the model.
QUBOTools.adjacency — Function
adjacency(model)An alias for topology.
QUBOTools.geometry — Function
geometryReturns a $n \times N$ matrix describing the placement of the $n$ variable sites in $N$-dimensional space.
System Specification
QUBOTools.AbstractArchitecture — Type
AbstractArchitectureQUBOTools.GenericArchitecture — Type
GenericArchitecture()This type is used to reach fallback implementations for AbstractArchitecture.
QUBOTools.architecture — Function
architecture(::Any)It should be defined to provide automatic architecture recognition when writing QUBO Solver interfaces.
Example
struct Solver
...
end
struct SolverArchitecture <: AbstractArchitecture
...
end
architecture(::Solver) = SolverArchitecture()QUBOTools.AbstractDevice — Type
AbstractDevice{A<:AbstractArchitecture,V,T,U} <: AbstractModel{V,T,U}A device instance is meant to represent an specific hardware or software device. It is the concrete implementation of an architecture. For example, the topology of a device must be contained within the ideal topology of its architecture.
QUBOTools.GenericDevice — Type
GenericDeviceA thin wrapper around a Model that fulfills the AbstractDevice interface.
QUBOTools.Layout — Type
LayoutQUBOTools.layout — Function
layout(::Any)
layout(::Any, ::G) where {G<:AbstractGraph}Returns the layout of a model, device architecture, i.e., a description of the geometrical placement of each site as long as the network of their connections.
Problem Synthesis
QUBOTools.AbstractProblem — Type
AbstractProType{T}QUBOTools.generate — Function
generate(problem)
generate(rng, problem)Generates a QUBO problem and returns it as a Model.
QUBOTools.SherringtonKirkpatrick — Type
SherringtonKirkpatrick{T}(n::Integer, μ::T, σ::T)Generates a Sherrington-Kirkpatrick model in $n$ variables. Coefficients are normally distributed with mean $\mu$ and variance $\sigma$.
QUBOTools.Wishart — Type
Wishart{T}(n::Integer, m::Integer)Represents the Wishart model on $n$ variables whose $\mathbf{W}$ matrix has $m$ columns.
When true, the discretize keyword limits the entries of the $\mathbf{R}$ matrix to $\pm 1$. The precision, on the other hand, is the amount of digits to round each entry $R_{i,j}$ after sampling from a normal distribution $\mathcal{N}(0, 1)$.
Solution Metrics
Timing
QUBOTools.total_time — Function
total_time(sol::AbstractSolution)Retrieves the total time spent during the whole solution gathering process, as experienced by the user.
QUBOTools.effective_time — Function
effective_time(sol::AbstractSolution)Retrieves the time spent by the algorithm in the strict sense, that is, excluding time spent with data access, precompilation and other activities. That said, it is assumed that $t_{\text{effective}} \le t_{\text{total}}$.
Solution Quality
QUBOTools.success_rate — Function
success_rate(sol::AbstractSolution{T}, λ::T) where {T}Returns the success rate according to the given solution and the target objective value $\lambda$.
Time-to-Target (TTT)
QUBOTools.time_to_target — Function
time_to_target(sol::AbstractSolution{T}, λ::T, s::Float64=0.99) where {T}Computes the time-to-target (TTT) given the solution and the target threshold $\lambda$. The success factor $s$ defaults to $0.99$.
time_to_target(t::Float64, p::Float64, s::Float64=0.99)Computes the time-to-target (TTT) given the effective time $t$ spent running the algorithm and the success probability $p$. The success factor $s$ defaults to $0.99$.
\[\text{ttt}(t, p; s) = t \frac{\log(1 - s)}{\log(1 - p)}\]
QUBOTools.ttt — Function
tttAlias for time_to_target.
Hamming Distance
QUBOTools.hamming_distance — Function
hamming_distance(x::Vector{U}, y::Vector{U}) where {U}
hamming_distance(x::Sample{T,U}, y::Sample{T,U}) where {T,U}Visualization
QUBOTools.AbstractVisualization — Type
AbstractVisualizationRepresents a conceptual visualization built from a set of data structures. Its realization may combine multiple plot recipes as well.
Examples
Model Density Heatmap
julia> using Plots
julia> p = QUBOTools.ModelDensityPlot(model)
julia> plot(p)Solution Energy vs. Frequency
julia> using Plots
julia> s = QUBOTools.solution(model)
julia> p = QUBOTools.EnergyFrequencyPlot(s)
julia> plot(p)or simply,
julia> using Plots
julia> p = QUBOTools.EnergyFrequencyPlot(model)
julia> plot(p)