// Models the cone of nonnegative polynomials on the finite interval [a,b] public static void nn_finite(Model M, Variable x, double a, double b) { //assert(a < b) int m = (int)x.Size() - 1; int n = m / 2; if (m == 2 * n) { Variable X1 = M.Variable(Domain.InPSDCone(n + 1)); Variable X2 = M.Variable(Domain.InPSDCone(n)); // x_i = Tr H(n,i)*X1 + (a+b)*Tr H(n-1,i-1) * X2 - a*b*Tr H(n-1,i)*X2 - Tr H(n-1,i-2)*X2, i=0,...,m for (int i = 0; i < m + 1; ++i) { M.Constraint(Expr.Sub(x.Index(i), Expr.Add(Expr.Sub(Expr.Dot(Hankel(n, i, 1.0), X1), Expr.Dot(Hankel(n - 1, i, a * b), X2)), Expr.Sub(Expr.Dot(Hankel(n - 1, i - 1, a + b), X2), Expr.Dot(Hankel(n - 1, i - 2, 1.0), X2)))), Domain.EqualsTo(0.0)); } } else { Variable X1 = M.Variable(Domain.InPSDCone(n + 1)); Variable X2 = M.Variable(Domain.InPSDCone(n + 1)); // x_i = Tr H(n,i-1)*X1 - a*Tr H(n,i)*X1 + b*Tr H(n,i)*X2 - Tr H(n,i-1)*X2, i=0,...,m for (int i = 0; i < m + 1; ++i) { M.Constraint(Expr.Sub(x.Index(i), Expr.Add(Expr.Sub(Expr.Dot(Hankel(n, i - 1, 1.0), X1), Expr.Dot(Hankel(n, i, a), X1)), Expr.Sub(Expr.Dot(Hankel(n, i, b), X2), Expr.Dot(Hankel(n, i - 1, 1.0), X2)))), Domain.EqualsTo(0.0)); } } }
// Models the cone of nonnegative polynomials on the finite interval [a,b] public static void nn_finite(Model M, Variable x, double a, double b) { //assert(a < b) int m = (int)x.Size()-1; int n = m/2; if (m == 2*n) { Variable X1 = M.Variable(Domain.InPSDCone(n+1)); Variable X2 = M.Variable(Domain.InPSDCone(n)); // x_i = Tr H(n,i)*X1 + (a+b)*Tr H(n-1,i-1) * X2 - a*b*Tr H(n-1,i)*X2 - Tr H(n-1,i-2)*X2, i=0,...,m for (int i = 0; i < m+1; ++i) M.Constraint( Expr.Sub(x.Index(i), Expr.Add(Expr.Sub(Expr.Dot(Hankel(n, i,1.0), X1), Expr.Dot(Hankel(n-1, i, a*b), X2)), Expr.Sub(Expr.Dot(Hankel(n-1, i-1, a+b), X2), Expr.Dot(Hankel(n-1, i-2,1.0), X2)))), Domain.EqualsTo(0.0) ); } else { Variable X1 = M.Variable(Domain.InPSDCone(n+1)); Variable X2 = M.Variable(Domain.InPSDCone(n+1)); // x_i = Tr H(n,i-1)*X1 - a*Tr H(n,i)*X1 + b*Tr H(n,i)*X2 - Tr H(n,i-1)*X2, i=0,...,m for (int i = 0; i < m+1; ++i) M.Constraint( Expr.Sub(x.Index(i), Expr.Add(Expr.Sub(Expr.Dot(Hankel(n, i-1,1.0), X1), Expr.Dot(Hankel(n, i, a), X1)), Expr.Sub(Expr.Dot(Hankel(n, i, b), X2), Expr.Dot(Hankel(n, i-1,1.0), X2)))), Domain.EqualsTo(0.0) ); } }
// returns variables u representing the derivative of // x(0) + x(1)*t + ... + x(n)*t^n, // with u(0) = x(1), u(1) = 2*x(2), ..., u(n-1) = n*x(n). public static Variable diff(Model M, Variable x) { int n = (int)x.Size() - 1; Variable u = M.Variable(n, Domain.Unbounded()); M.Constraint(Expr.Sub(u, Expr.MulElm(Matrix.Dense(n, 1, Range(1.0, n + 1)), x.Slice(1, n + 1))), Domain.EqualsTo(0.0)); return(u); }
// returns variables u representing the derivative of // x(0) + x(1)*t + ... + x(n)*t^n, // with u(0) = x(1), u(1) = 2*x(2), ..., u(n-1) = n*x(n). public static Variable diff(Model M, Variable x) { int n = (int)x.Size() - 1; Variable u = M.Variable(n, Domain.Unbounded()); Variable tmp = Variable.Reshape(x.Slice(1, n + 1), new NDSet(1, n)); M.Constraint(Expr.Sub(u, Expr.MulElm(new DenseMatrix(1, n, Range(1.0, n + 1)), tmp)), Domain.EqualsTo(0.0)); return(u); }
// Models the cone of nonnegative polynomials on the real axis public static void nn_inf(Model M, Variable x) { int m = (int)x.Size() - 1; int n = (m/2); // degree of polynomial is 2*n //assert(m == 2*n) // Setup variables Variable X = M.Variable(Domain.InPSDCone(n+1)); // x_i = Tr H(n, i) * X i=0,...,m for (int i = 0; i < m+1; ++i) M.Constraint( Expr.Sub(x.Index(i), Expr.Dot(Hankel(n,i,1.0),X)), Domain.EqualsTo(0.0)); }
// Models the cone of nonnegative polynomials on the real axis public static void nn_inf(Model M, Variable x) { int m = (int)x.Size() - 1; int n = (m / 2); // degree of polynomial is 2*n //assert(m == 2*n) // Setup variables Variable X = M.Variable(Domain.InPSDCone(n + 1)); // x_i = Tr H(n, i) * X i=0,...,m for (int i = 0; i < m + 1; ++i) { M.Constraint(Expr.Sub(x.Index(i), Expr.Dot(Hankel(n, i, 1.0), X)), Domain.EqualsTo(0.0)); } }
// Models the cone of nonnegative polynomials on the semi-infinite interval [0,inf) public static void nn_semiinf(Model M, Variable x) { int n = (int)x.Size()-1; int n1 = n/2, n2 = (n-1)/2; // Setup variables Variable X1 = M.Variable(Domain.InPSDCone(n1+1)); Variable X2 = M.Variable(Domain.InPSDCone(n2+1)); // x_i = Tr H(n1, i) * X1 + Tr H(n2,i-1) * X2, i=0,...,n for (int i = 0; i < n+1; ++i) M.Constraint( Expr.Sub(x.Index(i), Expr.Add(Expr.Dot(Hankel(n1,i,1.0), X1), Expr.Dot(Hankel(n2,i-1,1.0),X2))), Domain.EqualsTo(0.0) ); }
// Models the cone of nonnegative polynomials on the semi-infinite interval [0,inf) public static void nn_semiinf(Model M, Variable x) { int n = (int)x.Size() - 1; int n1 = n / 2, n2 = (n - 1) / 2; // Setup variables Variable X1 = M.Variable(Domain.InPSDCone(n1 + 1)); Variable X2 = M.Variable(Domain.InPSDCone(n2 + 1)); // x_i = Tr H(n1, i) * X1 + Tr H(n2,i-1) * X2, i=0,...,n for (int i = 0; i < n + 1; ++i) { M.Constraint(Expr.Sub(x.Index(i), Expr.Add(Expr.Dot(Hankel(n1, i, 1.0), X1), Expr.Dot(Hankel(n2, i - 1, 1.0), X2))), Domain.EqualsTo(0.0)); } }
/** * Purpose: Models the convex set * * S = { (x, t) \in R^n x R | x >= 0, t <= (x1 * x2 * ... *xn)^(1/n) }. * * as the intersection of rotated quadratic cones and affine hyperplanes, * see [1, p. 105]. This set can be interpreted as the hypograph of the * geometric mean of x. * * We illustrate the modeling procedure using the following example. * Suppose we have * * t <= (x1 * x2 * x3)^(1/3) * * for some t >= 0, x >= 0. We rewrite it as * * t^4 <= x1 * x2 * x3 * x4, x4 = t * * which is equivalent to (see [1]) * * x11^2 <= 2*x1*x2, x12^2 <= 2*x3*x4, * * x21^2 <= 2*x11*x12, * * sqrt(8)*x21 = t, x4 = t. * * References: * [1] "Lectures on Modern Optimization", Ben-Tal and Nemirovski, 2000. */ public static void geometric_mean(Model M, Variable x, Variable t) { int n = (int)x.Size(); int l = (int)System.Math.Ceiling(log2(n)); int m = pow2(l) - n; Variable x0; if (m == 0) { x0 = x; } else { x0 = Var.Vstack(x, M.Variable(m, Domain.GreaterThan(0.0))); } Variable z = x0; for (int i = 0; i < l - 1; ++i) { Variable xi = M.Variable(pow2(l - i - 1), Domain.GreaterThan(0.0)); for (int k = 0; k < pow2(l - i - 1); ++k) { M.Constraint(Var.Vstack(z.Index(2 * k), z.Index(2 * k + 1), xi.Index(k)), Domain.InRotatedQCone()); } z = xi; } Variable t0 = M.Variable(1, Domain.GreaterThan(0.0)); M.Constraint(Var.Vstack(z, t0), Domain.InRotatedQCone()); M.Constraint(Expr.Sub(Expr.Mul(System.Math.Pow(2, 0.5 * l), t), t0), Domain.EqualsTo(0.0)); for (int i = pow2(l - m); i < pow2(l); ++i) { M.Constraint(Expr.Sub(x0.Index(i), t), Domain.EqualsTo(0.0)); } }
/** Purpose: Models the convex set S = { (x, t) \in R^n x R | x >= 0, t <= (x1 * x2 * ... *xn)^(1/n) }. as the intersection of rotated quadratic cones and affine hyperplanes, see [1, p. 105]. This set can be interpreted as the hypograph of the geometric mean of x. We illustrate the modeling procedure using the following example. Suppose we have t <= (x1 * x2 * x3)^(1/3) for some t >= 0, x >= 0. We rewrite it as t^4 <= x1 * x2 * x3 * x4, x4 = t which is equivalent to (see [1]) x11^2 <= 2*x1*x2, x12^2 <= 2*x3*x4, x21^2 <= 2*x11*x12, sqrt(8)*x21 = t, x4 = t. References: [1] "Lectures on Modern Optimization", Ben-Tal and Nemirovski, 2000. */ public static void geometric_mean(Model M, Variable x, Variable t) { int n = (int)x.Size(); int l = (int)System.Math.Ceiling(log2(n)); int m = pow2(l) - n; Variable x0; if (m == 0) x0 = x; else x0 = Variable.Vstack(x, M.Variable(m, Domain.GreaterThan(0.0))); Variable z = x0; for (int i = 0; i < l-1; ++i) { Variable xi = M.Variable(pow2(l-i-1), Domain.GreaterThan(0.0)); for (int k = 0; k < pow2(l-i-1); ++k) M.Constraint(Variable.Vstack(z.Index(2*k),z.Index(2*k+1),xi.Index(k)), Domain.InRotatedQCone()); z = xi; } Variable t0 = M.Variable(1, Domain.GreaterThan(0.0)); M.Constraint(Variable.Vstack(z, t0), Domain.InRotatedQCone()); M.Constraint(Expr.Sub(Expr.Mul(System.Math.Pow(2,0.5*l),t),t0), Domain.EqualsTo(0.0)); for (int i = pow2(l-m); i < pow2(l); ++i) M.Constraint(Expr.Sub(x0.Index(i), t), Domain.EqualsTo(0.0)); }
// returns variables u representing the derivative of // x(0) + x(1)*t + ... + x(n)*t^n, // with u(0) = x(1), u(1) = 2*x(2), ..., u(n-1) = n*x(n). public static Variable diff(Model M, Variable x) { int n = (int)x.Size()-1; Variable u = M.Variable(n, Domain.Unbounded()); Variable tmp = Variable.Reshape(x.Slice(1,n+1),new NDSet(1,n)); M.Constraint(Expr.Sub(u, Expr.MulElm(new DenseMatrix(1,n,Range(1.0,n+1)), tmp)), Domain.EqualsTo(0.0)); return u; }