Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to treat equality constraints in domain differently #163

Open
tweisser opened this issue Jun 2, 2020 · 0 comments
Open

Option to treat equality constraints in domain differently #163

tweisser opened this issue Jun 2, 2020 · 0 comments

Comments

@tweisser
Copy link
Contributor

tweisser commented Jun 2, 2020

By default SumOfSquares handles equality constraints in the domain by working over the quotient ring R[x]/I where I is the ideal generated by the equality constraints.
This can lead to unexpected behaviour when dealing with noisy data, e.g., when the equality constraints are the result of some preprocessing step which involved floating point computations. A common source for such rounding errors could emmerge from normalizing data.

using DynamicPolynomials
using SemialgebraicSets

@polyvar vr[1:3]
@polyvar vi[1:3]
@polyvar pg[1:2]
@polyvar qg[1:2]
@polyvar pd[1]

p = [
vr[2]^2 + vi[2]^2 - 1.098778957631452,
 vr[3]^2 - 1.0,
 0.08879023307436182*vr[2]^2 - 0.04439511653718091*vr[2]*vr[3] - 0.04439511653718091*vr[2]*vr[1] - 1.3318534961154274*vr[2]*vi[1] + 1.3318534961154274*vr[3]*vi[2] + 1.3318534961154274*vr[1]*vi[2] + 0.08879023307436182*vi[2]^2 - 0.04439511653718091*vi[2]*vi[1] - 0.4117054263835753 ,
 1.9637069922308548*vr[2]^2 - 1.3318534961154274*vr[2]*vr[3] - 1.3318534961154274*vr[2]*vr[1] + 0.04439511653718091*vr[2]*vi[1] - 0.04439511653718091*vr[3]*vi[2] - 0.04439511653718091*vr[1]*vi[2] + 1.9637069922308548*vi[2]^2 - 1.3318534961154274*vi[2]*vi[1] - qg[1] + 0.5,
 -0.04439511653718091*vr[2]*vr[3] + 0.08879023307436182*vr[3]^2 - 0.04439511653718091*vr[3]*vr[1] - 1.3318534961154274*vr[3]*vi[2] - 1.3318534961154274*vr[3]*vi[1] - pg[2] + 1.0,
 -1.3318534961154274*vr[2]*vr[3] + 1.9637069922308548*vr[3]^2 - 1.3318534961154274*vr[3]*vr[1] + 0.04439511653718091*vr[3]*vi[2] + 0.04439511653718091*vr[3]*vi[1] - qg[2] + 0.5,
 -0.04439511653718091*vr[2]*vr[1] + 1.3318534961154274*vr[2]*vi[1] - 0.04439511653718091*vr[3]*vr[1] + 1.3318534961154274*vr[3]*vi[1] + 0.08879023307436182*vr[1]^2 - 1.3318534961154274*vr[1]*vi[2] - 0.04439511653718091*vi[2]*vi[1] + 0.08879023307436182*vi[1]^2 + pd[1],
 -1.3318534961154274*vr[2]*vr[1] - 0.04439511653718091*vr[2]*vi[1] - 1.3318534961154274*vr[3]*vr[1] - 0.04439511653718091*vr[3]*vi[1] + 1.9637069922308548*vr[1]^2 + 0.04439511653718091*vr[1]*vi[2] - 1.3318534961154274*vi[2]*vi[1] + 1.9637069922308548*vi[1]^2 + pd[1] - 0.5]

I = ideal(p)

Symbolically the ideal is empty:

SemialgebraicSets.computegröbnerbasis!(I)
println(I.p)
# Polynomial{true,Float64}[1.0]

However, if we allow for some numerical error the following point can be seen as a solution:

sub = Dict(
vr[1] =>  0.955906,
vr[2] =>  1.04674,
vr[3] => 1.0,
vi[1] => -0.395553,
vi[2] => -0.0558258,
vi[3] => 1.88079e-37,
pg[1] => 1.41171,
pg[2] =>1.60105,
qg[1] =>-0.111999,
qg[2] =>-0.223562,
pd[1] =>1.00000
)

subs.(p, sub...)

If we minimize pd[1] over the ideal intersected with (pd[1]-0.5)*(1.5-pd[1]) >=0 we could expect that the mimum is between 0.5 and 1. However, the problem is infeasible.

using SumOfSquares
using MosekTools

m = SOSModel(Mosek.Optimizer)
@variable m t
@objective m Max t
@constraint(m,
    pd[1]-t >=0,
    domain = basicsemialgebraicset(algebraicset(p), [(pd[1]-0.5)*(1.5-pd[1])]),
    maxdegree = 4
            )

optimize!(m)
termination_status(m)
# DUAL_INFEASIBLE::TerminationStatusCode = 3

This problem could be solved by introducing an option to encode equality constraints differently. A common way is to introduce polynomial multipliers for the equality (such as SOSPoly multipliers are introduced for inequalities).

vars = sort!(collect(keys(sub)); rev = true)
m = SOSModel(Mosek.Optimizer)
@variable m t
@objective m Max t
lhs = let 
    lhs = pd[1] - t
    for poly in p 
        pi = @variable m variable_type =  Poly(monomials(vars, 0:4-maxdegree(poly)))
    lhs -= pi*poly
    end
    lhs 
end
@constraint(m,
    lhs >=0,
    domain = @set((pd[1]-0.5)*(1.5-pd[1])>=0),
    maxdegree = 4
            )

optimize!(m)
termination_status(m)
# OPTIMAL::TerminationStatusCode = 1

Now the problem solves with optimal and actually returns an expected solutions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant