From 750938920921fc2cf3db7b6a65b762a494c8955d Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Fri, 24 Nov 2023 21:05:35 +0000 Subject: [PATCH] build based on 50f2b46 --- dev/.documenter-siteinfo.json | 2 +- dev/about/index.html | 2 +- dev/index.html | 2 +- dev/lib/methods/index.html | 4 ++-- dev/lib/types/index.html | 12 ++++++------ dev/search_index.js | 2 +- dev/tutorial/index.html | 14 ++++++++++++-- 7 files changed, 24 insertions(+), 14 deletions(-) diff --git a/dev/.documenter-siteinfo.json b/dev/.documenter-siteinfo.json index b02c4a0a..0a124716 100644 --- a/dev/.documenter-siteinfo.json +++ b/dev/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.9.3","generation_timestamp":"2023-11-03T18:16:21","documenter_version":"1.1.2"}} \ No newline at end of file +{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2023-11-24T21:05:31","documenter_version":"1.1.2"}} \ No newline at end of file diff --git a/dev/about/index.html b/dev/about/index.html index 33087dbf..54929264 100644 --- a/dev/about/index.html +++ b/dev/about/index.html @@ -1,4 +1,4 @@ About · RangeEnclosures.jl

About

This page contains some general information about this project, and recommendations about contributing.

Contributing

If you like this package, consider contributing! You can send bug reports (or fix them and send your code), add examples to the documentation, or propose new features.

Below some conventions that we follow when contributing to this package are detailed. For specific guidelines on documentation, see the Documentations Guidelines wiki.

Branches and pull requests (PR)

We use a standard pull request policy: You work in a private branch and eventually add a pull request, which is then reviewed by other programmers and merged into the master branch.

Each pull request should be pushed in a new branch with the name of the author followed by a descriptive name, e.g., mforets/my_feature. If the branch is associated to a previous discussion in one issue, we use the name of the issue for easier lookup, e.g., mforets/7.

Unit testing and continuous integration (CI)

This project is synchronized with GitHub Actions such that each PR gets tested before merging (and the build is automatically triggered after each new commit). For the maintainability of this project, it is important to make all unit tests pass.

To run the unit tests locally, you can do:

julia> using Pkg
 
-julia> Pkg.test("RangeEnclosures")

We also advise adding new unit tests when adding new features to ensure long-term support of your contributions.

Contributing to the documentation

New functions and types should be documented according to our guidelines directly in the source code.

You can view the source code documentation from inside the REPL by typing ? followed by the name of the type or function. For example, the following command will print the documentation of the enclose function:

julia> ?enclose

This documentation you are currently reading is written in Markdown, and it relies on Documenter.jl to produce the HTML layout. The sources for creating this documentation are found in docs/src. You can easily include the documentation that you wrote for your functions or types there (see the Documenter.jl guide or our sources for examples).

To generate the documentation locally, run make.jl, e.g., by executing the following command in the terminal:

$ julia --color=yes docs/make.jl

Credits

Core developers

The RangeEnclosures.jl library is maintained by (in alphabetic order):

Contributors

Huge thanks to all the contributors.

Acknowledgments

We are grateful to the following persons for enlightening discussions during the preparation of this package:

During Summer 2022, this project was financially supported by Google through the Google Summer of Code program. During Summer 2019, this project was financially supported by Julia through the Julia Season of Contributions program.

+julia> Pkg.test("RangeEnclosures")

We also advise adding new unit tests when adding new features to ensure long-term support of your contributions.

Contributing to the documentation

New functions and types should be documented according to our guidelines directly in the source code.

You can view the source code documentation from inside the REPL by typing ? followed by the name of the type or function. For example, the following command will print the documentation of the enclose function:

julia> ?enclose

This documentation you are currently reading is written in Markdown, and it relies on Documenter.jl to produce the HTML layout. The sources for creating this documentation are found in docs/src. You can easily include the documentation that you wrote for your functions or types there (see the Documenter.jl guide or our sources for examples).

To generate the documentation locally, run make.jl, e.g., by executing the following command in the terminal:

$ julia --color=yes docs/make.jl

Credits

Core developers

The RangeEnclosures.jl library is maintained by (in alphabetic order):

Contributors

Huge thanks to all the contributors.

Acknowledgments

We are grateful to the following persons for enlightening discussions during the preparation of this package:

During Summer 2022, this project was financially supported by Google through the Google Summer of Code program. During Summer 2019, this project was financially supported by Julia through the Julia Season of Contributions program.

diff --git a/dev/index.html b/dev/index.html index c27ee1d7..e1aa32ab 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,2 +1,2 @@ -Home · RangeEnclosures.jl

RangeEnclosures.jl

A Julia package to compute range enclosures of real-valued functions.

Features

  • Computation of lower and upper bounds of real-valued functions, either univariate or multivariate, over hyperrectangular (i.e. box shaped) domains.
  • The following solvers are always available (using the package IntervalArithmetic.jl):
    • NaturalEnclosure
    • MeanValueEnclosure
    • BranchAndBoundEnclosure
  • The following solvers are available upon loading other packages:

Quickstart

The package exports one single function, enclose, which receives a Julia function, a domain, and (optionally) a solver and additional options passed to the solver. See the README.md file for the basic usage, or consult the source code docstrings, either in the REPL or in the github repository source code

Library Outline

+Home · RangeEnclosures.jl

RangeEnclosures.jl

A Julia package to compute range enclosures of real-valued functions.

Features

  • Computation of lower and upper bounds of real-valued functions, either univariate or multivariate, over hyperrectangular (i.e. box shaped) domains.
  • The following solvers are always available (using the package IntervalArithmetic.jl):
    • NaturalEnclosure
    • MeanValueEnclosure
    • BranchAndBoundEnclosure
  • The following solvers are available upon loading other packages:

Quickstart

The package exports one single function, enclose, which receives a Julia function, a domain, and (optionally) a solver and additional options passed to the solver. See the README.md file for the basic usage, or consult the source code docstrings, either in the REPL or in the github repository source code

Library Outline

diff --git a/dev/lib/methods/index.html b/dev/lib/methods/index.html index d90f932b..360eebd5 100644 --- a/dev/lib/methods/index.html +++ b/dev/lib/methods/index.html @@ -5,11 +5,11 @@ julia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure()) [0.8125, 1.09375]

A vector of solvers can be passed in the solver options. Then, the result is obtained by intersecting the range enclosure of each solver.

julia> enclose(x -> 1 - x^4 + x^5, 0..1, [TaylorModelsEnclosure(), NaturalEnclosure()])
 [0.8125, 1.09375]
-
source

Utility functions

RangeEnclosures.relative_precisionFunction
relative_precision(x::Interval, xref::Interval)

Return the relative precision of an interval with respect to a reference interval.

Input

  • x – test interval
  • xref – reference interval

Output

Left and right relative precision (in %) computed as

  • rleft = (inf(xref) - inf(x)) / diam(xref) * 100%
  • rright = (sup(x) - sup(xright)) / diam(xref) * 100%

Examples

julia> xref = interval(-1.2, 4.6)
+
source

Utility functions

RangeEnclosures.relative_precisionFunction
relative_precision(x::Interval, xref::Interval)

Return the relative precision of an interval with respect to a reference interval.

Input

  • x – test interval
  • xref – reference interval

Output

Left and right relative precision (in %) computed as

  • rleft = (inf(xref) - inf(x)) / diam(xref) * 100%
  • rright = (sup(x) - sup(xright)) / diam(xref) * 100%

Examples

julia> xref = interval(-1.2, 4.6)
 [-1.2, 4.6]
 
 julia> x = interval(-1.25, 7.45)
 [-1.25, 7.45001]
 
 julia> relative_precision(x, xref)
-(0.8620689655172422, 49.13793103448277)

Algorithm

This function measures the relative precision of the result in a more informative way than taking the scalar overestimation because it evaluates the precision of the lower and the upper bounds separately (cf. Eq. (20) in [1]).

[1] Althoff, Matthias, Dmitry Grebenyuk, and Niklas Kochdumper. Implementation of Taylor models in CORA 2018. Proc. of the 5th International Workshop on Applied Verification for Continuous and Hybrid Systems. 2018.

source
+(0.8620689655172422, 49.13793103448277)

Algorithm

