+ `;
+
+ return filter_html;
+}
+
+/**
+ * Make the result component given a minisearch result data object and the value of the search input as queryString.
+ * To view the result object structure, refer: https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult
+ *
+ * @param {object} result
+ * @param {string} querystring
+ * @returns string
+ */
+function make_search_result(result, querystring) {
+ let search_divider = ``;
+ let display_link =
+ result.location.slice(Math.max(0), Math.min(50, result.location.length)) +
+ (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div
+
+ if (result.page !== "") {
+ display_link += ` (${result.page})`;
+ }
+
+ let textindex = new RegExp(`\\b${querystring}\\b`, "i").exec(result.text);
+ let text =
+ textindex !== null
+ ? result.text.slice(
+ Math.max(textindex.index - 100, 0),
+ Math.min(
+ textindex.index + querystring.length + 100,
+ result.text.length
+ )
+ )
+ : ""; // cut-off text before and after from the match
+
+ let display_result = text.length
+ ? "..." +
+ text.replace(
+ new RegExp(`\\b${querystring}\\b`, "i"), // For first occurrence
+ '$&'
+ ) +
+ "..."
+ : ""; // highlights the match
+
+ let in_code = false;
+ if (!["page", "section"].includes(result.category.toLowerCase())) {
+ in_code = true;
+ }
+
+ // We encode the full url to escape some special characters which can lead to broken links
+ let result_div = `
+
+
+ `
+);
+
+document.querySelector(".docs-search-query").addEventListener("click", () => {
+ openModal();
+});
+
+document.querySelector(".close-search-modal").addEventListener("click", () => {
+ closeModal();
+});
+
+$(document).on("click", ".search-result-link", function () {
+ closeModal();
+});
+
+document.addEventListener("keydown", (event) => {
+ if ((event.ctrlKey || event.metaKey) && event.key === "/") {
+ openModal();
+ } else if (event.key === "Escape") {
+ closeModal();
+ }
+
+ return false;
+});
+
+// Functions to open and close a modal
+function openModal() {
+ let searchModal = document.querySelector("#search-modal");
+
+ searchModal.classList.add("is-active");
+ document.querySelector(".documenter-search-input").focus();
+}
+
+function closeModal() {
+ let searchModal = document.querySelector("#search-modal");
+ let initial_search_body = `
+
Type something to get started!
+ `;
+
+ searchModal.classList.remove("is-active");
+ document.querySelector(".documenter-search-input").blur();
+
+ if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) {
+ $(".search-modal-card-body").addClass("is-justify-content-center");
+ }
+
+ $(".documenter-search-input").val("");
+ $(".search-modal-card-body").html(initial_search_body);
+}
+
+document
+ .querySelector("#search-modal .modal-background")
+ .addEventListener("click", () => {
+ closeModal();
+ });
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Manages the showing and hiding of the sidebar.
+$(document).ready(function () {
+ var sidebar = $("#documenter > .docs-sidebar");
+ var sidebar_button = $("#documenter-sidebar-button");
+ sidebar_button.click(function (ev) {
+ ev.preventDefault();
+ sidebar.toggleClass("visible");
+ if (sidebar.hasClass("visible")) {
+ // Makes sure that the current menu item is visible in the sidebar.
+ $("#documenter .docs-menu a.is-active").focus();
+ }
+ });
+ $("#documenter > .docs-main").bind("click", function (ev) {
+ if ($(ev.target).is(sidebar_button)) {
+ return;
+ }
+ if (sidebar.hasClass("visible")) {
+ sidebar.removeClass("visible");
+ }
+ });
+});
+
+// Resizes the package name / sitename in the sidebar if it is too wide.
+// Inspired by: https://github.com/davatron5000/FitText.js
+$(document).ready(function () {
+ e = $("#documenter .docs-autofit");
+ function resize() {
+ var L = parseInt(e.css("max-width"), 10);
+ var L0 = e.width();
+ if (L0 > L) {
+ var h0 = parseInt(e.css("font-size"), 10);
+ e.css("font-size", (L * h0) / L0);
+ // TODO: make sure it survives resizes?
+ }
+ }
+ // call once and then register events
+ resize();
+ $(window).resize(resize);
+ $(window).on("orientationchange", resize);
+});
+
+// Scroll the navigation bar to the currently selected menu item
+$(document).ready(function () {
+ var sidebar = $("#documenter .docs-menu").get(0);
+ var active = $("#documenter .docs-menu .is-active").get(0);
+ if (typeof active !== "undefined") {
+ sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15;
+ }
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// Theme picker setup
+$(document).ready(function () {
+ // onchange callback
+ $("#documenter-themepicker").change(function themepick_callback(ev) {
+ var themename = $("#documenter-themepicker option:selected").attr("value");
+ if (themename === "auto") {
+ // set_theme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
+ window.localStorage.removeItem("documenter-theme");
+ } else {
+ // set_theme(themename);
+ window.localStorage.setItem("documenter-theme", themename);
+ }
+ // We re-use the global function from themeswap.js to actually do the swapping.
+ set_theme_from_local_storage();
+ });
+
+ // Make sure that the themepicker displays the correct theme when the theme is retrieved
+ // from localStorage
+ if (typeof window.localStorage !== "undefined") {
+ var theme = window.localStorage.getItem("documenter-theme");
+ if (theme !== null) {
+ $("#documenter-themepicker option").each(function (i, e) {
+ e.selected = e.value === theme;
+ });
+ }
+ }
+});
+
+})
+////////////////////////////////////////////////////////////////////////////////
+require(['jquery'], function($) {
+
+// update the version selector with info from the siteinfo.js and ../versions.js files
+$(document).ready(function () {
+ // If the version selector is disabled with DOCUMENTER_VERSION_SELECTOR_DISABLED in the
+ // siteinfo.js file, we just return immediately and not display the version selector.
+ if (
+ typeof DOCUMENTER_VERSION_SELECTOR_DISABLED === "boolean" &&
+ DOCUMENTER_VERSION_SELECTOR_DISABLED
+ ) {
+ return;
+ }
+
+ var version_selector = $("#documenter .docs-version-selector");
+ var version_selector_select = $("#documenter .docs-version-selector select");
+
+ version_selector_select.change(function (x) {
+ target_href = version_selector_select
+ .children("option:selected")
+ .get(0).value;
+ window.location.href = target_href;
+ });
+
+ // add the current version to the selector based on siteinfo.js, but only if the selector is empty
+ if (
+ typeof DOCUMENTER_CURRENT_VERSION !== "undefined" &&
+ $("#version-selector > option").length == 0
+ ) {
+ var option = $(
+ ""
+ );
+ version_selector_select.append(option);
+ }
+
+ if (typeof DOC_VERSIONS !== "undefined") {
+ var existing_versions = version_selector_select.children("option");
+ var existing_versions_texts = existing_versions.map(function (i, x) {
+ return x.text;
+ });
+ DOC_VERSIONS.forEach(function (each) {
+ var version_url = documenterBaseURL + "/../" + each + "/";
+ var existing_id = $.inArray(each, existing_versions_texts);
+ // if not already in the version selector, add it as a new option,
+ // otherwise update the old option with the URL and enable it
+ if (existing_id == -1) {
+ var option = $(
+ ""
+ );
+ version_selector_select.append(option);
+ } else {
+ var option = existing_versions[existing_id];
+ option.value = version_url;
+ option.disabled = false;
+ }
+ });
+ }
+
+ // only show the version selector if the selector has been populated
+ if (version_selector_select.children("option").length > 0) {
+ version_selector.toggleClass("visible");
+ }
+});
+
+})
diff --git a/dev/assets/extra_styles.css b/dev/assets/extra_styles.css
new file mode 100644
index 00000000..2d249309
--- /dev/null
+++ b/dev/assets/extra_styles.css
@@ -0,0 +1,15 @@
+.docs-sidebar .docs-logo > img {
+ max-height: 16rem !important;
+ margin: auto;
+}
+
+/* Center images & diagrams */
+p:has(img) {
+ text-align: center;
+ margin: 0 auto;
+}
+
+div.mermaid {
+ text-align: center;
+ margin: 0 auto;
+}
diff --git a/dev/assets/favicon.ico b/dev/assets/favicon.ico
new file mode 100644
index 00000000..0644c05b
Binary files /dev/null and b/dev/assets/favicon.ico differ
diff --git a/dev/assets/figures/quantum-chip.png b/dev/assets/figures/quantum-chip.png
new file mode 100644
index 00000000..07629700
Binary files /dev/null and b/dev/assets/figures/quantum-chip.png differ
diff --git a/dev/assets/fonts/Sunflower-LICENSE.txt b/dev/assets/fonts/Sunflower-LICENSE.txt
new file mode 100644
index 00000000..cf3f912d
--- /dev/null
+++ b/dev/assets/fonts/Sunflower-LICENSE.txt
@@ -0,0 +1,22 @@
+MadeType
+behance.com/madetype
+
+https://www.fontspring.com/fonts/madetype
+https://creativemarket.com/MadeType
+https://www.youworkforthem.com/designer/1002/madetype/
+https://crella.net/store/madetype/
+https://thehungryjpeg.com/madetype
+
+
+END USER LICENSE AGREEMENT
+
+- FOR PERSONAL USE.
+
+- Contact me at Madetypeinfo@gmail.com before commercial using it.
+
+- MadeType is not liable for any damage resulting from the use ot this typeface.
+
+- All rights are retained by MadeType.
+
+
+THANK YOU!
\ No newline at end of file
diff --git a/dev/assets/fonts/Sunflower-LICENSE/index.html b/dev/assets/fonts/Sunflower-LICENSE/index.html
new file mode 100644
index 00000000..3c7127d5
--- /dev/null
+++ b/dev/assets/fonts/Sunflower-LICENSE/index.html
@@ -0,0 +1,2 @@
+
+Sunflower Font License · ToQUBO.jl
This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.
Quadratic Unconstrained Binary Optimization, as the name suggests, refers to the global minimization or maximization of a quadratic polynomial on binary variables. A common presentation, the quadratic matrix form, is written as
where $Q \in \mathbb{R}^{n \times n}$ is symmetric and $\mathbb{B} = \lbrace{0, 1}\rbrace$. Note that, since $x^{2} = x$ holds for $x \in \mathbb{B}$, the linear terms of the objective function are stored in the main diagonal of $Q$.
Mathematically speaking, there is a notorious equivalence between QUBO and Max-Cut problems, e.g. for every QUBO instance there is an information preserving Max-Cut reformulation and vice versa. This statement is followed by two immediate implications:
In the general case, solving QUBO globally is NP-Hard.
It is a simple yet expressive mathematical programming framework.
Implication 1. tells us that such problems are computationally intractable and that heuristics and metaheuristics are to be employed instead of exact methods. No 2. relates to the fact that we are able to represent many other optimization models by means of the QUBO formalism.
The Ising Model, on the other hand, is a mathematical abstraction to describe statistical interactions within mechanical systems with interesting properties for encoding combinatorial problems. Its Hamiltonian leads to an optimization formulation in terms of the spin values of their states, given by
with strictly upper triangular $J \in \mathbb{R}^{n \times n}$ and $\mathbf{h} \in \mathbb{R}$.
The Ising reformulation alternative draws the bridge between QUBO problems and devices designed to sample global or approximate ground states of the Ising Hamiltonian with high probability[Mohseni2022]. Some of the paradigms that stand out in this context are quantum gate-based optimization algorithms (QAOA and VQE), quantum annealers, hardware-accelerated platforms (Coherent Ising Machines and Simulated Bifurcation Machines) and physics-inspired methods (Simulated Annealing, Parallel Tempering). The significant advances in these computing systems contributed to the growing popularity of the model across the literature.
Mohseni2022Mohseni, N., McMahon, P. L. & Byrnes, T. Ising machines as hardware solvers of combinatorial optimization problems. Nat Rev Phys 4, 363–379 (2022). {arXiv}
Settings
This document was generated with Documenter.jl version 1.1.2 on Tuesday 14 November 2023. Using Julia version 1.9.3.
Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between optimization over quadratic PBFs and the QUBO formalism.
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.
A quadratization is a mapping $\mathcal{Q}: \mathscr{F} \to \mathscr{F}^{2}$ such that
\[\forall f \in \mathscr{F}, \forall x \in \{0, 1\}^{n}, \min_{y} \mathcal{Q}\left\lbrace{}f\right\rbrace{}(x; y) = f(x)\]
There are many quadratization methods available[Dattani2019], and ToQUBO implements two of them for now. However, using Julia's multiple dispatch paradigm, it's possible to extend the quadratization method coverage with your own algorithms.
The quadratization of a PBF does not guarantee that the resulting function will always be the same, as the order of terms can be different each time. This can be an issue in some situations where a deterministic output is required.
With said that, we have introduced the concept of Stable Quadratization, where the terms of the PBF are sorted, guaranteeing that the resulting PBF will be the same every time. We have defined it as an attribute of the compiler, with the ToQUBO.Attributes.StableQuadratization flag.
Dattani2019Nikesh S. Dattani, Quadratization in discrete optimization and quantum mechanics, ArXiv, 2019 {doi}
Settings
This document was generated with Documenter.jl version 1.1.2 on Tuesday 14 November 2023. Using Julia version 1.9.3.
As you may already know, QUBO models are comprised only of binary variables. So when we are reformulating general optimization problems, one important step is to encode variables into binary ones.
ToQUBO currently implements 6 encoding techniques. Each method introduces a different number of variables, quadratic terms and linear terms. Also, they differ in the magnitude of their coefficients $\Delta$.
The bounded-coefficient encoding method[Karimi2019] consists in limiting the magnitude of the coefficients in the encoding expansion to a parameter $\mu$. This can be applied to the Unary, Binary and Arithmetic encoding methods.
Let $\xi[a, b] : \mathbb{B}^{n} \to [a, b]$ be an encoding function over the closed interval $[a, b]$. The bounded-coefficient encoding function given $\mu$ is defined as
The one-hot encoding is a linear technique used to represent a variable $x \in \set{\gamma_{j}}_{j \in [n]}$.
The associated encoding function is combined with a constraint assuring that only one and exactly one of the expansion's variables $y_{j}$ is activated at a time.
Thus, for encoding methods that rely on the regular division of an interval, it is possible to define the number of samples $k$ necessary to limit the expected error according to an upper bound $\tau$, that is,
A QUBO model is unconstrained. So when ToQUBO is reformulating a problem, it needs to encode all constraints into the objective function losing as little information as possible.
As constraints are introduced into the objective function, we need to make sure that they won't be violated. In order to do that, ToQUBO multiplies the encoded constraint by a large penalty $\rho$, so that any violation would result in a sub-optimal solution to the problem.
Sometimes, the encoding process might introduce higher-order terms, demanding ToQUBO to reduce the offending polynomials back to a quadratic form.
Karimi2019Karimi, S. & Ronagh, P. Practical integer-to-binary mapping for quantum annealers. Quantum Inf Process 18, 94 (2019). {doi}
Chancellor2019Nicholas Chancellor, Domain wall encoding of discrete variables for quantum annealing and QAOA, Quantum Science Technology 4, 2019.
Settings
This document was generated with Documenter.jl version 1.1.2 on Tuesday 14 November 2023. Using Julia version 1.9.3.
During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.
This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.
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 encoding information for later expansion and evaluation.
ToQUBO.jl's main goal is to make use of parameterized stochastic optimization solvers, particularly those relying on non-conventional hardware such as Quantum Annealing and other Ising Machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO.jl via the QUBODrivers.jl companion package. Some of them are presented below.
Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configurations you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and research due to its robustness, simplicity and ease of use. The DWave.jl's DWave.Neal module uses QUBODrivers.jl to deliver an interface to this sampler.
Interfacing with D-Wave's quantum annealer is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi, FICO® Xpress and IBM® CPLEX®, this requires licensing and extra steps are needed to get an access token. In a first moment, for those willing to get started, the DWave.Neal optimizer might be enough to learn the ropes.
This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias $0 \le p \le 1$, which defaults to $p = 0.5$. After running the using QUBODrivers command, RandomSampler.Optimizer will be available.
Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with at most $\approxeq 20$ variables should be provided since visiting $2^{20} \approxeq 10^{6}$ states can already take up to a few seconds.
The most accessible alternative to the forementioned methods are Mixed-Integer Quadratic Programming (MIQP) solvers such as Gurobi, CPLEX, SCIP and BARON. These are not intended to be of regular use alongside ToQUBO.jl since providing a QUBO reformulation will usually make things harder for non-specialized solvers. Yet, there are still a few cases where they may be suitable, such as tests, benchmarks, or any other situation where global optimality is a must.
Settings
This document was generated with Documenter.jl version 1.1.2 on Tuesday 14 November 2023. Using Julia version 1.9.3.
The ideia behind ToQUBO.jl's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo[1], the translation for cube.
The colors were picked according to Julia's Reference for logo graphics[2]. Text color matches the innermost shape and renders fairly well in both light and dark background themes.
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, 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:
Now, lets fill a few more knapsacks. First, we generate uniform random costs $\mathbf{c}$ and weights $\mathbf{w}$ then set the knapsack's capacity $C$ to be a fraction of the total available weight i.e. $80\%$.
In this example, we will be exploring an optimization model for asset distribution where the expected return is maximized while mitigating the financial risk. The following approach was inspired by a JuMP tutorial, where monthly stock prices for three assets are provided, namely IBM, WMT and SEHI.
The modelling presented below aggregates the risk measurement $\mathbf{x}' \Sigma \mathbf{x}$ as a penalty term to the objective function, thus yielding
where $\mu_{i} = \mathbb{E}[r_{i}]$ is the expected return value for each investment $i$; $\Sigma$ is the covariance matrix and $\lambda$ is the risk-aversion penalty factor.
If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:
@software{toqubo:2023,
+ author = {Pedro Maciel Xavier and Pedro Ripper and Tiago Andrade and Joaquim Dias Garcia and David E. Bernal Neira},
+ title = {{ToQUBO.jl}},
+ month = {feb},
+ year = {2023},
+ publisher = {Zenodo},
+ version = {v0.1.5},
+ doi = {10.5281/zenodo.7644291},
+ url = {https://doi.org/10.5281/zenodo.7644291}
+}
Settings
This document was generated with Documenter.jl version 1.1.2 on Tuesday 14 November 2023. Using Julia version 1.9.3.
diff --git a/dev/manual/1-start/index.html b/dev/manual/1-start/index.html
new file mode 100644
index 00000000..5684f790
--- /dev/null
+++ b/dev/manual/1-start/index.html
@@ -0,0 +1,31 @@
+
+Getting Started · ToQUBO.jl
When set, this boolean flag enables stable quadratization methods, thus yielding predictable results. This is intended to be used during tests or other situations where deterministic output is desired. On the other hand, usage in production is not recommended since it requires increased memory and processing resources.
This document was generated with Documenter.jl version 1.1.2 on Tuesday 14 November 2023. Using Julia version 1.9.3.
diff --git a/dev/search_index.js b/dev/search_index.js
new file mode 100644
index 00000000..d9ab6d3f
--- /dev/null
+++ b/dev/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"assets/fonts/Sunflower-LICENSE/#Sunflower-Font-License","page":"Sunflower Font License","title":"Sunflower Font License","text":"","category":"section"},{"location":"assets/fonts/Sunflower-LICENSE/","page":"Sunflower Font License","title":"Sunflower Font License","text":"MadeType\nbehance.com/madetype\n\nhttps://www.fontspring.com/fonts/madetype\nhttps://creativemarket.com/MadeType\nhttps://www.youworkforthem.com/designer/1002/madetype/\nhttps://crella.net/store/madetype/\nhttps://thehungryjpeg.com/madetype\n\n\nEND USER LICENSE AGREEMENT\n\n- FOR PERSONAL USE. \n\n- Contact me at Madetypeinfo@gmail.com before commercial using it.\n\n- MadeType is not liable for any damage resulting from the use ot this typeface.\n\n- All rights are retained by MadeType.\n\n\nTHANK YOU!","category":"page"},{"location":"booklet/1-intro/#ToQUBO.jl-Booklet","page":"Introduction","title":"ToQUBO.jl Booklet","text":"","category":"section"},{"location":"booklet/1-intro/","page":"Introduction","title":"Introduction","text":"This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.","category":"page"},{"location":"booklet/1-intro/#Table-of-Contents","page":"Introduction","title":"Table of Contents","text":"","category":"section"},{"location":"booklet/1-intro/","page":"Introduction","title":"Introduction","text":"Pages = [\"2-qubo.md\", \"3-pbo.md\", \"4-encoding.md\", \"5-virtual.md\", \"6-compiler.md\", \"7-solvers.md\", \"8-appendix.md\"]\nDepth = 2","category":"page"},{"location":"manual/3-results/#Gathering-Results","page":"Gathering Results","title":"Gathering Results","text":"","category":"section"},{"location":"manual/3-results/","page":"Gathering Results","title":"Gathering Results","text":"warning: Work in progress\nWe hope to write this part of the documentation soon. Please come back later!","category":"page"},{"location":"booklet/4-encoding/#Encoding-Methods","page":"Encoding","title":"Encoding Methods","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO.Encoding.encode\nToQUBO.Encoding.encode!\nToQUBO.Encoding.encodes","category":"page"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.encode","page":"Encoding","title":"ToQUBO.Encoding.encode","text":"encode(var, e::VariableEncodingMethod, x::Union{VI,Nothing}, S)\n\n\n\n\n\n","category":"function"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.encode!","page":"Encoding","title":"ToQUBO.Encoding.encode!","text":"encode!(target, source...)\n\n\n\n\n\n","category":"function"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.encodes","page":"Encoding","title":"ToQUBO.Encoding.encodes","text":"encodes(f::AbstractPBF, S::Tuple{T,T}, tol::T) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/4-encoding/#Variables","page":"Encoding","title":"Variables","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"As you may already know, QUBO models are comprised only of binary variables. So when we are reformulating general optimization problems, one important step is to encode variables into binary ones.","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO currently implements 6 encoding techniques. Each method introduces a different number of variables, quadratic terms and linear terms. Also, they differ in the magnitude of their coefficients Delta.","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"Encoding Binary Variables # Linear terms # Quadratic terms Delta\nBinary O(log n) O(log n) - O(n)\nUnary O(n) O(n) - O(1)\nOne-Hot O(n) O(n) O(n^2) O(n)\nDomain-Wall O(n) O(n) O(n) O(n)\nBounded-Coefficient O(n) O(n) - O(1)\nArithmetic Prog O(sqrtn) O(sqrtn) - O(sqrtn)","category":"page"},{"location":"booklet/4-encoding/#Mirror-Encoding","page":"Encoding","title":"Mirror Encoding","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO.Encoding.VariableEncodingMethod\nToQUBO.Encoding.Mirror","category":"page"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.VariableEncodingMethod","page":"Encoding","title":"ToQUBO.Encoding.VariableEncodingMethod","text":"VariableEncodingMethod\n\nAbstract type for variable encoding methods.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.Mirror","page":"Encoding","title":"ToQUBO.Encoding.Mirror","text":"Mirror()\n\nSimply mirrors a binary variable x in mathbbB with a twin variable y in mathbbB.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#Interval-Encoding","page":"Encoding","title":"Interval Encoding","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO.Encoding.IntervalVariableEncodingMethod\nToQUBO.Encoding.Unary\nToQUBO.Encoding.Binary\nToQUBO.Encoding.Arithmetic","category":"page"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.IntervalVariableEncodingMethod","page":"Encoding","title":"ToQUBO.Encoding.IntervalVariableEncodingMethod","text":"IntervalVariableEncodingMethod\n\nAbstract type for methods that encode variables using a linear function, e.g.,\n\nxi(mathbfy) = beta + sum_i = 1^n gamma_i y_i\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.Unary","page":"Encoding","title":"ToQUBO.Encoding.Unary","text":"Unary{T}()\n\nInteger\n\nLet x in a b subset mathbbZ, n = b - a and mathbfy in mathbbB^n.\n\nxia b(mathbfy) = a + sum_j = 1^b - a y_j\n\nReal\n\nGiven n in mathbbN for x in a b subset mathbbR,\n\nxia b(mathbfy) = a + fracb - an sum_j = 1^n y_j\n\nRepresentation error\n\nGiven tau 0, for the expected encoding error to be less than or equal to tau, at least\n\nn ge 1 + fracb - a4 tau\n\nbinary variables become necessary.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.Binary","page":"Encoding","title":"ToQUBO.Encoding.Binary","text":"Binary{T}()\n\nInteger\n\nLet x in a b subset mathbbZ, n = leftlceil log_2(b - a) + 1 rightrceil and mathbfy in mathbbB^n.\n\nxia b(mathbfy) = a + left(b - a - 2^n - 1 + 1right) y_n + sum_j = 1^n - 1 2^j - 1 y_j\n\nReal\n\nGiven n in mathbbN for x in a b subset mathbbR,\n\nxia b(mathbfy) = a + fracb - a2^n - 1 sum_j = 1^n 2^j - 1 y_j\n\nRepresentation error\n\nGiven tau 0, for the expected encoding error to be less than or equal to tau, at least\n\nn ge log_2 left1 + fracb - a4 tauright\n\nbinary variables become necessary.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.Arithmetic","page":"Encoding","title":"ToQUBO.Encoding.Arithmetic","text":"Arithmetic{T}()\n\nInteger\n\nLet x in a b subset mathbbZ, n = leftlceil frac12 sqrt1 + 8 (b - a) - frac12 rightrceil and mathbfy in mathbbB^n.\n\nxia b(mathbfy) = a + left( b - a - fracn (n - 1)2 right) y_n + sum_j = 1^n - 1 j y_j\n\nReal\n\nGiven n in mathbbN for x in a b subset mathbbR,\n\nxia b(mathbfy) = a + fracb - an (n + 1) sum_j = 1^n j y_j\n\nRepresentation error\n\nGiven tau 0, for the expected encoding error to be less than or equal to tau, at least\n\nn ge frac12 left 1 + sqrt3 + frac(b - a)2 tau) right\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#Bounded-Coefficients","page":"Encoding","title":"Bounded Coefficients","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO.Encoding.Bounded","category":"page"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.Bounded","page":"Encoding","title":"ToQUBO.Encoding.Bounded","text":"Bounded{E,T}(μ::T) where {E<:Encoding,T}\n\nThe bounded-coefficient encoding method[Karimi2019] consists in limiting the magnitude of the coefficients in the encoding expansion to a parameter mu. This can be applied to the Unary, Binary and Arithmetic encoding methods.\n\nLet xia b mathbbB^n to a b be an encoding function over the closed interval a b. The bounded-coefficient encoding function given mu is defined as\n\nxi_mua b = xi0 delta(y_1 dots y_k) + sum_j = k + 1^r mu yj\n\n[Karimi2019]: Karimi, S. & Ronagh, P. Practical integer-to-binary mapping for quantum annealers. Quantum Inf Process 18, 94 (2019). {doi}\n\n```\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#Arbitrary-Set-Encoding","page":"Encoding","title":"Arbitrary Set Encoding","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO.Encoding.SetVariableEncodingMethod\nToQUBO.Encoding.OneHot\nToQUBO.Encoding.DomainWall","category":"page"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.SetVariableEncodingMethod","page":"Encoding","title":"ToQUBO.Encoding.SetVariableEncodingMethod","text":"SetVariableEncodingMethod\n\nAbstract type for methods that encode variables over an arbitrary set.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.OneHot","page":"Encoding","title":"ToQUBO.Encoding.OneHot","text":"OneHot{T}()\n\nThe one-hot encoding is a linear technique used to represent a variable x in setgamma_j_j in n.\n\nThe associated encoding function is combined with a constraint assuring that only one and exactly one of the expansion's variables y_j is activated at a time.\n\nxisetgamma_j_j in n(mathbfy) = sum_j = 1^n gamma_j y_j textrmst sum_j = 1^n y_j = 1\n\nWhen a variable is encoded following this approach, a penalty term of the form\n\nrho left sum_j = 1^n y_j - 1 right^2\n\nis added to the objective function.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.DomainWall","page":"Encoding","title":"ToQUBO.Encoding.DomainWall","text":"DomainWall{T}()\n\nThe Domain Wall[Chancellor2019] encoding method is a sequential approach that requires n - 1 bits to represent n distinct values.\n\nxisetgamma_j_j in n(mathbfy) = sum_j = 1^n gamma_j (y_j - y_j + 1) textrmst sum_j = 1^n y_j oplus y_j + 1 = 1 y_1 = 1 y_n + 1 = 0\n\nwhere mathbfy in mathbbB^n + 1.\n\n[Chancellor2019]: Nicholas Chancellor, Domain wall encoding of discrete variables for quantum annealing and QAOA, Quantum Science Technology 4, 2019.\n\n\n\n\n\n","category":"type"},{"location":"booklet/4-encoding/#Representation-Error","page":"Encoding","title":"Representation Error","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"ToQUBO.Encoding.encoding_bits\nToQUBO.Encoding.encoding_points","category":"page"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.encoding_bits","page":"Encoding","title":"ToQUBO.Encoding.encoding_bits","text":"encoding_bits(e::VariableEncodingMethod, S::Tuple{T,T}, tol::T) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/4-encoding/#ToQUBO.Encoding.encoding_points","page":"Encoding","title":"ToQUBO.Encoding.encoding_points","text":"encoding_points(e::SetVariableEncodingMethod, S::Tuple{T,T}, tol::T) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"Let setx_i_i in k be the collection of k evenly spaced samples from the discretization of an interval a b subseteq mathbbR.","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"The representation error for a given point x with respect to setx_i_i in k is","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"e_k(x) = min_i in k leftx - x_iright","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"Assuming that x behaves as a uniformly distributed random variable, the expected absolute encoding error is","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"beginalign*\nmathbbElefte_k(x)right = frac1b - a int_a^b e_k(x) mathrmdx \n = frac14 fracb - ak - 1\nendalign*","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"Thus, for encoding methods that rely on the regular division of an interval, it is possible to define the number of samples k necessary to limit the expected error according to an upper bound tau, that is,","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"mathbbElefte_k(x)right le tau implies k ge 1 + fracb - a4 tau","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"This allows the compiler to automatically infer the number of bits to allocate for an encoded variable given the tolerance factor.","category":"page"},{"location":"booklet/4-encoding/#Constraints","page":"Encoding","title":"Constraints","text":"","category":"section"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"A QUBO model is unconstrained. So when ToQUBO is reformulating a problem, it needs to encode all constraints into the objective function losing as little information as possible.","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"As constraints are introduced into the objective function, we need to make sure that they won't be violated. In order to do that, ToQUBO multiplies the encoded constraint by a large penalty rho, so that any violation would result in a sub-optimal solution to the problem.","category":"page"},{"location":"booklet/4-encoding/","page":"Encoding","title":"Encoding","text":"Sometimes, the encoding process might introduce higher-order terms, demanding ToQUBO to reduce the offending polynomials back to a quadratic form.","category":"page"},{"location":"manual/4-settings/#Compiler-Settings","page":"Compiler Settings","title":"Compiler Settings","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.StableCompilation","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.StableCompilation","page":"Compiler Settings","title":"ToQUBO.Attributes.StableCompilation","text":"StableCompilation()\n\nWhen set, this boolean flag enables stable reformulation methods, thus yielding predictable results.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#Compiler-Messages","page":"Compiler Settings","title":"Compiler Messages","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.Warnings","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.Warnings","page":"Compiler Settings","title":"ToQUBO.Attributes.Warnings","text":"Warnings()\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#Compiler-Optimization","page":"Compiler Settings","title":"Compiler Optimization","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.Optimization","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.Optimization","page":"Compiler Settings","title":"ToQUBO.Attributes.Optimization","text":"Optimization()\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#Working-with-target-architectures","page":"Compiler Settings","title":"Working with target architectures","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.Architecture","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.Architecture","page":"Compiler Settings","title":"ToQUBO.Attributes.Architecture","text":"Architecture()\n\nSelects which solver architecture to use. Defaults to QUBOTools.GenericArchitecture.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#Quadratization","page":"Compiler Settings","title":"Quadratization","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.Quadratize\nToQUBO.Attributes.QuadratizationMethod\nToQUBO.Attributes.StableQuadratization","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.Quadratize","page":"Compiler Settings","title":"ToQUBO.Attributes.Quadratize","text":"Quadratize()\n\nBoolean flag to conditionally perform the quadratization step. Is automatically set by the compiler when high-order functions are generated.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.QuadratizationMethod","page":"Compiler Settings","title":"ToQUBO.Attributes.QuadratizationMethod","text":"QuadratizationMethod()\n\nDefines which quadratization method to use. Available options are defined in the PBO submodule.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.StableQuadratization","page":"Compiler Settings","title":"ToQUBO.Attributes.StableQuadratization","text":"StableQuadratization()\n\nWhen set, this boolean flag enables stable quadratization methods, thus yielding predictable results. This is intended to be used during tests or other situations where deterministic output is desired. On the other hand, usage in production is not recommended since it requires increased memory and processing resources.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#Variable-and-Constraint-Encoding","page":"Compiler Settings","title":"Variable & Constraint Encoding","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.VariableEncodingBits\nToQUBO.Attributes.DefaultVariableEncodingBits\nToQUBO.Attributes.VariableEncodingATol\nToQUBO.Attributes.DefaultVariableEncodingATol\nToQUBO.Attributes.VariableEncodingMethod\nToQUBO.Attributes.DefaultVariableEncodingMethod\nToQUBO.Attributes.VariableEncodingPenalty\nToQUBO.Attributes.ConstraintEncodingPenalty","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.VariableEncodingBits","page":"Compiler Settings","title":"ToQUBO.Attributes.VariableEncodingBits","text":"VariableEncodingBits()\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.DefaultVariableEncodingBits","page":"Compiler Settings","title":"ToQUBO.Attributes.DefaultVariableEncodingBits","text":"DefaultVariableEncodingBits()\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.VariableEncodingATol","page":"Compiler Settings","title":"ToQUBO.Attributes.VariableEncodingATol","text":"VariableEncodingATol()\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.DefaultVariableEncodingATol","page":"Compiler Settings","title":"ToQUBO.Attributes.DefaultVariableEncodingATol","text":"DefaultVariableEncodingATol()\n\nFallback value for VariableEncodingATol.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.VariableEncodingMethod","page":"Compiler Settings","title":"ToQUBO.Attributes.VariableEncodingMethod","text":"VariableEncodingMethod()\n\nAvailable methods are:\n\nEncoding.Binary (default)\nEncoding.Unary\nEncoding.Arithmetic\nEncoding.OneHot\nEncoding.DomainWall\nEncoding.Bounded\n\nThe Encoding.Binary, Encoding.Unary and Encoding.Arithmetic encodings can have their expansion coefficients bounded by wrapping them with the Encoding.Bounded method.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.DefaultVariableEncodingMethod","page":"Compiler Settings","title":"ToQUBO.Attributes.DefaultVariableEncodingMethod","text":"DefaultVariableEncodingMethod()\n\nFallback value for VariableEncodingMethod.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.VariableEncodingPenalty","page":"Compiler Settings","title":"ToQUBO.Attributes.VariableEncodingPenalty","text":"VariableEncodingPenalty()\n\nAllows the user to set and retrieve the coefficients used for encoding variables when additional constraints are involved.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#ToQUBO.Attributes.ConstraintEncodingPenalty","page":"Compiler Settings","title":"ToQUBO.Attributes.ConstraintEncodingPenalty","text":"ConstraintEncodingPenalty()\n\nAllows the user to retrieve the coefficients used for encoding constraints.\n\n\n\n\n\n","category":"type"},{"location":"manual/4-settings/#Discretization","page":"Compiler Settings","title":"Discretization","text":"","category":"section"},{"location":"manual/4-settings/","page":"Compiler Settings","title":"Compiler Settings","text":"ToQUBO.Attributes.Discretize","category":"page"},{"location":"manual/4-settings/#ToQUBO.Attributes.Discretize","page":"Compiler Settings","title":"ToQUBO.Attributes.Discretize","text":"Discretize()\n\nWhen set, this boolean flag guarantees that every coefficient in the final formulation is an integer.\n\n\n\n\n\n","category":"type"},{"location":"examples/portfolio_optimization/#Portfolio-Optimization","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"","category":"section"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"In this example, we will be exploring an optimization model for asset distribution where the expected return is maximized while mitigating the financial risk. The following approach was inspired by a JuMP tutorial, where monthly stock prices for three assets are provided, namely IBM, WMT and SEHI.","category":"page"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"The modelling presented below aggregates the risk measurement mathbfx Sigma mathbfx as a penalty term to the objective function, thus yielding","category":"page"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"beginarrayrll\n max_mathbfx mathbfmumathbfx - lambda mathbfx Sigma mathbfx \n textrmst 0 le x_i le 1 forall i \n sum_i x_i = 1\nendarray","category":"page"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"where mu_i = mathbbEr_i is the expected return value for each investment i; Sigma is the covariance matrix and lambda is the risk-aversion penalty factor.","category":"page"},{"location":"examples/portfolio_optimization/#Stock-prices","page":"Portfolio Optimization","title":"Stock prices","text":"","category":"section"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"using DataFrames\nusing Statistics\n\nassets = [:IBM, :WMT, :SEHI]\n\ndf = DataFrames.DataFrame(\n [\n 93.043 51.826 1.063\n 84.585 52.823 0.938\n 111.453 56.477 1.000\n 99.525 49.805 0.938\n 95.819 50.287 1.438\n 114.708 51.521 1.700\n 111.515 51.531 2.540\n 113.211 48.664 2.390\n 104.942 55.744 3.120\n 99.827 47.916 2.980\n 91.607 49.438 1.900\n 107.937 51.336 1.750\n 115.590 55.081 1.800\n ],\n assets,\n)","category":"page"},{"location":"examples/portfolio_optimization/#Solving","page":"Portfolio Optimization","title":"Solving","text":"","category":"section"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"using JuMP\nusing ToQUBO\nusing DWave\n\nfunction solve(\n config!::Function,\n df::DataFrame,\n λ::Float64 = 10.;\n optimizer = DWave.Neal.Optimizer\n)\n # Number of assets\n n = size(df, 2)\n\n # Relative monthly return\n r = diff(Matrix(df); dims = 1) ./ Matrix(df[1:end-1, :])\n\n # Expected monthly return value for each stock\n μ = vec(Statistics.mean(r; dims = 1))\n\n # Covariance matrix\n Σ = Statistics.cov(r)\n\n # Build model\n model = Model(() -> ToQUBO.Optimizer(optimizer))\n\n @variable(model, 0 <= x[1:n] <= 1)\n @objective(model, Max, μ'x - λ * x' * Σ * x)\n @constraint(model, sum(x) == 1)\n\n config!(model)\n\n optimize!(model)\n\n return value.(x)\nend\n\nfunction solve(df::DataFrame, λ::Float64 = 10.; optimizer = DWave.Neal.Optimizer)\n return solve(identity, df, λ; optimizer)\nend","category":"page"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"solve(df) do model\n JuMP.set_silent(model)\n JuMP.set_optimizer_attribute(model, \"num_reads\", 2_000)\nend","category":"page"},{"location":"examples/portfolio_optimization/#Penalty-Analysis","page":"Portfolio Optimization","title":"Penalty Analysis","text":"","category":"section"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"To finish our discussion, we are going to sketch some graphics to help our reasoning on how the penalty factor lambda affects our investments.","category":"page"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"using Plots\nusing Measures\n\n# Make plots look professional\nPlots.default(;\n fontfamily = \"Computer Modern\",\n plot_titlefontsize = 16,\n titlefontsize = 14,\n guidefontsize = 12,\n legendfontsize = 10,\n tickfontsize = 10,\n margin = 5mm,\n)","category":"page"},{"location":"examples/portfolio_optimization/","page":"Portfolio Optimization","title":"Portfolio Optimization","text":"using Plots\n\nΛ = collect(0.:5.:50.)\nX = Dict{Symbol,Vector{Float64}}(tag => [] for tag in assets)\n\nfor λ = Λ\n x = solve(df, λ)\n\n for (i, tag) in enumerate(assets)\n push!(X[tag], x[i])\n end\nend\n\nplt = plot(;\n title=\"Portfolio Optimization\",\n xlabel=raw\"penalty factor ($\\lambda$)\",\n ylabel=raw\"investment share ($x$)\",\n)\n\nfor tag in assets\n plot!(plt, Λ, X[tag]; label=string(tag))\nend\n\nplt","category":"page"},{"location":"booklet/3-pbo/#Pseudo-Boolean-Optimization","page":"PBO","title":"Pseudo-Boolean Optimization","text":"","category":"section"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between optimization over quadratic PBFs and the QUBO formalism.","category":"page"},{"location":"booklet/3-pbo/#Quadratization","page":"PBO","title":"Quadratization","text":"","category":"section"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"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. ","category":"page"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"A quadratization is a mapping mathcalQ mathscrF to mathscrF^2 such that","category":"page"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"forall f in mathscrF forall x in 0 1^n min_y mathcalQleftlbracefrightrbrace(x y) = f(x)","category":"page"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"There are many quadratization methods available[Dattani2019], and ToQUBO implements two of them for now. However, using Julia's multiple dispatch paradigm, it's possible to extend the quadratization method coverage with your own algorithms.","category":"page"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"[Dattani2019]: Nikesh S. Dattani, Quadratization in discrete optimization and quantum mechanics, ArXiv, 2019 {doi}","category":"page"},{"location":"booklet/3-pbo/#Quadratization-Methods","page":"PBO","title":"Quadratization Methods","text":"","category":"section"},{"location":"booklet/3-pbo/#Stable-Quadratization","page":"PBO","title":"Stable Quadratization","text":"","category":"section"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"The quadratization of a PBF does not guarantee that the resulting function will always be the same, as the order of terms can be different each time. This can be an issue in some situations where a deterministic output is required.","category":"page"},{"location":"booklet/3-pbo/","page":"PBO","title":"PBO","text":"With said that, we have introduced the concept of Stable Quadratization, where the terms of the PBF are sorted, guaranteeing that the resulting PBF will be the same every time. We have defined it as an attribute of the compiler, with the ToQUBO.Attributes.StableQuadratization flag.","category":"page"},{"location":"booklet/6-compiler/#The-Compiler","page":"The Compiler","title":"The Compiler","text":"","category":"section"},{"location":"booklet/6-compiler/","page":"The Compiler","title":"The Compiler","text":"warning: Work in progress\nWe hope to write this part of the documentation soon. Please come back later!","category":"page"},{"location":"booklet/6-compiler/#Compilation-Steps","page":"The Compiler","title":"Compilation Steps","text":"","category":"section"},{"location":"booklet/6-compiler/#Setup","page":"The Compiler","title":"Setup","text":"","category":"section"},{"location":"booklet/6-compiler/","page":"The Compiler","title":"The Compiler","text":"ToQUBO.Compiler.reset!\nToQUBO.Compiler.setup!","category":"page"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.reset!","page":"The Compiler","title":"ToQUBO.Compiler.reset!","text":"reset!(model::Virtual.Model, arch::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.setup!","page":"The Compiler","title":"ToQUBO.Compiler.setup!","text":"setup!(model::Virtual.Model, ::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#Parsing","page":"The Compiler","title":"Parsing","text":"","category":"section"},{"location":"booklet/6-compiler/","page":"The Compiler","title":"The Compiler","text":"ToQUBO.Compiler.parse!\nToQUBO.Compiler._parse","category":"page"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.parse!","page":"The Compiler","title":"ToQUBO.Compiler.parse!","text":"parse!(\n model::Virtual.Model{T},\n g::PBO.PBF{VI,T},\n f::MOI.AbstractFunction,\n arch::AbstractArchitecture\n) where {T}\n\nParses the given MOI function f into PBF g.\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler._parse","page":"The Compiler","title":"ToQUBO.Compiler._parse","text":"\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#Reformulation","page":"The Compiler","title":"Reformulation","text":"","category":"section"},{"location":"booklet/6-compiler/","page":"The Compiler","title":"The Compiler","text":"ToQUBO.Compiler.sense!\nToQUBO.Compiler.variable!\nToQUBO.Compiler.variables!\nToQUBO.Compiler.constraint\nToQUBO.Compiler.constraints!\nToQUBO.Compiler.objective!\nToQUBO.Compiler.penalties!","category":"page"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.sense!","page":"The Compiler","title":"ToQUBO.Compiler.sense!","text":"sense!(model::Virtual.Model, ::AbstractArchitecture)\n\nCopies MOI.ObjectiveSense from model.source_model to model.target_model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.variable!","page":"The Compiler","title":"ToQUBO.Compiler.variable!","text":"variable!(model::Virtual.Model{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.variables!","page":"The Compiler","title":"ToQUBO.Compiler.variables!","text":"variables!(model::Virtual.Model{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.constraint","page":"The Compiler","title":"ToQUBO.Compiler.constraint","text":"constraint\n\nReturns the pseudo-boolean function associated to a given constraint from the source model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.constraints!","page":"The Compiler","title":"ToQUBO.Compiler.constraints!","text":"constraints!(model::Virtual.Model, ::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.objective!","page":"The Compiler","title":"ToQUBO.Compiler.objective!","text":"objective!(model::Virtual.Model, ::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.penalties!","page":"The Compiler","title":"ToQUBO.Compiler.penalties!","text":"penalties!(model::Virtual.Model, arch::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#Copying","page":"The Compiler","title":"Copying","text":"","category":"section"},{"location":"booklet/6-compiler/","page":"The Compiler","title":"The Compiler","text":"ToQUBO.Compiler.isqubo\nToQUBO.Compiler.copy!","category":"page"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.isqubo","page":"The Compiler","title":"ToQUBO.Compiler.isqubo","text":"isqubo(model::MOI.ModelLike)\n\nTells if a given model is ready to be interpreted as a QUBO model.\n\nFor it to be true, a few conditions must be met:\n\nAll variables must be binary (MOI.VariableIndex ∈ MOI.ZeroOne)\nNo other constraints are allowed\nThe objective function must be of type MOI.ScalarQuadraticFunction, MOI.ScalarAffineFunction or MOI.VariableIndex\nThe objective sense must be either MOI.MIN_SENSE or MOI.MAX_SENSE\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.copy!","page":"The Compiler","title":"ToQUBO.Compiler.copy!","text":"copy!(model::Virtual.Model, arch::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#Hamiltonian-Assembly","page":"The Compiler","title":"Hamiltonian Assembly","text":"","category":"section"},{"location":"booklet/6-compiler/","page":"The Compiler","title":"The Compiler","text":"ToQUBO.Compiler.build!\nToQUBO.Compiler.quadratize!","category":"page"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.build!","page":"The Compiler","title":"ToQUBO.Compiler.build!","text":"build!(model::Virtual.Model, arch::AbstractArchitecture)\n\n\n\n\n\n","category":"function"},{"location":"booklet/6-compiler/#ToQUBO.Compiler.quadratize!","page":"The Compiler","title":"ToQUBO.Compiler.quadratize!","text":"quadratize!(model::Virtual.Model, arch::AbstractArchitecture)\n\nQuadratizes the objective function from a model.\n\n\n\n\n\n","category":"function"},{"location":"manual/1-start/#Manual","page":"Getting Started","title":"Manual","text":"","category":"section"},{"location":"manual/1-start/#Quick-Start-Guide","page":"Getting Started","title":"Quick Start Guide","text":"","category":"section"},{"location":"manual/1-start/","page":"Getting Started","title":"Getting Started","text":"using JuMP\nusing ToQUBO\nusing DWave\n\nmodel = Model(() -> ToQUBO.Optimizer(DWave.Neal.Optimizer))\n\n@variable(model, x[1:3], Bin)\n\n@objective(model, Max, 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3])\n\n@constraint(model, 0.3 * x[1] + 0.5 * x[2] + 1.0 * x[3] <= 1.6)\n\noptimize!(model)\n\nsolution_summary(model)","category":"page"},{"location":"manual/1-start/#Table-of-Contents","page":"Getting Started","title":"Table of Contents","text":"","category":"section"},{"location":"manual/1-start/","page":"Getting Started","title":"Getting Started","text":"Pages = [\"2-model.md\", \"3-results.md\", \"4-settings.md\"]\nDepth = 2","category":"page"},{"location":"booklet/2-qubo/#QUBO","page":"QUBO","title":"QUBO","text":"","category":"section"},{"location":"booklet/2-qubo/#Definition","page":"QUBO","title":"Definition","text":"","category":"section"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"Quadratic Unconstrained Binary Optimization, as the name suggests, refers to the global minimization or maximization of a quadratic polynomial on binary variables. A common presentation, the quadratic matrix form, is written as","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"beginarrayrl\n min_mathbfx mathbfx Qmathbfx \n textrmst mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"where Q in mathbbR^n times n is symmetric and mathbbB = lbrace0 1rbrace. Note that, since x^2 = x holds for x in mathbbB, the linear terms of the objective function are stored in the main diagonal of Q.","category":"page"},{"location":"booklet/2-qubo/#OK,-but-why-QUBO?","page":"QUBO","title":"OK, but why QUBO?","text":"","category":"section"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"Mathematically speaking, there is a notorious equivalence between QUBO and Max-Cut problems, e.g. for every QUBO instance there is an information preserving Max-Cut reformulation and vice versa. This statement is followed by two immediate implications:","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"In the general case, solving QUBO globally is NP-Hard.\nIt is a simple yet expressive mathematical programming framework.","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"Implication 1. tells us that such problems are computationally intractable and that heuristics and metaheuristics are to be employed instead of exact methods. No 2. relates to the fact that we are able to represent many other optimization models by means of the QUBO formalism.","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"The Ising Model, on the other hand, is a mathematical abstraction to describe statistical interactions within mechanical systems with interesting properties for encoding combinatorial problems. Its Hamiltonian leads to an optimization formulation in terms of the spin values of their states, given by","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"beginarrayrl\n min_mathbfs mathbfhmathbfs + mathbfs Jmathbfs \n textrmst mathbfs in lbrace-1+1rbrace^n\nendarray","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"with strictly upper triangular J in mathbbR^n times n and mathbfh in mathbbR.","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"(Image: D-Wave Washington 1000Q)","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"The Ising reformulation alternative draws the bridge between QUBO problems and devices designed to sample global or approximate ground states of the Ising Hamiltonian with high probability[Mohseni2022]. Some of the paradigms that stand out in this context are quantum gate-based optimization algorithms (QAOA and VQE), quantum annealers, hardware-accelerated platforms (Coherent Ising Machines and Simulated Bifurcation Machines) and physics-inspired methods (Simulated Annealing, Parallel Tempering). The significant advances in these computing systems contributed to the growing popularity of the model across the literature.","category":"page"},{"location":"booklet/2-qubo/","page":"QUBO","title":"QUBO","text":"[Mohseni2022]: Mohseni, N., McMahon, P. L. & Byrnes, T. Ising machines as hardware solvers of combinatorial optimization problems. Nat Rev Phys 4, 363–379 (2022). {arXiv}","category":"page"},{"location":"booklet/8-appendix/#Appendix","page":"Appendix","title":"Appendix","text":"","category":"section"},{"location":"booklet/8-appendix/#ToQUBO.jl's-Assets","page":"Appendix","title":"ToQUBO.jl's Assets","text":"","category":"section"},{"location":"booklet/8-appendix/#Logo","page":"Appendix","title":"Logo","text":"","category":"section"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"The ideia behind ToQUBO.jl's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo[1], the translation for cube.","category":"page"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"(Image: ToQUBO.jl Logo)","category":"page"},{"location":"booklet/8-appendix/#Colors","page":"Appendix","title":"Colors","text":"","category":"section"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"The colors were picked according to Julia's Reference for logo graphics[2]. Text color matches the innermost shape and renders fairly well in both light and dark background themes.","category":"page"},{"location":"booklet/8-appendix/#Typography","page":"Appendix","title":"Typography","text":"","category":"section"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"The MADETYPE Sunflower[3] font was chosen. It was converted to a SVG path using the Google Font to Svg Path[4] online tool.","category":"page"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"[1]: IPA: [ˈkubʊ]","category":"page"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"[2]: github.com/JuliaLang/julia-logo-graphics","category":"page"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"[3]: Licensed by the authors for use in this project","category":"page"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"[4]: danmarshall.github.io/google-font-to-svg-path","category":"page"},{"location":"booklet/8-appendix/#Web-Icon-![ToQUBO.jl-Icon](../assets/favicon.ico)","page":"Appendix","title":"Web Icon (Image: ToQUBO.jl Icon)","text":"","category":"section"},{"location":"booklet/8-appendix/","page":"Appendix","title":"Appendix","text":"The icon used to decorate the documentation resembles an assembled version of the cube with its blue face making up the background.","category":"page"},{"location":"booklet/7-solvers/#QUBO-Solvers","page":"Solvers","title":"QUBO Solvers","text":"","category":"section"},{"location":"booklet/7-solvers/#Solvers,-Annealers-and-Samplers","page":"Solvers","title":"Solvers, Annealers & Samplers","text":"","category":"section"},{"location":"booklet/7-solvers/","page":"Solvers","title":"Solvers","text":"ToQUBO.jl's main goal is to make use of parameterized stochastic optimization solvers, particularly those relying on non-conventional hardware such as Quantum Annealing and other Ising Machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO.jl via the QUBODrivers.jl companion package. Some of them are presented below.","category":"page"},{"location":"booklet/7-solvers/#Simulated-Annealing","page":"Solvers","title":"Simulated Annealing","text":"","category":"section"},{"location":"booklet/7-solvers/","page":"Solvers","title":"Solvers","text":"Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configurations you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and research due to its robustness, simplicity and ease of use. The DWave.jl's DWave.Neal module uses QUBODrivers.jl to deliver an interface to this sampler.","category":"page"},{"location":"booklet/7-solvers/#Quantum-Annealing","page":"Solvers","title":"Quantum Annealing","text":"","category":"section"},{"location":"booklet/7-solvers/","page":"Solvers","title":"Solvers","text":"Interfacing with D-Wave's quantum annealer is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi, FICO® Xpress and IBM® CPLEX®, this requires licensing and extra steps are needed to get an access token. In a first moment, for those willing to get started, the DWave.Neal optimizer might be enough to learn the ropes.","category":"page"},{"location":"booklet/7-solvers/#Random-Sampling","page":"Solvers","title":"Random Sampling","text":"","category":"section"},{"location":"booklet/7-solvers/","page":"Solvers","title":"Solvers","text":"This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias 0 le p le 1, which defaults to p = 05. After running the using QUBODrivers command, RandomSampler.Optimizer will be available.","category":"page"},{"location":"booklet/7-solvers/#Exact-Solver-(Exhaustive-Enumeration)","page":"Solvers","title":"Exact Solver (Exhaustive Enumeration)","text":"","category":"section"},{"location":"booklet/7-solvers/","page":"Solvers","title":"Solvers","text":"Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with at most approxeq 20 variables should be provided since visiting 2^20 approxeq 10^6 states can already take up to a few seconds.","category":"page"},{"location":"booklet/7-solvers/#Mixed-Integer-Quadratic-Programming","page":"Solvers","title":"Mixed-Integer Quadratic Programming","text":"","category":"section"},{"location":"booklet/7-solvers/","page":"Solvers","title":"Solvers","text":"The most accessible alternative to the forementioned methods are Mixed-Integer Quadratic Programming (MIQP) solvers such as Gurobi, CPLEX, SCIP and BARON. These are not intended to be of regular use alongside ToQUBO.jl since providing a QUBO reformulation will usually make things harder for non-specialized solvers. Yet, there are still a few cases where they may be suitable, such as tests, benchmarks, or any other situation where global optimality is a must.","category":"page"},{"location":"manual/2-model/#Running-a-Model","page":"Running a Model","title":"Running a Model","text":"","category":"section"},{"location":"manual/2-model/","page":"Running a Model","title":"Running a Model","text":"warning: Work in progress\nWe hope to write this part of the documentation soon. Please come back later!","category":"page"},{"location":"booklet/5-virtual/#Virtual-Mapping","page":"Virtual Mapping","title":"Virtual Mapping","text":"","category":"section"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.","category":"page"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.","category":"page"},{"location":"booklet/5-virtual/#Virtual-Model","page":"Virtual Mapping","title":"Virtual Model","text":"","category":"section"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"ToQUBO.Virtual.Model","category":"page"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.Model","page":"Virtual Mapping","title":"ToQUBO.Virtual.Model","text":"Model{T}(optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing) where {T}\n\nThis Virtual Model links the final QUBO formulation to the original one, allowing variable value retrieving and other features.\n\n\n\n\n\n","category":"type"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"ToQUBO.Virtual.source\nToQUBO.Virtual.target","category":"page"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.source","page":"Virtual Mapping","title":"ToQUBO.Virtual.source","text":"source\n\n\n\n\n\n","category":"function"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.target","page":"Virtual Mapping","title":"ToQUBO.Virtual.target","text":"target\n\n\n\n\n\n","category":"function"},{"location":"booklet/5-virtual/#Virtual-Variables","page":"Virtual Mapping","title":"Virtual Variables","text":"","category":"section"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"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 encoding information for later expansion and evaluation.","category":"page"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"ToQUBO.Virtual.Variable","category":"page"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.Variable","page":"Virtual Mapping","title":"ToQUBO.Virtual.Variable","text":"Variable{T}\n\n\n\n\n\n","category":"type"},{"location":"booklet/5-virtual/","page":"Virtual Mapping","title":"Virtual Mapping","text":"ToQUBO.Virtual.encoding\nToQUBO.Virtual.expansion\nToQUBO.Virtual.penaltyfn","category":"page"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.encoding","page":"Virtual Mapping","title":"ToQUBO.Virtual.encoding","text":"encoding\n\n\n\n\n\n","category":"function"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.expansion","page":"Virtual Mapping","title":"ToQUBO.Virtual.expansion","text":"expansion\n\n\n\n\n\n","category":"function"},{"location":"booklet/5-virtual/#ToQUBO.Virtual.penaltyfn","page":"Virtual Mapping","title":"ToQUBO.Virtual.penaltyfn","text":"penaltyfn\n\n\n\n\n\n","category":"function"},{"location":"#ToQUBO.jl-Documentation","page":"Home","title":"ToQUBO.jl Documentation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ToQUBO.jl is a Julia Package intended to automatically translate models written in JuMP, into the QUBO mathematical optimization framework.","category":"page"},{"location":"#Quick-Start","page":"Home","title":"Quick Start","text":"","category":"section"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"julia> import Pkg\n\njulia> Pkg.add(\"ToQUBO\")","category":"page"},{"location":"#Example","page":"Home","title":"Example","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using JuMP\nusing ToQUBO\nusing DWave\n\nmodel = Model(() -> ToQUBO.Optimizer(DWave.Neal.Optimizer))\n\n@variable(model, x[1:3], Bin)\n@objective(model, Max, 1.0*x[1] + 2.0*x[2] + 3.0*x[3])\n@constraint(model, 0.3*x[1] + 0.5*x[2] + 1.0*x[3] <= 1.6)\n\noptimize!(model)\n\nsolution_summary(model)","category":"page"},{"location":"#Citing-ToQUBO.jl","page":"Home","title":"Citing ToQUBO.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:","category":"page"},{"location":"","page":"Home","title":"Home","text":"@software{toqubo:2023,\n author = {Pedro Maciel Xavier and Pedro Ripper and Tiago Andrade and Joaquim Dias Garcia and David E. Bernal Neira},\n title = {{ToQUBO.jl}},\n month = {feb},\n year = {2023},\n publisher = {Zenodo},\n version = {v0.1.5},\n doi = {10.5281/zenodo.7644291},\n url = {https://doi.org/10.5281/zenodo.7644291}\n}","category":"page"},{"location":"examples/integer_factorization/#Prime-Factorization","page":"Integer Factorization","title":"Prime Factorization","text":"","category":"section"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"A central problem in Number Theory and cryptography is to factor R in mathbbN, which is known to be the product of two distinct prime numbers p q in mathbbN. Shor's 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.","category":"page"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"A naïve approach to model this problem can be stated as a quadratically-constrained integer program:","category":"page"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"beginarrayrl\ntextst p times q = R \n p q ge 0 \n p q in mathbbZ\nendarray","category":"page"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"From the definition and the basics of number theory, we are able to retrieve a few assumptions about the problem's variables:","category":"page"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"p and q are bounded to the interval left1 Rright\nMoreover, it is fine to assume 1 p le sqrtR le q le R div 2.","category":"page"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"using JuMP\nusing ToQUBO\nusing DWave\n\nfunction factor(R::Integer; optimizer = DWave.Neal.Optimizer)\n return factor(identity, R; optimizer)\nend\n\nfunction factor(config!::Function, R::Integer; optimizer = DWave.Neal.Optimizer)\n model = Model(() -> ToQUBO.Optimizer(optimizer))\n\n @variable(model, 1 <= p <= √R, Int)\n @variable(model, √R <= q <= R ÷ 2, Int)\n\n @constraint(model, p * q == R)\n\n config!(model)\n\n optimize!(model)\n\n p = round(Int, value(model[:p]))\n q = round(Int, value(model[:q]))\n\n return (p, q)\nend","category":"page"},{"location":"examples/integer_factorization/","page":"Integer Factorization","title":"Integer Factorization","text":"p, q = factor(15) do model\n set_optimizer_attribute(model, \"num_reads\", 1_000)\n set_optimizer_attribute(model, \"num_sweeps\", 2_000)\nend\n\nprint(\"$p, $q\")","category":"page"},{"location":"examples/knapsack/#Knapsack","page":"Knapsack","title":"Knapsack","text":"","category":"section"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"We start with some instances of the discrete Knapsack Problem whose standard formulation is","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"beginarrayr l\n max mathbfc mathbfx \n textst mathbfw mathbfx le C \n mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"First, consider the following items","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"Item (i) Value (c_i) Weight (w_i)\n1 1 0.3\n2 2 0.5\n3 3 1.0","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"to be carried in a knapsack with capacity C = 16.","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"Writing down the data above as a linear program, we have","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"beginarrayr l\n max x_1 + 2 x_2 + 3 x_3 \n textst 03 x_1 + 05 x_2 + x_3 le 16 \n mathbfx in mathbbB^3\nendarray","category":"page"},{"location":"examples/knapsack/#Simple-JuMP-Model","page":"Knapsack","title":"Simple JuMP Model","text":"","category":"section"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"Writing this in JuMP we end up with","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"using JuMP\nusing ToQUBO\nusing DWave\n\nmodel = Model(() -> ToQUBO.Optimizer(DWave.Neal.Optimizer))\n\n@variable(model, x[1:3], Bin)\n@objective(model, Max, x[1] + 2 * x[2] + 3 * x[3])\n@constraint(model, 0.3 * x[1] + 0.5 * x[2] + x[3] ≤ 1.6)\n\noptimize!(model)\n\nsolution_summary(model)","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"The final decision is to take items 2 and 3, i.e., x_1 = 0 x_2 = 1 x_3 = 1.","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"value.(x)","category":"page"},{"location":"examples/knapsack/#Using-DataFrames","page":"Knapsack","title":"Using DataFrames","text":"","category":"section"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"Now, lets fill a few more knapsacks. First, we generate uniform random costs mathbfc and weights mathbfw then set the knapsack's capacity C to be a fraction of the total available weight i.e. 80.","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"This example was inspired by D-Wave's knapsack example repository.","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"using CSV\nusing DataFrames\nusing Random\n\n# Generate Data\nrng = MersenneTwister(1)\n\ndf = DataFrame(\n :cost => rand(rng, 1:100, 8),\n :weight => rand(rng, 1:100, 8),\n)\n\nCSV.write(\"knapsack.csv\", df)","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"using CSV\nusing DataFrames\n\ndf = CSV.read(\"knapsack.csv\", DataFrame)","category":"page"},{"location":"examples/knapsack/","page":"Knapsack","title":"Knapsack","text":"using JuMP\nusing ToQUBO\nusing DWave\n\nmodel = Model(() -> ToQUBO.Optimizer(DWave.Neal.Optimizer))\n\nn = size(df, 1)\nc = collect(Float64, df[!, :cost])\nw = collect(Float64, df[!, :weight])\nC = round(0.8 * sum(w))\n\n@variable(model, x[1:n], Bin)\n@objective(model, Max, c' * x)\n@constraint(model, w' * x <= C)\n\noptimize!(model)\n\n# Add Results as a new column\ndf[:,:select] = map(xi -> ifelse(xi > 0, \"✅\", \"❌\"), value.(x))\n\ndf","category":"page"}]
+}
diff --git a/dev/siteinfo.js b/dev/siteinfo.js
new file mode 100644
index 00000000..33434919
--- /dev/null
+++ b/dev/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "dev";
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..1a6cc116
--- /dev/null
+++ b/index.html
@@ -0,0 +1,2 @@
+
+
diff --git a/previews/PR30/assets/README/index.html b/previews/PR30/assets/README/index.html
new file mode 100644
index 00000000..44484f5d
--- /dev/null
+++ b/previews/PR30/assets/README/index.html
@@ -0,0 +1,2 @@
+
+Logo · ToQUBO.jl
The ideia behind ToQUBO's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo¹, the translation for cube.
The colors were chosen according to Julia's Reference for logo graphics². Text color matches the innermost shape and renders fairly well in both light and dark background themes.
This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.
toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:VI}) where {T}
+toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}) where {T}
+toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}) where {T}
Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between quadratic PBFs and QUBO forms.
where each $\Omega\left[{f}\right]$ is the multi-linear representation of $f$ as a set of terms. Each term is given by a unique set of indices $\omega \subseteq \mathbb{S}$ related to some coefficient $c_\omega \in \mathbb{T}$. We say that $\omega \in \Omega\left[{f}\right] \iff c_\omega \neq 0$. Variables $\mathbf{x}_i$ are indeed boolean, thus $f : \mathbb{B}^{n} \to \mathbb{T}$.
References
[1] Endre Boros, Peter L. Hammer, Pseudo-Boolean optimization, Discrete Applied Mathematics, 2002 {doi}
relaxed_gcd(x::T, y::T; tol::T = T(1e-6)) where {T <: AbstractFloat}
We define two real numbers $x$ and $y$ to be $\tau$-comensurable if, for some $\tau > 0$ there exists a continued fractions convergent $p_{k} \div q_{k}$ such that
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.
During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.
This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.
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.
:𝔹 - Used when a boolean variable is to be mirrored.
:ℤ₂ - Binary expansion for integer variable.
:ℤ₁ - Unary expansion for integer variable.
:ℝ₂ - Binary expansion for real variable.
:ℝ₁ - Unary expansion for real variable.
References:
[1] Chancellor, N. (2019). Domain wall encoding of discrete variables for quantum annealing and QAOA. Quantum Science and Technology, 4(4), 045004. {doi}
ToQUBO's main goal is to benefit from non-deterministic samplers, especially Quantum Adiabatic devices and other Annealing machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO via the Anneal.jl submodule and package prototype. Some of them are presented below.
Interfacing with D-Wave's quantum computers is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi and FICO® Xpress, this requires licensing and extra steps are needed to get access to it. In a first moment, for those willing to get started, the Simulated Annealing optimizer might be enough.
While in JuMP, run using Anneal and look for QuantumAnnealer.Optimizer.
Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configuration you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and during early research steps due to its simplicity and ease of use. It does not implement the most advanced Simulated Annealing algorithm available but performs fairly well on small instances. Anneal.jl exports this interface as SimulatedAnnealer.Optimizer.
This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias $0 \le p \le 1$, which defaults to $p = 0.5$. After running the using Anneal command, RandomSampler.Optimizer will be available.
Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with no more than 20 variables should be provided.
The most accessible alternative to Annealers and Samplers are Mixed-Integer Quadratic Programming (MIQP) Solvers such as Gurobi and CPLEX. These are not intended to be of regular use alongside ToQUBO since reformulation usually makes things harder for these folks. Yet, there are still cases where they may be suitable for tests on small instances.
We may now fill a few more knapsacks using JuMP. We will generate uniform random costs $\mathbf{c}$ and weights $\mathbf{w}$ then set the knapsack's capacity $C$ to be a fraction of the total available weight i.e. $80\%$.
If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:
@software{ToQUBO.jl:2022,
+ author = {Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal},
+ title = {ToQUBO.jl},
+ url = {https://github.com/psrenergy/ToQUBO.jl},
+ version = {0.1.0},
+ date = {2022-03-31},
+}
Settings
This document was generated with Documenter.jl version 0.27.15 on Thursday 24 March 2022. Using Julia version 1.6.5.
This document was generated with Documenter.jl version 0.27.15 on Thursday 24 March 2022. Using Julia version 1.6.5.
diff --git a/previews/PR30/search_index.js b/previews/PR30/search_index.js
new file mode 100644
index 00000000..8e2ad60d
--- /dev/null
+++ b/previews/PR30/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Knapsack","page":"Examples","title":"Knapsack","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"We start with some instances of the discrete Knapsack Problem whose standard formulation is","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"beginarrayr l\n max mathbfc mathbfx \n textst mathbfw mathbfx le C \n mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"examples/#MathOptInterface","page":"Examples","title":"MathOptInterface","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Using MOI directly to build a simple model is pretty straightforward. All that one has to do is to use MOI.instantiate and define the model as usual.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"import MathOptInterface as MOI\nconst MOIU = MOI.Utilities\n\nusing ToQUBO\nusing Anneal # <- Your favourite Annealer / Sampler / Solver here\n\n# Example from https://jump.dev/MathOptInterface.jl/stable/tutorials/example/\n\n# Virtual QUBO Model\nmodel = MOI.instantiate(\n () -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer),\n with_bridge_type = Float64,\n)\n\nn = 3;\nc = [1.0, 2.0, 3.0]\nw = [0.3, 0.5, 1.0]\nC = 3.2;\n\n# -*- Variables -*- #\nx = MOI.add_variables(model, n);\n\n# -*- Objective -*- #\nMOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)\n\nMOI.set(\n model,\n MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),\n MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0),\n);\n\n# -*- Constraints -*- #\nMOI.add_constraint(\n model,\n MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(w, x), 0.0),\n MOI.LessThan(C),\n);\n\nfor xᵢ in x\n MOI.add_constraint(model, xᵢ, MOI.ZeroOne())\nend\n\n# Run!\nMOI.optimize!(model)\n\n# Collect Solution\nMOI.get(model, MOI.VariablePrimal(), x)","category":"page"},{"location":"examples/#JuMP-D-Wave-Examples","page":"Examples","title":"JuMP + D-Wave Examples","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"We may now fill a few more knapsacks using JuMP. We will generate uniform random costs mathbfc and weights mathbfw then set the knapsack's capacity C to be a fraction of the total available weight i.e. 80.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This example was inspired by D-Wave's knapsack example repository.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using CSV\nusing DataFrames\nusing Random\n\n# -> Generate Data <-\nrng = MersenneTwister(1)\n\ndf = DataFrame(\n :cost => rand(rng, 1:100, 16),\n :weight => rand(rng, 1:100, 16),\n)\n\nCSV.write(\"knapsack.csv\", df)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using CSV\nusing DataFrames\n\ndf = CSV.read(\"knapsack.csv\", DataFrame)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using JuMP\nusing ToQUBO\nusing Anneal # <- Your favourite Annealer / Sampler / Solver here\n\n# -> Model <-\nmodel = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))\n\nn = size(df, 1)\nc = collect(Float64, df[!, :cost])\nw = collect(Float64, df[!, :weight])\nC = round(0.8 * sum(w))\n\n# -> Variables <-\n@variable(model, x[i=1:n], Bin)\n\n# -> Objective <-\n@objective(model, Max, c' * x)\n\n# -> Constraint <-\n@constraint(model, w' * x <= C)\n\n# ->-> Run! ->->\noptimize!(model)\n\n# Add Results as a new column\ninsertcols!(\n df,\n 3, \n :select => map(\n (ξ) -> (ξ > 0.0) ? \"Yes\" : \"No\",\n value.(x),\n ),\n)","category":"page"},{"location":"manual/#Manual","page":"Manual","title":"Manual","text":"","category":"section"},{"location":"manual/#Quick-Start-Guide","page":"Manual","title":"Quick Start Guide","text":"","category":"section"},{"location":"manual/","page":"Manual","title":"Manual","text":"using JuMP\nusing ToQUBO\nusing Anneal\n\nmodel = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))\n\n@variable(model, x[1:3], Bin)\n@objective(model, Max, 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3])\n@constraint(model, 0.3 * x[1] + 0.5 * x[2] + 1.0 * x[3] <= 3.2)\n\noptimize!(model)\n\nsolution_summary(model)","category":"page"},{"location":"#ToQUBO.jl-Documentation","page":"Home","title":"ToQUBO.jl Documentation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ToQUBO.jl is a Julia Package intended to automatically translate models written in JuMP, into the QUBO mathematical optimization framework.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"#**Pre-release-note:**","page":"Home","title":"Pre-release note:","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This project is not yet available through Julia's package manager. Thus, it is still necessary to clone ToQUBO.jl from its GitHub repo.","category":"page"},{"location":"","page":"Home","title":"Home","text":"$ git clone https://github.com/psrenergy/ToQUBO.jl\n$ cd ToQUBO.jl\n$ julia --project=.","category":"page"},{"location":"","page":"Home","title":"Home","text":"To use the Anneal.jl submodule, it will be necessary to run","category":"page"},{"location":"","page":"Home","title":"Home","text":"(ToQUBO) pkg> dev .\\\\src\\\\Anneal.jl","category":"page"},{"location":"","page":"Home","title":"Home","text":"on Julia's REPL beforehand.","category":"page"},{"location":"#Citing-ToQUBO.jl","page":"Home","title":"Citing ToQUBO.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:","category":"page"},{"location":"","page":"Home","title":"Home","text":"@software{ToQUBO.jl:2022,\n author = {Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal},\n title = {ToQUBO.jl},\n url = {https://github.com/psrenergy/ToQUBO.jl},\n version = {0.1.0},\n date = {2022-03-31},\n}","category":"page"},{"location":"booklet/#ToQUBO.jl-Booklet","page":"Booklet","title":"ToQUBO.jl Booklet","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.","category":"page"},{"location":"booklet/#QUBO","page":"Booklet","title":"QUBO","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"beginarrayrl\n min mathbfx^intercal Qmathbfx \n textst mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.isqubo\nToQUBO.toqubo\nToQUBO.toqubo!","category":"page"},{"location":"booklet/#ToQUBO.isqubo","page":"Booklet","title":"ToQUBO.isqubo","text":"isqubo(model::MOI.ModelLike)\n\nTells if a given model is ready to be interpreted as a QUBO model.\n\nFor it to be true, a few conditions must be met:\n\nAll variables must be binary (MOI.VariableIndex ∈ MOI.ZeroOne)\nNo other constraints are allowed\nThe objective function must be of type MOI.ScalarQuadraticFunction, MOI.ScalarAffineFunction or MOI.VariableIndex\nThe objective sense must be either MOI.MIN_SENSE or MOI.MAX_SENSE\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo","page":"Booklet","title":"ToQUBO.toqubo","text":"toqubo(T::Type, source::MOI.ModelLike, optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing)\ntoqubo(source::MOI.ModelLike, optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing)\n\nLow-level interface to create a ::VirtualQUBOModel{T} from ::MOI.ModelLike instance. If provided, an ::MOI.AbstractOptimizer is attached to the model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo!","page":"Booklet","title":"ToQUBO.toqubo!","text":"toqubo!(model::VirtualQUBOModel{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.toqubo_sense!\nToQUBO.toqubo_variables!\nToQUBO.toqubo_constraint!\nToQUBO.toqubo_objective!","category":"page"},{"location":"booklet/#ToQUBO.toqubo_sense!","page":"Booklet","title":"ToQUBO.toqubo_sense!","text":"toqubo_sense!(model::VirtualQUBOModel)\n\nCopies MOI.ObjectiveSense from model.source_model to model.target_model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_variables!","page":"Booklet","title":"ToQUBO.toqubo_variables!","text":"toqubo_variables!(model::VirtualQUBOModel{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_constraint!","page":"Booklet","title":"ToQUBO.toqubo_constraint!","text":"toqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}, S::Type{<:EQ{T}}) where {T}\ntoqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}, S::Type{<:LT{T}}) where {T}\ntoqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}, S::Type{<:EQ{T}}) where {T}\ntoqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}, S::Type{<:LT{T}}) where {T}\ntoqubo_constraint!(::VirtualQUBOModel{T}, ::Type{<:VI}, ::Type{<:Union{MOI.ZeroOne, MOI.Integer, MOI.Interval{T}, MOI.LessThan{T}, MOI.GreaterThan{T}}}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_objective!","page":"Booklet","title":"ToQUBO.toqubo_objective!","text":"toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:VI}) where {T}\ntoqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}) where {T}\ntoqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Pseudo-Boolean-Optimization","page":"Booklet","title":"Pseudo-Boolean Optimization","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between quadratic PBFs and QUBO forms.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.PBO.PseudoBooleanFunction\nToQUBO.PBO.residual\nToQUBO.PBO.derivative\nToQUBO.PBO.gradient\nToQUBO.PBO.gap\nToQUBO.PBO.sharpness\nToQUBO.PBO.discretize\nToQUBO.PBO.relaxed_gcd","category":"page"},{"location":"booklet/#ToQUBO.PBO.PseudoBooleanFunction","page":"Booklet","title":"ToQUBO.PBO.PseudoBooleanFunction","text":"PseudoBooleanFunction{S, T}(c::T)\nPseudoBooleanFunction{S, T}(ps::Pair{Vector{S}, T}...)\n\nA Pseudo-Boolean Function f in mathscrF over some field mathbbT takes the form\n\nf(mathbfx) = sum_omega in Omegaleftfright c_omega prod_j in omega mathbbx_j\n\nwhere each Omegaleftfright is the multi-linear representation of f as a set of terms. Each term is given by a unique set of indices omega subseteq mathbbS related to some coefficient c_omega in mathbbT. We say that omega in Omegaleftfright iff c_omega neq 0. Variables mathbfx_i are indeed boolean, thus f mathbbB^n to mathbbT.\n\nReferences\n\n[1] Endre Boros, Peter L. Hammer, Pseudo-Boolean optimization, Discrete Applied Mathematics, 2002 {doi}\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.PBO.residual","page":"Booklet","title":"ToQUBO.PBO.residual","text":"residual(f::PBF{S, T}, i::S) where {S, T}\nresidual(f::PBF{S, T}, i::Int) where {S, T}\n\nThe residual of function f in mathscrF with respect to the i-th variable.\n\n Theta_i f(mathbfx) = f(mathbfx) - mathbfx_i Delta_i f(mathbfx) =\n sum_omega in Omegaleftfright setminus leftiright\n c_omega prod_k in omega mathbfx_k\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.derivative","page":"Booklet","title":"ToQUBO.PBO.derivative","text":"derivative(f::PBF{S, T}, i::S) where {S, T}\nderivative(f::PBF{S, T}, i::Int) where {S, T}\n\nThe partial derivate of function f in mathscrF with respect to the i-th variable.\n\n Delta_i f(mathbfx) = fracpartial f(mathbfx)partial mathbfx_i =\n sum_omega in Omegaleftfright setminus leftiright\n c_omega cup leftiright prod_k in omega mathbfx_k\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.gradient","page":"Booklet","title":"ToQUBO.PBO.gradient","text":"gradient(f::PBF)\n\nComputes the gradient of f in mathscrF where the i-th derivative is given by derivative.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.gap","page":"Booklet","title":"ToQUBO.PBO.gap","text":"gap(f::PBF{S, T}; bound::Symbol=:loose) where {S, T}\n\nComputes the least upper bound for the greatest variantion possible under some f in mathscrF i. e.\n\nbeginarrayr l\n min M \n textst leftf(mathbfx) - f(mathbfy)right le M forall mathbfx mathbfy in mathbbB^n \nendarray\n\nA simple approach, avaiable using the bound=:loose parameter, is to define\n\nM triangleq sum_omega neq varnothing leftc_omegaright\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.sharpness","page":"Booklet","title":"ToQUBO.PBO.sharpness","text":"sharpness(f::PBF{S, T}; bound::Symbol=:loose, tol::T = T(1e-6)) where {S, T<:AbstractFloat}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.discretize","page":"Booklet","title":"ToQUBO.PBO.discretize","text":"discretize(f::PBF{S, T}; tol::T) where {S, T}\n\nFor a given function f in mathscrF written as\n\n fleft(mathbfxright) = sum_omega in Omegaleftfright c_omega prod_i in omega mathbfx_i\n\ncomputes an approximate function g mathbbB^n to mathbbZ such that\n\n argmin_mathbfx in mathbbB^n gleft(mathbfxright) = argmin_mathbfx in mathbbB^n fleft(mathbfxright)\n\nThis is done by rationalizing every coefficient c_omega according to some tolerance tol.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.relaxed_gcd","page":"Booklet","title":"ToQUBO.PBO.relaxed_gcd","text":"relaxed_gcd(x::T, y::T; tol::T = T(1e-6)) where {T <: AbstractFloat}\n\nWe define two real numbers x and y to be tau-comensurable if, for some tau 0 there exists a continued fractions convergent p_k div q_k such that\n\n left q_k x - p_k y right le tau\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Quadratization","page":"Booklet","title":"Quadratization","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"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.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.PBO.quadratize\nToQUBO.PBO.@quadratization","category":"page"},{"location":"booklet/#ToQUBO.PBO.quadratize","page":"Booklet","title":"ToQUBO.PBO.quadratize","text":"quadratize(f::PBF{S, T}; slack::Any) where {S, T}\n\nQuadratizes a given PBF, i.e. creates a function g in mathscrF^2 from f in mathscrF^k k ge 3.\n\nA function f 2^S to mathbbR is said to be submodular if\n\nf(X cup Y) + f(X cap Y) le f(X) + f(Y) forall X Y subset S\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.@quadratization","page":"Booklet","title":"ToQUBO.PBO.@quadratization","text":"@quadratization(name, nsv, nst)\n\nDefines a new quadratization technique.\n\n\n\n\n\n","category":"macro"},{"location":"booklet/#Virtual-Mapping","page":"Booklet","title":"Virtual Mapping","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.","category":"page"},{"location":"booklet/#Virtual-Variables","page":"Booklet","title":"Virtual Variables","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"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.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.VirtualMapping.VirtualVariable\nToQUBO.VirtualMapping.mapvar!\nToQUBO.VirtualMapping.expandℝ!\nToQUBO.VirtualMapping.slackℝ!\nToQUBO.VirtualMapping.expandℤ!\nToQUBO.VirtualMapping.slackℤ!\nToQUBO.VirtualMapping.mirror𝔹!\nToQUBO.VirtualMapping.slack𝔹!","category":"page"},{"location":"booklet/#ToQUBO.VirtualMapping.VirtualVariable","page":"Booklet","title":"ToQUBO.VirtualMapping.VirtualVariable","text":"VirtualVariable{S, T}(\n newvar::Function,\n source::Union{S, Nothing};\n bits::Union{Int, Nothing},\n tech::Symbol,\n name::Union{Symbol, Nothing}=nothing,\n α::T=zero(T),\n β::T=one(T)\n) where {S, T}\n\nThe Virtual Variable Mapping\n\nVariable Expansion techniques:\n\n:𝔹 - Used when a boolean variable is to be mirrored.\n:ℤ₂ - Binary expansion for integer variable.\n:ℤ₁ - Unary expansion for integer variable.\n:ℝ₂ - Binary expansion for real variable.\n:ℝ₁ - Unary expansion for real variable.\n\nReferences:\n\n[1] Chancellor, N. (2019). Domain wall encoding of discrete variables for quantum annealing and QAOA. Quantum Science and Technology, 4(4), 045004. {doi}\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.VirtualMapping.mapvar!","page":"Booklet","title":"ToQUBO.VirtualMapping.mapvar!","text":"mapvar!(model::AbstractVirtualModel{T}, v::VirtualMOIVariable{T}) where {T}\n\nMaps newly created virtual variable v within the virtual model structure. It follows these steps:\n\nMaps v's source to it in the model's source mapping.\nFor every one of v's targets, maps it to itself and adds a binary constraint to it.\nAdds v to the end of the model's varvec. \n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.expandℝ!","page":"Booklet","title":"ToQUBO.VirtualMapping.expandℝ!","text":"expandℝ!(model::QUBOModel{T}, src::VI; bits::Int, name::Symbol, α::T, β::T, semi::Bool) where T\n\nReal Binary Expansion within the closed interval alpha beta.\n\nFor a given variable x in alpha beta we approximate it by\n\nx approx alpha + frac(beta - alpha)2^n - 1 sum_i=0^n-1 2^i y_i\n\nwhere n is the number of bits and y_i in mathbbB.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.slackℝ!","page":"Booklet","title":"ToQUBO.VirtualMapping.slackℝ!","text":"slackℝ!(model::AbstractVirtualModel{T}; name::Symbol, α::T, β::T, semi::Bool) where T\n\nAdds real slack variable according to expandℝ!'s expansion method.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.expandℤ!","page":"Booklet","title":"ToQUBO.VirtualMapping.expandℤ!","text":"expandℤ!(model::QUBOModel{T}, src::VI; name::Symbol, α::T, β::T, semi::Bool) where T\n\nInteger Binary Expansion within the closed interval leftlceilalpharightrceil leftlfloorbetarightrfloor.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.slackℤ!","page":"Booklet","title":"ToQUBO.VirtualMapping.slackℤ!","text":"slackℤ!(model::AbstractVirtualModel{T}; name::Symbol, α::T, β::T) where {T}\n\nAdds integer slack variable according to expandℤ!'s expansion method.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.mirror𝔹!","page":"Booklet","title":"ToQUBO.VirtualMapping.mirror𝔹!","text":"mirror𝔹!(model::AbstractVirtualModel{T}, src::Union{VI, Nothing}; name::Symbol) where T\n\nSimply crates a virtual-mapped Doppelgänger into the destination model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.slack𝔹!","page":"Booklet","title":"ToQUBO.VirtualMapping.slack𝔹!","text":"slack𝔹!(model::AbstractVirtualModel{T}; name::Symbol) where {T}\n\nAdds a binary slack variable to the model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Virtual-Models","page":"Booklet","title":"Virtual Models","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.VirtualMapping.AbstractVirtualModel\nToQUBO.VirtualQUBOModel","category":"page"},{"location":"booklet/#ToQUBO.VirtualMapping.AbstractVirtualModel","page":"Booklet","title":"ToQUBO.VirtualMapping.AbstractVirtualModel","text":"abstract type AbstractVirtualModel{T} <: MOI.AbstractOptimizer end\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.VirtualQUBOModel","page":"Booklet","title":"ToQUBO.VirtualQUBOModel","text":"VirtualQUBOModel{T}(optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing) where {T}\n\nThis QUBO Virtual Model links the final QUBO formulation to the original one, allowing variable value retrieving and other features.\n\n\n\n\n\n","category":"type"},{"location":"booklet/#Annealing-and-Sampling","page":"Booklet","title":"Annealing & Sampling","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO's main goal is to benefit from non-deterministic samplers, especially Quantum Adiabatic devices and other Annealing machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO via the Anneal.jl submodule and package prototype. Some of them are presented below.","category":"page"},{"location":"booklet/#Quantum-Annealing","page":"Booklet","title":"Quantum Annealing","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Interfacing with D-Wave's quantum computers is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi and FICO® Xpress, this requires licensing and extra steps are needed to get access to it. In a first moment, for those willing to get started, the Simulated Annealing optimizer might be enough.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"While in JuMP, run using Anneal and look for QuantumAnnealer.Optimizer.","category":"page"},{"location":"booklet/#Simulated-Annealing","page":"Booklet","title":"Simulated Annealing","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configuration you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and during early research steps due to its simplicity and ease of use. It does not implement the most advanced Simulated Annealing algorithm available but performs fairly well on small instances. Anneal.jl exports this interface as SimulatedAnnealer.Optimizer.","category":"page"},{"location":"booklet/#Random-Sampling","page":"Booklet","title":"Random Sampling","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias 0 le p le 1, which defaults to p = 05. After running the using Anneal command, RandomSampler.Optimizer will be available.","category":"page"},{"location":"booklet/#Exact-Solver-(Exaustive-Enumeration)","page":"Booklet","title":"Exact Solver (Exaustive Enumeration)","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with no more than 20 variables should be provided.","category":"page"},{"location":"booklet/#MIQP-Solvers","page":"Booklet","title":"MIQP Solvers","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"The most accessible alternative to Annealers and Samplers are Mixed-Integer Quadratic Programming (MIQP) Solvers such as Gurobi and CPLEX. These are not intended to be of regular use alongside ToQUBO since reformulation usually makes things harder for these folks. Yet, there are still cases where they may be suitable for tests on small instances.","category":"page"},{"location":"booklet/#Custom-Error-Types","page":"Booklet","title":"Custom Error Types","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.QUBOError","category":"page"},{"location":"booklet/#ToQUBO.QUBOError","page":"Booklet","title":"ToQUBO.QUBOError","text":"QUBOError(msg::Union{Nothing, String})\n\nThis error indicates any failure during QUBO formulation\n\n\n\n\n\n","category":"type"},{"location":"assets/README/#Logo","page":"Logo","title":"Logo","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The ideia behind ToQUBO's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo¹, the translation for cube.","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"(Image: ToQUBO.jl)","category":"page"},{"location":"assets/README/#Colors","page":"Logo","title":"Colors","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The colors were chosen according to Julia's Reference for logo graphics². Text color matches the innermost shape and renders fairly well in both light and dark background themes.","category":"page"},{"location":"assets/README/#Typography","page":"Logo","title":"Typography","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"MADETYPE Sunflower³ Font was used. It was converted to a SVG path through the Google Font to Svg Path⁴ online tool.","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"¹ IPA: [ˈkubʊ]","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"² github.com/JuliaLang/julia-logo-graphics","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"³ Licensed by the authors for use in this project","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"⁴ danmarshall.github.io/google-font-to-svg-path","category":"page"},{"location":"assets/README/#Web-Icon-[![ToQUBO.jl](favicon.ico)](/docs/src/assets)","page":"Logo","title":"Web Icon (Image: ToQUBO.jl)","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The icon used to decorate the documentation resembles an assembled version of the cube with its blue face making up the background.","category":"page"}]
+}
diff --git a/previews/PR30/siteinfo.js b/previews/PR30/siteinfo.js
new file mode 100644
index 00000000..2094867d
--- /dev/null
+++ b/previews/PR30/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "previews/PR30";
diff --git a/previews/PR34/assets/README/index.html b/previews/PR34/assets/README/index.html
new file mode 100644
index 00000000..77b04572
--- /dev/null
+++ b/previews/PR34/assets/README/index.html
@@ -0,0 +1,2 @@
+
+Logo · ToQUBO.jl
The ideia behind ToQUBO's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo¹, the translation for cube.
The colors were chosen according to Julia's Reference for logo graphics². Text color matches the innermost shape and renders fairly well in both light and dark background themes.
This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.
toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:VI}) where {T}
+toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}) where {T}
+toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}) where {T}
Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between quadratic PBFs and QUBO forms.
where each $\Omega\left[{f}\right]$ is the multi-linear representation of $f$ as a set of terms. Each term is given by a unique set of indices $\omega \subseteq \mathbb{S}$ related to some coefficient $c_\omega \in \mathbb{T}$. We say that $\omega \in \Omega\left[{f}\right] \iff c_\omega \neq 0$. Variables $\mathbf{x}_i$ are indeed boolean, thus $f : \mathbb{B}^{n} \to \mathbb{T}$.
References
[1] Endre Boros, Peter L. Hammer, Pseudo-Boolean optimization, Discrete Applied Mathematics, 2002 {doi}
relaxed_gcd(x::T, y::T; tol::T = T(1e-6)) where {T <: AbstractFloat}
We define two real numbers $x$ and $y$ to be $\tau$-comensurable if, for some $\tau > 0$ there exists a continued fractions convergent $p_{k} \div q_{k}$ such that
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.
During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.
This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.
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.
:𝔹 - Used when a boolean variable is to be mirrored.
:ℤ₂ - Binary expansion for integer variable.
:ℤ₁ - Unary expansion for integer variable.
:ℝ₂ - Binary expansion for real variable.
:ℝ₁ - Unary expansion for real variable.
References:
[1] Chancellor, N. (2019). Domain wall encoding of discrete variables for quantum annealing and QAOA. Quantum Science and Technology, 4(4), 045004. {doi}
ToQUBO's main goal is to benefit from non-deterministic samplers, especially Quantum Adiabatic devices and other Annealing machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO via the Anneal.jl submodule and package prototype. Some of them are presented below.
Interfacing with D-Wave's quantum computers is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi and FICO® Xpress, this requires licensing and extra steps are needed to get access to it. In a first moment, for those willing to get started, the Simulated Annealing optimizer might be enough.
While in JuMP, run using Anneal and look for QuantumAnnealer.Optimizer.
Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configuration you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and during early research steps due to its simplicity and ease of use. It does not implement the most advanced Simulated Annealing algorithm available but performs fairly well on small instances. Anneal.jl exports this interface as SimulatedAnnealer.Optimizer.
This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias $0 \le p \le 1$, which defaults to $p = 0.5$. After running the using Anneal command, RandomSampler.Optimizer will be available.
Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with no more than 20 variables should be provided.
The most accessible alternative to Annealers and Samplers are Mixed-Integer Quadratic Programming (MIQP) Solvers such as Gurobi and CPLEX. These are not intended to be of regular use alongside ToQUBO since reformulation usually makes things harder for these folks. Yet, there are still cases where they may be suitable for tests on small instances.
We may now fill a few more knapsacks using JuMP. We will generate uniform random costs $\mathbf{c}$ and weights $\mathbf{w}$ then set the knapsack's capacity $C$ to be a fraction of the total available weight i.e. $80\%$.
If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:
@software{ToQUBO.jl:2022,
+ author = {Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal},
+ title = {ToQUBO.jl},
+ url = {https://github.com/psrenergy/ToQUBO.jl},
+ version = {0.1.0},
+ date = {2022-03-31},
+}
Settings
This document was generated with Documenter.jl version 0.27.15 on Friday 8 April 2022. Using Julia version 1.6.6.
This document was generated with Documenter.jl version 0.27.15 on Friday 8 April 2022. Using Julia version 1.6.6.
diff --git a/previews/PR34/search_index.js b/previews/PR34/search_index.js
new file mode 100644
index 00000000..8e2ad60d
--- /dev/null
+++ b/previews/PR34/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Knapsack","page":"Examples","title":"Knapsack","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"We start with some instances of the discrete Knapsack Problem whose standard formulation is","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"beginarrayr l\n max mathbfc mathbfx \n textst mathbfw mathbfx le C \n mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"examples/#MathOptInterface","page":"Examples","title":"MathOptInterface","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Using MOI directly to build a simple model is pretty straightforward. All that one has to do is to use MOI.instantiate and define the model as usual.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"import MathOptInterface as MOI\nconst MOIU = MOI.Utilities\n\nusing ToQUBO\nusing Anneal # <- Your favourite Annealer / Sampler / Solver here\n\n# Example from https://jump.dev/MathOptInterface.jl/stable/tutorials/example/\n\n# Virtual QUBO Model\nmodel = MOI.instantiate(\n () -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer),\n with_bridge_type = Float64,\n)\n\nn = 3;\nc = [1.0, 2.0, 3.0]\nw = [0.3, 0.5, 1.0]\nC = 3.2;\n\n# -*- Variables -*- #\nx = MOI.add_variables(model, n);\n\n# -*- Objective -*- #\nMOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)\n\nMOI.set(\n model,\n MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),\n MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0),\n);\n\n# -*- Constraints -*- #\nMOI.add_constraint(\n model,\n MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(w, x), 0.0),\n MOI.LessThan(C),\n);\n\nfor xᵢ in x\n MOI.add_constraint(model, xᵢ, MOI.ZeroOne())\nend\n\n# Run!\nMOI.optimize!(model)\n\n# Collect Solution\nMOI.get(model, MOI.VariablePrimal(), x)","category":"page"},{"location":"examples/#JuMP-D-Wave-Examples","page":"Examples","title":"JuMP + D-Wave Examples","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"We may now fill a few more knapsacks using JuMP. We will generate uniform random costs mathbfc and weights mathbfw then set the knapsack's capacity C to be a fraction of the total available weight i.e. 80.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This example was inspired by D-Wave's knapsack example repository.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using CSV\nusing DataFrames\nusing Random\n\n# -> Generate Data <-\nrng = MersenneTwister(1)\n\ndf = DataFrame(\n :cost => rand(rng, 1:100, 16),\n :weight => rand(rng, 1:100, 16),\n)\n\nCSV.write(\"knapsack.csv\", df)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using CSV\nusing DataFrames\n\ndf = CSV.read(\"knapsack.csv\", DataFrame)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using JuMP\nusing ToQUBO\nusing Anneal # <- Your favourite Annealer / Sampler / Solver here\n\n# -> Model <-\nmodel = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))\n\nn = size(df, 1)\nc = collect(Float64, df[!, :cost])\nw = collect(Float64, df[!, :weight])\nC = round(0.8 * sum(w))\n\n# -> Variables <-\n@variable(model, x[i=1:n], Bin)\n\n# -> Objective <-\n@objective(model, Max, c' * x)\n\n# -> Constraint <-\n@constraint(model, w' * x <= C)\n\n# ->-> Run! ->->\noptimize!(model)\n\n# Add Results as a new column\ninsertcols!(\n df,\n 3, \n :select => map(\n (ξ) -> (ξ > 0.0) ? \"Yes\" : \"No\",\n value.(x),\n ),\n)","category":"page"},{"location":"manual/#Manual","page":"Manual","title":"Manual","text":"","category":"section"},{"location":"manual/#Quick-Start-Guide","page":"Manual","title":"Quick Start Guide","text":"","category":"section"},{"location":"manual/","page":"Manual","title":"Manual","text":"using JuMP\nusing ToQUBO\nusing Anneal\n\nmodel = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))\n\n@variable(model, x[1:3], Bin)\n@objective(model, Max, 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3])\n@constraint(model, 0.3 * x[1] + 0.5 * x[2] + 1.0 * x[3] <= 3.2)\n\noptimize!(model)\n\nsolution_summary(model)","category":"page"},{"location":"#ToQUBO.jl-Documentation","page":"Home","title":"ToQUBO.jl Documentation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ToQUBO.jl is a Julia Package intended to automatically translate models written in JuMP, into the QUBO mathematical optimization framework.","category":"page"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"#**Pre-release-note:**","page":"Home","title":"Pre-release note:","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"This project is not yet available through Julia's package manager. Thus, it is still necessary to clone ToQUBO.jl from its GitHub repo.","category":"page"},{"location":"","page":"Home","title":"Home","text":"$ git clone https://github.com/psrenergy/ToQUBO.jl\n$ cd ToQUBO.jl\n$ julia --project=.","category":"page"},{"location":"","page":"Home","title":"Home","text":"To use the Anneal.jl submodule, it will be necessary to run","category":"page"},{"location":"","page":"Home","title":"Home","text":"(ToQUBO) pkg> dev .\\\\src\\\\Anneal.jl","category":"page"},{"location":"","page":"Home","title":"Home","text":"on Julia's REPL beforehand.","category":"page"},{"location":"#Citing-ToQUBO.jl","page":"Home","title":"Citing ToQUBO.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:","category":"page"},{"location":"","page":"Home","title":"Home","text":"@software{ToQUBO.jl:2022,\n author = {Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal},\n title = {ToQUBO.jl},\n url = {https://github.com/psrenergy/ToQUBO.jl},\n version = {0.1.0},\n date = {2022-03-31},\n}","category":"page"},{"location":"booklet/#ToQUBO.jl-Booklet","page":"Booklet","title":"ToQUBO.jl Booklet","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.","category":"page"},{"location":"booklet/#QUBO","page":"Booklet","title":"QUBO","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"beginarrayrl\n min mathbfx^intercal Qmathbfx \n textst mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.isqubo\nToQUBO.toqubo\nToQUBO.toqubo!","category":"page"},{"location":"booklet/#ToQUBO.isqubo","page":"Booklet","title":"ToQUBO.isqubo","text":"isqubo(model::MOI.ModelLike)\n\nTells if a given model is ready to be interpreted as a QUBO model.\n\nFor it to be true, a few conditions must be met:\n\nAll variables must be binary (MOI.VariableIndex ∈ MOI.ZeroOne)\nNo other constraints are allowed\nThe objective function must be of type MOI.ScalarQuadraticFunction, MOI.ScalarAffineFunction or MOI.VariableIndex\nThe objective sense must be either MOI.MIN_SENSE or MOI.MAX_SENSE\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo","page":"Booklet","title":"ToQUBO.toqubo","text":"toqubo(T::Type, source::MOI.ModelLike, optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing)\ntoqubo(source::MOI.ModelLike, optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing)\n\nLow-level interface to create a ::VirtualQUBOModel{T} from ::MOI.ModelLike instance. If provided, an ::MOI.AbstractOptimizer is attached to the model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo!","page":"Booklet","title":"ToQUBO.toqubo!","text":"toqubo!(model::VirtualQUBOModel{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.toqubo_sense!\nToQUBO.toqubo_variables!\nToQUBO.toqubo_constraint!\nToQUBO.toqubo_objective!","category":"page"},{"location":"booklet/#ToQUBO.toqubo_sense!","page":"Booklet","title":"ToQUBO.toqubo_sense!","text":"toqubo_sense!(model::VirtualQUBOModel)\n\nCopies MOI.ObjectiveSense from model.source_model to model.target_model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_variables!","page":"Booklet","title":"ToQUBO.toqubo_variables!","text":"toqubo_variables!(model::VirtualQUBOModel{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_constraint!","page":"Booklet","title":"ToQUBO.toqubo_constraint!","text":"toqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}, S::Type{<:EQ{T}}) where {T}\ntoqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}, S::Type{<:LT{T}}) where {T}\ntoqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}, S::Type{<:EQ{T}}) where {T}\ntoqubo_constraint!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}, S::Type{<:LT{T}}) where {T}\ntoqubo_constraint!(::VirtualQUBOModel{T}, ::Type{<:VI}, ::Type{<:Union{MOI.ZeroOne, MOI.Integer, MOI.Interval{T}, MOI.LessThan{T}, MOI.GreaterThan{T}}}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_objective!","page":"Booklet","title":"ToQUBO.toqubo_objective!","text":"toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:VI}) where {T}\ntoqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}) where {T}\ntoqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Pseudo-Boolean-Optimization","page":"Booklet","title":"Pseudo-Boolean Optimization","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between quadratic PBFs and QUBO forms.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.PBO.PseudoBooleanFunction\nToQUBO.PBO.residual\nToQUBO.PBO.derivative\nToQUBO.PBO.gradient\nToQUBO.PBO.gap\nToQUBO.PBO.sharpness\nToQUBO.PBO.discretize\nToQUBO.PBO.relaxed_gcd","category":"page"},{"location":"booklet/#ToQUBO.PBO.PseudoBooleanFunction","page":"Booklet","title":"ToQUBO.PBO.PseudoBooleanFunction","text":"PseudoBooleanFunction{S, T}(c::T)\nPseudoBooleanFunction{S, T}(ps::Pair{Vector{S}, T}...)\n\nA Pseudo-Boolean Function f in mathscrF over some field mathbbT takes the form\n\nf(mathbfx) = sum_omega in Omegaleftfright c_omega prod_j in omega mathbbx_j\n\nwhere each Omegaleftfright is the multi-linear representation of f as a set of terms. Each term is given by a unique set of indices omega subseteq mathbbS related to some coefficient c_omega in mathbbT. We say that omega in Omegaleftfright iff c_omega neq 0. Variables mathbfx_i are indeed boolean, thus f mathbbB^n to mathbbT.\n\nReferences\n\n[1] Endre Boros, Peter L. Hammer, Pseudo-Boolean optimization, Discrete Applied Mathematics, 2002 {doi}\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.PBO.residual","page":"Booklet","title":"ToQUBO.PBO.residual","text":"residual(f::PBF{S, T}, i::S) where {S, T}\nresidual(f::PBF{S, T}, i::Int) where {S, T}\n\nThe residual of function f in mathscrF with respect to the i-th variable.\n\n Theta_i f(mathbfx) = f(mathbfx) - mathbfx_i Delta_i f(mathbfx) =\n sum_omega in Omegaleftfright setminus leftiright\n c_omega prod_k in omega mathbfx_k\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.derivative","page":"Booklet","title":"ToQUBO.PBO.derivative","text":"derivative(f::PBF{S, T}, i::S) where {S, T}\nderivative(f::PBF{S, T}, i::Int) where {S, T}\n\nThe partial derivate of function f in mathscrF with respect to the i-th variable.\n\n Delta_i f(mathbfx) = fracpartial f(mathbfx)partial mathbfx_i =\n sum_omega in Omegaleftfright setminus leftiright\n c_omega cup leftiright prod_k in omega mathbfx_k\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.gradient","page":"Booklet","title":"ToQUBO.PBO.gradient","text":"gradient(f::PBF)\n\nComputes the gradient of f in mathscrF where the i-th derivative is given by derivative.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.gap","page":"Booklet","title":"ToQUBO.PBO.gap","text":"gap(f::PBF{S, T}; bound::Symbol=:loose) where {S, T}\n\nComputes the least upper bound for the greatest variantion possible under some f in mathscrF i. e.\n\nbeginarrayr l\n min M \n textst leftf(mathbfx) - f(mathbfy)right le M forall mathbfx mathbfy in mathbbB^n \nendarray\n\nA simple approach, avaiable using the bound=:loose parameter, is to define\n\nM triangleq sum_omega neq varnothing leftc_omegaright\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.sharpness","page":"Booklet","title":"ToQUBO.PBO.sharpness","text":"sharpness(f::PBF{S, T}; bound::Symbol=:loose, tol::T = T(1e-6)) where {S, T<:AbstractFloat}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.discretize","page":"Booklet","title":"ToQUBO.PBO.discretize","text":"discretize(f::PBF{S, T}; tol::T) where {S, T}\n\nFor a given function f in mathscrF written as\n\n fleft(mathbfxright) = sum_omega in Omegaleftfright c_omega prod_i in omega mathbfx_i\n\ncomputes an approximate function g mathbbB^n to mathbbZ such that\n\n argmin_mathbfx in mathbbB^n gleft(mathbfxright) = argmin_mathbfx in mathbbB^n fleft(mathbfxright)\n\nThis is done by rationalizing every coefficient c_omega according to some tolerance tol.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.relaxed_gcd","page":"Booklet","title":"ToQUBO.PBO.relaxed_gcd","text":"relaxed_gcd(x::T, y::T; tol::T = T(1e-6)) where {T <: AbstractFloat}\n\nWe define two real numbers x and y to be tau-comensurable if, for some tau 0 there exists a continued fractions convergent p_k div q_k such that\n\n left q_k x - p_k y right le tau\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Quadratization","page":"Booklet","title":"Quadratization","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"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.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.PBO.quadratize\nToQUBO.PBO.@quadratization","category":"page"},{"location":"booklet/#ToQUBO.PBO.quadratize","page":"Booklet","title":"ToQUBO.PBO.quadratize","text":"quadratize(f::PBF{S, T}; slack::Any) where {S, T}\n\nQuadratizes a given PBF, i.e. creates a function g in mathscrF^2 from f in mathscrF^k k ge 3.\n\nA function f 2^S to mathbbR is said to be submodular if\n\nf(X cup Y) + f(X cap Y) le f(X) + f(Y) forall X Y subset S\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.@quadratization","page":"Booklet","title":"ToQUBO.PBO.@quadratization","text":"@quadratization(name, nsv, nst)\n\nDefines a new quadratization technique.\n\n\n\n\n\n","category":"macro"},{"location":"booklet/#Virtual-Mapping","page":"Booklet","title":"Virtual Mapping","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.","category":"page"},{"location":"booklet/#Virtual-Variables","page":"Booklet","title":"Virtual Variables","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"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.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.VirtualMapping.VirtualVariable\nToQUBO.VirtualMapping.mapvar!\nToQUBO.VirtualMapping.expandℝ!\nToQUBO.VirtualMapping.slackℝ!\nToQUBO.VirtualMapping.expandℤ!\nToQUBO.VirtualMapping.slackℤ!\nToQUBO.VirtualMapping.mirror𝔹!\nToQUBO.VirtualMapping.slack𝔹!","category":"page"},{"location":"booklet/#ToQUBO.VirtualMapping.VirtualVariable","page":"Booklet","title":"ToQUBO.VirtualMapping.VirtualVariable","text":"VirtualVariable{S, T}(\n newvar::Function,\n source::Union{S, Nothing};\n bits::Union{Int, Nothing},\n tech::Symbol,\n name::Union{Symbol, Nothing}=nothing,\n α::T=zero(T),\n β::T=one(T)\n) where {S, T}\n\nThe Virtual Variable Mapping\n\nVariable Expansion techniques:\n\n:𝔹 - Used when a boolean variable is to be mirrored.\n:ℤ₂ - Binary expansion for integer variable.\n:ℤ₁ - Unary expansion for integer variable.\n:ℝ₂ - Binary expansion for real variable.\n:ℝ₁ - Unary expansion for real variable.\n\nReferences:\n\n[1] Chancellor, N. (2019). Domain wall encoding of discrete variables for quantum annealing and QAOA. Quantum Science and Technology, 4(4), 045004. {doi}\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.VirtualMapping.mapvar!","page":"Booklet","title":"ToQUBO.VirtualMapping.mapvar!","text":"mapvar!(model::AbstractVirtualModel{T}, v::VirtualMOIVariable{T}) where {T}\n\nMaps newly created virtual variable v within the virtual model structure. It follows these steps:\n\nMaps v's source to it in the model's source mapping.\nFor every one of v's targets, maps it to itself and adds a binary constraint to it.\nAdds v to the end of the model's varvec. \n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.expandℝ!","page":"Booklet","title":"ToQUBO.VirtualMapping.expandℝ!","text":"expandℝ!(model::QUBOModel{T}, src::VI; bits::Int, name::Symbol, α::T, β::T, semi::Bool) where T\n\nReal Binary Expansion within the closed interval alpha beta.\n\nFor a given variable x in alpha beta we approximate it by\n\nx approx alpha + frac(beta - alpha)2^n - 1 sum_i=0^n-1 2^i y_i\n\nwhere n is the number of bits and y_i in mathbbB.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.slackℝ!","page":"Booklet","title":"ToQUBO.VirtualMapping.slackℝ!","text":"slackℝ!(model::AbstractVirtualModel{T}; name::Symbol, α::T, β::T, semi::Bool) where T\n\nAdds real slack variable according to expandℝ!'s expansion method.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.expandℤ!","page":"Booklet","title":"ToQUBO.VirtualMapping.expandℤ!","text":"expandℤ!(model::QUBOModel{T}, src::VI; name::Symbol, α::T, β::T, semi::Bool) where T\n\nInteger Binary Expansion within the closed interval leftlceilalpharightrceil leftlfloorbetarightrfloor.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.slackℤ!","page":"Booklet","title":"ToQUBO.VirtualMapping.slackℤ!","text":"slackℤ!(model::AbstractVirtualModel{T}; name::Symbol, α::T, β::T) where {T}\n\nAdds integer slack variable according to expandℤ!'s expansion method.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.mirror𝔹!","page":"Booklet","title":"ToQUBO.VirtualMapping.mirror𝔹!","text":"mirror𝔹!(model::AbstractVirtualModel{T}, src::Union{VI, Nothing}; name::Symbol) where T\n\nSimply crates a virtual-mapped Doppelgänger into the destination model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.VirtualMapping.slack𝔹!","page":"Booklet","title":"ToQUBO.VirtualMapping.slack𝔹!","text":"slack𝔹!(model::AbstractVirtualModel{T}; name::Symbol) where {T}\n\nAdds a binary slack variable to the model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Virtual-Models","page":"Booklet","title":"Virtual Models","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.VirtualMapping.AbstractVirtualModel\nToQUBO.VirtualQUBOModel","category":"page"},{"location":"booklet/#ToQUBO.VirtualMapping.AbstractVirtualModel","page":"Booklet","title":"ToQUBO.VirtualMapping.AbstractVirtualModel","text":"abstract type AbstractVirtualModel{T} <: MOI.AbstractOptimizer end\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.VirtualQUBOModel","page":"Booklet","title":"ToQUBO.VirtualQUBOModel","text":"VirtualQUBOModel{T}(optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing) where {T}\n\nThis QUBO Virtual Model links the final QUBO formulation to the original one, allowing variable value retrieving and other features.\n\n\n\n\n\n","category":"type"},{"location":"booklet/#Annealing-and-Sampling","page":"Booklet","title":"Annealing & Sampling","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO's main goal is to benefit from non-deterministic samplers, especially Quantum Adiabatic devices and other Annealing machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO via the Anneal.jl submodule and package prototype. Some of them are presented below.","category":"page"},{"location":"booklet/#Quantum-Annealing","page":"Booklet","title":"Quantum Annealing","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Interfacing with D-Wave's quantum computers is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi and FICO® Xpress, this requires licensing and extra steps are needed to get access to it. In a first moment, for those willing to get started, the Simulated Annealing optimizer might be enough.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"While in JuMP, run using Anneal and look for QuantumAnnealer.Optimizer.","category":"page"},{"location":"booklet/#Simulated-Annealing","page":"Booklet","title":"Simulated Annealing","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configuration you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and during early research steps due to its simplicity and ease of use. It does not implement the most advanced Simulated Annealing algorithm available but performs fairly well on small instances. Anneal.jl exports this interface as SimulatedAnnealer.Optimizer.","category":"page"},{"location":"booklet/#Random-Sampling","page":"Booklet","title":"Random Sampling","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias 0 le p le 1, which defaults to p = 05. After running the using Anneal command, RandomSampler.Optimizer will be available.","category":"page"},{"location":"booklet/#Exact-Solver-(Exaustive-Enumeration)","page":"Booklet","title":"Exact Solver (Exaustive Enumeration)","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with no more than 20 variables should be provided.","category":"page"},{"location":"booklet/#MIQP-Solvers","page":"Booklet","title":"MIQP Solvers","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"The most accessible alternative to Annealers and Samplers are Mixed-Integer Quadratic Programming (MIQP) Solvers such as Gurobi and CPLEX. These are not intended to be of regular use alongside ToQUBO since reformulation usually makes things harder for these folks. Yet, there are still cases where they may be suitable for tests on small instances.","category":"page"},{"location":"booklet/#Custom-Error-Types","page":"Booklet","title":"Custom Error Types","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.QUBOError","category":"page"},{"location":"booklet/#ToQUBO.QUBOError","page":"Booklet","title":"ToQUBO.QUBOError","text":"QUBOError(msg::Union{Nothing, String})\n\nThis error indicates any failure during QUBO formulation\n\n\n\n\n\n","category":"type"},{"location":"assets/README/#Logo","page":"Logo","title":"Logo","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The ideia behind ToQUBO's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo¹, the translation for cube.","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"(Image: ToQUBO.jl)","category":"page"},{"location":"assets/README/#Colors","page":"Logo","title":"Colors","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The colors were chosen according to Julia's Reference for logo graphics². Text color matches the innermost shape and renders fairly well in both light and dark background themes.","category":"page"},{"location":"assets/README/#Typography","page":"Logo","title":"Typography","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"MADETYPE Sunflower³ Font was used. It was converted to a SVG path through the Google Font to Svg Path⁴ online tool.","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"¹ IPA: [ˈkubʊ]","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"² github.com/JuliaLang/julia-logo-graphics","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"³ Licensed by the authors for use in this project","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"⁴ danmarshall.github.io/google-font-to-svg-path","category":"page"},{"location":"assets/README/#Web-Icon-[![ToQUBO.jl](favicon.ico)](/docs/src/assets)","page":"Logo","title":"Web Icon (Image: ToQUBO.jl)","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The icon used to decorate the documentation resembles an assembled version of the cube with its blue face making up the background.","category":"page"}]
+}
diff --git a/previews/PR34/siteinfo.js b/previews/PR34/siteinfo.js
new file mode 100644
index 00000000..15966a93
--- /dev/null
+++ b/previews/PR34/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "previews/PR34";
diff --git a/previews/PR50/assets/README/index.html b/previews/PR50/assets/README/index.html
new file mode 100644
index 00000000..ecab8607
--- /dev/null
+++ b/previews/PR50/assets/README/index.html
@@ -0,0 +1,2 @@
+
+Logo · ToQUBO.jl
The ideia behind ToQUBO's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo¹, the translation for cube.
The colors were chosen according to Julia's Reference for logo graphics². Text color matches the innermost shape and renders fairly well in both light and dark background themes.
This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.
toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:VI}) where {T}
+toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}) where {T}
+toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}) where {T}
Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between quadratic PBFs and QUBO forms.
where each $\Omega\left[{f}\right]$ is the multi-linear representation of $f$ as a set of terms. Each term is given by a unique set of indices $\omega \subseteq \mathbb{S}$ related to some coefficient $c_\omega \in \mathbb{T}$. We say that $\omega \in \Omega\left[{f}\right] \iff c_\omega \neq 0$. Variables $\mathbf{x}_i$ are indeed boolean, thus $f : \mathbb{B}^{n} \to \mathbb{T}$.
References
[1] Endre Boros, Peter L. Hammer, Pseudo-Boolean optimization, Discrete Applied Mathematics, 2002 {doi}
relaxed_gcd(x::T, y::T; tol::T = T(1e-6)) where {T <: AbstractFloat}
We define two real numbers $x$ and $y$ to be $\tau$-comensurable if, for some $\tau > 0$ there exists a continued fractions convergent $p_{k} \div q_{k}$ such that
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.
During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.
This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.
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.
- Linear
+- Unary
+- Binary
+- One Hot
+- Domain Wall
References:
[1] Chancellor, N. (2019). Domain wall encoding of discrete variables for quantum annealing and QAOA. Quantum Science and Technology, 4(4), 045004. {doi}
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.mapvar!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.expandℝ!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.slackℝ!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.expandℤ!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.slackℤ!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.mirror𝔹!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for ToQUBO.VirtualMapping.slack𝔹!. Check Documenter's build log for details.
ToQUBO's main goal is to benefit from non-deterministic samplers, especially Quantum Adiabatic devices and other Annealing machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO via the Anneal.jl submodule and package prototype. Some of them are presented below.
Interfacing with D-Wave's quantum computers is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi and FICO® Xpress, this requires licensing and extra steps are needed to get access to it. In a first moment, for those willing to get started, the Simulated Annealing optimizer might be enough.
While in JuMP, run using Anneal and look for QuantumAnnealer.Optimizer.
Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configuration you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and during early research steps due to its simplicity and ease of use. It does not implement the most advanced Simulated Annealing algorithm available but performs fairly well on small instances. Anneal.jl exports this interface as SimulatedAnnealer.Optimizer.
This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias $0 \le p \le 1$, which defaults to $p = 0.5$. After running the using Anneal command, RandomSampler.Optimizer will be available.
Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with no more than 20 variables should be provided.
The most accessible alternative to Annealers and Samplers are Mixed-Integer Quadratic Programming (MIQP) Solvers such as Gurobi and CPLEX. These are not intended to be of regular use alongside ToQUBO since reformulation usually makes things harder for these folks. Yet, there are still cases where they may be suitable for tests on small instances.
We may now fill a few more knapsacks using JuMP. We will generate uniform random costs $\mathbf{c}$ and weights $\mathbf{w}$ then set the knapsack's capacity $C$ to be a fraction of the total available weight i.e. $80\%$.
If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:
@software{toqubo:2022,
+ author = {Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal},
+ title = {{ToQUBO.jl}},
+ month = mar,
+ year = 2022,
+ publisher = {Zenodo},
+ version = {v0.1.0},
+ doi = {10.5281/zenodo.6387592},
+ url = {https://doi.org/10.5281/zenodo.6387592}
+}
Settings
This document was generated with Documenter.jl version 0.27.23 on Friday 30 September 2022. Using Julia version 1.6.7.
This document was generated with Documenter.jl version 0.27.23 on Friday 30 September 2022. Using Julia version 1.6.7.
diff --git a/previews/PR50/search_index.js b/previews/PR50/search_index.js
new file mode 100644
index 00000000..8ba28df4
--- /dev/null
+++ b/previews/PR50/search_index.js
@@ -0,0 +1,3 @@
+var documenterSearchIndex = {"docs":
+[{"location":"examples/prime_factoring/#Prime-Factoring","page":"Prime Factoring","title":"Prime Factoring","text":"","category":"section"},{"location":"examples/prime_factoring/","page":"Prime Factoring","title":"Prime Factoring","text":"using JuMP\nusing ToQUBO","category":"page"},{"location":"examples/prime_factoring/","page":"Prime Factoring","title":"Prime Factoring","text":"P = 3\nQ = 5\nR = P * Q\n\nmodel = Model(() -> ToQUBO.Optimizer(ExactSampler.Optimizer))\n\n@variable(model, 0 <= p <= P, Integer)\n@variable(model, 0 <= q <= Q, Integer)\n\n@objective(model, Min, (R - p * q) ^ 2)\n\noptimize!(model)","category":"page"},{"location":"examples/#Examples","page":"Examples","title":"Examples","text":"","category":"section"},{"location":"examples/#Knapsack","page":"Examples","title":"Knapsack","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"We start with some instances of the discrete Knapsack Problem whose standard formulation is","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"beginarrayr l\n max mathbfc mathbfx \n textst mathbfw mathbfx le C \n mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"examples/#MathOptInterface","page":"Examples","title":"MathOptInterface","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"Using MOI directly to build a simple model is pretty straightforward. All that one has to do is to use MOI.instantiate and define the model as usual.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"import MathOptInterface as MOI\nconst MOIU = MOI.Utilities\n\nusing ToQUBO\nusing Anneal # <- Your favourite Annealer / Sampler / Solver here\n\n# Example from https://jump.dev/MathOptInterface.jl/stable/tutorials/example/\n\n# Virtual QUBO Model\nmodel = MOI.instantiate(\n () -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer),\n with_bridge_type = Float64,\n)\n\nn = 3;\nc = [1.0, 2.0, 3.0]\nw = [0.3, 0.5, 1.0]\nC = 3.2;\n\n# -*- Variables -*- #\nx = MOI.add_variables(model, n);\n\n# -*- Objective -*- #\nMOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE)\n\nMOI.set(\n model,\n MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),\n MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0),\n);\n\n# -*- Constraints -*- #\nMOI.add_constraint(\n model,\n MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(w, x), 0.0),\n MOI.LessThan(C),\n);\n\nfor xᵢ in x\n MOI.add_constraint(model, xᵢ, MOI.ZeroOne())\nend\n\n# Run!\nMOI.optimize!(model)\n\n# Collect Solution\nMOI.get(model, MOI.VariablePrimal(), x)","category":"page"},{"location":"examples/#JuMP-D-Wave-Examples","page":"Examples","title":"JuMP + D-Wave Examples","text":"","category":"section"},{"location":"examples/","page":"Examples","title":"Examples","text":"We may now fill a few more knapsacks using JuMP. We will generate uniform random costs mathbfc and weights mathbfw then set the knapsack's capacity C to be a fraction of the total available weight i.e. 80.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"This example was inspired by D-Wave's knapsack example repository.","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using CSV\nusing DataFrames\nusing Random\n\n# -> Generate Data <-\nrng = MersenneTwister(1)\n\ndf = DataFrame(\n :cost => rand(rng, 1:100, 16),\n :weight => rand(rng, 1:100, 16),\n)\n\nCSV.write(\"knapsack.csv\", df)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using CSV\nusing DataFrames\n\ndf = CSV.read(\"knapsack.csv\", DataFrame)","category":"page"},{"location":"examples/","page":"Examples","title":"Examples","text":"using JuMP\nusing ToQUBO\nusing Anneal # <- Your favourite Annealer / Sampler / Solver here\n\n# -> Model <-\nmodel = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))\n\nn = size(df, 1)\nc = collect(Float64, df[!, :cost])\nw = collect(Float64, df[!, :weight])\nC = round(0.8 * sum(w))\n\n# -> Variables <-\n@variable(model, x[i=1:n], Bin)\n\n# -> Objective <-\n@objective(model, Max, c' * x)\n\n# -> Constraint <-\n@constraint(model, w' * x <= C)\n\n# ->-> Run! ->->\noptimize!(model)\n\n# Add Results as a new column\ninsertcols!(\n df,\n 3, \n :select => map(\n (ξ) -> (ξ > 0.0) ? \"Yes\" : \"No\",\n value.(x),\n ),\n)","category":"page"},{"location":"manual/#Manual","page":"Manual","title":"Manual","text":"","category":"section"},{"location":"manual/#Quick-Start-Guide","page":"Manual","title":"Quick Start Guide","text":"","category":"section"},{"location":"manual/","page":"Manual","title":"Manual","text":"using JuMP\nusing ToQUBO\nusing Anneal\n\nmodel = Model(() -> ToQUBO.Optimizer(SimulatedAnnealer.Optimizer))\n\n@variable(model, x[1:3], Bin)\n@objective(model, Max, 1.0 * x[1] + 2.0 * x[2] + 3.0 * x[3])\n@constraint(model, 0.3 * x[1] + 0.5 * x[2] + 1.0 * x[3] <= 3.2)\n\noptimize!(model)\n\nsolution_summary(model)","category":"page"},{"location":"#ToQUBO.jl-Documentation","page":"Home","title":"ToQUBO.jl Documentation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"ToQUBO.jl is a Julia Package intended to automatically translate models written in JuMP, into the QUBO mathematical optimization framework.","category":"page"},{"location":"#Getting-Started","page":"Home","title":"Getting Started","text":"","category":"section"},{"location":"#Installation","page":"Home","title":"Installation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"julia> import Pkg\n\njulia> Pkg.add(\"ToQUBO\")","category":"page"},{"location":"#Running","page":"Home","title":"Running","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"using JuMP, ToQUBO, Anneal\n\nmodel = Model(() -> ToQUBO.Optimizer(ExactSampler.Optimizer))\n\n@variable(model, x[1:3], Bin)\n\n@objective(model, Max, 1.0*x[1] + 2.0*x[2] + 3.0*x[3])\n\n@constraint(model, 0.3*x[1] + 0.5*x[2] + 1.0*x[3] <= 1.6)\n\noptimize!(model)\n\nfor i = 1:result_count(model)\n xᵢ = value.(x, result = i)\n yᵢ = objective_value(model, result = i)\n println(\"f($xᵢ) = $yᵢ\")\nend","category":"page"},{"location":"#Citing-ToQUBO.jl","page":"Home","title":"Citing ToQUBO.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"If you use ToQUBO.jl in your work, we kindly ask you to include the following citation:","category":"page"},{"location":"","page":"Home","title":"Home","text":"@software{toqubo:2022,\n author = {Pedro Xavier and Tiago Andrade and Joaquim Garcia and David Bernal},\n title = {{ToQUBO.jl}},\n month = mar,\n year = 2022,\n publisher = {Zenodo},\n version = {v0.1.0},\n doi = {10.5281/zenodo.6387592},\n url = {https://doi.org/10.5281/zenodo.6387592}\n}","category":"page"},{"location":"booklet/#ToQUBO.jl-Booklet","page":"Booklet","title":"ToQUBO.jl Booklet","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This booklet aims to gather the theoretical and practical details behind ToQUBO and provide documentation for project internals. The target audience includes, among others, advanced users and those willing to contribute to the project. The latter are advised to read the following sections, as they give a glimpse of the ideas employed up to now.","category":"page"},{"location":"booklet/#QUBO","page":"Booklet","title":"QUBO","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"beginarrayrl\n min mathbfx^intercal Qmathbfx \n textst mathbfx in mathbbB^n\nendarray","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.isqubo\nToQUBO.toqubo\nToQUBO.toqubo!","category":"page"},{"location":"booklet/#ToQUBO.isqubo","page":"Booklet","title":"ToQUBO.isqubo","text":"isqubo(model::MOI.ModelLike)\n\nTells if a given model is ready to be interpreted as a QUBO model.\n\nFor it to be true, a few conditions must be met:\n\nAll variables must be binary (MOI.VariableIndex ∈ MOI.ZeroOne)\nNo other constraints are allowed\nThe objective function must be of type MOI.ScalarQuadraticFunction, MOI.ScalarAffineFunction or MOI.VariableIndex\nThe objective sense must be either MOI.MIN_SENSE or MOI.MAX_SENSE\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo","page":"Booklet","title":"ToQUBO.toqubo","text":"toqubo(T::Type, source::MOI.ModelLike, optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing)\ntoqubo(source::MOI.ModelLike, optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing)\n\nLow-level interface to create a ::VirtualQUBOModel{T} from ::MOI.ModelLike instance. If provided, an ::MOI.AbstractOptimizer is attached to the model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo!","page":"Booklet","title":"ToQUBO.toqubo!","text":"toqubo!(model::VirtualQUBOModel{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.toqubo_sense!\nToQUBO.toqubo_variables!\nToQUBO.toqubo_constraint!\nToQUBO.toqubo_objective!","category":"page"},{"location":"booklet/#ToQUBO.toqubo_sense!","page":"Booklet","title":"ToQUBO.toqubo_sense!","text":"toqubo_sense!(model::VirtualQUBOModel)\n\nCopies MOI.ObjectiveSense from model.source_model to model.target_model.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_variables!","page":"Booklet","title":"ToQUBO.toqubo_variables!","text":"toqubo_variables!(model::VirtualQUBOModel{T}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.toqubo_objective!","page":"Booklet","title":"ToQUBO.toqubo_objective!","text":"toqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:VI}) where {T}\ntoqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SAF{T}}) where {T}\ntoqubo_objective!(model::VirtualQUBOModel{T}, F::Type{<:SQF{T}}) where {T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Pseudo-Boolean-Optimization","page":"Booklet","title":"Pseudo-Boolean Optimization","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Internally, problems are represented through a Pseudo-Boolean Optimization (PBO) framework. The main goal is to represent a given problem using a Pseudo-Boolean Function (PBF) since there is an immediate correspondence between quadratic PBFs and QUBO forms.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.PBO.PseudoBooleanFunction\nToQUBO.PBO.residual\nToQUBO.PBO.derivative\nToQUBO.PBO.gradient\nToQUBO.PBO.gap\nToQUBO.PBO.sharpness\nToQUBO.PBO.discretize\nToQUBO.PBO.relaxed_gcd","category":"page"},{"location":"booklet/#ToQUBO.PBO.PseudoBooleanFunction","page":"Booklet","title":"ToQUBO.PBO.PseudoBooleanFunction","text":"A Pseudo-Boolean Function f in mathscrF over some field mathbbT takes the form\n\nf(mathbfx) = sum_omega in Omegaleftfright c_omega prod_j in omega mathbbx_j\n\nwhere each Omegaleftfright is the multi-linear representation of f as a set of terms. Each term is given by a unique set of indices omega subseteq mathbbS related to some coefficient c_omega in mathbbT. We say that omega in Omegaleftfright iff c_omega neq 0. Variables mathbfx_i are indeed boolean, thus f mathbbB^n to mathbbT.\n\nReferences\n\n[1] Endre Boros, Peter L. Hammer, Pseudo-Boolean optimization, Discrete Applied Mathematics, 2002 {doi}\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.PBO.residual","page":"Booklet","title":"ToQUBO.PBO.residual","text":"residual(f::PBF{S, T}, i::S) where {S, T}\nresidual(f::PBF{S, T}, i::Int) where {S, T}\n\nThe residual of function f in mathscrF with respect to the i-th variable.\n\n Theta_i f(mathbfx) = f(mathbfx) - mathbfx_i Delta_i f(mathbfx) =\n sum_omega in Omegaleftfright setminus leftiright\n c_omega prod_k in omega mathbfx_k\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.derivative","page":"Booklet","title":"ToQUBO.PBO.derivative","text":"derivative(f::PBF{S, T}, i::S) where {S, T}\nderivative(f::PBF{S, T}, i::Int) where {S, T}\n\nThe partial derivate of function f in mathscrF with respect to the i-th variable.\n\n Delta_i f(mathbfx) = fracpartial f(mathbfx)partial mathbfx_i =\n sum_omega in Omegaleftfright setminus leftiright\n c_omega cup leftiright prod_k in omega mathbfx_k\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.gradient","page":"Booklet","title":"ToQUBO.PBO.gradient","text":"gradient(f::PBF)\n\nComputes the gradient of f in mathscrF where the i-th derivative is given by derivative.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.gap","page":"Booklet","title":"ToQUBO.PBO.gap","text":"gap(f::PBF{S, T}; bound::Symbol=:loose) where {S, T}\n\nComputes the least upper bound for the greatest variantion possible under some f in mathscrF i. e.\n\nbeginarrayr l\n min M \n textst leftf(mathbfx) - f(mathbfy)right le M forall mathbfx mathbfy in mathbbB^n \nendarray\n\nA simple approach, avaiable using the bound=:loose parameter, is to define\n\nM triangleq sum_omega neq varnothing leftc_omegaright\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.sharpness","page":"Booklet","title":"ToQUBO.PBO.sharpness","text":"sharpness(f::PBF{S, T}; bound::Symbol=:loose, tol::T = T(1e-6)) where {S, T}\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.discretize","page":"Booklet","title":"ToQUBO.PBO.discretize","text":"discretize(f::PBF{S, T}; tol::T) where {S, T}\n\nFor a given function f in mathscrF written as\n\n fleft(mathbfxright) = sum_omega in Omegaleftfright c_omega prod_i in omega mathbfx_i\n\ncomputes an approximate function g mathbbB^n to mathbbZ such that\n\n argmin_mathbfx in mathbbB^n gleft(mathbfxright) = argmin_mathbfx in mathbbB^n fleft(mathbfxright)\n\nThis is done by rationalizing every coefficient c_omega according to some tolerance tol.\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.relaxed_gcd","page":"Booklet","title":"ToQUBO.PBO.relaxed_gcd","text":"relaxed_gcd(x::T, y::T; tol::T = T(1e-6)) where {T <: AbstractFloat}\n\nWe define two real numbers x and y to be tau-comensurable if, for some tau 0 there exists a continued fractions convergent p_k div q_k such that\n\n left q_k x - p_k y right le tau\n\n\n\n\n\n","category":"function"},{"location":"booklet/#Quadratization","page":"Booklet","title":"Quadratization","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"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.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.PBO.quadratize\nToQUBO.PBO.@quadratization","category":"page"},{"location":"booklet/#ToQUBO.PBO.quadratize","page":"Booklet","title":"ToQUBO.PBO.quadratize","text":"quadratize(f::PBF{S, T}; slack::Function) where {S, T}\n\nQuadratizes a given PBF, i.e. creates a function g in mathscrF^2 from f in mathscrF^k k ge 3.\n\nA function f 2^S to mathbbR is said to be submodular if\n\nf(X cup Y) + f(X cap Y) le f(X) + f(Y) forall X Y subset S\n\n\n\n\n\n","category":"function"},{"location":"booklet/#ToQUBO.PBO.@quadratization","page":"Booklet","title":"ToQUBO.PBO.@quadratization","text":"@quadratization(name, nsv, nst)\n\nDefines a new quadratization technique.\n\n\n\n\n\n","category":"macro"},{"location":"booklet/#Virtual-Mapping","page":"Booklet","title":"Virtual Mapping","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"During reformulation, ToQUBO holds two distinct models, namely the Source Model and the Target Model. The source model is a generic MOI model restricted to the supported constraints. The target one is on the QUBO form used during the solving process. Both lie within a Virtual Model, which provides the necessary API integration and keeps all variable and constraint mapping tied together.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This is done in a transparent fashion for both agents since the user will mostly interact with the presented model, and the solvers will only access the generated one.","category":"page"},{"location":"booklet/#Virtual-Variables","page":"Booklet","title":"Virtual Variables","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"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.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.VirtualMapping.VirtualVariable\nToQUBO.VirtualMapping.mapvar!\nToQUBO.VirtualMapping.expandℝ!\nToQUBO.VirtualMapping.slackℝ!\nToQUBO.VirtualMapping.expandℤ!\nToQUBO.VirtualMapping.slackℤ!\nToQUBO.VirtualMapping.mirror𝔹!\nToQUBO.VirtualMapping.slack𝔹!","category":"page"},{"location":"booklet/#ToQUBO.VirtualMapping.VirtualVariable","page":"Booklet","title":"ToQUBO.VirtualMapping.VirtualVariable","text":"Variable Expansion methods:\n\n- Linear\n- Unary\n- Binary\n- One Hot\n- Domain Wall\n\nReferences:\n\n[1] Chancellor, N. (2019). Domain wall encoding of discrete variables for quantum annealing and QAOA. Quantum Science and Technology, 4(4), 045004. {doi}\n\n\n\n\n\n","category":"type"},{"location":"booklet/#Virtual-Models","page":"Booklet","title":"Virtual Models","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.VirtualMapping.AbstractVirtualModel\nToQUBO.VirtualQUBOModel","category":"page"},{"location":"booklet/#ToQUBO.VirtualMapping.AbstractVirtualModel","page":"Booklet","title":"ToQUBO.VirtualMapping.AbstractVirtualModel","text":"abstract type AbstractVirtualModel{T} <: MOI.AbstractOptimizer end\n\n\n\n\n\n","category":"type"},{"location":"booklet/#ToQUBO.VirtualQUBOModel","page":"Booklet","title":"ToQUBO.VirtualQUBOModel","text":"VirtualQUBOModel{T}(optimizer::Union{Nothing, Type{<:MOI.AbstractOptimizer}} = nothing) where {T}\n\nThis QUBO Virtual Model links the final QUBO formulation to the original one, allowing variable value retrieving and other features.\n\n\n\n\n\n","category":"type"},{"location":"booklet/#Annealing-and-Sampling","page":"Booklet","title":"Annealing & Sampling","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO's main goal is to benefit from non-deterministic samplers, especially Quantum Adiabatic devices and other Annealing machines. A few MOI-compliant interfaces for annealers and samplers are bundled within ToQUBO via the Anneal.jl submodule and package prototype. Some of them are presented below.","category":"page"},{"location":"booklet/#Quantum-Annealing","page":"Booklet","title":"Quantum Annealing","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Interfacing with D-Wave's quantum computers is one of the milestones we expect to achieve with this package. Like other proprietary optimization resources such as Gurobi and FICO® Xpress, this requires licensing and extra steps are needed to get access to it. In a first moment, for those willing to get started, the Simulated Annealing optimizer might be enough.","category":"page"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"While in JuMP, run using Anneal and look for QuantumAnnealer.Optimizer.","category":"page"},{"location":"booklet/#Simulated-Annealing","page":"Booklet","title":"Simulated Annealing","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Provided by D-Wave's open-source code libraries, this Simulated Annealing engine implements some of the features and configuration you would find using the Quantum API. Its adoption is recommended for basic usage, tests, and during early research steps due to its simplicity and ease of use. It does not implement the most advanced Simulated Annealing algorithm available but performs fairly well on small instances. Anneal.jl exports this interface as SimulatedAnnealer.Optimizer.","category":"page"},{"location":"booklet/#Random-Sampling","page":"Booklet","title":"Random Sampling","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"This sampler is implemented for test purposes and simply assigns 0 or 1 to each variable according to a given probability bias 0 le p le 1, which defaults to p = 05. After running the using Anneal command, RandomSampler.Optimizer will be available.","category":"page"},{"location":"booklet/#Exact-Solver-(Exaustive-Enumeration)","page":"Booklet","title":"Exact Solver (Exaustive Enumeration)","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"Also made to be used in tests, the ExactSolver.Optimizer interface runs through all possible state configurations, which implies in an exponential time complexity on the number of variables. Thus, only problems with no more than 20 variables should be provided.","category":"page"},{"location":"booklet/#MIQP-Solvers","page":"Booklet","title":"MIQP Solvers","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"The most accessible alternative to Annealers and Samplers are Mixed-Integer Quadratic Programming (MIQP) Solvers such as Gurobi and CPLEX. These are not intended to be of regular use alongside ToQUBO since reformulation usually makes things harder for these folks. Yet, there are still cases where they may be suitable for tests on small instances.","category":"page"},{"location":"booklet/#Custom-Error-Types","page":"Booklet","title":"Custom Error Types","text":"","category":"section"},{"location":"booklet/","page":"Booklet","title":"Booklet","text":"ToQUBO.QUBOError","category":"page"},{"location":"booklet/#ToQUBO.QUBOError","page":"Booklet","title":"ToQUBO.QUBOError","text":"QUBOError(msg::Union{Nothing, String})\n\nThis error indicates any failure during QUBO formulation\n\n\n\n\n\n","category":"type"},{"location":"assets/README/#Logo","page":"Logo","title":"Logo","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The ideia behind ToQUBO's logo comes from a wordplay in Portuguese and Spanish. The package's main purpose is to assemble QUBO Models, which sounds like cubo¹, the translation for cube.","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"(Image: ToQUBO.jl)","category":"page"},{"location":"assets/README/#Colors","page":"Logo","title":"Colors","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The colors were chosen according to Julia's Reference for logo graphics². Text color matches the innermost shape and renders fairly well in both light and dark background themes.","category":"page"},{"location":"assets/README/#Typography","page":"Logo","title":"Typography","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"MADETYPE Sunflower³ Font was used. It was converted to a SVG path through the Google Font to Svg Path⁴ online tool.","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"¹ IPA: [ˈkubʊ]","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"² github.com/JuliaLang/julia-logo-graphics","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"³ Licensed by the authors for use in this project","category":"page"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"⁴ danmarshall.github.io/google-font-to-svg-path","category":"page"},{"location":"assets/README/#Web-Icon-[![ToQUBO.jl](favicon.ico)](/docs/src/assets)","page":"Logo","title":"Web Icon (Image: ToQUBO.jl)","text":"","category":"section"},{"location":"assets/README/","page":"Logo","title":"Logo","text":"The icon used to decorate the documentation resembles an assembled version of the cube with its blue face making up the background.","category":"page"}]
+}
diff --git a/previews/PR50/siteinfo.js b/previews/PR50/siteinfo.js
new file mode 100644
index 00000000..7cde162d
--- /dev/null
+++ b/previews/PR50/siteinfo.js
@@ -0,0 +1 @@
+var DOCUMENTER_CURRENT_VERSION = "previews/PR50";
diff --git a/versions.js b/versions.js
new file mode 100644
index 00000000..4ec0f8f9
--- /dev/null
+++ b/versions.js
@@ -0,0 +1,5 @@
+var DOC_VERSIONS = [
+ "dev",
+];
+var DOCUMENTER_NEWEST = "dev";
+var DOCUMENTER_STABLE = "dev";