carl  24.04
Computer ARithmetic Library
SoSDecomposition.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "Degree.h"
4 #include "Power.h"
5 
6 #include "../MultivariatePolynomial.h"
7 #include "VarInfo.h"
8 
9 namespace carl {
10 
11 template<typename C, typename O, typename P>
12 std::vector<std::pair<C,MultivariatePolynomial<C,O,P>>> sos_decomposition(const MultivariatePolynomial<C,O,P>& p, bool not_trivial = false) {
13  std::vector<std::pair<C,MultivariatePolynomial<C,O,P>>> result;
14  if (carl::is_negative(p.lcoeff())) {
15  return result;
16  }
17  if (!not_trivial) {
18  for (auto term = p.rbegin(); term != p.rend(); ++term) {
19  if (!carl::is_negative(term->coeff())) {
20  assert(!carl::is_zero(term->coeff()));
21  if (is_constant(*term)) {
22  result.emplace_back(term->coeff(), MultivariatePolynomial<C,O,P>(constant_one<C>::get()));
23  } else {
24  auto resMonomial = term->monomial()->sqrt();
25  if (resMonomial == nullptr) {
26  break;
27  }
28  result.emplace_back(term->coeff(), MultivariatePolynomial<C,O,P>(resMonomial));
29  }
30  } else {
31  break;
32  }
33  }
34  result.clear();
35  }
36  // TODO: If cheap, find substitution of monomials to variables such that applied to this polynomial a quadratic form is achieved.
37  // Only compute sos for quadratic forms.
38  if (p.total_degree() != 2) {
39  return result;
40  }
41  auto rem = p;
42  while (!rem.is_constant()) {
43  CARL_LOG_TRACE("carl.core.sos_decomposition", "Consider " << rem);
44  assert(rem.total_degree() <= 2);
45  Variable var = (*rem.lterm().monomial())[0].first;
46  // Complete the square for var
47  CARL_LOG_TRACE("carl.core.sos_decomposition", "Complete the square for " << var);
48  auto varInfos = carl::var_info(rem, var, true);
49  auto lcoeffIter = varInfos.coeffs().find(2);
50  if (lcoeffIter == varInfos.coeffs().end()) {
51  CARL_LOG_TRACE("carl.core.sos_decomposition", "Cannot construct sos due to line " << __LINE__);
52  return {};
53  }
54  assert(lcoeffIter->second.is_constant());
55  if (carl::is_negative(lcoeffIter->second.constant_part())) {
56  CARL_LOG_TRACE("carl.core.sos_decomposition", "Cannot construct sos due to line " << __LINE__);
57  return {};
58  }
59  assert(!carl::is_zero(lcoeffIter->second.constant_part()));
60  auto constCoeffIter = varInfos.coeffs().find(0);
61  rem = constCoeffIter != varInfos.coeffs().end() ? constCoeffIter->second : MultivariatePolynomial<C,O,P>();
62  CARL_LOG_TRACE("carl.core.sos_decomposition", "Constant part is " << rem);
63  auto coeffIter = varInfos.coeffs().find(1);
64  if (coeffIter != varInfos.coeffs().end()) {
65  MultivariatePolynomial<C,O,P> qr = coeffIter->second/(C(2)*lcoeffIter->second.constant_part());
66  result.emplace_back(lcoeffIter->second.constant_part(), MultivariatePolynomial<C,O,P>(var)+qr);
67  rem -= carl::pow(qr, 2)*lcoeffIter->second.constant_part();
68  } else {
69  result.emplace_back(lcoeffIter->second.constant_part(), MultivariatePolynomial<C,O,P>(var));
70  }
71  CARL_LOG_TRACE("carl.core.sos_decomposition", "Add " << result.back().first << " * (" << result.back().second << ")^2");
72  }
73  if (carl::is_negative(rem.constant_part())) {
74  CARL_LOG_TRACE("carl.core.sos_decomposition", "Cannot construct sos due to line " << __LINE__);
75  return {};
76  } else if(!carl::is_zero(rem.constant_part())) {
77  result.emplace_back(rem.constant_part(), MultivariatePolynomial<C,O,P>(constant_one<C>::get()));
78  }
79  CARL_LOG_TRACE("carl.core.sos_decomposition", "Add " << result.back().first << " * (" << result.back().second << ")^2");
80  return result;
81 }
82 
83 }
Implements utility functions concerning the (total) degree of monomials, terms and polynomials.
#define CARL_LOG_TRACE(channel, msg)
Definition: carl-logging.h:44
carl is the main namespace for the library.
std::vector< std::pair< C, MultivariatePolynomial< C, O, P > > > sos_decomposition(const MultivariatePolynomial< C, O, P > &p, bool not_trivial=false)
bool is_constant(const ContextPolynomial< Coeff, Ordering, Policies > &p)
bool is_zero(const Interval< Number > &i)
Check if this interval is a point-interval containing 0.
Definition: Interval.h:1453
VarInfo< MultivariatePolynomial< Coeff, Ordering, Policies > > var_info(const MultivariatePolynomial< Coeff, Ordering, Policies > &poly, const Variable var, bool collect_coeff=false)
Definition: VarInfo.h:54
bool is_negative(const cln::cl_I &n)
Definition: operations.h:47
Interval< Number > pow(const Interval< Number > &i, Integer exp)
Definition: Power.h:11
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
The general-purpose multivariate polynomial class.
const Coeff & lcoeff() const
Returns the coefficient of the leading term.
std::size_t total_degree() const
Calculates the max.