Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor for v0.1.5 #59

Merged
merged 38 commits into from
Feb 15, 2023
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
768dd21
Add variable encoding
pedroripper Jan 3, 2023
5f372dc
Add compiler attributes
pedromxavier Jan 5, 2023
98c841c
Add type assertion
pedromxavier Jan 5, 2023
95a944f
Add `sizehint!`
pedromxavier Jan 5, 2023
919f8d4
Merge remote-tracking branch 'origin/pr/performance' into px/refactor
pedromxavier Jan 5, 2023
9fd4f6f
Minor Fix
pedromxavier Jan 5, 2023
246aec9
Fix `parse` call
pedromxavier Jan 5, 2023
a529582
Add missing `PBO` identifier
pedromxavier Jan 5, 2023
6cbc1bd
Remove `MutableArithmetics`
pedromxavier Jan 5, 2023
08ab187
Add fast-track `qubo_copy!`
pedromxavier Jan 13, 2023
1fc60c9
Fix interface
pedromxavier Jan 13, 2023
a90197b
Fix `qubo` and `ising`
pedromxavier Jan 14, 2023
0a0576f
Update Interface
pedromxavier Jan 16, 2023
61424a9
Require `QUBOTools >= 0.6.1`
pedromxavier Jan 17, 2023
fa38c49
Fix attribute access
pedromxavier Jan 30, 2023
ca91e3c
Add docs
pedromxavier Jan 30, 2023
72f93ec
Fix attributes
pedromxavier Jan 30, 2023
56e66de
Add `Bounded{Unary}` and `Bounded{Binary}` encoding methods
pedromxavier Feb 2, 2023
4407c1f
Add `Bounded{Arithmetic}` encoding method
pedromxavier Feb 2, 2023
0cf6652
Add `MOI.get` for `MOI.ListOfNonstandardBridges`
pedromxavier Feb 3, 2023
2bae011
Drop fancy comments + rename variables [no ci]
pedromxavier Feb 3, 2023
41cdf6b
Remove unnecessary comments
pedromxavier Feb 3, 2023
ebf9b2f
Add docstring reference for `Bounded` encoding
pedromxavier Feb 3, 2023
adc3d96
Update `Anneal >= 0.6.1`
pedromxavier Feb 3, 2023
286a851
Fix attribute access rules
pedromxavier Feb 3, 2023
02c1476
Use `DWaveNeal` instead of `RandomSampler`
pedromxavier Feb 3, 2023
e2f0d47
Adjust comment + Trigger CI
pedromxavier Feb 3, 2023
4cd4eb0
Add tests for continuous encoding methods
pedromxavier Feb 9, 2023
f624d46
Fix model cleanup before compilation
pedromxavier Feb 9, 2023
9795ac5
Fix continuous encoding steps
pedromxavier Feb 9, 2023
600273e
Change comments in `constraints.jl` [no ci]
pedroripper Feb 13, 2023
73dc29c
Small changes [no ci]
pedroripper Feb 13, 2023
a474039
Fix [no ci]
pedroripper Feb 13, 2023
e4b962d
Add `VARIABLE_ENCODING_BITS` compiler setting
pedromxavier Feb 13, 2023
1977f0b
Place `ToQUBO` flags under `Attributes` submodule
pedromxavier Feb 14, 2023
6e325f5
Remove all emoji in the code😢
pedromxavier Feb 15, 2023
2891027
Enhance PBO docs
pedromxavier Feb 15, 2023
51ffe74
Adjust comment
pedromxavier Feb 15, 2023
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
28 changes: 16 additions & 12 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
name = "ToQUBO"
uuid = "9a412ddf-83fa-43b6-9748-7843c851aa65"
authors = ["pedromxavier <pedroxavier@psr-inc.com>", "joaquimg <joaquim@psr-inc.com>", "AndradeTiago <tiago.andrade@psr-inc.com>", "David Bernal <dbernalneira@usra.edu>"]
name = "ToQUBO"
uuid = "9a412ddf-83fa-43b6-9748-7843c851aa65"
authors = [
"pedromxavier <pedroxavier@psr-inc.com>",
"pedroripper <pedroripper@psr-inc.com>",
"joaquimg <joaquim@psr-inc.com>",
"AndradeTiago <tiago.andrade@psr-inc.com>",
"bernalde <dbernalneira@usra.edu>",
]
version = "0.1.4"