This function measures the relative precision of the result in a more informative way than taking the scalar overestimation because it evaluates the precision of the lower and the upper bounds separately (cf. Eq. (20) in [1]).

[1] Althoff, Matthias, Dmitry Grebenyuk, and Niklas Kochdumper. Implementation of Taylor models in CORA 2018. Proc. of the 5th International Workshop on Applied Verification for Continuous and Hybrid Systems. 2018.

source diff --git a/dev/lib/types/index.html b/dev/lib/types/index.html index 1f9c6cb5..070d8995 100644 --- a/dev/lib/types/index.html +++ b/dev/lib/types/index.html @@ -1,24 +1,24 @@ -Types · RangeEnclosures.jl

Types

This section describes systems types implemented in RangeEnclosures.jl.

RangeEnclosures.AffineArithmeticEnclosureType
AffineArithmeticEnclosure <: AbstractDirectRangeAlgorithm

Data type to bound the range of f over X using affine arithmetic. See AffineArithmetic.jl for more details.

Notes

To use this algorithm, you need to load AffineArithmetic.jl. Note also that AffineArithmetic.jl currently supports only arithmetic operations.

source
RangeEnclosures.BranchAndBoundEnclosureType
BranchAndBoundEnclosure <: AbstractIterativeRangeAlgorithm

Data type to bound the range of f over X using the branch and bound algorithm.

Fields

  • maxdepth (default 10): maximum depth of the search tree
  • tol (default 1e-3): tolerance to compute the range of the function

Algorithm

The algorithm evaluates a function f over an interval X. If the maximum depth is reached or the width of f(X) is below the tolerance, the algorithm returns the computed range; otherwise it bisects the interval/interval box.

The algorithm also looks at the sign of the derivative / gradient to see if the range can be computed directly. By default, the derivative / gradient is computed using ForwardDiff.jl, but a custom value can be passed via the df keyword argument to enclose.

Examples

julia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure())
+Types · RangeEnclosures.jl

Types

This section describes systems types implemented in RangeEnclosures.jl.

RangeEnclosures.AffineArithmeticEnclosureType
AffineArithmeticEnclosure <: AbstractDirectRangeAlgorithm

Data type to bound the range of f over X using affine arithmetic. See AffineArithmetic.jl for more details.

Notes

To use this algorithm, you need to load AffineArithmetic.jl. Note also that AffineArithmetic.jl currently supports only arithmetic operations.

source
RangeEnclosures.BranchAndBoundEnclosureType
BranchAndBoundEnclosure <: AbstractIterativeRangeAlgorithm

Data type to bound the range of f over X using the branch and bound algorithm.

Fields

  • maxdepth (default 10): maximum depth of the search tree
  • tol (default 1e-3): tolerance to compute the range of the function

Algorithm

The algorithm evaluates a function f over an interval X. If the maximum depth is reached or the width of f(X) is below the tolerance, the algorithm returns the computed range; otherwise it bisects the interval/interval box.

The algorithm also looks at the sign of the derivative / gradient to see if the range can be computed directly. By default, the derivative / gradient is computed using ForwardDiff.jl, but a custom value can be passed via the df keyword argument to enclose.

Examples

julia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure())
 [4.83333, 10.5709]
 
 julia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure(tol=1e-2); df=x->-x^2/2+5)
-[4.83333, 10.5709]
source
RangeEnclosures.NaturalEnclosureType

NaturalEnclosure <: AbstractDirectRangeAlgorithm

Data type to bound the range of f over X using natural enclosure, i.e., to evaluate f(X) with interval arithmetic.

Examples

julia> enclose(x -> 1 - x^4 + x^5, 0..1, NaturalEnclosure())
-[0, 2]
source
RangeEnclosures.MeanValueEnclosureType
MeanValueEnclosure

Data type to bound the range of f over X using the mean value form, that is the range is bounded by the expression $f(Xc) + f'(X) * (X - Xc)$, where Xc is the midpoint of X and f' is the derivative of f (gradient in the multivariate case).

source
RangeEnclosures.MooreSkelboeEnclosureType
MooreSkelboeEnclosure{T} <: AbstractIterativeRangeAlgorithm

Data type to bound the range of f over X using the Moore-Skelboe algorithm, which rigorously computes the global minimum and maximum of the function. See IntervalOptimisation.jl for more details.

Fields

  • structure – (default: HeapedVector) the way in which vector elements are kept arranged; possible options are HeapedVector and SortedVector
  • tol – (default 1e-3) tolerance to which the optima are computed

Notes

To use this algorithm, you need to load IntervalOptimisation.jl.

Examples

julia> using IntervalOptimisation
+[4.83333, 10.5709]
source
RangeEnclosures.NaturalEnclosureType

NaturalEnclosure <: AbstractDirectRangeAlgorithm

Data type to bound the range of f over X using natural enclosure, i.e., to evaluate f(X) with interval arithmetic.

Examples

julia> enclose(x -> 1 - x^4 + x^5, 0..1, NaturalEnclosure())
+[0, 2]
source
RangeEnclosures.MeanValueEnclosureType
MeanValueEnclosure

Data type to bound the range of f over X using the mean value form, that is the range is bounded by the expression $f(Xc) + f'(X) * (X - Xc)$, where Xc is the midpoint of X and f' is the derivative of f (gradient in the multivariate case).

source
RangeEnclosures.MooreSkelboeEnclosureType
MooreSkelboeEnclosure{T} <: AbstractIterativeRangeAlgorithm

Data type to bound the range of f over X using the Moore-Skelboe algorithm, which rigorously computes the global minimum and maximum of the function. See IntervalOptimisation.jl for more details.

Fields

  • structure – (default: HeapedVector) the way in which vector elements are kept arranged; possible options are HeapedVector and SortedVector
  • tol – (default 1e-3) tolerance to which the optima are computed

Notes

To use this algorithm, you need to load IntervalOptimisation.jl.

Examples

julia> using IntervalOptimisation
 
 julia> enclose(x -> 1 - x^4 + x^5, 0..1, MooreSkelboeEnclosure()) # default parameters
 [0.916034, 1.00213]
 
 julia> enclose(x -> 1 - x^4 + x^5, 0..1, MooreSkelboeEnclosure(; tol=1e-2))
-[0.900812, 1.0326]
source
RangeEnclosures.SumOfSquaresEnclosureType
SumOfSquaresEnclosure{T} <: AbstractIterativeRangeAlgorithm

Data type to bound the range of f over X using sum-of-squares optimization. See SumOfSquares.jl for more details

Fields

  • backend – backend used to solve the optimization problem; a list of available backends can be found here
  • order – (default 5), maximum degree of the SDP relaxation

Notes

To use this solver, you need to load SumOfSquares.jl and a backend.

Since the optimization problem is solved numerically and not with interval arithmetic, the result of this algorithm is not rigorous.

Examples

julia> using SumOfSquares, SDPA, DynamicPolynomials
+[0.900812, 1.0326]
source
RangeEnclosures.SumOfSquaresEnclosureType
SumOfSquaresEnclosure{T} <: AbstractIterativeRangeAlgorithm

Data type to bound the range of f over X using sum-of-squares optimization. See SumOfSquares.jl for more details

Fields

  • backend – backend used to solve the optimization problem; a list of available backends can be found here
  • order – (default 5), maximum degree of the SDP relaxation

Notes

To use this solver, you need to load SumOfSquares.jl and a backend.

Since the optimization problem is solved numerically and not with interval arithmetic, the result of this algorithm is not rigorous.

Examples

julia> using SumOfSquares, SDPA, DynamicPolynomials
 
 julia> backend = SDPA.Optimizer;
 
 julia> @polyvar x;
 
 julia> enclose(-x^3/6 + 5x, 1..4, SumOfSquaresEnclosure(; backend=backend))
-[4.83333, 10.541]
source
RangeEnclosures.TaylorModelsEnclosureType
TaylorModelsEnclosure <: AbstractDirectRangeAlgorithm

Data type to bound the range of f over X using Taylor models. See TaylorModels.jl for more details.

Fields

  • order – (default: 10) order of the Taylor model used to compute an enclosure of f over dom
  • normalize – (default: true) if true, normalize the Taylor model on the unit symmetric box around the origin

Notes

To use this solver, you need to load TaylorModels.jl and a backend.

Examples

