22 struct SignSymmetry <: Sparsity.Pattern end
33
44Sign symmetry as developed in [Section III.C, L09].
5+ Let `n` be the number of variables.
6+ A *sign-symmetry* is a binary vector `r` of `{0, 1}^n`
7+ such that `dot(r, e)` is even for all exponent `e`.
58
6- [L09] Lofberg, Johan.
9+ Let `o(e)` be the binary vector of `{0, 1}^n` for which the `i`th bit is `i`
10+ iff the `i`th entry of `e` is odd.
11+ Let `O` be the set of `o(e)` for exponents of `e`.
12+ The sign symmetry of `r` is then equivalent to its orthogonality
13+ with all elements of `O`.
14+
15+ Since we are only interested in the orthogonal subspace, say `R`, of `O`,
16+ even if `O` is not a linear subspace (i.e., it is not invariant under `xor`),
17+ we compute its span.
18+ We start by creating row echelon form of the span of `O` using
19+ [`XORSpace`](@ref).
20+ We then compute a basis for `R`.
21+ The set `R` of sign symmetries will be the span of this basis.
22+
23+ Let `a`, `b` be exponents of monomials of the gram basis. For any `r in R`,
24+ ```
25+ ⟨r, o(a + b)⟩ = ⟨r, xor(o(a), o(b)⟩ = xor(⟨r, o(a)⟩, ⟨r, o(b)⟩)
26+ ```
27+ For `o(a, b)` to be sign symmetric, this scalar product should be zero for all
28+ sign symmetry `r`.
29+ This is equivalent to saying that `⟨r, o(a)⟩` and `⟨r, o(b)⟩` are equal
30+ for all `r in R`.
31+ In other words, the projection of `o(a)` and `o(b)` to `R` have the same
32+ coordinates in the basis.
33+ If we order the monomials by grouping them by equal coordinates of projection,
34+ we see that the product that are sign symmetric form a block diagonal
35+ structure.
36+ This means that we can group the monomials by these coordinates.
37+
38+ [L09] Löfberg, Johan.
739*Pre-and post-processing sum-of-squares programs in practice*.
840IEEE transactions on automatic control 54, no. 5 (2009): 1007-1011.
941"""
@@ -24,7 +56,9 @@ function buckets_sign_symmetry(monos, r, ::Type{T}, ::Type{U}) where {T,U}
2456 # We store vector of indices instead of vector of monos in the bucket
2557 # as `monos` is already sorted and the buckets content will be sorted
2658 # so it will remain sorted and `DynamicPolynomials` can keep the
27- # `MonomialVector` struct in `monos[I]`.
59+ # `MonomialVector` struct in `monos[I]`. With MultivariateBases, the
60+ # sorted state will be ensured by the basis struct so it will also
61+ # serve other MultivariatePolynomials implementations
2862 buckets = Dict {U,Vector{Int}} ()
2963 for (idx, mono) in enumerate (monos)
3064 exp = binary_exponent (MP. exponents (mono), T)
@@ -51,11 +85,8 @@ function sign_symmetry(
5185end
5286function sparsity (
5387 monos:: AbstractVector{<:MP.AbstractMonomial} ,
54- sp:: SignSymmetry ,
55- gram_monos:: AbstractVector = SumOfSquares. Certificate. monomials_half_newton_polytope (
56- monos,
57- tuple (),
58- ),
88+ :: SignSymmetry ,
89+ gram_monos:: AbstractVector{<:MP.AbstractMonomial} ,
5990)
6091 n = MP. nvariables (monos)
6192 return sign_symmetry (monos, n, appropriate_type (n), gram_monos)
0 commit comments