[deps]
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
QUBOTools = "60eb5b62-0a39-4ddc-84c5-97d2adff9319"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
QUBOTools = "60eb5b62-0a39-4ddc-84c5-97d2adff9319"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

[compat]
MathOptInterface = "1"
MutableArithmetics = "1"
QUBOTools = "0.4"
julia = "1.6"
MathOptInterface = "1"
QUBOTools = "0.6.1"
julia = "1.6"
6 changes: 4 additions & 2 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
[deps]
Anneal = "e4d9eb7f-b088-426e-aeb5-1c0dae3d8abb"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DWaveNeal = "870cdf72-5502-4b10-839c-127ceab78f22"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
MQLib = "16f11440-1623-44c9-850c-358a6c72f3c9"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
ToQUBO = "9a412ddf-83fa-43b6-9748-7843c851aa65"

[compat]
Anneal = "0.1"
Anneal = "0.6"
CSV = "0.10"
DataFrames = "1.3"
Documenter = "0.27"
JuMP = "0.23"
JuMP = "1"
MathOptInterface = "1"
ToQUBO = "0.1"
19 changes: 13 additions & 6 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,21 @@ makedocs(;
authors="Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal",
pages=[
"Home" => "index.md",
"manual.md",
"examples.md",
"Manual" => "manual.md",
"Examples" => [
"Knapsack" =>"examples/knapsack.md",
"Prime Factorization" => "examples/prime_factorization.md",
],
"Booklet" => "booklet.md"
],
workdir="."
)

deploydocs(
repo=raw"github.com/psrenergy/ToQUBO.jl.git",
push_preview = true
)
if "--skip-deploy" ∈ ARGS
@warn "Skipping deployment"
else
deploydocs(
repo=raw"github.com/psrenergy/ToQUBO.jl.git",
push_preview = true
)
end
41 changes: 27 additions & 14 deletions docs/src/booklet.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ ToQUBO.toqubo!
```@docs
ToQUBO.toqubo_sense!
ToQUBO.toqubo_variables!
ToQUBO.toqubo_constraint!
ToQUBO.toqubo_constraint
ToQUBO.toqubo_constraints!
ToQUBO.toqubo_objective!
ToQUBO.toqubo_penalties!
ToQUBO.toqubo_parse!
ToQUBO.toqubo_build!
```

