From f2bdb6ff494fd6f8bd0a0e046926a5dfa0b96bd2 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Wed, 22 May 2024 06:19:34 +0000 Subject: [PATCH] build based on 4e2094f --- dev/.documenter-siteinfo.json | 2 +- dev/assets/documenter.js | 923 +++++++++++++++---------- dev/assets/themes/documenter-dark.css | 2 +- dev/assets/themes/documenter-light.css | 2 +- dev/atoms/index.html | 54 +- dev/index.html | 2 +- dev/moments/index.html | 6 +- dev/objects.inv | Bin 0 -> 935 bytes dev/search_index.js | 2 +- 9 files changed, 577 insertions(+), 416 deletions(-) create mode 100644 dev/objects.inv diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index 1d3c64c..2d40ba6 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2023-12-07T15:41:16","documenter_version":"1.2.1"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.3","generation_timestamp":"2024-05-22T06:19:30","documenter_version":"1.4.1"}} \ No newline at end of file diff --git a/dev/assets/documenter.js b/dev/assets/documenter.js index f531160..c6562b5 100644 --- a/dev/assets/documenter.js +++ b/dev/assets/documenter.js @@ -4,7 +4,6 @@ requirejs.config({ 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min', 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min', - 'minisearch': 'https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min', 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min', 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', @@ -103,9 +102,10 @@ $(document).on("click", ".docstring header", function () { }); }); -$(document).on("click", ".docs-article-toggle-button", function () { +$(document).on("click", ".docs-article-toggle-button", function (event) { let articleToggleTitle = "Expand docstring"; let navArticleToggleTitle = "Expand all docstrings"; + let animationSpeed = event.noToggleAnimation ? 0 : 400; debounce(() => { if (isExpanded) { @@ -116,7 +116,7 @@ $(document).on("click", ".docs-article-toggle-button", function () { isExpanded = false; - $(".docstring section").slideUp(); + $(".docstring section").slideUp(animationSpeed); } else { $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); $(".docstring-article-toggle-button") @@ -127,7 +127,7 @@ $(document).on("click", ".docs-article-toggle-button", function () { articleToggleTitle = "Collapse docstring"; navArticleToggleTitle = "Collapse all docstrings"; - $(".docstring section").slideDown(); + $(".docstring section").slideDown(animationSpeed); } $(this).prop("title", navArticleToggleTitle); @@ -224,224 +224,465 @@ $(document).ready(function () { }) //////////////////////////////////////////////////////////////////////////////// -require(['jquery', 'minisearch'], function($, minisearch) { - -// In general, most search related things will have "search" as a prefix. -// To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc +require(['jquery'], function($) { -let results = []; -let timer = undefined; +$(document).ready(function () { + let meta = $("div[data-docstringscollapsed]").data(); -let data = documenterSearchIndex["docs"].map((x, key) => { - x["id"] = key; // minisearch requires a unique for each object - return x; + if (meta?.docstringscollapsed) { + $("#documenter-article-toggle-button").trigger({ + type: "click", + noToggleAnimation: true, + }); + } }); -// list below is the lunr 2.1.3 list minus the intersect with names(Base) -// (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) -// ideally we'd just filter the original list but it's not available as a variable -const stopWords = new Set([ - "a", - "able", - "about", - "across", - "after", - "almost", - "also", - "am", - "among", - "an", - "and", - "are", - "as", - "at", - "be", - "because", - "been", - "but", - "by", - "can", - "cannot", - "could", - "dear", - "did", - "does", - "either", - "ever", - "every", - "from", - "got", - "had", - "has", - "have", - "he", - "her", - "hers", - "him", - "his", - "how", - "however", - "i", - "if", - "into", - "it", - "its", - "just", - "least", - "like", - "likely", - "may", - "me", - "might", - "most", - "must", - "my", - "neither", - "no", - "nor", - "not", - "of", - "off", - "often", - "on", - "or", - "other", - "our", - "own", - "rather", - "said", - "say", - "says", - "she", - "should", - "since", - "so", - "some", - "than", - "that", - "the", - "their", - "them", - "then", - "there", - "these", - "they", - "this", - "tis", - "to", - "too", - "twas", - "us", - "wants", - "was", - "we", - "were", - "what", - "when", - "who", - "whom", - "why", - "will", - "would", - "yet", - "you", - "your", -]); - -let index = new minisearch({ - fields: ["title", "text"], // fields to index for full-text search - storeFields: ["location", "title", "text", "category", "page"], // fields to return with search results - processTerm: (term) => { - let word = stopWords.has(term) ? null : term; - if (word) { - // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names - word = word - .replace(/^[^a-zA-Z0-9@!]+/, "") - .replace(/[^a-zA-Z0-9@!]+$/, ""); - } +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { - return word ?? null; - }, - // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not find anything if searching for "add!", only for the entire qualification - tokenize: (string) => string.split(/[\s\-\.]+/), - // options which will be applied during the search - searchOptions: { - boost: { title: 100 }, - fuzzy: 2, +/* +To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc + +PSEUDOCODE: + +Searching happens automatically as the user types or adjusts the selected filters. +To preserve responsiveness, as much as possible of the slow parts of the search are done +in a web worker. Searching and result generation are done in the worker, and filtering and +DOM updates are done in the main thread. The filters are in the main thread as they should +be very quick to apply. This lets filters be changed without re-searching with minisearch +(which is possible even if filtering is on the worker thread) and also lets filters be +changed _while_ the worker is searching and without message passing (neither of which are +possible if filtering is on the worker thread) + +SEARCH WORKER: + +Import minisearch + +Build index + +On message from main thread + run search + find the first 200 unique results from each category, and compute their divs for display + note that this is necessary and sufficient information for the main thread to find the + first 200 unique results from any given filter set + post results to main thread + +MAIN: + +Launch worker + +Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) + +On text update + if worker is not running, launch_search() + +launch_search + set worker_is_running to true, set last_search_text to the search text + post the search query to worker + +on message from worker + if last_search_text is not the same as the text in the search field, + the latest search result is not reflective of the latest search query, so update again + launch_search() + otherwise + set worker_is_running to false + + regardless, display the new search results to the user + save the unfiltered_results as a global + update_search() + +on filter click + adjust the filter selection + update_search() + +update_search + apply search filters by looping through the unfiltered_results and finding the first 200 + unique results that match the filters + + Update the DOM +*/ + +/////// SEARCH WORKER /////// + +function worker_function(documenterSearchIndex, documenterBaseURL, filters) { + importScripts( + "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" + ); + + let data = documenterSearchIndex.map((x, key) => { + x["id"] = key; // minisearch requires a unique for each object + return x; + }); + + // list below is the lunr 2.1.3 list minus the intersect with names(Base) + // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) + // ideally we'd just filter the original list but it's not available as a variable + const stopWords = new Set([ + "a", + "able", + "about", + "across", + "after", + "almost", + "also", + "am", + "among", + "an", + "and", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "does", + "either", + "ever", + "every", + "from", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "into", + "it", + "its", + "just", + "least", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "who", + "whom", + "why", + "will", + "would", + "yet", + "you", + "your", + ]); + + let index = new MiniSearch({ + fields: ["title", "text"], // fields to index for full-text search + storeFields: ["location", "title", "text", "category", "page"], // fields to return with results processTerm: (term) => { let word = stopWords.has(term) ? null : term; if (word) { + // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names word = word .replace(/^[^a-zA-Z0-9@!]+/, "") .replace(/[^a-zA-Z0-9@!]+$/, ""); + + word = word.toLowerCase(); } return word ?? null; }, + // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not + // find anything if searching for "add!", only for the entire qualification tokenize: (string) => string.split(/[\s\-\.]+/), - }, -}); + // options which will be applied during the search + searchOptions: { + prefix: true, + boost: { title: 100 }, + fuzzy: 2, + }, + }); -index.addAll(data); + index.addAll(data); + + /** + * Used to map characters to HTML entities. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const htmlEscapes = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + }; + + /** + * Used to match HTML entities and HTML characters. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const reUnescapedHtml = /[&<>"']/g; + const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** + * Escape function from lodash + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + function escape(string) { + return string && reHasUnescapedHtml.test(string) + ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) + : string || ""; + } -let filters = [...new Set(data.map((x) => x.category))]; -var modal_filters = make_modal_body_filters(filters); -var filter_results = []; + /** + * 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})`; + } -$(document).on("keyup", ".documenter-search-input", function (event) { - // Adding a debounce to prevent disruptions from super-speed typing! - debounce(() => update_search(filter_results), 300); + let textindex = new RegExp(`${querystring}`, "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 + + text = text.length ? escape(text) : ""; + + let display_result = text.length + ? "..." + + text.replace( + new RegExp(`${escape(querystring)}`, "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 = ` + +
+
${escape(result.title)}
+
${result.category}
+
+

+ ${display_result} +

+
+ ${display_link} +
+
+ ${search_divider} + `; + + return result_div; + } + + self.onmessage = function (e) { + let query = e.data; + let results = index.search(query, { + filter: (result) => { + // Only return relevant results + return result.score >= 1; + }, + }); + + // Pre-filter to deduplicate and limit to 200 per category to the extent + // possible without knowing what the filters are. + let filtered_results = []; + let counts = {}; + for (let filter of filters) { + counts[filter] = 0; + } + let present = {}; + + for (let result of results) { + cat = result.category; + cnt = counts[cat]; + if (cnt < 200) { + id = cat + "---" + result.location; + if (present[id]) { + continue; + } + present[id] = true; + filtered_results.push({ + location: result.location, + category: cat, + div: make_search_result(result, query), + }); + } + } + + postMessage(filtered_results); + }; +} + +// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! +const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), +]; +const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; +const worker_blob = new Blob([worker_str], { type: "text/javascript" }); +const worker = new Worker(URL.createObjectURL(worker_blob)); + +/////// SEARCH MAIN /////// + +// Whether the worker is currently handling a search. This is a boolean +// as the worker only ever handles 1 or 0 searches at a time. +var worker_is_running = false; + +// The last search text that was sent to the worker. This is used to determine +// if the worker should be launched again when it reports back results. +var last_search_text = ""; + +// The results of the last search. This, in combination with the state of the filters +// in the DOM, is used compute the results to display on calls to update_search. +var unfiltered_results = []; + +// Which filter is currently selected +var selected_filter = ""; + +$(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } }); +function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); +} + +worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } + + unfiltered_results = e.data; + update_search(); +}; + $(document).on("click", ".search-filter", function () { if ($(this).hasClass("search-filter-selected")) { - $(this).removeClass("search-filter-selected"); + selected_filter = ""; } else { - $(this).addClass("search-filter-selected"); + selected_filter = $(this).text().toLowerCase(); } - // Adding a debounce to prevent disruptions from crazy clicking! - debounce(() => get_filters(), 300); + // This updates search results and toggles classes for UI: + update_search(); }); -/** - * A debounce function, takes a function and an optional timeout in milliseconds - * - * @function callback - * @param {number} timeout - */ -function debounce(callback, timeout = 300) { - clearTimeout(timer); - timer = setTimeout(callback, timeout); -} - /** * Make/Update the search component - * - * @param {string[]} selected_filters */ -function update_search(selected_filters = []) { - let initial_search_body = ` -
Type something to get started!
- `; - +function update_search() { let querystring = $(".documenter-search-input").val(); if (querystring.trim()) { - results = index.search(querystring, { - filter: (result) => { - // Filtering results - if (selected_filters.length === 0) { - return result.score >= 1; - } else { - return ( - result.score >= 1 && selected_filters.includes(result.category) - ); - } - }, - }); + if (selected_filter == "") { + results = unfiltered_results; + } else { + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); + } let search_result_container = ``; + let modal_filters = make_modal_body_filters(); let search_divider = `
`; if (results.length) { @@ -449,19 +690,23 @@ function update_search(selected_filters = []) { let count = 0; let search_results = ""; - results.forEach(function (result) { - if (result.location) { - // Checking for duplication of results for the same page - if (!links.includes(result.location)) { - search_results += make_search_result(result, querystring); - count++; - } - + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; links.push(result.location); } - }); + } - let result_count = `
${count} result(s)
`; + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; search_result_container = `
@@ -490,125 +735,37 @@ function update_search(selected_filters = []) { $(".search-modal-card-body").html(search_result_container); } else { - filter_results = []; - modal_filters = make_modal_body_filters(filters, filter_results); - if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { $(".search-modal-card-body").addClass("is-justify-content-center"); } - $(".search-modal-card-body").html(initial_search_body); + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); } } /** * Make the modal filter html * - * @param {string[]} filters - * @param {string[]} selected_filters * @returns string */ -function make_modal_body_filters(filters, selected_filters = []) { - let str = ``; - - filters.forEach((val) => { - if (selected_filters.includes(val)) { - str += `${val}`; - } else { - str += `${val}`; - } - }); +function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); - let filter_html = ` + return `
Filters: ${str} -
- `; - - 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 = ` - -
-
${result.title}
-
${result.category}
-
-

- ${display_result} -

-
- ${display_link} -
-
- ${search_divider} - `; - - return result_div; -} - -/** - * Get selected filters, remake the filter html and lastly update the search modal - */ -function get_filters() { - let ele = $(".search-filters .search-filter-selected").get(); - filter_results = ele.map((x) => $(x).text().toLowerCase()); - modal_filters = make_modal_body_filters(filters, filter_results); - update_search(filter_results); +
`; } }) @@ -635,103 +792,107 @@ $(document).ready(function () { //////////////////////////////////////////////////////////////////////////////// require(['jquery'], function($) { -let search_modal_header = ` - -`; - -let initial_search_body = ` -
Type something to get started!
-`; - -let search_modal_footer = ` - -`; - -$(document.body).append( - ` - source diff --git a/dev/index.html b/dev/index.html index bdfdd53..41c09d7 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Index · MultivariateMoments
+Index · MultivariateMoments
diff --git a/dev/moments/index.html b/dev/moments/index.html index 6085062..a62c1ae 100644 --- a/dev/moments/index.html +++ b/dev/moments/index.html @@ -1,4 +1,4 @@ -Moments and expectation · MultivariateMoments

Moments and expectation

Moment

Given a measure $\mu$ and a monomial $m$, the moment $m$ of the measure is defined by the expectation $\mathbb{E}_\mu[m]$. Given a monomial and a value for the moment, a moment can be created using the moment function

The moment function returns an AbstractMoment which is a subtype of AbstractMomentLike. An AbstractMomentLike is a type that can act like an AbstractMoment (it is similar to MultivariatePolynomials' AbstractMonomialLike, AbstractTermLike and AbstractPolynomialLike), that is, it implements the following two functions

Measure

Given a monomials and a values for the moments, a "measure" can be created using the measure function

MultivariateMoments.measureFunction
measure(a::AbstractVector{T}, X::AbstractVector{<:AbstractMonomial}; rtol=Base.rtoldefault(T), atol=zero(T))

Creates a measure with moments moment(a[i], X[i]) for each i. An error is thrown if there exists i and j such that X[i] == X[j] but !isapprox(a[i], a[j]; rtol=rtol, atol=atol).

source

The measure function returns an AbstractMeasure which is a subtype of AbstractMeasureLike. Note that it does not actually compute the probability density function of a measure having these moments, it simply stores a vector of moments belonging to a hypothetical measure. However, it acts like a measure when taking its scalar product with a polynomial.

An AbstractMeasureLike is a type that can act like an AbstractMeasure, that is, it implements the following two functions

MultivariatePolynomials.variablesMethod
variables(μ::AbstractMeasureLike)

Returns the variables of μ in decreasing order. Just like in MultivariatePolynomials, it could contain variables of zero degree in every monomial.

source

The moments of the dirac measure for a vector of monomials can be obtained by the dirac function

MultivariateMoments.diracFunction
dirac(X::AbstractVector{<:AbstractMoment}, s::AbstractSubstitution...)

Creates the dirac measure by evaluating the moments of X using s.

Examples

Calling dirac([x*y, x*y^2], x=>3, y=>2) should the measure with moment x*y of value 6 and moment x*y^2 of value 12.

source

Expectation

The expectation of polynomial with respect to a measure can be computed either using MultivariateMoments.expectation or using the Base.dot scalar product.

MultivariateMoments.expectationFunction
MultivariateMoments.expectation(μ::AbstractMeasureLike, p::AbstractPolynomialLike)
-MultivariateMoments.expectation(p::AbstractPolynomialLike, μ::AbstractMeasureLike)

Computes the expectation $\mathbb{E}_{\mu}[p]$.

source
+Moments and expectation · MultivariateMoments

Moments and expectation

Moment

Given a measure $\mu$ and a monomial $m$, the moment $m$ of the measure is defined by the expectation $\mathbb{E}_\mu[m]$. Given a monomial and a value for the moment, a moment can be created using the moment function

The moment function returns an AbstractMoment which is a subtype of AbstractMomentLike. An AbstractMomentLike is a type that can act like an AbstractMoment (it is similar to MultivariatePolynomials' AbstractMonomialLike, AbstractTermLike and AbstractPolynomialLike), that is, it implements the following two functions

Measure

Given a monomials and a values for the moments, a "moment vector" can be created using the moment_vector function

MultivariateMoments.moment_vectorFunction
moment_vector(values::AbstractVector{T}, monos::AbstractVector{<:AbstractMonomial}; rtol=Base.rtoldefault(T), atol=zero(T))

Creates a measure with moments moment(values[i], monos[i]) for each i. An error is thrown if there exists i and j such that monos[i] == monos[j] but !isapprox(values[i], values[j]; rtol=rtol, atol=atol).

source

The moment_vector function returns an AbstractMeasure which is a subtype of AbstractMeasureLike. Note that it does not actually compute the probability density function of a measure having these moments, it simply stores a vector of moments belonging to a hypothetical measure. However, it acts like a measure when taking its scalar product with a polynomial.

An AbstractMeasureLike is a type that can act like an AbstractMeasure, that is, it implements the following two functions

MultivariatePolynomials.variablesMethod
variables(μ::MomentVector)

Returns the variables of μ in decreasing order. Just like in MultivariatePolynomials, it could contain variables of zero degree in every monomial.

source

The moments of the dirac measure for a vector of monomials can be obtained by the dirac function

MultivariateMoments.diracFunction
dirac(X::AbstractVector{<:AbstractMoment}, s::AbstractSubstitution...)

Creates the dirac measure by evaluating the moments of X using s.

Examples

Calling dirac([x*y, x*y^2], x=>3, y=>2) should the measure with moment x*y of value 6 and moment x*y^2 of value 12.

source

Expectation

The expectation of polynomial with respect to a measure can be computed either using MultivariateMoments.expectation or using the Base.dot scalar product.

MultivariateMoments.expectationFunction
MultivariateMoments.expectation(μ::AbstractMeasureLike, p::AbstractPolynomialLike)
+MultivariateMoments.expectation(p::AbstractPolynomialLike, μ::AbstractMeasureLike)

Computes the expectation $\mathbb{E}_{\mu}[p]$.

source
diff --git a/dev/objects.inv b/dev/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..d21be23ce70b8ef7866c9c71d54bef78e1bc1c81 GIT binary patch literal 935 zcmV;Y16cecAX9K?X>NERX>N99Zgg*Qc_4OWa&u{KZXhxWBOp+6Z)#;@bUGkSb!>EL zc42a9VRU6pZ*666baM(LAXa5^b7^mGIv_AEG%hv@BOp|0Wgv28ZDDC{WMy(7Z)PBL zXlZjGW@&6?AZc?TV{dJ6a%FRKWn>_Ab7^j8AbMQa?>ynzUL{-lpNjC zawzoHHtA3%VVI_rqh}*;Y*EQFlAIaoZIt58VV_lB$@9#fhdp%riOoR+S7L3BG>!VFhy8W~6yEonUZ}+*{01nCw zRyLNcGPt0^b^1-ic2wkAWO~{ECgY}9JFr!|!=~Lky0pTI#TgB)LUhP-8x33W-NM`G z&+B>I@b3dkPBn#WXgTtYUFdm^LCayd(FGGvk%a6qVlmStY*J*lDtn>!*9QEGG)eVH zuqjIS;8oy>6g*NiO9}=ungT0O`6V(CPj|-Cpf|X8k9|XD7?&`22oXFlG)Ah(b0PJs z%~?7iyJx3cLR_*0#}X*H5;8{VThJbzOi-G?6j*t-d%@hn>U#kaqXadrMAxeamiKFz zRT0~OimAC=zMuik5M&Q?G-+l8-A_15=|o?rf}whxd(s6M8v}XtV@!*grnBa%>Xdt+ zK_;m5dQ)a~GuhJDqor<_!ct=;=^Q*SA?s;!l z**_JGsT_RTwY&_A;_tr{mK!zjI2PWFT+9`ourCUwA2r&gJ4`**oSWWBN+MNXSr0{e z4&E+GKuBTk>D)~b+Ke&J*GrLa&6PX(G*C%E;UR)yv$BtpFC{L=N-!h(-a2eqeg%pu zcTgGSIz{5az|oxhP79W(823uuUd*k|=vxj6j!F%1rFxqH)za8V_y2Qg&6P8khCskf zDf0ug462zw;!Vwb-_~eaW#>!78wR>RGsChf0q$=PLTqNTJ2Y@Q^(V3Y#_^`eaw>D6 z{>sw?vln~iR$V!hqy0(X*`v`z&u<#(lN6axJKM9mhZ2<?5 J{{i2N%LeRruSNg> literal 0 HcmV?d00001 diff --git a/dev/search_index.js b/dev/search_index.js index 1830374..143baae 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"moments/#Moments-and-expectation","page":"Moments and expectation","title":"Moments and expectation","text":"","category":"section"},{"location":"moments/#Moment","page":"Moments and expectation","title":"Moment","text":"","category":"section"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"Given a measure mu and a monomial m, the moment m of the measure is defined by the expectation mathbbE_mum. Given a monomial and a value for the moment, a moment can be created using the moment function","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"moment","category":"page"},{"location":"moments/#MultivariateMoments.moment","page":"Moments and expectation","title":"MultivariateMoments.moment","text":"moment(α, m::AbstractMonomial)\n\nCreates the moment of the monomial m of value α.\n\n\n\n\n\n","category":"function"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The moment function returns an AbstractMoment which is a subtype of AbstractMomentLike. An AbstractMomentLike is a type that can act like an AbstractMoment (it is similar to MultivariatePolynomials' AbstractMonomialLike, AbstractTermLike and AbstractPolynomialLike), that is, it implements the following two functions","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"moment_value\nMultivariatePolynomials.monomial(::MultivariateMoments.Moment)","category":"page"},{"location":"moments/#MultivariateMoments.moment_value","page":"Moments and expectation","title":"MultivariateMoments.moment_value","text":"moment_value(m::AbstractMomentLike)\n\nReturns the value of the moment m.\n\nExamples\n\nCalling moment_value(moment(3.1, x*y^2)) should return 3.1.\n\n\n\n\n\n","category":"function"},{"location":"moments/#MultivariatePolynomials.monomial-Tuple{Moment}","page":"Moments and expectation","title":"MultivariatePolynomials.monomial","text":"monomial(m::AbstractMomentLike)\n\nReturns the monomial of the moment m.\n\nExamples\n\nCalling monomial(moment(3.1, x*y^2)) should return x*y^2.\n\n\n\n\n\n","category":"method"},{"location":"moments/#Measure","page":"Moments and expectation","title":"Measure","text":"","category":"section"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"Given a monomials and a values for the moments, a \"measure\" can be created using the measure function","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"measure","category":"page"},{"location":"moments/#MultivariateMoments.measure","page":"Moments and expectation","title":"MultivariateMoments.measure","text":"measure(a::AbstractVector{T}, X::AbstractVector{<:AbstractMonomial}; rtol=Base.rtoldefault(T), atol=zero(T))\n\nCreates a measure with moments moment(a[i], X[i]) for each i. An error is thrown if there exists i and j such that X[i] == X[j] but !isapprox(a[i], a[j]; rtol=rtol, atol=atol).\n\n\n\n\n\n","category":"function"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The measure function returns an AbstractMeasure which is a subtype of AbstractMeasureLike. Note that it does not actually compute the probability density function of a measure having these moments, it simply stores a vector of moments belonging to a hypothetical measure. However, it acts like a measure when taking its scalar product with a polynomial.","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"An AbstractMeasureLike is a type that can act like an AbstractMeasure, that is, it implements the following two functions","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"MultivariatePolynomials.variables(::MultivariateMoments.Measure)\nMultivariatePolynomials.monomials(::MultivariateMoments.Measure)\nMultivariatePolynomials.maxdegree(::MultivariateMoments.Measure)\nMultivariatePolynomials.mindegree(::MultivariateMoments.Measure)\nMultivariatePolynomials.extdegree(::MultivariateMoments.Measure)\nmoments","category":"page"},{"location":"moments/#MultivariatePolynomials.variables-Tuple{Measure}","page":"Moments and expectation","title":"MultivariatePolynomials.variables","text":"variables(μ::AbstractMeasureLike)\n\nReturns the variables of μ in decreasing order. Just like in MultivariatePolynomials, it could contain variables of zero degree in every monomial.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.monomials-Tuple{Measure}","page":"Moments and expectation","title":"MultivariatePolynomials.monomials","text":"monomials(μ::AbstractMeasureLike)\n\nReturns an iterator over the monomials of μ sorted in the decreasing order.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.maxdegree-Tuple{Measure}","page":"Moments and expectation","title":"MultivariatePolynomials.maxdegree","text":"maxdegree(μ::AbstractMeasureLike)\n\nReturns the maximal degree of the monomials of μ.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.mindegree-Tuple{Measure}","page":"Moments and expectation","title":"MultivariatePolynomials.mindegree","text":"mindegree(μ::AbstractMeasureLike)\n\nReturns the minimal degree of the monomials of μ.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.extdegree-Tuple{Measure}","page":"Moments and expectation","title":"MultivariatePolynomials.extdegree","text":"extdegree(μ::AbstractMeasureLike)\n\nReturns the extremal degrees of the monomials of μ.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariateMoments.moments","page":"Moments and expectation","title":"MultivariateMoments.moments","text":"moments(μ::AbstractMeasureLike)\n\nReturns an iterator over the moments of μ sorted in decreasing order of monomial.\n\n\n\n\n\n","category":"function"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The moments of the dirac measure for a vector of monomials can be obtained by the dirac function","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"dirac","category":"page"},{"location":"moments/#MultivariateMoments.dirac","page":"Moments and expectation","title":"MultivariateMoments.dirac","text":"dirac(X::AbstractVector{<:AbstractMoment}, s::AbstractSubstitution...)\n\nCreates the dirac measure by evaluating the moments of X using s.\n\nExamples\n\nCalling dirac([x*y, x*y^2], x=>3, y=>2) should the measure with moment x*y of value 6 and moment x*y^2 of value 12.\n\n\n\n\n\n","category":"function"},{"location":"moments/#Expectation","page":"Moments and expectation","title":"Expectation","text":"","category":"section"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The expectation of polynomial with respect to a measure can be computed either using MultivariateMoments.expectation or using the Base.dot scalar product.","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"MultivariateMoments.expectation\nMultivariateMoments.dot","category":"page"},{"location":"moments/#MultivariateMoments.expectation","page":"Moments and expectation","title":"MultivariateMoments.expectation","text":"MultivariateMoments.expectation(μ::AbstractMeasureLike, p::AbstractPolynomialLike)\nMultivariateMoments.expectation(p::AbstractPolynomialLike, μ::AbstractMeasureLike)\n\nComputes the expectation mathbbE_mup.\n\n\n\n\n\n","category":"function"},{"location":"moments/#LinearAlgebra.dot","page":"Moments and expectation","title":"LinearAlgebra.dot","text":"dot(μ::AbstractMeasureLike, p::AbstractPolynomialLike)\ndot(p::AbstractPolynomialLike, μ::AbstractMeasureLike)\n\nSee expectation\n\n\n\n\n\n","category":"function"},{"location":"#MultivariateMoments-–-Multivariate-Moments-for-Julia","page":"Index","title":"MultivariateMoments –- Multivariate Moments for Julia","text":"","category":"section"},{"location":"","page":"Index","title":"Index","text":"Extension of MultivariatePolynomials to moments of multivariate measures and their scalar product with polynomials. It also includes the extraction of atomic measures from moment matrices which is related to the moment problem.","category":"page"},{"location":"#Contents","page":"Index","title":"Contents","text":"","category":"section"},{"location":"","page":"Index","title":"Index","text":"Pages = [\"moments.md\", \"atoms.md\"]\nDepth = 2","category":"page"},{"location":"atoms/#Atoms-extration","page":"Atoms extraction","title":"Atoms extration","text":"","category":"section"},{"location":"atoms/#Vectorized-matrix","page":"Atoms extraction","title":"Vectorized matrix","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"SymMatrix\nVectorizedHermitianMatrix\nsquare_getindex\nsymmetric_setindex!","category":"page"},{"location":"atoms/#MultivariateMoments.SymMatrix","page":"Atoms extraction","title":"MultivariateMoments.SymMatrix","text":"struct SymMatrix{T} <: AbstractMatrix{T}\n Q::Vector{T}\n n::Int\nend\n\nSymmetric n times n matrix storing the vectorized upper triangular part of the matrix in the Q vector (this corresponds to the vectorized form of MathOptInterface.PositiveSemidefiniteConeTriangle). It implement the AbstractMatrix interface except for setindex! as it might break its symmetry. The symmetric_setindex! function should be used instead.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.VectorizedHermitianMatrix","page":"Atoms extraction","title":"MultivariateMoments.VectorizedHermitianMatrix","text":"struct VectorizedHermitianMatrix{T} <: AbstractMatrix{Complex{T}}\n Q::Vector{T}\n n::Int\nend\n\nHermitian n times n matrix storing the vectorized upper triangular real part of the matrix followed by the vectorized upper triangular imaginary part in the Q vector (this corresponds to the vectorized form of ComplexOptInterface.HermitianPositiveSemidefiniteConeTriangle). It implement the AbstractMatrix interface except for setindex! as it might break its symmetry. The symmetric_setindex! function should be used instead.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.square_getindex","page":"Atoms extraction","title":"MultivariateMoments.square_getindex","text":"square_getindex!(Q::SymMatrix, I)\n\nReturn the SymMatrix corresponding to Q[I, I].\n\n\n\n\n\nsquare_getindex!(Q::VectorizedHermitianMatrix, I)\n\nReturn the VectorizedHermitianMatrix corresponding to Q[I, I].\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.symmetric_setindex!","page":"Atoms extraction","title":"MultivariateMoments.symmetric_setindex!","text":"symmetric_setindex!(Q::SymMatrix, value, i::Integer, j::Integer)\n\nSet Q[i, j] and Q[j, i] to the value value.\n\n\n\n\n\nsymmetric_setindex!(Q::VectorizedHermitianMatrix, value, i::Integer, j::Integer)\n\nSet Q[i, j] to the value value and Q[j, i] to the value -value.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#Moment-matrix","page":"Atoms extraction","title":"Moment matrix","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"MomentMatrix\nmoment_matrix","category":"page"},{"location":"atoms/#MultivariateMoments.MomentMatrix","page":"Atoms extraction","title":"MultivariateMoments.MomentMatrix","text":"mutable struct MomentMatrix{T, B<:MultivariateBases.AbstractPolynomialBasis, MT<:AbstractMatrix{T}} <: AbstractMeasureLike{T}\n Q::MT\n basis::B\n support::Union{Nothing, AlgebraicSet}\nend\n\nMeasure nu represented by the moments of the monomial matrix x x^top in the symmetric matrix Q. The set of points that are zeros of all the polynomials p such that mathbbE_nup = 0 is stored in the field support when it is computed.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.moment_matrix","page":"Atoms extraction","title":"MultivariateMoments.moment_matrix","text":"moment_matrix(μ::Measure, x)\n\nCreates a matrix the moment matrix for the moment matrix x x^top using the moments of μ.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#Atomic-measure","page":"Atoms extraction","title":"Atomic measure","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"WeightedDiracMeasure\nAtomicMeasure","category":"page"},{"location":"atoms/#MultivariateMoments.WeightedDiracMeasure","page":"Atoms extraction","title":"MultivariateMoments.WeightedDiracMeasure","text":"struct WeightedDiracMeasure{T}\n center::Vector{T}\n weight::T\nend\n\nRepresents a weighted dirac measure with centered at center and with weight weight.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AtomicMeasure","page":"Atoms extraction","title":"MultivariateMoments.AtomicMeasure","text":"struct AtomicMeasure{T, AT, V} <: AbstractMeasureLike{T}\n variables::V # Vector/Tuple of variables\n atoms::Vector{WeightedDiracMeasure{T, AT}} # Atoms of the measure\nend\n\nAn measure is said to be atomic if it is a sum of weighted dirac measures. For instance, eta = 2 delta_(1 0) + 3 delta_(12 12) is an atomic measure since it is a sum of the diracs centered at (1 0) and (12 12) and weighted respectively by 2 and 3. That is, mathbbE_etap = 2p(1 0) + 3p(12 12).\n\nThe AtomicMeasure struct stores an atomic measure where variables contains the variables and atoms contains atoms of the measure.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#Atoms-extraction","page":"Atoms extraction","title":"Atoms extraction","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"Given a MomentMatrix containing the moments of an atomic measure, atomic_measure attempts to recover the dirac centers and weights by first computing an algebraic system with the atom centers as solution with compute_support!.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"compute_support!\natomic_measure","category":"page"},{"location":"atoms/#MultivariateMoments.compute_support!","page":"Atoms extraction","title":"MultivariateMoments.compute_support!","text":"function compute_support!(ν::MomentMatrix, rank_check, solver) end\n\nComputes the support field of ν wth solver using a low-rank decomposition with the rank evaluated with rank_check.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.atomic_measure","page":"Atoms extraction","title":"MultivariateMoments.atomic_measure","text":"atomic_measure(ν::MomentMatrix, rank_check::RankCheck, [dec::LowRankLDLTAlgorithm], [solver::SemialgebraicSets.AbstractAlgebraicSolver])\n\nReturn an AtomicMeasure with the atoms of ν if it is atomic or nothing if ν is not atomic. The rank_check and dec parameters are passed as is to the low_rank_ldlt function. By default, dec is an instance of SVDLDLT. The extraction relies on the solution of a system of algebraic equations. using solver. For instance, given a MomentMatrix, μ, the following extract atoms using a rank_check of 1e-4 for the low-rank decomposition and homotopy continuation to solve the obtained system of algebraic equations.\n\nusing HomotopyContinuation\nsolver = SemialgebraicSetsHCSolver(; compile = false)\natoms = atomic_measure(ν, 1e-4, solver)\n\nIf no solver is given, the default solver of SemialgebraicSets is used which currently computes the Gröbner basis, then the multiplication matrices and then the Schur decomposition of a random combination of these matrices. For floating point arithmetics, homotopy continuation is recommended as it is more numerically stable than Gröbner basis computation.\n\n\n\n\n\n","category":"function"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"For the first step of compute_support!, there are two approaches. The first one is to exploit the flat extension to directly obtain the multiplication matrices.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"FlatExtension","category":"page"},{"location":"atoms/#MultivariateMoments.FlatExtension","page":"Atoms extraction","title":"MultivariateMoments.FlatExtension","text":"struct FlatExtension{\n MMS<:SemialgebraicSets.AbstractMultiplicationMatricesSolver,\n}\n multiplication_matrices_solver::MMS\nend\n\nGiven a moment matrix satisfying the flat extension property described in [L09, Section 5.3], computes the multiplication matrices using the formula given in [L09, Lemma 6.21] or [LLR08, Section 4.4.4]. Given the multiplication matrices, the solutions are obtained with multiplication_matrices_solver.\n\n[L09] Laurent, Monique. Sums of squares, moment matrices and optimization over polynomials. Emerging applications of algebraic geometry (2009): 157-270.\n\n[LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp. Semidefinite characterization and computation of zero-dimensional real radical ideals. Foundations of Computational Mathematics 8 (2008): 607-647.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The second approach is to first obtain the image space of the moment matrix, represented as a MacaulayNullspace and to then compute the multiplication matrices from this image space. This is implemented by the ImageSpaceSolver.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"MacaulayNullspace\nImageSpaceSolver","category":"page"},{"location":"atoms/#MultivariateMoments.MacaulayNullspace","page":"Atoms extraction","title":"MultivariateMoments.MacaulayNullspace","text":"struct MacaulayNullspace{T,MT<:AbstractMatrix{T},BT}\n matrix::MT\n basis::BT\n accuracy::T\nend\n\nThis matrix with rows indexed by basis can either be interpreted as the right null space of a Macaulay matrix with columns indexed by basis (resp. or the image space of a moment matrix with rows and columns indexed by basis). The value of matrix[i, j] should be interpreted as the value of the ith element of basis for the jth generator of the null space (resp. image) space.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.ImageSpaceSolver","page":"Atoms extraction","title":"MultivariateMoments.ImageSpaceSolver","text":"struct ImageSpaceSolver{A<:LowRankLDLTAlgorithm,S<:MacaulayNullspaceSolver}\n ldlt::A\n null::S\nend\n\nComputes the image space of the moment matrix using ldlt and then solve it with null.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"This image space is obtained from a low rank LDLT decomposition of the moment matrix. This decomposition can either be obtained by a cholesky or SVD decomposition from which we remove the rows corresponding to the negligeable eigen/singular values.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"LowRankLDLTAlgorithm\nShiftCholeskyLDLT\nSVDLDLT\nlow_rank_ldlt\nLowRankLDLT","category":"page"},{"location":"atoms/#MultivariateMoments.LowRankLDLTAlgorithm","page":"Atoms extraction","title":"MultivariateMoments.LowRankLDLTAlgorithm","text":"LowRankLDLTAlgorithm\n\nMethod for computing a r times n matrix U of a n times n rank r psd matrix Q such that Q = U'U.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.ShiftCholeskyLDLT","page":"Atoms extraction","title":"MultivariateMoments.ShiftCholeskyLDLT","text":"ShiftCholeskyLDLT <: LowRankLDLTAlgorithm\n\nShift the matrix by shift times the identity matrix before cholesky.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.SVDLDLT","page":"Atoms extraction","title":"MultivariateMoments.SVDLDLT","text":"SVDLDLT <: LowRankLDLTAlgorithm\n\nUse SVD decomposition.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.low_rank_ldlt","page":"Atoms extraction","title":"MultivariateMoments.low_rank_ldlt","text":"MultivariateMoments.low_rank_ldlt(Q::AbstractMatrix, dec::LowRankLDLTAlgorithm, ranktol)\n\nReturns a r times n matrix U of a n times n rank r positive semidefinite matrix Q such that Q = U^top U. The rank of Q is the number of singular values larger than ranktol cdot sigma_1 where sigma_1 is the largest singular value.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.LowRankLDLT","page":"Atoms extraction","title":"MultivariateMoments.LowRankLDLT","text":"struct LowRankLDLT{T,Tr,C<:RankCheck}\n L::Matrix{T}\n singular_values::Vector{Tr}\n rank_check::C\nend\n\nLow-Rank cholesky decomposition L * Diagonal(singular_values) * L' of size (n, r) of a n x n matrix with singular values singular_values[1] > ... > singular_values[n]. The rank was chosen given singular_values using rank_check via the rank_from_singular_values function.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The choice of cutoff between the significant and negligeable eigen/singular values is parametrized by the following interface:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"RankCheck\nrank_from_singular_values\naccuracy\ndoubt","category":"page"},{"location":"atoms/#MultivariateMoments.RankCheck","page":"Atoms extraction","title":"MultivariateMoments.RankCheck","text":"abstract type RankCheck end\n\nMethod for computing the rank with rank_from_singular_values based on a list of singular values.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.rank_from_singular_values","page":"Atoms extraction","title":"MultivariateMoments.rank_from_singular_values","text":"rank_from_singular_values(σ, check::RankCheck)\n\nReturn the rank of a matrix with singular values σ (in decreasing order) using check.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.accuracy","page":"Atoms extraction","title":"MultivariateMoments.accuracy","text":"accuracy(σ, r, check::RankCheck)\n\nReturns a value measuring the accuracy of the rank check check returning rank r. This is used by Echelon to determine the accuracy to use for the Gaussian elimination.\n\n\n\n\n\naccuracy(chol::LowRankLDLT)\n\nReturn the ratio rtol = σ[r+1]/σ[1] where σ is the vector of singular values of the matrix for which chol is the rank-r Cholesky decomposition. This is a good relative tolerance to use with the matrix as σ[r+1] is the first singular value that was discarded.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.doubt","page":"Atoms extraction","title":"MultivariateMoments.doubt","text":"doubt(σ, check::RankCheck)\n\nReturns a value measuring the doubt of the rank check check. Lower values means more doubt so less certainty. This is used by FallbackRank for deciding whether the fallback should be used.\n\n\n\n\n\n","category":"function"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The rank check can be chosen among the following:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"UserRank\nFixedRank\nFixedRanks\nAbsoluteRankTol\nLeadingRelativeRankTol\nDifferentialRankTol\nLargestDifferentialRank\nFallbackRank","category":"page"},{"location":"atoms/#MultivariateMoments.UserRank","page":"Atoms extraction","title":"MultivariateMoments.UserRank","text":"struct UserRank <: RankCheck\n pagesize::Int\nend\n\nThe user chooses the rank given the singular values in a REPL.TerminalMenus.RadioMenu of page size pagesize.\n\nExample\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], UserRank())\nChoose the last significant singular value:\n 1.0\n 0.1\n > 0.05\n 1.0e-5\n 5.0e-6\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.FixedRank","page":"Atoms extraction","title":"MultivariateMoments.FixedRank","text":"struct FixedRank <: RankCheck\n r::Int\nend\n\nThe rank is hardcoded to r, independently of the singular values.\n\nExample\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], FixedRank(3))\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.FixedRanks","page":"Atoms extraction","title":"MultivariateMoments.FixedRanks","text":"mutable struct FixedRanks <: RankCheck\n r::Vector{Int}\n current::Int\nend\n\nThe ith rank is hardcoded to r[i], independently of the singular values. The field current indicates how many ranks have already been asked. When current is length(r), no rank can be asked anymore.\n\nExample\n\njulia> check = FixedRanks([2, 3])\nFixedRanks([2, 3], 0)\n\njulia> rank_from_singular_values([1, 1e-1, 5e-5, 1e-5, 5e-6], check)\n2\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], check)\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AbsoluteRankTol","page":"Atoms extraction","title":"MultivariateMoments.AbsoluteRankTol","text":"struct AbsoluteRankTol{T} <: RankCheck\n tol::T\nend\n\nThe rank is the number of singular values that are strictly larger than tol.\n\nExample\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], AbsoluteRankTol(1e-4))\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.LeadingRelativeRankTol","page":"Atoms extraction","title":"MultivariateMoments.LeadingRelativeRankTol","text":"struct LeadingRelativeRankTol{T} <: RankCheck\n tol::T\nend\n\nThe rank is the number of singular values that are strictly larger than tol * maximum(σ) where maximum(σ) is the largest singular value.\n\nExample\n\nWhen the matrix is obtained from a homogeneous problem where the scaling is irrelevant, LeadingRelativeRankTol may be preferable to AbsoluteRankTol as shown below\n\njulia> rank_from_singular_values(1e6 * [1, 1e-1, 5e-2, 1e-5, 5e-6], AbsoluteRankTol(1e-4))\n5\n\njulia> rank_from_singular_values(1e6 * [1, 1e-1, 5e-2, 1e-5, 5e-6], LeadingRelativeRankTol(1e-4))\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.DifferentialRankTol","page":"Atoms extraction","title":"MultivariateMoments.DifferentialRankTol","text":"struct DifferentialRankTol{T} <: RankCheck\n tol::T\nend\n\nThe rank is the number of singular values before a singular value (not included) is tol times the previous one (included).\n\nExample\n\nIt is sometimes difficult to figure out the tolerance to use in LeadingRelativeRankTol. For instance, choosing 1e-3 will consider 1e-3 in the example below as not part of the rank while DifferentialRankTol would include it because it is close to the previous singular value.\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-2, 5e-3, 1e-3, 1e-6, 5e-7], LeadingRelativeRankTol(1e-3))\n5\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-2, 5e-3, 1e-3, 1e-6, 5e-7], DifferentialRankTol(1e-2))\n6\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.LargestDifferentialRank","page":"Atoms extraction","title":"MultivariateMoments.LargestDifferentialRank","text":"struct LargestDifferentialRank <: RankCheck\nend\n\nThe rank is the number of singular values until the singular value that has the largest ratio with the next singular value.\n\nExample\n\nIt is sometimes difficult to figure out the tolerance to use in DifferentialRankTol. For instance, choosing 1e-2 will consider 1e-2, 5e-2 and 1e-3 in the example below as not part of the rank while LargestDifferentialRank would include them because there is a largest gap later.\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 1e-6, 5e-7], DifferentialRankTol(1e-2))\n1\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 1e-6, 5e-7], LargestDifferentialRank())\n4\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.FallbackRank","page":"Atoms extraction","title":"MultivariateMoments.FallbackRank","text":"struct FallbackRank{T,D,F} <: RankCheck\n tol::T\n default::D\n fallback::F\nend\n\nDefaults to checking the rank with default and falls back to fallback if the doubt is strictly larger than tol. By default, fallback is UserRank.\n\nExample\n\nThe advantage of UserRank is that the user get to see if the rank check is ambiguous and act accordingly. The downside is that it might be cumbersome if there are many rank checks to do. With FallbackRank, the user only has to sort out the tricky ones. In the example below, the first example is handled by LargestDifferentialRank. For the second one, the user sees that this is a tricky choice and can manually choose one of the two ranks, then see the result of the rest of his code using this value of the code and then choose the other rank and see the impact of this different choice.\n\njulia> check = FallbackRank(1e-1, LargestDifferentialRank())\nFallbackRank{Float64, LargestDifferentialRank, UserRank}(0.1, LargestDifferentialRank(), UserRank(8))\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 1e-6, 5e-7], check)\n4\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 5e-6, 5e-7], check)\nChoose the last significant singular value:\n > 1.0\n 0.01\n 0.05\n 0.001\n 5.0e-6\n 5.0e-7\n1\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 5e-6, 5e-7], check)\nChoose the last significant singular value:\n 1.0\n 0.01\n 0.05\n > 0.001\n 5.0e-6\n 5.0e-7\n4\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"Given the MacaulayNullspace, there are two approaches implemented to obtain the moment matrices:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"ShiftNullspace\nEchelon","category":"page"},{"location":"atoms/#MultivariateMoments.ShiftNullspace","page":"Atoms extraction","title":"MultivariateMoments.ShiftNullspace","text":"struct ShiftNullspace{D,C<:RankCheck} <: MacaulayNullspaceSolver\n check::C\nend\n\nFrom the MacaulayNullspace, computes multiplication matrices by exploiting the shift property of the rows [DBD12]. The rank check check is used to determine the standard monomials among the row indices of the null space.\n\n[DBD12] Dreesen, Philippe, Batselier, Kim, and De Moor, Bart. Back to the roots: Polynomial system solving, linear algebra, systems theory. IFAC Proceedings Volumes 45.16 (2012): 1203-1208.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.Echelon","page":"Atoms extraction","title":"MultivariateMoments.Echelon","text":"struct Echelon{D,S<:Union{Nothing,SemialgebraicSets.AbstractAlgebraicSolver}} <:\n MacaulayNullspaceSolver\n solver::S\nend\n\nGiven a MacaulayNullspace, computes its echelon form (corresponding to the Canonical Null Space of [D13]) with Gaussian elimination. From this echelon form, the left null space can easily be computed using using [HL05, (8)]. This left null space forms a system of polynomial equations.\n\nnote: Note\nIn the context of compute_support!, if the MacaulayNullspace was obtained using SVDLDLT, the left null space can easily be obtained from the singular vectors corresponding to the negligeable singular values that were removed. However, as mentioned [LLR08, Section 4.4.5], these will usually give an overdetermined bases. As shown in [S04, Section 10.8.2], it is desirable to avoid overdetermined bases because it could lead to inconsistencies in the basis for numerical reasons. For this reason, this method computes the left null space from the echelon form of the significant singular values instead.\n\nLet B be the set of monomials corresponding to the rows of the pivots of this echelon form. If the moment matrix satisfies the flat extension property described in [L09, Section 5.3] then all monomials of the border of B (as defined in [LLR08, (2.3)]) will correspond to a row of of the matrix. In that case, the polynomial of the system obtained by [HL05, (8)] form a rewriting family for B [L09, (2.16)] a.k.a. a B-border prebasis (as defined in [LLR08, (2.4)]). Therefore, they can be used to compute multiplication matrices.\n\n[HL05] Henrion, D. & Lasserre, J-B. Detecting Global Optimality and Extracting Solutions of GloptiPoly 2005\n\n[D13] Dreesen, Philippe. Back to the Roots: Polynomial System Solving Using Linear Algebra Ph.D. thesis (2013)\n\n[L09] Laurent, Monique. Sums of squares, moment matrices and optimization over polynomials. Emerging applications of algebraic geometry (2009): 157-270.\n\n[LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp. Semidefinite characterization and computation of zero-dimensional real radical ideals. Foundations of Computational Mathematics 8 (2008): 607-647.\n\n[S04] Stetter, Hans J. Numerical polynomial algebra. Society for Industrial and Applied Mathematics, 2004.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The Echelon uses the RowEchelon package to determine the independent rows (which is not numerically stable) while the ShiftNullspace uses RankChecks with the singular values so it should have better numerical behavior. They can either simply distinguish the dependency of rows with LinearDependence or use a sieve with StaircaseDependence to save some the computation of the singular values for some submatrices:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"LinearDependence\nStaircaseDependence\nBasisDependence","category":"page"},{"location":"atoms/#MultivariateMoments.LinearDependence","page":"Atoms extraction","title":"MultivariateMoments.LinearDependence","text":"@enum LinearDependence INDEPENDENT TRIVIAL DEPENDENT\n\nLinear dependence of the element of a basis representing the indices of the rows of a [MacaulayNullspace]. DEPENDENT indicates that it is linearly dependent to rows that appear earlier in the basis. TRIVIAL indicates that the element was not in the original basis so it is trivially independent.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.StaircaseDependence","page":"Atoms extraction","title":"MultivariateMoments.StaircaseDependence","text":"struct StaircaseDependence\n standard_or_corner::Bool\n linear::LinearDependence\nend\n\nDependence of the element of a basis representing the indices of the rows of a [MacaulayNullspace]. If the field standard_or_corner is true then the elements is either standard or is a corner (depending on the linear dependence encoded in the linear field). Otherwise, it is a border that is not a corner or it is not even a border. See LinearDependence for the linear field.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.BasisDependence","page":"Atoms extraction","title":"MultivariateMoments.BasisDependence","text":"struct BasisDependence{D,B<:MB.AbstractPolynomialBasis}\n basis::B\n dependence::Vector{D}\nend\n\nThe dependence between the elements of a basis.\n\ntip: Tip\nIf the number of variables is 2 or 3, it can be visualized with Plots.jl.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The relationship between the dependent and the independent rows are then stored in a BorderBasis. By default, calling solve with only a BorderBasisas argument or providing aSemialgebraicSets.AbstractMultiplicationMatricesSolveras second argument will try to construct the moment matrices from these and find the solutions from these moment matrices. Alternatively, give an [AlgebraicBorderSolver](@ref) or a [AlgebraicFallbackBorderSolver`](@ref) as second argument to solve the system formed by these relations with these instead.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"BorderBasis\nAlgebraicBorderSolver\nAlgebraicFallbackBorderSolver","category":"page"},{"location":"atoms/#MultivariateMoments.BorderBasis","page":"Atoms extraction","title":"MultivariateMoments.BorderBasis","text":"struct BorderBasis{D,T,MT<:AbstractMatrix{T},B}\n dependence::BasisDependence{D,B}\n matrix::MT\nend\n\nThis matrix with rows indexed by standard and columns indexed by border a standard-border basis of the ideal border .- matrix' * standard [LLR08, Section 2.5]. For solving this with a multiplication matrix solver, it is necessary for the basis border to be a superset of the set of corners of standard and it is sufficient for it to be the border of standard.\n\n[LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp. Semidefinite characterization and computation of zero-dimensional real radical ideals. Foundations of Computational Mathematics 8 (2008): 607-647.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AlgebraicBorderSolver","page":"Atoms extraction","title":"MultivariateMoments.AlgebraicBorderSolver","text":"Base.@kwdef struct AlgebraicBorderSolver{\n D,\n A<:Union{Nothing,SS.AbstractGröbnerBasisAlgorithm},\n S<:Union{Nothing,SS.AbstractAlgebraicSolver},\n}\n algorithm::A = nothing\n solver::S = nothing\nend\n\nSolve a border basis using algorithm and solver by first converting it to aBorderBasis{D}`.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AlgebraicFallbackBorderSolver","page":"Atoms extraction","title":"MultivariateMoments.AlgebraicFallbackBorderSolver","text":"struct AlgebraicFallbackBorderSolver{\n M<:Union{Nothing,SS.AbstractMultiplicationMatricesSolver},\n S<:AlgebraicBorderSolver,\n}\n multiplication_matrices_solver::M\n algebraic_solver::S\nend\n\nSolve with multiplication_matrices_solver and if it fails, falls back to solving the algebraic system formed by the border basis with algebraic_solver.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"Once the center of the atoms are determined, a linear system is solved to determine the weights corresponding to each dirac. By default, MomentMatrixWeightSolver is used by atomic_measure so that if there are small differences between moment values corresponding to the same monomial in the matrix (which can happen if these moments were computed numerically by a semidefinite proramming solvers, e.g., with SumOfSquares), the linear system handles that automatically.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"MomentMatrixWeightSolver\nMomentVectorWeightSolver","category":"page"},{"location":"atoms/#MultivariateMoments.MomentMatrixWeightSolver","page":"Atoms extraction","title":"MultivariateMoments.MomentMatrixWeightSolver","text":"struct MomentMatrixWeightSolver\n rtol::T\n atol::T\nend\n\nGiven a moment matrix ν and the atom centers, determine the weights by solving a linear system over all the moments of the moment matrix, keeping duplicates (e.g., entries corresponding to the same monomial).\n\nIf the moment values corresponding to the same monomials are known to be equal prefer MomentVectorWeightSolver instead.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.MomentVectorWeightSolver","page":"Atoms extraction","title":"MultivariateMoments.MomentVectorWeightSolver","text":"struct MomentVectorWeightSolver{T}\n rtol::T\n atol::T\nend\n\nGiven a moment matrix ν and the atom centers, first convert the moment matrix to a vector of moments, using measure(ν; rtol=rtol, atol=atol) and then determine the weights by solving a linear system over the monomials obtained.\n\nIf the moment values corresponding to the same monomials can have small differences, measure can throw an error if rtol and atol are not small enough. Alternatively to tuning these tolerances MomentVectorWeightSolver can be used instead.\n\n\n\n\n\n","category":"type"}] +[{"location":"moments/#Moments-and-expectation","page":"Moments and expectation","title":"Moments and expectation","text":"","category":"section"},{"location":"moments/#Moment","page":"Moments and expectation","title":"Moment","text":"","category":"section"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"Given a measure mu and a monomial m, the moment m of the measure is defined by the expectation mathbbE_mum. Given a monomial and a value for the moment, a moment can be created using the moment function","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"moment","category":"page"},{"location":"moments/#MultivariateMoments.moment","page":"Moments and expectation","title":"MultivariateMoments.moment","text":"moment(α, p)\n\nCreates the moment of the polynomial p of value α.\n\n\n\n\n\n","category":"function"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The moment function returns an AbstractMoment which is a subtype of AbstractMomentLike. An AbstractMomentLike is a type that can act like an AbstractMoment (it is similar to MultivariatePolynomials' AbstractMonomialLike, AbstractTermLike and AbstractPolynomialLike), that is, it implements the following two functions","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"moment_value","category":"page"},{"location":"moments/#MultivariateMoments.moment_value","page":"Moments and expectation","title":"MultivariateMoments.moment_value","text":"moment_value(m::AbstractMomentLike)\n\nReturns the value of the moment m.\n\nExamples\n\nCalling moment_value(moment(3.1, x*y^2)) should return 3.1.\n\n\n\n\n\n","category":"function"},{"location":"moments/#Measure","page":"Moments and expectation","title":"Measure","text":"","category":"section"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"Given a monomials and a values for the moments, a \"moment vector\" can be created using the moment_vector function","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"moment_vector","category":"page"},{"location":"moments/#MultivariateMoments.moment_vector","page":"Moments and expectation","title":"MultivariateMoments.moment_vector","text":"moment_vector(values::AbstractVector{T}, monos::AbstractVector{<:AbstractMonomial}; rtol=Base.rtoldefault(T), atol=zero(T))\n\nCreates a measure with moments moment(values[i], monos[i]) for each i. An error is thrown if there exists i and j such that monos[i] == monos[j] but !isapprox(values[i], values[j]; rtol=rtol, atol=atol).\n\n\n\n\n\n","category":"function"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The moment_vector function returns an AbstractMeasure which is a subtype of AbstractMeasureLike. Note that it does not actually compute the probability density function of a measure having these moments, it simply stores a vector of moments belonging to a hypothetical measure. However, it acts like a measure when taking its scalar product with a polynomial.","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"An AbstractMeasureLike is a type that can act like an AbstractMeasure, that is, it implements the following two functions","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"MultivariatePolynomials.variables(::MultivariateMoments.MomentVector)\nMultivariatePolynomials.maxdegree(::MultivariateMoments.MomentVector)\nMultivariatePolynomials.mindegree(::MultivariateMoments.MomentVector)\nMultivariatePolynomials.extdegree(::MultivariateMoments.MomentVector)\nmoments","category":"page"},{"location":"moments/#MultivariatePolynomials.variables-Tuple{MomentVector}","page":"Moments and expectation","title":"MultivariatePolynomials.variables","text":"variables(μ::MomentVector)\n\nReturns the variables of μ in decreasing order. Just like in MultivariatePolynomials, it could contain variables of zero degree in every monomial.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.maxdegree-Tuple{MomentVector}","page":"Moments and expectation","title":"MultivariatePolynomials.maxdegree","text":"maxdegree(μ::AbstractMeasureLike)\n\nReturns the maximal degree of the monomials of μ.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.mindegree-Tuple{MomentVector}","page":"Moments and expectation","title":"MultivariatePolynomials.mindegree","text":"mindegree(μ::MomentVector)\n\nReturns the minimal degree of the monomials of μ.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariatePolynomials.extdegree-Tuple{MomentVector}","page":"Moments and expectation","title":"MultivariatePolynomials.extdegree","text":"extdegree(μ::MomentVector)\n\nReturns the extremal degrees of the monomials of μ.\n\n\n\n\n\n","category":"method"},{"location":"moments/#MultivariateMoments.moments","page":"Moments and expectation","title":"MultivariateMoments.moments","text":"moments(μ::MomentVector)\n\nReturns an iterator over the moments of μ sorted in decreasing order of monomial.\n\n\n\n\n\n","category":"function"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The moments of the dirac measure for a vector of monomials can be obtained by the dirac function","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"dirac","category":"page"},{"location":"moments/#MultivariateMoments.dirac","page":"Moments and expectation","title":"MultivariateMoments.dirac","text":"dirac(X::AbstractVector{<:AbstractMoment}, s::AbstractSubstitution...)\n\nCreates the dirac measure by evaluating the moments of X using s.\n\nExamples\n\nCalling dirac([x*y, x*y^2], x=>3, y=>2) should the measure with moment x*y of value 6 and moment x*y^2 of value 12.\n\n\n\n\n\n","category":"function"},{"location":"moments/#Expectation","page":"Moments and expectation","title":"Expectation","text":"","category":"section"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"The expectation of polynomial with respect to a measure can be computed either using MultivariateMoments.expectation or using the Base.dot scalar product.","category":"page"},{"location":"moments/","page":"Moments and expectation","title":"Moments and expectation","text":"MultivariateMoments.expectation\nMultivariateMoments.dot","category":"page"},{"location":"moments/#MultivariateMoments.expectation","page":"Moments and expectation","title":"MultivariateMoments.expectation","text":"MultivariateMoments.expectation(μ::AbstractMeasureLike, p::AbstractPolynomialLike)\nMultivariateMoments.expectation(p::AbstractPolynomialLike, μ::AbstractMeasureLike)\n\nComputes the expectation mathbbE_mup.\n\n\n\n\n\n","category":"function"},{"location":"moments/#LinearAlgebra.dot","page":"Moments and expectation","title":"LinearAlgebra.dot","text":"dot(μ::AbstractMeasureLike, p::AbstractPolynomialLike)\ndot(p::AbstractPolynomialLike, μ::AbstractMeasureLike)\n\nSee expectation\n\n\n\n\n\n","category":"function"},{"location":"#MultivariateMoments-–-Multivariate-Moments-for-Julia","page":"Index","title":"MultivariateMoments –- Multivariate Moments for Julia","text":"","category":"section"},{"location":"","page":"Index","title":"Index","text":"Extension of MultivariatePolynomials to moments of multivariate measures and their scalar product with polynomials. It also includes the extraction of atomic measures from moment matrices which is related to the moment problem.","category":"page"},{"location":"#Contents","page":"Index","title":"Contents","text":"","category":"section"},{"location":"","page":"Index","title":"Index","text":"Pages = [\"moments.md\", \"atoms.md\"]\nDepth = 2","category":"page"},{"location":"atoms/#Atoms-extration","page":"Atoms extraction","title":"Atoms extration","text":"","category":"section"},{"location":"atoms/#Vectorized-matrix","page":"Atoms extraction","title":"Vectorized matrix","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"SymMatrix\nVectorizedHermitianMatrix\nsquare_getindex\nsymmetric_setindex!","category":"page"},{"location":"atoms/#MultivariateMoments.SymMatrix","page":"Atoms extraction","title":"MultivariateMoments.SymMatrix","text":"struct SymMatrix{T} <: AbstractMatrix{T}\n Q::Vector{T}\n n::Int\nend\n\nSymmetric n times n matrix storing the vectorized upper triangular part of the matrix in the Q vector (this corresponds to the vectorized form of MathOptInterface.PositiveSemidefiniteConeTriangle). It implement the AbstractMatrix interface except for setindex! as it might break its symmetry. The symmetric_setindex! function should be used instead.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.VectorizedHermitianMatrix","page":"Atoms extraction","title":"MultivariateMoments.VectorizedHermitianMatrix","text":"struct VectorizedHermitianMatrix{T} <: AbstractMatrix{Complex{T}}\n Q::Vector{T}\n n::Int\nend\n\nHermitian n times n matrix storing the vectorized upper triangular real part of the matrix followed by the vectorized upper triangular imaginary part in the Q vector (this corresponds to the vectorized form of ComplexOptInterface.HermitianPositiveSemidefiniteConeTriangle). It implement the AbstractMatrix interface except for setindex! as it might break its symmetry. The symmetric_setindex! function should be used instead.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.square_getindex","page":"Atoms extraction","title":"MultivariateMoments.square_getindex","text":"square_getindex!(Q::SymMatrix, I)\n\nReturn the SymMatrix corresponding to Q[I, I].\n\n\n\n\n\nsquare_getindex!(Q::VectorizedHermitianMatrix, I)\n\nReturn the VectorizedHermitianMatrix corresponding to Q[I, I].\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.symmetric_setindex!","page":"Atoms extraction","title":"MultivariateMoments.symmetric_setindex!","text":"symmetric_setindex!(Q::SymMatrix, value, i::Integer, j::Integer)\n\nSet Q[i, j] and Q[j, i] to the value value.\n\n\n\n\n\nsymmetric_setindex!(Q::VectorizedHermitianMatrix, value, i::Integer, j::Integer)\n\nSet Q[i, j] to the value value and Q[j, i] to the value -value.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#Moment-matrix","page":"Atoms extraction","title":"Moment matrix","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"MomentMatrix\nmoment_matrix","category":"page"},{"location":"atoms/#MultivariateMoments.MomentMatrix","page":"Atoms extraction","title":"MultivariateMoments.MomentMatrix","text":"mutable struct MomentMatrix{T,B<:SA.ExplicitBasis,MT<:AbstractMatrix{T}} <: AbstractMeasureLike{T}\n Q::MT\n basis::B\n support::Union{Nothing, AlgebraicSet}\nend\n\nMeasure nu represented by the moments of the monomial matrix x x^top in the symmetric matrix Q. The set of points that are zeros of all the polynomials p such that mathbbE_nup = 0 is stored in the field support when it is computed.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.moment_matrix","page":"Atoms extraction","title":"MultivariateMoments.moment_matrix","text":"moment_matrix(μ::MomentVector, x)\n\nCreates a matrix the moment matrix for the moment matrix x x^top using the moments of μ.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#Atomic-measure","page":"Atoms extraction","title":"Atomic measure","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"WeightedDiracMeasure\nAtomicMeasure","category":"page"},{"location":"atoms/#MultivariateMoments.WeightedDiracMeasure","page":"Atoms extraction","title":"MultivariateMoments.WeightedDiracMeasure","text":"struct WeightedDiracMeasure{T}\n center::Vector{T}\n weight::T\nend\n\nRepresents a weighted dirac measure with centered at center and with weight weight.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AtomicMeasure","page":"Atoms extraction","title":"MultivariateMoments.AtomicMeasure","text":"struct AtomicMeasure{T, AT, V} <: AbstractMeasureLike{T}\n variables::V # Vector/Tuple of variables\n atoms::Vector{WeightedDiracMeasure{T, AT}} # Atoms of the measure\nend\n\nAn measure is said to be atomic if it is a sum of weighted dirac measures. For instance, eta = 2 delta_(1 0) + 3 delta_(12 12) is an atomic measure since it is a sum of the diracs centered at (1 0) and (12 12) and weighted respectively by 2 and 3. That is, mathbbE_etap = 2p(1 0) + 3p(12 12).\n\nThe AtomicMeasure struct stores an atomic measure where variables contains the variables and atoms contains atoms of the measure.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#Atoms-extraction","page":"Atoms extraction","title":"Atoms extraction","text":"","category":"section"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"Given a MomentMatrix containing the moments of an atomic measure, atomic_measure attempts to recover the dirac centers and weights by first computing an algebraic system with the atom centers as solution with compute_support!.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"compute_support!\natomic_measure","category":"page"},{"location":"atoms/#MultivariateMoments.compute_support!","page":"Atoms extraction","title":"MultivariateMoments.compute_support!","text":"function compute_support!(ν::MomentMatrix, rank_check, solver) end\n\nComputes the support field of ν wth solver using a low-rank decomposition with the rank evaluated with rank_check.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.atomic_measure","page":"Atoms extraction","title":"MultivariateMoments.atomic_measure","text":"atomic_measure(ν::MomentMatrix, rank_check::RankCheck, [dec::LowRankLDLTAlgorithm], [solver::SemialgebraicSets.AbstractAlgebraicSolver])\n\nReturn an AtomicMeasure with the atoms of ν if it is atomic or nothing if ν is not atomic. The rank_check and dec parameters are passed as is to the low_rank_ldlt function. By default, dec is an instance of SVDLDLT. The extraction relies on the solution of a system of algebraic equations. using solver. For instance, given a MomentMatrix, μ, the following extract atoms using a rank_check of 1e-4 for the low-rank decomposition and homotopy continuation to solve the obtained system of algebraic equations.\n\nusing HomotopyContinuation\nsolver = SemialgebraicSetsHCSolver(; compile = false)\natoms = atomic_measure(ν, 1e-4, solver)\n\nIf no solver is given, the default solver of SemialgebraicSets is used which currently computes the Gröbner basis, then the multiplication matrices and then the Schur decomposition of a random combination of these matrices. For floating point arithmetics, homotopy continuation is recommended as it is more numerically stable than Gröbner basis computation.\n\n\n\n\n\n","category":"function"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"For the first step of compute_support!, there are two approaches. The first one is to exploit the flat extension to directly obtain the multiplication matrices.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"FlatExtension","category":"page"},{"location":"atoms/#MultivariateMoments.FlatExtension","page":"Atoms extraction","title":"MultivariateMoments.FlatExtension","text":"struct FlatExtension{\n MMS<:SemialgebraicSets.AbstractMultiplicationMatricesSolver,\n}\n multiplication_matrices_solver::MMS\nend\n\nGiven a moment matrix satisfying the flat extension property described in [L09, Section 5.3], computes the multiplication matrices using the formula given in [L09, Lemma 6.21] or [LLR08, Section 4.4.4]. Given the multiplication matrices, the solutions are obtained with multiplication_matrices_solver.\n\n[L09] Laurent, Monique. Sums of squares, moment matrices and optimization over polynomials. Emerging applications of algebraic geometry (2009): 157-270.\n\n[LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp. Semidefinite characterization and computation of zero-dimensional real radical ideals. Foundations of Computational Mathematics 8 (2008): 607-647.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The second approach is to first obtain the image space of the moment matrix, represented as a MacaulayNullspace and to then compute the multiplication matrices from this image space. This is implemented by the ImageSpaceSolver.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"MacaulayNullspace\nImageSpaceSolver","category":"page"},{"location":"atoms/#MultivariateMoments.MacaulayNullspace","page":"Atoms extraction","title":"MultivariateMoments.MacaulayNullspace","text":"struct MacaulayNullspace{T,MT<:AbstractMatrix{T},BT}\n matrix::MT\n basis::BT\n accuracy::T\nend\n\nThis matrix with rows indexed by basis can either be interpreted as the right null space of a Macaulay matrix with columns indexed by basis (resp. or the image space of a moment matrix with rows and columns indexed by basis). The value of matrix[i, j] should be interpreted as the value of the ith element of basis for the jth generator of the null space (resp. image) space.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.ImageSpaceSolver","page":"Atoms extraction","title":"MultivariateMoments.ImageSpaceSolver","text":"struct ImageSpaceSolver{A<:LowRankLDLTAlgorithm,S<:MacaulayNullspaceSolver}\n ldlt::A\n null::S\nend\n\nComputes the image space of the moment matrix using ldlt and then solve it with null.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"This image space is obtained from a low rank LDLT decomposition of the moment matrix. This decomposition can either be obtained by a cholesky or SVD decomposition from which we remove the rows corresponding to the negligeable eigen/singular values.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"LowRankLDLTAlgorithm\nShiftCholeskyLDLT\nSVDLDLT\nlow_rank_ldlt\nLowRankLDLT","category":"page"},{"location":"atoms/#MultivariateMoments.LowRankLDLTAlgorithm","page":"Atoms extraction","title":"MultivariateMoments.LowRankLDLTAlgorithm","text":"LowRankLDLTAlgorithm\n\nMethod for computing a r times n matrix U of a n times n rank r psd matrix Q such that Q = U'U.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.ShiftCholeskyLDLT","page":"Atoms extraction","title":"MultivariateMoments.ShiftCholeskyLDLT","text":"ShiftCholeskyLDLT <: LowRankLDLTAlgorithm\n\nShift the matrix by shift times the identity matrix before cholesky.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.SVDLDLT","page":"Atoms extraction","title":"MultivariateMoments.SVDLDLT","text":"SVDLDLT <: LowRankLDLTAlgorithm\n\nUse SVD decomposition.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.low_rank_ldlt","page":"Atoms extraction","title":"MultivariateMoments.low_rank_ldlt","text":"MultivariateMoments.low_rank_ldlt(Q::AbstractMatrix, dec::LowRankLDLTAlgorithm, ranktol)\n\nReturns a r times n matrix U of a n times n rank r positive semidefinite matrix Q such that Q = U^top U. The rank of Q is the number of singular values larger than ranktol cdot sigma_1 where sigma_1 is the largest singular value.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.LowRankLDLT","page":"Atoms extraction","title":"MultivariateMoments.LowRankLDLT","text":"struct LowRankLDLT{T,Tr,C<:RankCheck}\n L::Matrix{T}\n singular_values::Vector{Tr}\n rank_check::C\nend\n\nLow-Rank cholesky decomposition L * Diagonal(singular_values) * L' of size (n, r) of a n x n matrix with singular values singular_values[1] > ... > singular_values[n]. The rank was chosen given singular_values using rank_check via the rank_from_singular_values function.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The choice of cutoff between the significant and negligeable eigen/singular values is parametrized by the following interface:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"RankCheck\nrank_from_singular_values\naccuracy\ndoubt","category":"page"},{"location":"atoms/#MultivariateMoments.RankCheck","page":"Atoms extraction","title":"MultivariateMoments.RankCheck","text":"abstract type RankCheck end\n\nMethod for computing the rank with rank_from_singular_values based on a list of singular values.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.rank_from_singular_values","page":"Atoms extraction","title":"MultivariateMoments.rank_from_singular_values","text":"rank_from_singular_values(σ, check::RankCheck)\n\nReturn the rank of a matrix with singular values σ (in decreasing order) using check.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.accuracy","page":"Atoms extraction","title":"MultivariateMoments.accuracy","text":"accuracy(σ, r, check::RankCheck)\n\nReturns a value measuring the accuracy of the rank check check returning rank r. This is used by Echelon to determine the accuracy to use for the Gaussian elimination.\n\n\n\n\n\naccuracy(chol::LowRankLDLT)\n\nReturn the ratio rtol = σ[r+1]/σ[1] where σ is the vector of singular values of the matrix for which chol is the rank-r Cholesky decomposition. This is a good relative tolerance to use with the matrix as σ[r+1] is the first singular value that was discarded.\n\n\n\n\n\n","category":"function"},{"location":"atoms/#MultivariateMoments.doubt","page":"Atoms extraction","title":"MultivariateMoments.doubt","text":"doubt(σ, check::RankCheck)\n\nReturns a value measuring the doubt of the rank check check. Lower values means more doubt so less certainty. This is used by FallbackRank for deciding whether the fallback should be used.\n\n\n\n\n\n","category":"function"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The rank check can be chosen among the following:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"UserRank\nFixedRank\nFixedRanks\nAbsoluteRankTol\nLeadingRelativeRankTol\nDifferentialRankTol\nLargestDifferentialRank\nFallbackRank","category":"page"},{"location":"atoms/#MultivariateMoments.UserRank","page":"Atoms extraction","title":"MultivariateMoments.UserRank","text":"struct UserRank <: RankCheck\n pagesize::Int\nend\n\nThe user chooses the rank given the singular values in a REPL.TerminalMenus.RadioMenu of page size pagesize.\n\nExample\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], UserRank())\nChoose the last significant singular value:\n 1.0\n 0.1\n > 0.05\n 1.0e-5\n 5.0e-6\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.FixedRank","page":"Atoms extraction","title":"MultivariateMoments.FixedRank","text":"struct FixedRank <: RankCheck\n r::Int\nend\n\nThe rank is hardcoded to r, independently of the singular values.\n\nExample\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], FixedRank(3))\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.FixedRanks","page":"Atoms extraction","title":"MultivariateMoments.FixedRanks","text":"mutable struct FixedRanks <: RankCheck\n r::Vector{Int}\n current::Int\nend\n\nThe ith rank is hardcoded to r[i], independently of the singular values. The field current indicates how many ranks have already been asked. When current is length(r), no rank can be asked anymore.\n\nExample\n\njulia> check = FixedRanks([2, 3])\nFixedRanks([2, 3], 0)\n\njulia> rank_from_singular_values([1, 1e-1, 5e-5, 1e-5, 5e-6], check)\n2\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], check)\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AbsoluteRankTol","page":"Atoms extraction","title":"MultivariateMoments.AbsoluteRankTol","text":"struct AbsoluteRankTol{T} <: RankCheck\n tol::T\nend\n\nThe rank is the number of singular values that are strictly larger than tol.\n\nExample\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-5, 5e-6], AbsoluteRankTol(1e-4))\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.LeadingRelativeRankTol","page":"Atoms extraction","title":"MultivariateMoments.LeadingRelativeRankTol","text":"struct LeadingRelativeRankTol{T} <: RankCheck\n tol::T\nend\n\nThe rank is the number of singular values that are strictly larger than tol * maximum(σ) where maximum(σ) is the largest singular value.\n\nExample\n\nWhen the matrix is obtained from a homogeneous problem where the scaling is irrelevant, LeadingRelativeRankTol may be preferable to AbsoluteRankTol as shown below\n\njulia> rank_from_singular_values(1e6 * [1, 1e-1, 5e-2, 1e-5, 5e-6], AbsoluteRankTol(1e-4))\n5\n\njulia> rank_from_singular_values(1e6 * [1, 1e-1, 5e-2, 1e-5, 5e-6], LeadingRelativeRankTol(1e-4))\n3\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.DifferentialRankTol","page":"Atoms extraction","title":"MultivariateMoments.DifferentialRankTol","text":"struct DifferentialRankTol{T} <: RankCheck\n tol::T\nend\n\nThe rank is the number of singular values before a singular value (not included) is tol times the previous one (included).\n\nExample\n\nIt is sometimes difficult to figure out the tolerance to use in LeadingRelativeRankTol. For instance, choosing 1e-3 will consider 1e-3 in the example below as not part of the rank while DifferentialRankTol would include it because it is close to the previous singular value.\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-2, 5e-3, 1e-3, 1e-6, 5e-7], LeadingRelativeRankTol(1e-3))\n5\n\njulia> rank_from_singular_values([1, 1e-1, 5e-2, 1e-2, 5e-3, 1e-3, 1e-6, 5e-7], DifferentialRankTol(1e-2))\n6\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.LargestDifferentialRank","page":"Atoms extraction","title":"MultivariateMoments.LargestDifferentialRank","text":"struct LargestDifferentialRank <: RankCheck\nend\n\nThe rank is the number of singular values until the singular value that has the largest ratio with the next singular value.\n\nExample\n\nIt is sometimes difficult to figure out the tolerance to use in DifferentialRankTol. For instance, choosing 1e-2 will consider 1e-2, 5e-2 and 1e-3 in the example below as not part of the rank while LargestDifferentialRank would include them because there is a largest gap later.\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 1e-6, 5e-7], DifferentialRankTol(1e-2))\n1\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 1e-6, 5e-7], LargestDifferentialRank())\n4\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.FallbackRank","page":"Atoms extraction","title":"MultivariateMoments.FallbackRank","text":"struct FallbackRank{T,D,F} <: RankCheck\n tol::T\n default::D\n fallback::F\nend\n\nDefaults to checking the rank with default and falls back to fallback if the doubt is strictly larger than tol. By default, fallback is UserRank.\n\nExample\n\nThe advantage of UserRank is that the user get to see if the rank check is ambiguous and act accordingly. The downside is that it might be cumbersome if there are many rank checks to do. With FallbackRank, the user only has to sort out the tricky ones. In the example below, the first example is handled by LargestDifferentialRank. For the second one, the user sees that this is a tricky choice and can manually choose one of the two ranks, then see the result of the rest of his code using this value of the code and then choose the other rank and see the impact of this different choice.\n\njulia> check = FallbackRank(1e-1, LargestDifferentialRank())\nFallbackRank{Float64, LargestDifferentialRank, UserRank}(0.1, LargestDifferentialRank(), UserRank(8))\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 1e-6, 5e-7], check)\n4\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 5e-6, 5e-7], check)\nChoose the last significant singular value:\n > 1.0\n 0.01\n 0.05\n 0.001\n 5.0e-6\n 5.0e-7\n1\n\njulia> rank_from_singular_values([1, 1e-2, 5e-2, 1e-3, 5e-6, 5e-7], check)\nChoose the last significant singular value:\n 1.0\n 0.01\n 0.05\n > 0.001\n 5.0e-6\n 5.0e-7\n4\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"Given the MacaulayNullspace, there are two approaches implemented to obtain the moment matrices:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"ShiftNullspace\nEchelon","category":"page"},{"location":"atoms/#MultivariateMoments.ShiftNullspace","page":"Atoms extraction","title":"MultivariateMoments.ShiftNullspace","text":"struct ShiftNullspace{D,C<:RankCheck} <: MacaulayNullspaceSolver\n check::C\nend\n\nFrom the MacaulayNullspace, computes multiplication matrices by exploiting the shift property of the rows [DBD12]. The rank check check is used to determine the standard monomials among the row indices of the null space.\n\n[DBD12] Dreesen, Philippe, Batselier, Kim, and De Moor, Bart. Back to the roots: Polynomial system solving, linear algebra, systems theory. IFAC Proceedings Volumes 45.16 (2012): 1203-1208.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.Echelon","page":"Atoms extraction","title":"MultivariateMoments.Echelon","text":"struct Echelon{D,S<:Union{Nothing,SemialgebraicSets.AbstractAlgebraicSolver}} <:\n MacaulayNullspaceSolver\n solver::S\nend\n\nGiven a MacaulayNullspace, computes its echelon form (corresponding to the Canonical Null Space of [D13]) with Gaussian elimination. From this echelon form, the left null space can easily be computed using using [HL05, (8)]. This left null space forms a system of polynomial equations.\n\nnote: Note\nIn the context of compute_support!, if the MacaulayNullspace was obtained using SVDLDLT, the left null space can easily be obtained from the singular vectors corresponding to the negligeable singular values that were removed. However, as mentioned [LLR08, Section 4.4.5], these will usually give an overdetermined bases. As shown in [S04, Section 10.8.2], it is desirable to avoid overdetermined bases because it could lead to inconsistencies in the basis for numerical reasons. For this reason, this method computes the left null space from the echelon form of the significant singular values instead.\n\nLet B be the set of monomials corresponding to the rows of the pivots of this echelon form. If the moment matrix satisfies the flat extension property described in [L09, Section 5.3] then all monomials of the border of B (as defined in [LLR08, (2.3)]) will correspond to a row of of the matrix. In that case, the polynomial of the system obtained by [HL05, (8)] form a rewriting family for B [L09, (2.16)] a.k.a. a B-border prebasis (as defined in [LLR08, (2.4)]). Therefore, they can be used to compute multiplication matrices.\n\n[HL05] Henrion, D. & Lasserre, J-B. Detecting Global Optimality and Extracting Solutions of GloptiPoly 2005\n\n[D13] Dreesen, Philippe. Back to the Roots: Polynomial System Solving Using Linear Algebra Ph.D. thesis (2013)\n\n[L09] Laurent, Monique. Sums of squares, moment matrices and optimization over polynomials. Emerging applications of algebraic geometry (2009): 157-270.\n\n[LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp. Semidefinite characterization and computation of zero-dimensional real radical ideals. Foundations of Computational Mathematics 8 (2008): 607-647.\n\n[S04] Stetter, Hans J. Numerical polynomial algebra. Society for Industrial and Applied Mathematics, 2004.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The Echelon uses the RowEchelon package to determine the independent rows (which is not numerically stable) while the ShiftNullspace uses RankChecks with the singular values so it should have better numerical behavior. They can either simply distinguish the dependency of rows with LinearDependence or use a sieve with StaircaseDependence to save some the computation of the singular values for some submatrices:","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"LinearDependence\nStaircaseDependence\nBasisDependence","category":"page"},{"location":"atoms/#MultivariateMoments.LinearDependence","page":"Atoms extraction","title":"MultivariateMoments.LinearDependence","text":"@enum LinearDependence INDEPENDENT TRIVIAL DEPENDENT\n\nLinear dependence of the element of a basis representing the indices of the rows of a [MacaulayNullspace]. DEPENDENT indicates that it is linearly dependent to rows that appear earlier in the basis. TRIVIAL indicates that the element was not in the original basis so it is trivially independent.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.StaircaseDependence","page":"Atoms extraction","title":"MultivariateMoments.StaircaseDependence","text":"struct StaircaseDependence\n standard_or_corner::Bool\n linear::LinearDependence\nend\n\nDependence of the element of a basis representing the indices of the rows of a [MacaulayNullspace]. If the field standard_or_corner is true then the elements is either standard or is a corner (depending on the linear dependence encoded in the linear field). Otherwise, it is a border that is not a corner or it is not even a border. See LinearDependence for the linear field.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.BasisDependence","page":"Atoms extraction","title":"MultivariateMoments.BasisDependence","text":"struct BasisDependence{D,B<:SA.ExplicitBasis}\n basis::B\n dependence::Vector{D}\nend\n\nThe dependence between the elements of a basis.\n\ntip: Tip\nIf the number of variables is 2 or 3, it can be visualized with Plots.jl.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"The relationship between the dependent and the independent rows are then stored in a BorderBasis. By default, calling solve with only a BorderBasisas argument or providing aSemialgebraicSets.AbstractMultiplicationMatricesSolveras second argument will try to construct the moment matrices from these and find the solutions from these moment matrices. Alternatively, give an [AlgebraicBorderSolver](@ref) or a [AlgebraicFallbackBorderSolver`](@ref) as second argument to solve the system formed by these relations with these instead.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"BorderBasis\nAlgebraicBorderSolver\nAlgebraicFallbackBorderSolver","category":"page"},{"location":"atoms/#MultivariateMoments.BorderBasis","page":"Atoms extraction","title":"MultivariateMoments.BorderBasis","text":"struct BorderBasis{D,T,MT<:AbstractMatrix{T},B}\n dependence::BasisDependence{D,B}\n matrix::MT\nend\n\nThis matrix with rows indexed by standard and columns indexed by border a standard-border basis of the ideal border .- matrix' * standard [LLR08, Section 2.5]. For solving this with a multiplication matrix solver, it is necessary for the basis border to be a superset of the set of corners of standard and it is sufficient for it to be the border of standard.\n\n[LLR08] Lasserre, Jean Bernard and Laurent, Monique, and Rostalski, Philipp. Semidefinite characterization and computation of zero-dimensional real radical ideals. Foundations of Computational Mathematics 8 (2008): 607-647.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AlgebraicBorderSolver","page":"Atoms extraction","title":"MultivariateMoments.AlgebraicBorderSolver","text":"Base.@kwdef struct AlgebraicBorderSolver{\n D,\n A<:Union{Nothing,SS.AbstractGröbnerBasisAlgorithm},\n S<:Union{Nothing,SS.AbstractAlgebraicSolver},\n}\n algorithm::A = nothing\n solver::S = nothing\nend\n\nSolve a border basis using algorithm and solver by first converting it to aBorderBasis{D}`.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.AlgebraicFallbackBorderSolver","page":"Atoms extraction","title":"MultivariateMoments.AlgebraicFallbackBorderSolver","text":"struct AlgebraicFallbackBorderSolver{\n M<:Union{Nothing,SS.AbstractMultiplicationMatricesSolver},\n S<:AlgebraicBorderSolver,\n}\n multiplication_matrices_solver::M\n algebraic_solver::S\nend\n\nSolve with multiplication_matrices_solver and if it fails, falls back to solving the algebraic system formed by the border basis with algebraic_solver.\n\n\n\n\n\n","category":"type"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"Once the center of the atoms are determined, a linear system is solved to determine the weights corresponding to each dirac. By default, MomentMatrixWeightSolver is used by atomic_measure so that if there are small differences between moment values corresponding to the same monomial in the matrix (which can happen if these moments were computed numerically by a semidefinite proramming solvers, e.g., with SumOfSquares), the linear system handles that automatically.","category":"page"},{"location":"atoms/","page":"Atoms extraction","title":"Atoms extraction","text":"MomentMatrixWeightSolver\nMomentVectorWeightSolver","category":"page"},{"location":"atoms/#MultivariateMoments.MomentMatrixWeightSolver","page":"Atoms extraction","title":"MultivariateMoments.MomentMatrixWeightSolver","text":"struct MomentMatrixWeightSolver\n rtol::T\n atol::T\nend\n\nGiven a moment matrix ν and the atom centers, determine the weights by solving a linear system over all the moments of the moment matrix, keeping duplicates (e.g., entries corresponding to the same monomial).\n\nIf the moment values corresponding to the same monomials are known to be equal prefer MomentVectorWeightSolver instead.\n\n\n\n\n\n","category":"type"},{"location":"atoms/#MultivariateMoments.MomentVectorWeightSolver","page":"Atoms extraction","title":"MultivariateMoments.MomentVectorWeightSolver","text":"struct MomentVectorWeightSolver{T}\n rtol::T\n atol::T\nend\n\nGiven a moment matrix ν and the atom centers, first convert the moment matrix to a vector of moments, using moment_vector(ν; rtol=rtol, atol=atol) and then determine the weights by solving a linear system over the monomials obtained.\n\nIf the moment values corresponding to the same monomials can have small differences, moment_vector can throw an error if rtol and atol are not small enough. Alternatively to tuning these tolerances MomentVectorWeightSolver can be used instead.\n\n\n\n\n\n","category":"type"}] }