julia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure()) # default parameters
+[4.83333, 10.541]
source
RangeEnclosures.TaylorModelsEnclosureType
TaylorModelsEnclosure <: AbstractDirectRangeAlgorithm

Data type to bound the range of f over X using Taylor models. See TaylorModels.jl for more details.

Fields

  • order – (default: 10) order of the Taylor model used to compute an enclosure of f over dom
  • normalize – (default: true) if true, normalize the Taylor model on the unit symmetric box around the origin

Notes

To use this solver, you need to load TaylorModels.jl and a backend.

Examples

julia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure()) # default parameters
 [0.8125, 1.09375]
 
 julia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure(; order=4))
-[0.78125, 1.125]
source
+[0.78125, 1.125]
source
diff --git a/dev/search_index.js b/dev/search_index.js index fbcd059e..31765235 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"about/#About","page":"About","title":"About","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"This page contains some general information about this project, and recommendations about contributing.","category":"page"},{"location":"about/","page":"About","title":"About","text":"Pages = [\"about.md\"]","category":"page"},{"location":"about/#Contributing","page":"About","title":"Contributing","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"If you like this package, consider contributing! You can send bug reports (or fix them and send your code), add examples to the documentation, or propose new features.","category":"page"},{"location":"about/","page":"About","title":"About","text":"Below some conventions that we follow when contributing to this package are detailed. For specific guidelines on documentation, see the Documentations Guidelines wiki.","category":"page"},{"location":"about/#Branches-and-pull-requests-(PR)","page":"About","title":"Branches and pull requests (PR)","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"We use a standard pull request policy: You work in a private branch and eventually add a pull request, which is then reviewed by other programmers and merged into the master branch.","category":"page"},{"location":"about/","page":"About","title":"About","text":"Each pull request should be pushed in a new branch with the name of the author followed by a descriptive name, e.g., mforets/my_feature. If the branch is associated to a previous discussion in one issue, we use the name of the issue for easier lookup, e.g., mforets/7.","category":"page"},{"location":"about/#Unit-testing-and-continuous-integration-(CI)","page":"About","title":"Unit testing and continuous integration (CI)","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"This project is synchronized with GitHub Actions such that each PR gets tested before merging (and the build is automatically triggered after each new commit). For the maintainability of this project, it is important to make all unit tests pass.","category":"page"},{"location":"about/","page":"About","title":"About","text":"To run the unit tests locally, you can do:","category":"page"},{"location":"about/","page":"About","title":"About","text":"julia> using Pkg\n\njulia> Pkg.test(\"RangeEnclosures\")","category":"page"},{"location":"about/","page":"About","title":"About","text":"We also advise adding new unit tests when adding new features to ensure long-term support of your contributions.","category":"page"},{"location":"about/#Contributing-to-the-documentation","page":"About","title":"Contributing to the documentation","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"New functions and types should be documented according to our guidelines directly in the source code.","category":"page"},{"location":"about/","page":"About","title":"About","text":"You can view the source code documentation from inside the REPL by typing ? followed by the name of the type or function. For example, the following command will print the documentation of the enclose function:","category":"page"},{"location":"about/","page":"About","title":"About","text":"julia> ?enclose","category":"page"},{"location":"about/","page":"About","title":"About","text":"This documentation you are currently reading is written in Markdown, and it relies on Documenter.jl to produce the HTML layout. The sources for creating this documentation are found in docs/src. You can easily include the documentation that you wrote for your functions or types there (see the Documenter.jl guide or our sources for examples).","category":"page"},{"location":"about/","page":"About","title":"About","text":"To generate the documentation locally, run make.jl, e.g., by executing the following command in the terminal:","category":"page"},{"location":"about/","page":"About","title":"About","text":"$ julia --color=yes docs/make.jl","category":"page"},{"location":"about/#Credits","page":"About","title":"Credits","text":"","category":"section"},{"location":"about/#Core-developers","page":"About","title":"Core developers","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"The RangeEnclosures.jl library is maintained by (in alphabetic order):","category":"page"},{"location":"about/","page":"About","title":"About","text":"Luca Ferranti, University of Vasaa\nMarcelo Forets, Universidad de la República\nChristian Schilling, Aalborg University","category":"page"},{"location":"about/#Contributors","page":"About","title":"Contributors","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"Huge thanks to all the contributors.","category":"page"},{"location":"about/#Acknowledgments","page":"About","title":"Acknowledgments","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"We are grateful to the following persons for enlightening discussions during the preparation of this package:","category":"page"},{"location":"about/","page":"About","title":"About","text":"Luis Benet\nBenoît Legat\nDavid P. Sanders","category":"page"},{"location":"about/","page":"About","title":"About","text":"During Summer 2022, this project was financially supported by Google through the Google Summer of Code program. During Summer 2019, this project was financially supported by Julia through the Julia Season of Contributions program.","category":"page"},{"location":"lib/types/#Types","page":"Types","title":"Types","text":"","category":"section"},{"location":"lib/types/","page":"Types","title":"Types","text":"This section describes systems types implemented in RangeEnclosures.jl.","category":"page"},{"location":"lib/types/","page":"Types","title":"Types","text":"Pages = [\"types.md\"]\nDepth = 3","category":"page"},{"location":"lib/types/","page":"Types","title":"Types","text":"CurrentModule = RangeEnclosures","category":"page"},{"location":"lib/types/","page":"Types","title":"Types","text":"AbstractEnclosureAlgorithm\nAbstractDirectRangeAlgorithm\nAbstractIterativeRangeAlgorithm\nAffineArithmeticEnclosure\nBranchAndBoundEnclosure\nNaturalEnclosure\nMeanValueEnclosure\nMooreSkelboeEnclosure\nSumOfSquaresEnclosure\nTaylorModelsEnclosure","category":"page"},{"location":"lib/types/#RangeEnclosures.AbstractEnclosureAlgorithm","page":"Types","title":"RangeEnclosures.AbstractEnclosureAlgorithm","text":"AbstractEnclosureAlgorithm\n\nAbstract type for range enclosure algorithms.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.AbstractDirectRangeAlgorithm","page":"Types","title":"RangeEnclosures.AbstractDirectRangeAlgorithm","text":"AbstractDirectRangeAlgorithm <: AbstractEnclosureAlgorithm\n\nAbstract type for range enclosure algorithms that directly evaluate the functions over a given domain.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.AbstractIterativeRangeAlgorithm","page":"Types","title":"RangeEnclosures.AbstractIterativeRangeAlgorithm","text":"AbstractIterativeRangeAlgorithm <: AbstractEnclosureAlgorithm\n\nAbstract type for algorithms that iteratively bound the range of a function over a given domain.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.AffineArithmeticEnclosure","page":"Types","title":"RangeEnclosures.AffineArithmeticEnclosure","text":"AffineArithmeticEnclosure <: AbstractDirectRangeAlgorithm\n\nData type to bound the range of f over X using affine arithmetic. See AffineArithmetic.jl for more details.\n\nNotes\n\nTo use this algorithm, you need to load AffineArithmetic.jl. Note also that AffineArithmetic.jl currently supports only arithmetic operations.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.BranchAndBoundEnclosure","page":"Types","title":"RangeEnclosures.BranchAndBoundEnclosure","text":"BranchAndBoundEnclosure <: AbstractIterativeRangeAlgorithm\n\nData type to bound the range of f over X using the branch and bound algorithm.\n\nFields\n\nmaxdepth (default 10): maximum depth of the search tree\ntol (default 1e-3): tolerance to compute the range of the function\n\nAlgorithm\n\nThe algorithm evaluates a function f over an interval X. If the maximum depth is reached or the width of f(X) is below the tolerance, the algorithm returns the computed range; otherwise it bisects the interval/interval box.\n\nThe algorithm also looks at the sign of the derivative / gradient to see if the range can be computed directly. By default, the derivative / gradient is computed using ForwardDiff.jl, but a custom value can be passed via the df keyword argument to enclose.\n\nExamples\n\njulia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure())\n[4.83333, 10.5709]\n\njulia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure(tol=1e-2); df=x->-x^2/2+5)\n[4.83333, 10.5709]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.NaturalEnclosure","page":"Types","title":"RangeEnclosures.NaturalEnclosure","text":"NaturalEnclosure <: AbstractDirectRangeAlgorithm\n\nData type to bound the range of f over X using natural enclosure, i.e., to evaluate f(X) with interval arithmetic.\n\nExamples\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, NaturalEnclosure())\n[0, 2]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.MeanValueEnclosure","page":"Types","title":"RangeEnclosures.MeanValueEnclosure","text":"MeanValueEnclosure\n\nData type to bound the range of f over X using the mean value form, that is the range is bounded by the expression f(Xc) + f(X) * (X - Xc), where Xc is the midpoint of X and f' is the derivative of f (gradient in the multivariate case).\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.MooreSkelboeEnclosure","page":"Types","title":"RangeEnclosures.MooreSkelboeEnclosure","text":"MooreSkelboeEnclosure{T} <: AbstractIterativeRangeAlgorithm\n\nData type to bound the range of f over X using the Moore-Skelboe algorithm, which rigorously computes the global minimum and maximum of the function. See IntervalOptimisation.jl for more details.\n\nFields\n\nstructure – (default: HeapedVector) the way in which vector elements are kept arranged; possible options are HeapedVector and SortedVector\ntol – (default 1e-3) tolerance to which the optima are computed\n\nNotes\n\nTo use this algorithm, you need to load IntervalOptimisation.jl.\n\nExamples\n\njulia> using IntervalOptimisation\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, MooreSkelboeEnclosure()) # default parameters\n[0.916034, 1.00213]\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, MooreSkelboeEnclosure(; tol=1e-2))\n[0.900812, 1.0326]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.SumOfSquaresEnclosure","page":"Types","title":"RangeEnclosures.SumOfSquaresEnclosure","text":"SumOfSquaresEnclosure{T} <: AbstractIterativeRangeAlgorithm\n\nData type to bound the range of f over X using sum-of-squares optimization. See SumOfSquares.jl for more details\n\nFields\n\nbackend – backend used to solve the optimization problem; a list of available backends can be found here\norder – (default 5), maximum degree of the SDP relaxation\n\nNotes\n\nTo use this solver, you need to load SumOfSquares.jl and a backend.\n\nSince the optimization problem is solved numerically and not with interval arithmetic, the result of this algorithm is not rigorous.\n\nExamples\n\njulia> using SumOfSquares, SDPA, DynamicPolynomials\n\njulia> backend = SDPA.Optimizer;\n\njulia> @polyvar x;\n\njulia> enclose(-x^3/6 + 5x, 1..4, SumOfSquaresEnclosure(; backend=backend))\n[4.83333, 10.541]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.TaylorModelsEnclosure","page":"Types","title":"RangeEnclosures.TaylorModelsEnclosure","text":"TaylorModelsEnclosure <: AbstractDirectRangeAlgorithm\n\nData type to bound the range of f over X using Taylor models. See TaylorModels.jl for more details.\n\nFields\n\norder – (default: 10) order of the Taylor model used to compute an enclosure of f over dom\nnormalize – (default: true) if true, normalize the Taylor model on the unit symmetric box around the origin\n\nNotes\n\nTo use this solver, you need to load TaylorModels.jl and a backend.\n\nExamples\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure()) # default parameters\n[0.8125, 1.09375]\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure(; order=4))\n[0.78125, 1.125]\n\n\n\n\n\n","category":"type"},{"location":"#RangeEnclosures.jl","page":"Home","title":"RangeEnclosures.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"A Julia package to compute range enclosures of real-valued functions.","category":"page"},{"location":"#Features","page":"Home","title":"Features","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Computation of lower and upper bounds of real-valued functions, either univariate or multivariate, over hyperrectangular (i.e. box shaped) domains.\nThe following solvers are always available (using the package IntervalArithmetic.jl):\nNaturalEnclosure\nMeanValueEnclosure\nBranchAndBoundEnclosure\nThe following solvers are available upon loading other packages:\nMooreSkelboeEnclosure, which requires IntervalOptimisation.jl\nTaylorModelsEnclosure, which requires TaylorModels.jl\nSumOfSquaresEnclosure, which requires SumOfSquares.jl\nAffineArithmeticEnclosure, which requires AffineArithmetic.jl","category":"page"},{"location":"#Quickstart","page":"Home","title":"Quickstart","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The package exports one single function, enclose, which receives a Julia function, a domain, and (optionally) a solver and additional options passed to the solver. See the README.md file for the basic usage, or consult the source code docstrings, either in the REPL or in the github repository source code","category":"page"},{"location":"#Library-Outline","page":"Home","title":"Library Outline","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Pages = [\n \"lib/types.md\",\n \"lib/methods.md\"\n]\nDepth = 2","category":"page"},{"location":"tutorial/#Tutorial","page":"Tutorial","title":"Tutorial","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"This tutorial will teach you how to use RangeEnclosures. First, we will give a basic overview of the package and its functionalities. Next, we will discuss in more detail how to use the package in different scenarios (1D, higher dimension, using algorithms from external libraries, etc.).","category":"page"},{"location":"tutorial/#Setup","page":"Tutorial","title":"Setup","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Assuming you have installed Julia, you can install the package from the Julia REPL with the following lines.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using Pkg\nPkg.add(\"RangeEnclosures\")","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Then you can load the package in the standard way.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using RangeEnclosures","category":"page"},{"location":"tutorial/#Overview","page":"Tutorial","title":"Overview","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"RangeEnclosures is used to bound the range of a given function f. The main function provided by this package is enclose, and its basic usage is the following.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(f, D, solver; kwargs...)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"where","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"f is the function whose range we want to bound,\nD is the domain over which we want to compute the range,\nsolver is the solver used to compute the range (which is optional; if not specified, the package will default to the NaturalEnclosure solver), and\nkwargs... are possible keyword arguments used by the solver.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"The solvers can be divided into two families: direct solvers, which compute the range enclosure over the whole domain, and iterative solvers, which recursively split the domain into smaller subdomains to get a more accurate estimate. A detailed list of available solvers can be found here.","category":"page"},{"location":"tutorial/#Usage-Examples","page":"Tutorial","title":"Usage Examples","text":"","category":"section"},{"location":"tutorial/#A-one-dimensional-example","page":"Tutorial","title":"A one-dimensional example","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Suppose we want to compute the range of the function","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"f(x) = -sum_k=1^5kxsinleft(frack(x-3)3right)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"over the domain D = -10 10.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"If we call enclose without specifying the solver, it will evaluate f(D) using plain interval arithmetic (this is called natural enclosure), as the following example shows.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"f(x) = -sum(k*x*sin(k*(x-3)/3) for k in 1:5)\nD = -10..10\nR = enclose(f, D)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Generally, using natural enclosures leads to unpleasantly large overestimates, which is due to the dependency problem. To overcome this, you may want to use some other solvers in your application. The next example bounds the range using the BranchAndBoundEnclosure solver.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Rbb = enclose(f, D, BranchAndBoundEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"As you can see, the result is much tighter now, while still being rigorous! The results can be visualized using Plots.jl.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using Plots\nplot(xlabel=\"x\", ylabel=\"f(x)\", legendfontsize=12, tickfontsize=12,\n xguidefont=font(15, \"Times\"), yguidefont=font(15, \"Times\"))\nplot!(IntervalBox(D, R), label=\"natural enclosure\")\nplot!(IntervalBox(D, Rbb), label=\"branch and bound\", alpha=1)\nplot!(f, -10, 10, lw=2, c=:black, label=\"f\")\nsavefig(\"tutorial-2d.png\"); nothing # hide","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"(Image: )","category":"page"},{"location":"tutorial/#Tuning-parameters","page":"Tutorial","title":"Tuning parameters","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Some solvers have parameters that can be tuned. For example, looking at the BranchAndBoundEnclosure documentation, we can see that it has two parameters, tol and maxdepth. If you want to use different values from the default ones, you can pass the parameters as keyword arguments to the solver constructor. For example, you can limit the depth of the search tree to 6 the following way:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(f, D, BranchAndBoundEnclosure(maxdepth=6))","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Generally, tuning parameters can be a good idea to achieve the desired accuracy tradeoff in your application.","category":"page"},{"location":"tutorial/#Combining-different-solvers","page":"Tutorial","title":"Combining different solvers","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Sometimes there is no strictly \"best\" solver, as one solver might give a tighter estimate of the range's upper bound and another solver might give a tighter estimate on the lower bound. In this case, the results can be combined by taking the intersection. For example, let us consider the function g(x) = x^2 - 2x + 1, which we want to bound over the domain D_g = 0 4. Let us first use plain interval arithmetic:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"g(x) = x^2 - 2*x + 1\nDg = 0..4\nenclose(g, Dg, NaturalEnclosure()) # this is equivalent to enclose(g, Dg)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Now let us bound the range using the MeanValueEnclosure solver, which uses the mean-value form of the function:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(g, Dg, MeanValueEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"As you can see, there is no clear winner and a better enclosure could be obtained by taking the intersection of the two results. This can be easily done in one command by passing a vector of solvers to enclose:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(g, Dg, [NaturalEnclosure(), MeanValueEnclosure()])","category":"page"},{"location":"tutorial/#Using-solvers-based-on-external-libraries","page":"Tutorial","title":"Using solvers based on external libraries","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Some of the available solvers are implemented in external libraries. To keep the start-up time of RangeEnclosures.jl low, these libraries are not imported by default. To use more solvers, these libraries need to be manually loaded. For example, suppose we want to bound the previous function using the Moore-Skelboe algorithm. Trying the following will fail:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(f, D, MooreSkelboeEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"ERROR: AssertionError: package 'IntervalOptimisation' not loaded (it is required for executing `enclose`)\n...","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"This is because the algorithm is implemented in IntervalOptimisation.jl and to use it you need to load that package first (note that you need to have it installed before loading it). Let us fix our example.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using IntervalOptimisation\nenclose(f, D, MooreSkelboeEnclosure())","category":"page"},{"location":"tutorial/#Bounding-multivariate-functions","page":"Tutorial","title":"Bounding multivariate functions","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"While our previous examples were in one dimension, the techniques generalize to multivariate functions mathbbR^nrightarrowmathbbR, the only difference is that the domain, instead of being an interval, should be an IntervalBox. For example, consider the function","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"h(x_1 x_2) = sin(x_1) - cos(x_2) - sin(x_1)cos(x_1)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"over the domain D_h = -5 5 times -5 5. An enclosure can be computed as follows.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"h(x) = sin(x[1]) - cos(x[2]) - sin(x[1]) * cos(x[1])\nDh = IntervalBox(-5..5, -5..5)\nRh = enclose(h, Dh, BranchAndBoundEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"We can visualize the result with the following script. For this we use the API of IntervalArithmetic, which must be loaded first.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using IntervalArithmetic\n\nx = y = -5:0.1:5\nf(x, y) = h([x, y])\nplot(legend=:none, size=(800, 800), xlabel=\"x\", ylabel=\"y\", zlabel=\"h(x,y)\",\n tickfontsize=18, guidefont=font(22, \"Times\"), zticks=[-2, 0, 2])\nsurface!(x, y, [inf(Rh) for _ in x, _ in y], α=0.4)\nsurface!(x, y, f.(x', y), zlims=(-4, 4))\nsurface!(x, y, [sup(Rh) for _ in x, _ in y], α=0.4)\nsavefig(\"tutorial-3d.png\"); nothing # hide","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"(Image: )","category":"page"},{"location":"lib/methods/#Methods","page":"Methods","title":"Methods","text":"","category":"section"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"This section describes systems methods implemented in RangeEnclosures.jl.","category":"page"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"Pages = [\"methods.md\"]\nDepth = 3","category":"page"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"CurrentModule = RangeEnclosures","category":"page"},{"location":"lib/methods/#The-enclose-function","page":"Methods","title":"The enclose function","text":"","category":"section"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"enclose","category":"page"},{"location":"lib/methods/#RangeEnclosures.enclose","page":"Methods","title":"RangeEnclosures.enclose","text":"enclose(f, dom[, solver=NaturalEnclosure()]; kwargs...)\n\nReturn a range enclosure of a univariate or multivariate function on the given domain.\n\nInput\n\nf – function or AbstractPolynomialLike object\ndom – hyperrectangular domain, either a unidimensional Interval or a multidimensional IntervalBox\nsolver – (optional, default: NaturalEnclosure()) choose one among the available solvers; you can get a list of available solvers with subtypes(AbstractEnclosureAlgorithm)\nkwargs – optional keyword arguments passed to the solver; for available options see the documentation of each solver\n\nOutput\n\nAn interval enclosure of the range of f over dom.\n\nExamples\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1) # use default solver\n[0, 2]\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure())\n[0.8125, 1.09375]\n\nA vector of solvers can be passed in the solver options. Then, the result is obtained by intersecting the range enclosure of each solver.\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, [TaylorModelsEnclosure(), NaturalEnclosure()])\n[0.8125, 1.09375]\n\n\n\n\n\n\n","category":"function"},{"location":"lib/methods/#Utility-functions","page":"Methods","title":"Utility functions","text":"","category":"section"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"relative_precision","category":"page"},{"location":"lib/methods/#RangeEnclosures.relative_precision","page":"Methods","title":"RangeEnclosures.relative_precision","text":"relative_precision(x::Interval, xref::Interval)\n\nReturn the relative precision of an interval with respect to a reference interval.\n\nInput\n\nx – test interval\nxref – reference interval\n\nOutput\n\nLeft and right relative precision (in %) computed as\n\nrleft = (inf(xref) - inf(x)) / diam(xref) * 100%\nrright = (sup(x) - sup(xright)) / diam(xref) * 100%\n\nExamples\n\njulia> xref = interval(-1.2, 4.6)\n[-1.2, 4.6]\n\njulia> x = interval(-1.25, 7.45)\n[-1.25, 7.45001]\n\njulia> relative_precision(x, xref)\n(0.8620689655172422, 49.13793103448277)\n\nAlgorithm\n\nThis function measures the relative precision of the result in a more informative way than taking the scalar overestimation because it evaluates the precision of the lower and the upper bounds separately (cf. Eq. (20) in [1]).\n\n[1] Althoff, Matthias, Dmitry Grebenyuk, and Niklas Kochdumper. Implementation of Taylor models in CORA 2018. Proc. of the 5th International Workshop on Applied Verification for Continuous and Hybrid Systems. 2018.\n\n\n\n\n\n","category":"function"}] +[{"location":"about/#About","page":"About","title":"About","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"This page contains some general information about this project, and recommendations about contributing.","category":"page"},{"location":"about/","page":"About","title":"About","text":"Pages = [\"about.md\"]","category":"page"},{"location":"about/#Contributing","page":"About","title":"Contributing","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"If you like this package, consider contributing! You can send bug reports (or fix them and send your code), add examples to the documentation, or propose new features.","category":"page"},{"location":"about/","page":"About","title":"About","text":"Below some conventions that we follow when contributing to this package are detailed. For specific guidelines on documentation, see the Documentations Guidelines wiki.","category":"page"},{"location":"about/#Branches-and-pull-requests-(PR)","page":"About","title":"Branches and pull requests (PR)","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"We use a standard pull request policy: You work in a private branch and eventually add a pull request, which is then reviewed by other programmers and merged into the master branch.","category":"page"},{"location":"about/","page":"About","title":"About","text":"Each pull request should be pushed in a new branch with the name of the author followed by a descriptive name, e.g., mforets/my_feature. If the branch is associated to a previous discussion in one issue, we use the name of the issue for easier lookup, e.g., mforets/7.","category":"page"},{"location":"about/#Unit-testing-and-continuous-integration-(CI)","page":"About","title":"Unit testing and continuous integration (CI)","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"This project is synchronized with GitHub Actions such that each PR gets tested before merging (and the build is automatically triggered after each new commit). For the maintainability of this project, it is important to make all unit tests pass.","category":"page"},{"location":"about/","page":"About","title":"About","text":"To run the unit tests locally, you can do:","category":"page"},{"location":"about/","page":"About","title":"About","text":"julia> using Pkg\n\njulia> Pkg.test(\"RangeEnclosures\")","category":"page"},{"location":"about/","page":"About","title":"About","text":"We also advise adding new unit tests when adding new features to ensure long-term support of your contributions.","category":"page"},{"location":"about/#Contributing-to-the-documentation","page":"About","title":"Contributing to the documentation","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"New functions and types should be documented according to our guidelines directly in the source code.","category":"page"},{"location":"about/","page":"About","title":"About","text":"You can view the source code documentation from inside the REPL by typing ? followed by the name of the type or function. For example, the following command will print the documentation of the enclose function:","category":"page"},{"location":"about/","page":"About","title":"About","text":"julia> ?enclose","category":"page"},{"location":"about/","page":"About","title":"About","text":"This documentation you are currently reading is written in Markdown, and it relies on Documenter.jl to produce the HTML layout. The sources for creating this documentation are found in docs/src. You can easily include the documentation that you wrote for your functions or types there (see the Documenter.jl guide or our sources for examples).","category":"page"},{"location":"about/","page":"About","title":"About","text":"To generate the documentation locally, run make.jl, e.g., by executing the following command in the terminal:","category":"page"},{"location":"about/","page":"About","title":"About","text":"$ julia --color=yes docs/make.jl","category":"page"},{"location":"about/#Credits","page":"About","title":"Credits","text":"","category":"section"},{"location":"about/#Core-developers","page":"About","title":"Core developers","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"The RangeEnclosures.jl library is maintained by (in alphabetic order):","category":"page"},{"location":"about/","page":"About","title":"About","text":"Luca Ferranti, University of Vasaa\nMarcelo Forets, Universidad de la República\nChristian Schilling, Aalborg University","category":"page"},{"location":"about/#Contributors","page":"About","title":"Contributors","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"Huge thanks to all the contributors.","category":"page"},{"location":"about/#Acknowledgments","page":"About","title":"Acknowledgments","text":"","category":"section"},{"location":"about/","page":"About","title":"About","text":"We are grateful to the following persons for enlightening discussions during the preparation of this package:","category":"page"},{"location":"about/","page":"About","title":"About","text":"Luis Benet\nBenoît Legat\nDavid P. Sanders","category":"page"},{"location":"about/","page":"About","title":"About","text":"During Summer 2022, this project was financially supported by Google through the Google Summer of Code program. During Summer 2019, this project was financially supported by Julia through the Julia Season of Contributions program.","category":"page"},{"location":"lib/types/#Types","page":"Types","title":"Types","text":"","category":"section"},{"location":"lib/types/","page":"Types","title":"Types","text":"This section describes systems types implemented in RangeEnclosures.jl.","category":"page"},{"location":"lib/types/","page":"Types","title":"Types","text":"Pages = [\"types.md\"]\nDepth = 3","category":"page"},{"location":"lib/types/","page":"Types","title":"Types","text":"CurrentModule = RangeEnclosures","category":"page"},{"location":"lib/types/","page":"Types","title":"Types","text":"AbstractEnclosureAlgorithm\nAbstractDirectRangeAlgorithm\nAbstractIterativeRangeAlgorithm\nAffineArithmeticEnclosure\nBranchAndBoundEnclosure\nNaturalEnclosure\nMeanValueEnclosure\nMooreSkelboeEnclosure\nSumOfSquaresEnclosure\nTaylorModelsEnclosure","category":"page"},{"location":"lib/types/#RangeEnclosures.AbstractEnclosureAlgorithm","page":"Types","title":"RangeEnclosures.AbstractEnclosureAlgorithm","text":"AbstractEnclosureAlgorithm\n\nAbstract type for range enclosure algorithms.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.AbstractDirectRangeAlgorithm","page":"Types","title":"RangeEnclosures.AbstractDirectRangeAlgorithm","text":"AbstractDirectRangeAlgorithm <: AbstractEnclosureAlgorithm\n\nAbstract type for range enclosure algorithms that directly evaluate the functions over a given domain.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.AbstractIterativeRangeAlgorithm","page":"Types","title":"RangeEnclosures.AbstractIterativeRangeAlgorithm","text":"AbstractIterativeRangeAlgorithm <: AbstractEnclosureAlgorithm\n\nAbstract type for algorithms that iteratively bound the range of a function over a given domain.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.AffineArithmeticEnclosure","page":"Types","title":"RangeEnclosures.AffineArithmeticEnclosure","text":"AffineArithmeticEnclosure <: AbstractDirectRangeAlgorithm\n\nData type to bound the range of f over X using affine arithmetic. See AffineArithmetic.jl for more details.\n\nNotes\n\nTo use this algorithm, you need to load AffineArithmetic.jl. Note also that AffineArithmetic.jl currently supports only arithmetic operations.\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.BranchAndBoundEnclosure","page":"Types","title":"RangeEnclosures.BranchAndBoundEnclosure","text":"BranchAndBoundEnclosure <: AbstractIterativeRangeAlgorithm\n\nData type to bound the range of f over X using the branch and bound algorithm.\n\nFields\n\nmaxdepth (default 10): maximum depth of the search tree\ntol (default 1e-3): tolerance to compute the range of the function\n\nAlgorithm\n\nThe algorithm evaluates a function f over an interval X. If the maximum depth is reached or the width of f(X) is below the tolerance, the algorithm returns the computed range; otherwise it bisects the interval/interval box.\n\nThe algorithm also looks at the sign of the derivative / gradient to see if the range can be computed directly. By default, the derivative / gradient is computed using ForwardDiff.jl, but a custom value can be passed via the df keyword argument to enclose.\n\nExamples\n\njulia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure())\n[4.83333, 10.5709]\n\njulia> enclose(x -> -x^3/6 + 5x, 1..4, BranchAndBoundEnclosure(tol=1e-2); df=x->-x^2/2+5)\n[4.83333, 10.5709]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.NaturalEnclosure","page":"Types","title":"RangeEnclosures.NaturalEnclosure","text":"NaturalEnclosure <: AbstractDirectRangeAlgorithm\n\nData type to bound the range of f over X using natural enclosure, i.e., to evaluate f(X) with interval arithmetic.\n\nExamples\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, NaturalEnclosure())\n[0, 2]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.MeanValueEnclosure","page":"Types","title":"RangeEnclosures.MeanValueEnclosure","text":"MeanValueEnclosure\n\nData type to bound the range of f over X using the mean value form, that is the range is bounded by the expression f(Xc) + f(X) * (X - Xc), where Xc is the midpoint of X and f' is the derivative of f (gradient in the multivariate case).\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.MooreSkelboeEnclosure","page":"Types","title":"RangeEnclosures.MooreSkelboeEnclosure","text":"MooreSkelboeEnclosure{T} <: AbstractIterativeRangeAlgorithm\n\nData type to bound the range of f over X using the Moore-Skelboe algorithm, which rigorously computes the global minimum and maximum of the function. See IntervalOptimisation.jl for more details.\n\nFields\n\nstructure – (default: HeapedVector) the way in which vector elements are kept arranged; possible options are HeapedVector and SortedVector\ntol – (default 1e-3) tolerance to which the optima are computed\n\nNotes\n\nTo use this algorithm, you need to load IntervalOptimisation.jl.\n\nExamples\n\njulia> using IntervalOptimisation\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, MooreSkelboeEnclosure()) # default parameters\n[0.916034, 1.00213]\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, MooreSkelboeEnclosure(; tol=1e-2))\n[0.900812, 1.0326]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.SumOfSquaresEnclosure","page":"Types","title":"RangeEnclosures.SumOfSquaresEnclosure","text":"SumOfSquaresEnclosure{T} <: AbstractIterativeRangeAlgorithm\n\nData type to bound the range of f over X using sum-of-squares optimization. See SumOfSquares.jl for more details\n\nFields\n\nbackend – backend used to solve the optimization problem; a list of available backends can be found here\norder – (default 5), maximum degree of the SDP relaxation\n\nNotes\n\nTo use this solver, you need to load SumOfSquares.jl and a backend.\n\nSince the optimization problem is solved numerically and not with interval arithmetic, the result of this algorithm is not rigorous.\n\nExamples\n\njulia> using SumOfSquares, SDPA, DynamicPolynomials\n\njulia> backend = SDPA.Optimizer;\n\njulia> @polyvar x;\n\njulia> enclose(-x^3/6 + 5x, 1..4, SumOfSquaresEnclosure(; backend=backend))\n[4.83333, 10.541]\n\n\n\n\n\n","category":"type"},{"location":"lib/types/#RangeEnclosures.TaylorModelsEnclosure","page":"Types","title":"RangeEnclosures.TaylorModelsEnclosure","text":"TaylorModelsEnclosure <: AbstractDirectRangeAlgorithm\n\nData type to bound the range of f over X using Taylor models. See TaylorModels.jl for more details.\n\nFields\n\norder – (default: 10) order of the Taylor model used to compute an enclosure of f over dom\nnormalize – (default: true) if true, normalize the Taylor model on the unit symmetric box around the origin\n\nNotes\n\nTo use this solver, you need to load TaylorModels.jl and a backend.\n\nExamples\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure()) # default parameters\n[0.8125, 1.09375]\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure(; order=4))\n[0.78125, 1.125]\n\n\n\n\n\n","category":"type"},{"location":"#RangeEnclosures.jl","page":"Home","title":"RangeEnclosures.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"A Julia package to compute range enclosures of real-valued functions.","category":"page"},{"location":"#Features","page":"Home","title":"Features","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Computation of lower and upper bounds of real-valued functions, either univariate or multivariate, over hyperrectangular (i.e. box shaped) domains.\nThe following solvers are always available (using the package IntervalArithmetic.jl):\nNaturalEnclosure\nMeanValueEnclosure\nBranchAndBoundEnclosure\nThe following solvers are available upon loading other packages:\nMooreSkelboeEnclosure, which requires IntervalOptimisation.jl\nTaylorModelsEnclosure, which requires TaylorModels.jl\nSumOfSquaresEnclosure, which requires SumOfSquares.jl\nAffineArithmeticEnclosure, which requires AffineArithmetic.jl","category":"page"},{"location":"#Quickstart","page":"Home","title":"Quickstart","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"The package exports one single function, enclose, which receives a Julia function, a domain, and (optionally) a solver and additional options passed to the solver. See the README.md file for the basic usage, or consult the source code docstrings, either in the REPL or in the github repository source code","category":"page"},{"location":"#Library-Outline","page":"Home","title":"Library Outline","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Pages = [\n \"lib/types.md\",\n \"lib/methods.md\"\n]\nDepth = 2","category":"page"},{"location":"tutorial/#Tutorial","page":"Tutorial","title":"Tutorial","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"This tutorial will teach you how to use RangeEnclosures. First, we will give a basic overview of the package and its functionalities. Next, we will discuss in more detail how to use the package in different scenarios (1D, higher dimension, using algorithms from external libraries, etc.).","category":"page"},{"location":"tutorial/#Setup","page":"Tutorial","title":"Setup","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Assuming you have installed Julia, you can install the package from the Julia REPL with the following lines.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using Pkg\nPkg.add(\"RangeEnclosures\")","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Then you can load the package in the standard way.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using RangeEnclosures","category":"page"},{"location":"tutorial/#Overview","page":"Tutorial","title":"Overview","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"RangeEnclosures is used to bound the range of a given function f. The main function provided by this package is enclose, and its basic usage is the following.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(f, D, solver; kwargs...)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"where","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"f is the function whose range we want to bound,\nD is the domain over which we want to compute the range,\nsolver is the solver used to compute the range (which is optional; if not specified, the package will default to the NaturalEnclosure solver), and\nkwargs... are possible keyword arguments used by the solver.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"The solvers can be divided into two families: direct solvers, which compute the range enclosure over the whole domain, and iterative solvers, which recursively split the domain into smaller subdomains to get a more accurate estimate. A detailed list of available solvers can be found here.","category":"page"},{"location":"tutorial/#Usage-Examples","page":"Tutorial","title":"Usage Examples","text":"","category":"section"},{"location":"tutorial/#A-one-dimensional-example","page":"Tutorial","title":"A one-dimensional example","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Suppose we want to compute the range of the function","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"f(x) = -sum_k=1^5kxsinleft(frack(x-3)3right)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"over the domain D = -10 10.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"If we call enclose without specifying the solver, it will evaluate f(D) using plain interval arithmetic (this is called natural enclosure), as the following example shows.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"f(x) = -sum(k*x*sin(k*(x-3)/3) for k in 1:5)\nD = -10..10\nR = enclose(f, D)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Generally, using natural enclosures leads to unpleasantly large overestimates, which is due to the dependency problem. To overcome this, you may want to use some other solvers in your application. The next example bounds the range using the BranchAndBoundEnclosure solver.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Rbb = enclose(f, D, BranchAndBoundEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"As you can see, the result is much tighter now, while still being rigorous! The results can be visualized using Plots.jl.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using Plots\nplot(xlabel=\"x\", ylabel=\"f(x)\", legendfontsize=12, tickfontsize=12,\n xguidefont=font(15, \"Times\"), yguidefont=font(15, \"Times\"))\nplot!(IntervalBox(D, R), label=\"natural enclosure\")\nplot!(IntervalBox(D, Rbb), label=\"branch and bound\", alpha=1)\nplot!(f, -10, 10, lw=2, c=:black, label=\"f\")\nsavefig(\"tutorial-2d.png\"); nothing # hide","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"(Image: )","category":"page"},{"location":"tutorial/#Tuning-parameters","page":"Tutorial","title":"Tuning parameters","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Some solvers have parameters that can be tuned. For example, looking at the BranchAndBoundEnclosure documentation, we can see that it has two parameters, tol and maxdepth. If you want to use different values from the default ones, you can pass the parameters as keyword arguments to the solver constructor. For example, you can limit the depth of the search tree to 6 the following way:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(f, D, BranchAndBoundEnclosure(maxdepth=6))","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Generally, tuning parameters can be a good idea to achieve the desired accuracy tradeoff in your application.","category":"page"},{"location":"tutorial/#Combining-different-solvers","page":"Tutorial","title":"Combining different solvers","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Sometimes there is no strictly \"best\" solver, as one solver might give a tighter estimate of the range's upper bound and another solver might give a tighter estimate on the lower bound. In this case, the results can be combined by taking the intersection. For example, let us consider the function g(x) = x^2 - 2x + 1, which we want to bound over the domain D_g = 0 4. Let us first use plain interval arithmetic:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"g(x) = x^2 - 2*x + 1\nDg = 0..4\nenclose(g, Dg, NaturalEnclosure()) # this is equivalent to enclose(g, Dg)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Now let us bound the range using the MeanValueEnclosure solver, which uses the mean-value form of the function:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(g, Dg, MeanValueEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"As you can see, there is no clear winner and a better enclosure could be obtained by taking the intersection of the two results. This can be easily done in one command by passing a vector of solvers to enclose:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(g, Dg, [NaturalEnclosure(), MeanValueEnclosure()])","category":"page"},{"location":"tutorial/#Using-solvers-based-on-external-libraries","page":"Tutorial","title":"Using solvers based on external libraries","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Some of the available solvers are implemented in external libraries. To keep the start-up time of RangeEnclosures.jl low, these libraries are not imported by default. To use more solvers, these libraries need to be manually loaded. For example, suppose we want to bound the previous function using the Moore-Skelboe algorithm. Trying the following will fail:","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"enclose(f, D, MooreSkelboeEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"ERROR: AssertionError: package 'IntervalOptimisation' not loaded (it is required for executing `enclose`)\n...","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"This is because the algorithm is implemented in IntervalOptimisation.jl and to use it you need to load that package first (note that you need to have it installed before loading it). Let us fix our example.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using IntervalOptimisation\nenclose(f, D, MooreSkelboeEnclosure())","category":"page"},{"location":"tutorial/#Bounding-multivariate-functions","page":"Tutorial","title":"Bounding multivariate functions","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"While our previous examples were in one dimension, the techniques generalize to multivariate functions mathbbR^nrightarrowmathbbR, the only difference is that the domain, instead of being an interval, should be an IntervalBox. For example, consider the function","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"h(x_1 x_2) = sin(x_1) - cos(x_2) - sin(x_1)cos(x_1)","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"over the domain D_h = -5 5 times -5 5. An enclosure can be computed as follows.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"h(x) = sin(x[1]) - cos(x[2]) - sin(x[1]) * cos(x[1])\nDh = IntervalBox(-5..5, -5..5)\nRh = enclose(h, Dh, BranchAndBoundEnclosure())","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"We can visualize the result with the following script. For this we use the API of IntervalArithmetic, which must be loaded first.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using IntervalArithmetic\n\nx = y = -5:0.1:5\nf(x, y) = h([x, y])\nplot(legend=:none, size=(800, 800), xlabel=\"x\", ylabel=\"y\", zlabel=\"h(x,y)\",\n tickfontsize=18, guidefont=font(22, \"Times\"), zticks=[-2, 0, 2])\nsurface!(x, y, [inf(Rh) for _ in x, _ in y], α=0.4)\nsurface!(x, y, f.(x', y), zlims=(-4, 4))\nsurface!(x, y, [sup(Rh) for _ in x, _ in y], α=0.4)\nsavefig(\"tutorial-3d.png\"); nothing # hide","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"(Image: )","category":"page"},{"location":"tutorial/#Adding-a-new-enclosure-algorithm","page":"Tutorial","title":"Adding a new enclosure algorithm","text":"","category":"section"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"To add a new enclosure algorithm, or solver, just add a corresponding struct (let us call it MyEnclosure) and extend the method enclose, as the following code snippet demonstrates.","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"using RangeEnclosures\nimport RangeEnclosures: enclose\nusing IntervalArithmetic: Interval\n\nstruct MyEnclosure end\n\nfunction enclose(f::Function,\n D::Union{Interval,IntervalBox},\n solver::MyEnclosure; kwargs...)\n # solver-specific implementation\nend\nnothing # hide","category":"page"},{"location":"tutorial/","page":"Tutorial","title":"Tutorial","text":"Note that the domain D can be of type Interval for univariate (n = 1) functions or of type IntervalBox for multivariate (n 1) functions.","category":"page"},{"location":"lib/methods/#Methods","page":"Methods","title":"Methods","text":"","category":"section"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"This section describes systems methods implemented in RangeEnclosures.jl.","category":"page"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"Pages = [\"methods.md\"]\nDepth = 3","category":"page"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"CurrentModule = RangeEnclosures","category":"page"},{"location":"lib/methods/#The-enclose-function","page":"Methods","title":"The enclose function","text":"","category":"section"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"enclose","category":"page"},{"location":"lib/methods/#RangeEnclosures.enclose","page":"Methods","title":"RangeEnclosures.enclose","text":"enclose(f, dom[, solver=NaturalEnclosure()]; kwargs...)\n\nReturn a range enclosure of a univariate or multivariate function on the given domain.\n\nInput\n\nf – function or AbstractPolynomialLike object\ndom – hyperrectangular domain, either a unidimensional Interval or a multidimensional IntervalBox\nsolver – (optional, default: NaturalEnclosure()) choose one among the available solvers; you can get a list of available solvers with subtypes(AbstractEnclosureAlgorithm)\nkwargs – optional keyword arguments passed to the solver; for available options see the documentation of each solver\n\nOutput\n\nAn interval enclosure of the range of f over dom.\n\nExamples\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1) # use default solver\n[0, 2]\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, TaylorModelsEnclosure())\n[0.8125, 1.09375]\n\nA vector of solvers can be passed in the solver options. Then, the result is obtained by intersecting the range enclosure of each solver.\n\njulia> enclose(x -> 1 - x^4 + x^5, 0..1, [TaylorModelsEnclosure(), NaturalEnclosure()])\n[0.8125, 1.09375]\n\n\n\n\n\n\n","category":"function"},{"location":"lib/methods/#Utility-functions","page":"Methods","title":"Utility functions","text":"","category":"section"},{"location":"lib/methods/","page":"Methods","title":"Methods","text":"relative_precision","category":"page"},{"location":"lib/methods/#RangeEnclosures.relative_precision","page":"Methods","title":"RangeEnclosures.relative_precision","text":"relative_precision(x::Interval, xref::Interval)\n\nReturn the relative precision of an interval with respect to a reference interval.\n\nInput\n\nx – test interval\nxref – reference interval\n\nOutput\n\nLeft and right relative precision (in %) computed as\n\nrleft = (inf(xref) - inf(x)) / diam(xref) * 100%\nrright = (sup(x) - sup(xright)) / diam(xref) * 100%\n\nExamples\n\njulia> xref = interval(-1.2, 4.6)\n[-1.2, 4.6]\n\njulia> x = interval(-1.25, 7.45)\n[-1.25, 7.45001]\n\njulia> relative_precision(x, xref)\n(0.8620689655172422, 49.13793103448277)\n\nAlgorithm\n\nThis function measures the relative precision of the result in a more informative way than taking the scalar overestimation because it evaluates the precision of the lower and the upper bounds separately (cf. Eq. (20) in [1]).\n\n[1] Althoff, Matthias, Dmitry Grebenyuk, and Niklas Kochdumper. Implementation of Taylor models in CORA 2018. Proc. of the 5th International Workshop on Applied Verification for Continuous and Hybrid Systems. 2018.\n\n\n\n\n\n","category":"function"}] } diff --git a/dev/tutorial/index.html b/dev/tutorial/index.html index 6b615fd4..a2a1be6b 100644 --- a/dev/tutorial/index.html +++ b/dev/tutorial/index.html @@ -1,5 +1,5 @@ -Tutorial · RangeEnclosures.jl

Tutorial

This tutorial will teach you how to use RangeEnclosures. First, we will give a basic overview of the package and its functionalities. Next, we will discuss in more detail how to use the package in different scenarios (1D, higher dimension, using algorithms from external libraries, etc.).

Setup

Assuming you have installed Julia, you can install the package from the Julia REPL with the following lines.

using Pkg
+Tutorial · RangeEnclosures.jl

Tutorial

This tutorial will teach you how to use RangeEnclosures. First, we will give a basic overview of the package and its functionalities. Next, we will discuss in more detail how to use the package in different scenarios (1D, higher dimension, using algorithms from external libraries, etc.).

Setup

Assuming you have installed Julia, you can install the package from the Julia REPL with the following lines.

using Pkg
 Pkg.add("RangeEnclosures")

Then you can load the package in the standard way.

using RangeEnclosures

Overview

RangeEnclosures is used to bound the range of a given function f. The main function provided by this package is enclose, and its basic usage is the following.

enclose(f, D, solver; kwargs...)

where

  • f is the function whose range we want to bound,
  • D is the domain over which we want to compute the range,
  • solver is the solver used to compute the range (which is optional; if not specified, the package will default to the NaturalEnclosure solver), and
  • kwargs... are possible keyword arguments used by the solver.

The solvers can be divided into two families: direct solvers, which compute the range enclosure over the whole domain, and iterative solvers, which recursively split the domain into smaller subdomains to get a more accurate estimate. A detailed list of available solvers can be found here.

Usage Examples

A one-dimensional example

Suppose we want to compute the range of the function

\[f(x) = -\sum_{k=1}^5kx\sin\left(\frac{k(x-3)}{3}\right)\]

over the domain $D = [-10, 10]$.

If we call enclose without specifying the solver, it will evaluate $f(D)$ using plain interval arithmetic (this is called natural enclosure), as the following example shows.

f(x) = -sum(k*x*sin(k*(x-3)/3) for k in 1:5)
 D = -10..10
 R = enclose(f, D)
[-150, 150]

Generally, using natural enclosures leads to unpleasantly large overestimates, which is due to the dependency problem. To overcome this, you may want to use some other solvers in your application. The next example bounds the range using the BranchAndBoundEnclosure solver.

Rbb = enclose(f, D, BranchAndBoundEnclosure())
[-56.4232, 34.9988]

As you can see, the result is much tighter now, while still being rigorous! The results can be visualized using Plots.jl.

using Plots
@@ -21,4 +21,14 @@
      tickfontsize=18, guidefont=font(22, "Times"), zticks=[-2, 0, 2])
 surface!(x, y, [inf(Rh) for _ in x, _ in y], α=0.4)
 surface!(x, y, f.(x', y), zlims=(-4, 4))
-surface!(x, y, [sup(Rh) for _ in x, _ in y], α=0.4)

+surface!(x, y, [sup(Rh) for _ in x, _ in y], α=0.4)

Adding a new enclosure algorithm

To add a new enclosure algorithm, or solver, just add a corresponding struct (let us call it MyEnclosure) and extend the method enclose, as the following code snippet demonstrates.

using RangeEnclosures
+import RangeEnclosures: enclose
+using IntervalArithmetic: Interval
+
+struct MyEnclosure end
+
+function enclose(f::Function,
+                 D::Union{Interval,IntervalBox},
+                 solver::MyEnclosure; kwargs...)
+    # solver-specific implementation
+end

Note that the domain D can be of type Interval for univariate ($n = 1$) functions or of type IntervalBox for multivariate ($n > 1$) functions.