## Pseudo-Boolean Optimization
Expand All @@ -32,16 +36,23 @@ ToQUBO.PBO.derivative
ToQUBO.PBO.gradient
ToQUBO.PBO.gap
ToQUBO.PBO.sharpness
ToQUBO.PBO.discretize
ToQUBO.PBO.relaxed_gcd
```

### A Primer on Submodularity
A set function ``f : 2^{S} \to \mathbb{R}`` is said to be submodular if

```math
f(X \cup Y) + f(X \cap Y) \le f(X) + f(Y) \forall X, Y \subset S
```

holds.

pedromxavier marked this conversation as resolved.
Show resolved Hide resolved
### Quadratization
In order to successfully achieve a QUBO formulation, sometimes it is needed to quadratize the resulting PBF, i.e., reduce its degree until reaching the quadratic case. There are many quadratization methods available, and `ToQUBO` implements a few of them.

```@docs
ToQUBO.PBO.quadratize
ToQUBO.PBO.@quadratization
ToQUBO.PBO.quadratize!
```

## Virtual Mapping
Expand All @@ -53,20 +64,22 @@ This is done in a transparent fashion for both agents since the user will mostly
Every virtual model stores a collection of virtual variables, intended to provide a link between those in the source and those to be created in the target model. Each virtual variable stores enconding information for later expansion and evaluation.

```@docs
ToQUBO.VirtualMapping.VirtualVariable
ToQUBO.VirtualMapping.mapvar!
ToQUBO.VirtualMapping.expandℝ!
ToQUBO.VirtualMapping.slackℝ!
ToQUBO.VirtualMapping.expandℤ!
ToQUBO.VirtualMapping.slackℤ!
ToQUBO.VirtualMapping.mirror𝔹!
ToQUBO.VirtualMapping.slack𝔹!
ToQUBO.VirtualVariable
ToQUBO.encode!
```

### Variable Encoding
```@docs
ToQUBO.Binary
ToQUBO.Unary
ToQUBO.Arithmetic
ToQUBO.OneHot
ToQUBO.DomainWall
```

### Virtual Models
```@docs
ToQUBO.VirtualMapping.AbstractVirtualModel
ToQUBO.VirtualQUBOModel
ToQUBO.VirtualModel
```

### Annealing & Sampling
Expand Down
44 changes: 12 additions & 32 deletions docs/src/examples.md → docs/src/examples/knapsack.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# Examples

## Knapsack
We start with some instances of the discrete [Knapsack Problem](https://en.wikipedia.org/wiki/Knapsack_problem) whose standard formulation is
```math
Expand All @@ -18,13 +16,13 @@ import MathOptInterface as MOI
const MOIU = MOI.Utilities

using ToQUBO
using Anneal # <- Your favourite Annealer / Sampler / Solver here
using DWaveNeal # <- Your favourite Annealer / Sampler / Solver here

# Example from https://jump.dev/MathOptInterface.jl/stable/tutorials/example/

# Virtual QUBO Model
model = MOI.instantiate(
() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer),
() -> ToQUBO.Optimizer(DWaveNeal.Optimizer),
with_bridge_type = Float64,
)

Expand All @@ -33,10 +31,12 @@ c = [1.0, 2.0, 3.0]
w = [0.3, 0.5, 1.0]
C = 3.2;

# -*- Variables -*- #
x = MOI.add_variables(model, n);

# -*- Objective -*- #
for xᵢ in x
MOI.add_constraint(model, xᵢ, MOI.ZeroOne())
end

MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)

MOI.set(
Expand All @@ -45,22 +45,16 @@ MOI.set(
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0),
);

# -*- Constraints -*- #
MOI.add_constraint(
model,
MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(w, x), 0.0),
MOI.LessThan(C),
);

for xᵢ in x
MOI.add_constraint(model, xᵢ, MOI.ZeroOne())
end

# Run!
MOI.optimize!(model)

# Collect Solution
MOI.get(model, MOI.VariablePrimal(), x)
MOI.get.(model, MOI.VariablePrimal(), x)
```

### JuMP + D-Wave Examples
Expand All @@ -73,7 +67,7 @@ using CSV
using DataFrames
using Random

# -> Generate Data <-
# Generate Data
rng = MersenneTwister(1)

df = DataFrame(
Expand All @@ -94,35 +88,21 @@ df = CSV.read("knapsack.csv", DataFrame)
```@example dwave-knapsack
using JuMP
using ToQUBO
using Anneal # <- Your favourite Annealer / Sampler / Solver here
using DWaveNeal # <- Your favourite Annealer/Sampler/Solver here

# -> Model <-
model = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))
model = Model(() -> ToQUBO.Optimizer(DWaveNeal.Optimizer))

n = size(df, 1)
c = collect(Float64, df[!, :cost])
w = collect(Float64, df[!, :weight])
C = round(0.8 * sum(w))

# -> Variables <-
@variable(model, x[i=1:n], Bin)

