Skip to content

Commit 815fd11

Browse files
committed
Add hypercube example
1 parent 766dbba commit 815fd11

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# # Hypercube
2+
3+
#md # [![](https://mybinder.org/badge_logo.svg)](@__BINDER_ROOT_URL__/generated/Extension/hypercube.ipynb)
4+
#md # [![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](@__NBVIEWER_ROOT_URL__/generated/Extension/hypercube.ipynb)
5+
# **Contributed by**: Benoît Legat
6+
7+
# Given a Sum-of-Squares constraint on an algebraic set:
8+
# ```math
9+
# g_1(x) = , \ldots, g_m(x) = 0 \Rightarrow p(x) \ge 0.
10+
# ```
11+
# We can either use the certificate:
12+
# ```math
13+
# p(x) = s(x) + \lambda_1(x) g_1(x) + \cdots + \lambda_m(x) g_m(x), s_0(x) \text{ is SOS},
14+
# ```
15+
# or
16+
# ```math
17+
# p(x) \equiv s(x) \pmod{\la g_1(x), \ldots, g_m(x) \ra}, s_0(x) \text{ is SOS}.
18+
# ```
19+
# the second one leads to a *simpler* SDP but needs to compute a *Gr\"obner* basis:
20+
# * SemialgebraicSets implements Buchberger's algorithm.
21+
# * The `@set` macro recognizes variable fix, e.g., `x = 1`
22+
# and provides shortcut.
23+
# * If you know a \alert{better} way to take modulo,
24+
# better create your \alert{own} type of algebraic set!
25+
26+
# We illustrate this in this example.
27+
28+
using DynamicPolynomials
29+
@polyvar x[1:3]
30+
p = sum(x)^2
31+
using SumOfSquares
32+
S = algebraicset([xi^2 - 1 for xi in x])
33+
34+
# We will now search for the minimum of `x` over `S` using Sum of Squares Programming.
35+
# We first need to pick an SDP solver, see [here](https://jump.dev/JuMP.jl/v0.21.6/installation/#Supported-solvers) for a list of the available choices.
36+
37+
import CSDP
38+
solver = optimizer_with_attributes(CSDP.Optimizer, MOI.Silent() => true)
39+
40+
function min_algebraic(S)
41+
model = SOSModel(solver)
42+
@variable(model, α)
43+
@objective(model, Max, α)
44+
@constraint(model, c, p >= α, domain = S)
45+
optimize!(model)
46+
@show termination_status(model)
47+
@show objective_value(model)
48+
end
49+
50+
min_algebraic(S)
51+
52+
# Note that the minimum is in fact `1`.
53+
# Indeed, since each variables is odd (it is either `-1` or `1`)
54+
# and there is an odd number of variables, their sum is odd.
55+
# Therefore it cannot be zero!
56+
57+
# We can see that the Gröbner basis of `S` was computed
58+
59+
@show S.I.gröbnerbasis
60+
S.I.algo
61+
62+
# The Gröbner basis is simple to compute in this case as the vector
63+
# of `xi^2 - 1` is already a Gröbner basis.
64+
# However, we still need to divide polynomials by the Gröbner basis
65+
# which can be simplified in this case.
66+
67+
const MP = MultivariatePolynomials
68+
const SS = SemialgebraicSets
69+
struct HypercubeIdeal{V} <: SS.AbstractPolynomialIdeal
70+
variables::Vector{V}
71+
end
72+
struct HypercubeSet{V} <: SS.AbstractAlgebraicSet
73+
ideal::HypercubeIdeal{V}
74+
end
75+
MP.changecoefficienttype(set::HypercubeSet, ::Type) = set
76+
SS.ideal(set::HypercubeSet) = set.ideal
77+
function Base.rem(p, set::HypercubeIdeal)
78+
return MP.polynomial(map(MP.terms(p)) do term
79+
mono = MP.monomial(term)
80+
new_mono = one(mono)
81+
for (var, exp) in powers(mono)
82+
if var in set.variables
83+
exp = rem(exp, 2)
84+
end
85+
new_mono *= var^exp
86+
end
87+
MP.coefficient(term) * new_mono
88+
end)
89+
end
90+
91+
H = HypercubeSet(HypercubeIdeal(x))
92+
93+
min_algebraic(H)
94+
95+
# Let's now try to find the correct lower bound:
96+
97+
function min_algebraic_rational(S, d)
98+
model = SOSModel(solver)
99+
@variable(model, q, SOSPoly(MP.monomials(x, 0:d)))
100+
deno = q + 1
101+
@constraint(model, c, deno * p >= deno, domain = S)
102+
optimize!(model)
103+
@show termination_status(model)
104+
end
105+
106+
# With `d = 0`, it's the same as previously
107+
108+
min_algebraic_rational(H, 0)
109+
110+
# But with `d = 1`, we can find the correct lower bound
111+
112+
min_algebraic_rational(H, 1)

0 commit comments

Comments
 (0)