# -> Objective <-
@variable(model, x[1:n], Bin)
@objective(model, Max, c' * x)

# -> Constraint <-
@constraint(model, w' * x <= C)

# ->-> Run! ->->
optimize!(model)

# Add Results as a new column
insertcols!(
df,
3,
:select => map(
(ξ) -> (ξ > 0.0) ? "Yes" : "No",
value.(x),
),
)
insertcols!(df, 3, :select => map((ξ) -> (ξ > 0.0) ? "Yes" : "No", value.(x)))
pedromxavier marked this conversation as resolved.
Show resolved Hide resolved
```
21 changes: 0 additions & 21 deletions docs/src/examples/prime_factoring.md

This file was deleted.

57 changes: 57 additions & 0 deletions docs/src/examples/prime_factorization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Prime Factorization
pedromxavier marked this conversation as resolved.
Show resolved Hide resolved

A central problem in Number Theory and cryptography is to factor ``R \in \mathbb{N}``, which is known
to be the product of two distinct prime numbers ``p, q \in \mathbb{N}``.
[Shor's Algorithm](https://en.wikipedia.org/wiki/Shor%27s_algorithm), designed to address such task is
often regarded as one of the major theoretical landmarks in Quantum Computing, being responsible for
driving increasingly greater interest to the area.

A naïve approach to model this problem can be stated as a quadratically-constrained integer program:
```math
\begin{array}{rl}
\text{s.t.} & p \times q = R \\
& p, q \ge 0 \\
& p, q \in \mathbb{Z}
\end{array}
```

From the definition and the basics of number theory, we are able to retrieve a few assumptions about the problem's variables:
- ``p`` and ``q`` are bounded to the interval ``\left[1, R\right]``
- Moreover, it is fine to assume ``1 < p \le \sqrt{R} \le q \le R \div 2``.

```@example prime-factorization
using JuMP
using ToQUBO
using DWaveNeal

function factor(R::Integer; optimizer = DWaveNeal.Optimizer)
return factor(identity, R; optimizer = optimizer)
end

function factor(config!::Function, R::Integer; optimizer = DWaveNeal.Optimizer)
model = Model(() -> ToQUBO.Optimizer(optimizer))

@variable(model, 1 <= p <= √R, Int)
@variable(model, √R <= q <= R ÷ 2, Int)

@constraint(model, p * q == R)

config!(model)

optimize!(model)

p = round(Int, value(model[:p]))
q = round(Int, value(model[:q]))

return (p, q)
end
```

```@example prime-factorization
p, q = factor(15) do model
set_optimizer_attribute(model, "num_reads", 1_000)
set_optimizer_attribute(model, "num_sweeps", 2_000)
end

print("$p, $q")
```
29 changes: 26 additions & 3 deletions docs/src/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,38 @@
```@example quick-start
using JuMP
using ToQUBO
using Anneal
using DWaveNeal # <- Your favourite Annealer/Sampler/Solver here

model = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))
model = Model(() -> ToQUBO.Optimizer(DWaveNeal.Optimizer))

pedromxavier marked this conversation as resolved.
Show resolved Hide resolved
@variable(model, x[1:3], Bin)

@objective(model, Max, 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3])
@constraint(model, 0.3 * x[1] + 0.5 * x[2] + 1.0 * x[3] <= 3.2)

@constraint(model, 0.3 * x[1] + 0.5 * x[2] + 1.0 * x[3] <= 1.6)

optimize!(model)

solution_summary(model)
```

## Compiler Flags

### Architecture
```@docs
ToQUBO.ARCHITECTURE
```

### Quadratization
```@docs
ToQUBO.QUADRATIZE
ToQUBO.QUADRATIZATION_METHOD
ToQUBO.STABLE_QUADRATIZATION
```

### Variable & Constraint Encoding
```@docs
ToQUBO.VARIABLE_ENCODING_METHOD
ToQUBO.VARIABLE_ENCODING_PENALTY
ToQUBO.CONSTRAINT_ENCODING_PENALTY
```
Loading