carl  24.04
Computer ARithmetic Library
Contraction.h
Go to the documentation of this file.
1 /*
2  * File: Contraction.h
3  * Author: stefan
4  *
5  * Created on August 30, 2013, 4:55 PM
6  */
7 
8 #pragma once
11 #include <carl-arith/core/Sign.h>
14 #include <algorithm>
15 
16 //#define CONTRACTION_DEBUG
17 //#define USE_HORNER
18 
19 namespace carl {
20 
21  template<typename Polynomial>
23  {
24  private:
25  /// The variable, for which to solve.
27  /// Stores n, if the nth root has to be taken of mNumerator/mDenominator
29  /// Stores the numerator
30  Polynomial mNumerator;
31  /// Stores the denominator, which is one, if mDenominator == nullptr
32  std::shared_ptr<const typename Polynomial::MonomType> mDenominator;
33 
34 
35 
36  public:
37  VarSolutionFormula() = delete;
38 
39  /**
40  * Constructs the solution formula for the given variable x in the equation p = 0, where p is the given polynomial.
41  * The polynomial p must have one of the following forms:
42  * 1.) ax+h, with a being a rational number and h a linear polynomial not containing x and not having a constant part
43  * 2.) x^i*m-y, with i being a positive integer, m being a monomial not containing x and y being a variable different from x
44  * @param p The polynomial containing the given variable to construct a solution formula for.
45  * @param x The variable to construct a solution formula for.
46  */
47 
48  VarSolutionFormula(const Polynomial& p, Variable::Arg x):
49  mVar(x),
50  mRoot(1),
51  mNumerator(),
52  mDenominator(nullptr)
53  {
54 
55  #ifdef CONTRACTION_DEBUG
56  std::cout << __func__ << ": [Polynome]: " << p << " [#Terms]: " << p.nr_terms() << std::endl;
57  #endif
58 
59 
60  assert(p.has(x));
61  assert(!p.has_constant_term());
62  assert(p.is_linear() || (p.nr_terms() == 2 && (carl::is_one(p.begin()->coeff()) || carl::is_one(p.rbegin()->coeff()))
63  && ((p.begin()->has(x) && !p.rbegin()->has(x))
64  || (p.rbegin()->has(x) && !p.begin()->has(x)))));
65 
66  // Construct the solution formula for x in p = 0
67 
68  #ifdef CONTRACTION_DEBUG
69  std::cout << __func__ << ": Propagating... " << std::endl;
70  #endif
71 
72  // Case 1.):
73  if (p.is_linear())
74  {
75  #ifdef CONTRACTION_DEBUG
76  std::cout << __func__ << ": Case 1. (linear)... " << std::endl;
77  #endif
78  for (const auto& t: p) {
79  assert(t.monomial() != nullptr);
80  if (t.has(x)) {
81 
82  mNumerator = p / t.coeff();
83  mNumerator -= x;
84  mNumerator *= (-1);
85 
86  #ifdef CONTRACTION_DEBUG
87  std::cout << __func__ << ": Setting mNumerator:" << mNumerator << std::endl;
88  #endif
89 
90  return;
91  }
92  }
93  }
94 
95  // Case 2.)
96  else
97  {
98  #ifdef CONTRACTION_DEBUG
99  std::cout << __func__ << ": Case 2. (non-linear)... " << std::endl;
100  #endif
101 
102  assert(p.nr_terms() == 2);
103  typename Polynomial::TermsType::const_iterator yIter;
104  typename Polynomial::TermsType::const_iterator xIter;
105  if (p.begin()->has(x))
106  {
107  xIter = p.begin();
108  yIter = xIter;
109  ++yIter;
110  }
111  else
112  {
113  yIter = p.begin();
114  xIter = yIter;
115  ++xIter;
116  }
117 
118  assert(xIter->monomial() != nullptr);
119  assert(!xIter->is_linear() || xIter->coeff() == (-1));
120  //std::cout << "[Case 2]" << std::endl;
121  if (xIter->is_linear())
122  {
123  mNumerator = Polynomial ( *yIter );
124  }
125  else
126  {
127  mRoot = xIter->monomial()->exponent_of_variable(x);
128  #ifdef CONTRACTION_DEBUG
129  std::cout << __func__ << ": Setting mRoot:" << mRoot << std::endl;
130  #endif
131 
132  mDenominator = xIter->monomial()->drop_variable(x);
133  #ifdef CONTRACTION_DEBUG
134  std::cout << __func__ << ": Setting mDenominator:" << mDenominator << std::endl;
135  #endif
136  mNumerator = -Polynomial ( *yIter );
137  }
138  #ifdef CONTRACTION_DEBUG
139  std::cout << __func__ << ": Setting mNumerator:" << mNumerator << std::endl;
140  #endif
141  }
142  }
143 
144  void addRoot( const Interval<double>& _interv, const Interval<double>& _varInterval, std::vector<Interval<double>>& _result ) const
145  {
146  Interval<double> tmp = _interv.root((int) mRoot);
147  CARL_LOG_DEBUG("carl.contraction", mRoot << "th root of " << _interv << " = " << tmp);
148  if( mRoot % 2 == 0 )
149  {
150  Interval<double> rootA, rootB;
151  if( carl::set_union(tmp, -tmp, rootA, rootB ) )
152  {
153  CARL_LOG_DEBUG("carl.contraction", tmp << " and " << -tmp << " = " << rootA << " and " << rootB);
154  if (mVar.type() == VariableType::VT_INT) {
155  rootA = rootA.integral_part();
156  }
157  rootA = set_intersection(rootA, _varInterval);
158  CARL_LOG_DEBUG("carl.contraction", "first intersected with " << _varInterval << " = " << rootA);
159  if( !rootA.is_empty() )
160  _result.push_back(std::move(rootA));
161  if (mVar.type() == VariableType::VT_INT) {
162  rootB = rootB.integral_part();
163  }
164  rootB = set_intersection(rootB, _varInterval);
165  CARL_LOG_DEBUG("carl.contraction", "second intersected with " << _varInterval << " = " << rootB);
166  if( !rootB.is_empty() )
167  _result.push_back(std::move(rootB));
168  }
169  else
170  {
171  CARL_LOG_DEBUG("carl.contraction", tmp << " and " << -tmp << " = " << rootA << " and " << rootB);
172  if (mVar.type() == VariableType::VT_INT) {
173  rootA = rootA.integral_part();
174  }
175  rootA = set_intersection(rootA, _varInterval);
176  if( !rootA.is_empty() )
177  _result.push_back(std::move(rootA));
178  }
179  }
180  else
181  {
182  if (mVar.type() == VariableType::VT_INT) {
183  tmp = tmp.integral_part();
184  }
185  _result.push_back( std::move(tmp) );
186  }
187  }
188 
189  /**
190  * Evaluates this solution formula for the given mapping of the variables occurring in the solution formula to double intervals.
191  * @param intervals The mapping of the variables occurring in the solution formula to double intervals
192  * @param resA The first interval of the result.
193  * @param resB The second interval of the result.
194  * @return true, if the second interval is not empty. (the first interval must then be also nonempty)
195  */
196  std::vector<Interval<double>> evaluate(const Interval<double>::evalintervalmap& intervals) const
197  {
198  // evaluate monomial
199  std::vector<Interval<double>> result;
200  assert( intervals.find(mVar) != intervals.end() );
201  const Interval<double>& varInterval = intervals.at(mVar);
202  Interval<double> numerator = carl::evaluate(mNumerator, intervals);
203  CARL_LOG_DEBUG("carl.contraction", mNumerator << " -> " << numerator);
204  if (mDenominator == nullptr)
205  {
206  addRoot( numerator, varInterval, result );
207  CARL_LOG_DEBUG("carl.contraction", "no denominator -> " << result);
208  return result;
209  }
210  Interval<double> denominator = carl::evaluate(*mDenominator, intervals);
211  CARL_LOG_DEBUG("carl.contraction", *mDenominator << " -> " << denominator);
212  Interval<double> result1, result2;
213  // divide:
214  bool split = numerator.div_ext(denominator, result1, result2);
215  CARL_LOG_DEBUG("carl.contraction", numerator << " / " << denominator << " -> " << result1 << " and " << result2);
216  // extract root:
217  assert(mRoot <= std::numeric_limits<int>::max());
218  if( split )
219  {
220  // TODO: division returns two intervals, which might be united to one interval
221  Interval<double> tmpA, tmpB;
222  if( carl::set_union(result1, result2, tmpA, tmpB ) )
223  {
224  addRoot( tmpA, varInterval, result );
225  addRoot( tmpB, varInterval, result );
226  }
227  else
228  {
229  addRoot( tmpA, varInterval, result );
230  }
231  }
232  else
233  {
234  addRoot( result1, varInterval, result );
235  }
236  CARL_LOG_DEBUG("carl.contraction", "Finally: " << result);
237  return result;
238  }
239  };
240 
241  template <template<typename> class Operator, typename Polynomial>
242  class Contraction : private Operator<Polynomial> {
243 
244  private:
245  Polynomial mConstraint; // Todo: Should be a reference.
246  Polynomial* mpOriginal;
247  #ifdef USE_HORNER
249  std::map<Variable, MultivariateHorner<Polynomial,strategy>> mDerivatives;
250  #else
251  std::map<Variable, Polynomial> mDerivatives;
252  #endif
253  std::map<Variable, VarSolutionFormula<Polynomial>> mVarSolutionFormulas;
254  std::map<Polynomial, MultivariateHorner<Polynomial,strategy>> mHornerSchemes;
255 
256  public:
257  Contraction() = delete;
258  Contraction(const Polynomial& constraint):
259  Operator<Polynomial>(),
260  mConstraint(constraint),
261  mpOriginal(nullptr),
262  #ifdef USE_HORNER
263  mHornerForm(constraint),
264  #endif
265  mDerivatives(),
268  {}
269 
270  Contraction(const Polynomial& constraint, const Polynomial& _original ):
271  Operator<Polynomial>(),
272  mConstraint(constraint),
273  mpOriginal (_original.is_linear() ? nullptr : new Polynomial(_original)),
274  #ifdef USE_HORNER
275  mHornerForm( mpOriginal == nullptr ? constraint : _original ),
276  #endif
277  mDerivatives(),
280  {}
281  Contraction(const Contraction&) = delete;
282 
283  Contraction(Contraction&& _contraction ):
284  Operator<Polynomial>(),
285  mConstraint(std::move(_contraction.mConstraint)),
286  mpOriginal(_contraction.mpOriginal),
287  #ifdef USE_HORNER
288  mHornerForm(std::move(_contraction.mHornerForm)),
289  #endif
290  mDerivatives(std::move(_contraction.mDerivatives)),
291  mVarSolutionFormulas(std::move(_contraction.mVarSolutionFormulas)),
292  mHornerSchemes(std::move(_contraction.mHornerSchemes))
293  {
294  _contraction.mpOriginal = nullptr;
295  }
296 
297  Contraction& operator=(const Contraction&) = delete;
299 
301  {
302  if( mpOriginal != nullptr )
303  delete mpOriginal;
304  }
305 
306  const Polynomial& polynomial() const
307  {
308  return mpOriginal == nullptr ? mConstraint : *mpOriginal;
309  }
310 
311  bool operator()(const Interval<double>::evalintervalmap& intervals, Variable::Arg variable, Interval<double>& resA, Interval<double>& resB, bool useNiceCenter = false, bool usePropagation = false)
312  {
313  bool splitOccurredInContraction = false;
314  if( !usePropagation || mpOriginal == nullptr || !mConstraint.is_linear() )
315  {
316  #ifdef USE_HORNER
317  typename std::map<Variable, MultivariateHorner<Polynomial,strategy>>::const_iterator it = mDerivatives.find(variable);
318  #else
319  typename std::map<Variable, Polynomial>::const_iterator it = mDerivatives.find(variable);
320  #endif
321 
322  if( it == mDerivatives.end() )
323  {
324  #ifdef USE_HORNER
325  //Deriviate and convert to Horner
326  if( mpOriginal == nullptr )
327  it = mDerivatives.emplace(variable, std::move(MultivariateHorner<Polynomial, strategy>( mConstraint.derivative(variable)))).first;
328  else
329  it = mDerivatives.emplace(variable, std::move(MultivariateHorner<Polynomial, strategy>( mpOriginal->derivative(variable)))).first;
330  #else
331  if( mpOriginal == nullptr )
332  it = mDerivatives.emplace(variable, derivative(mConstraint, variable)).first;
333  else
334  it = mDerivatives.emplace(variable, derivative(*mpOriginal, variable)).first;
335  #endif
336  }
337 
338  #ifdef CONTRACTION_DEBUG
339  std::cout << __func__ << ": contraction of " << variable << " with " << intervals << " in " << mConstraint << " mpOriginal: " << mpOriginal << std::endl;
340  #endif
341 
342  #ifdef USE_HORNER
343  splitOccurredInContraction = Operator<Polynomial>::contract(intervals, variable, mHornerForm, (*it).second, resA, resB, useNiceCenter);
344  #else
345  splitOccurredInContraction = Operator<Polynomial>::contract(intervals, variable, (mpOriginal == nullptr ? mConstraint : *mpOriginal), (*it).second, resA, resB, useNiceCenter);
346  #endif
347  }
348  else
349  {
350  CARL_LOG_DEBUG("carl.contraction", "Trivial case...");
351  resA = intervals.at(variable);
353  }
354 
355  CARL_LOG_DEBUG("carl.contraction", " after propagation: " << resA << " / " << resB);
356  CARL_LOG_DEBUG("carl.contraction", " Split? " << splitOccurredInContraction);
357 
358  if( usePropagation )
359  {
360  typename std::map<Variable, VarSolutionFormula<Polynomial>>::const_iterator const_iterator_VarSolutionFormula = mVarSolutionFormulas.find(variable);
361  if( const_iterator_VarSolutionFormula == mVarSolutionFormulas.end() )
362  {
363  const_iterator_VarSolutionFormula = mVarSolutionFormulas.emplace(variable, std::move(VarSolutionFormula<Polynomial>(mConstraint,variable))).first;
364  }
365 
366  // calculate result of propagation
367  std::vector<Interval<double>> resultPropagation = const_iterator_VarSolutionFormula->second.evaluate( intervals );
368 
369  #ifdef CONTRACTION_DEBUG
370  std::cout << " propagation result: " << resultPropagation << std::endl;
371  #endif
372 
373  if( resultPropagation.empty() )
374  {
377  CARL_LOG_DEBUG("carl.contraction", " after propagation: " << resA << " / " << resB);
378  return false;
379  }
380 
381  // intersect with result of contraction
382  std::vector<Interval<double>> resultingIntervals;
383  if( splitOccurredInContraction )
384  {
385  Interval<double> tmp;
386  for( const auto& i : resultPropagation )
387  {
388  tmp = carl::set_intersection(i, resA);
389  CARL_LOG_DEBUG("carl.contraction", " intersection(" << i << ", " << resA << ") = " << tmp);
390  if( !tmp.is_empty() )
391  resultingIntervals.push_back(tmp);
392  tmp = carl::set_intersection(i, resB);
393  CARL_LOG_DEBUG("carl.contraction", " intersection(" << i << ", " << resB << ") = " << tmp);
394  if( !tmp.is_empty() )
395  resultingIntervals.push_back(tmp);
396  }
397  }
398 
399  else
400  {
401  Interval<double> tmp;
402  for( const auto& i : resultPropagation )
403  {
404  tmp = carl::set_intersection(i, resA);
405  CARL_LOG_DEBUG("carl.contraction", " intersection(" << i << ", " << resA << ") = " << tmp);
406  if( !tmp.is_empty() )
407  resultingIntervals.push_back(tmp);
408  }
409  }
410  if( resultingIntervals.empty() )
411  {
414  CARL_LOG_DEBUG("carl.contraction", " after propagation: " << resA << " / " << resB);
415  return false;
416  }
417  if( resultingIntervals.size() == 1 )
418  {
419  resA = resultingIntervals[0];
421  CARL_LOG_DEBUG("carl.contraction", " after propagation: " << resA << " / " << resB);
422  return false;
423  }
424  if( resultingIntervals.size() == 2 )
425  {
426  if( resultingIntervals[0] < resultingIntervals[1] )
427  {
428  resA = resultingIntervals[0];
429  resB = resultingIntervals[1];
430  }
431  else
432  {
433  assert(resultingIntervals[1] < resultingIntervals[0]);
434  resA = resultingIntervals[1];
435  resB = resultingIntervals[0];
436  }
437  CARL_LOG_DEBUG("carl.contraction", " after propagation: " << resA << " / " << resB);
438  return true;
439  }
440  else
441  {
442  std::sort( resultPropagation.begin(), resultPropagation.end(),
443  [](const Interval<double>& i,const Interval<double> j)
444  { if(i<j){return true;} else { assert(j<i); return false; } }
445  );
446  auto intervalBeforeBiggestGap = resultPropagation.begin();
447  auto iter = resultPropagation.begin();
448  ++iter;
449  double bestDistance = intervalBeforeBiggestGap->distance(*iter);
450  for( ; iter != resultPropagation.end(); ++iter )
451  {
452  auto jter = iter;
453  ++jter;
454  if( jter == resultPropagation.end() )
455  {
456  break;
457  }
458  else
459  {
460  double distance = iter->distance(*jter);
461  if( bestDistance < distance )
462  {
463  bestDistance = distance;
464  intervalBeforeBiggestGap = iter;
465  }
466  }
467  }
468  resA = *intervalBeforeBiggestGap;
469  for( iter = resultPropagation.begin(); iter != intervalBeforeBiggestGap; ++iter )
470  {
471  resA = resA.convex_hull( *iter );
472  }
473  ++iter;
474  resB = *iter;
475  for( ; iter != resultPropagation.end(); ++iter )
476  {
477  resB = resB.convex_hull( *iter );
478  }
479  #ifdef CONTRACTION_DEBUG
480  std::cout << " after propagation: " << resA; if( !resB.is_empty() ) { std::cout << " and " << resB; } std::cout << std::endl;
481  #endif
482  return true;
483  }
484  }
485  return splitOccurredInContraction;
486  }
487  };
488 
489  template<typename Polynomial>
490  class SimpleNewton {
491  public:
492 
493  template <typename evalType>
495  Variable::Arg variable,
496  const evalType& constraint,
497  const evalType& derivative,
498  Interval<double>& resA,
499  Interval<double>& resB,
500  bool useNiceCenter = false)
501  {
502  bool splitOccurred = false;
503 
504  double center = useNiceCenter ? carl::sample(intervals.at(variable)) : carl::center(intervals.at(variable));
505  if( center == std::numeric_limits<double>::infinity() || center == -std::numeric_limits<double>::infinity() )
506  {
507  resA = intervals.at(variable);
508  return false;
509  }
510  Interval<double> centerInterval = Interval<double>(center);
511 
512  #ifdef CONTRACTION_DEBUG
513  std::cout << "variable = " << variable << std::endl;
514  std::cout << "constraint = " << constraint << std::endl;
515  std::cout << "derivative = " << derivative << std::endl;
516  std::cout << __func__ << ": centerInterval: " << centerInterval << std::endl;
517  #endif
518 
519  // Create map for replacement of variables by intervals and replacement of center by point interval
520  typename Interval<double>::evalintervalmap substitutedIntervalMap = intervals;
521  substitutedIntervalMap[variable] = centerInterval;
522 
523  Interval<double> numerator (0);
524  Interval<double> denominator(0);
525 
526 
527 
528  // Create Newton Operator
529  numerator = carl::evaluate(constraint, substitutedIntervalMap);
530  denominator = carl::evaluate(derivative, intervals);
531 
532 
533  Interval<double> result1, result2;
534 
535  #ifdef CONTRACTION_DEBUG
536  std::cout << __func__ << ": numerator: " << numerator << ", denominator: " << denominator << std::endl;
537  #endif
538 
539  bool split = numerator.div_ext(denominator, result1, result2);
540  if (split) {
541  #ifdef CONTRACTION_DEBUG
542  std::cout << __func__ << ": caused split: " << result1 << " and " << result2 << std::endl;
543  #endif
544  splitOccurred = true;
545  if(result1 >= result2) {
546  resA = carl::set_intersection(intervals.at(variable), centerInterval.sub(result1));
547  resB = carl::set_intersection(intervals.at(variable), centerInterval.sub(result2));
548  }
549  else
550  {
551  resA = carl::set_intersection(intervals.at(variable), centerInterval.sub(result2));
552  resB = carl::set_intersection(intervals.at(variable), centerInterval.sub(result1));
553  }
554  if (variable.type() == VariableType::VT_INT) {
555  resA = resA.integral_part();
556  resB = resB.integral_part();
557  }
558  #ifdef CONTRACTION_DEBUG
559  std::cout << __func__ << ": result after intersection: " << resA << " and " << resB << std::endl;
560  #endif
561  if( resB.is_empty() )
562  {
563  splitOccurred = false;
564  }
565  else if( resA.is_empty() ) // resB is not empty at this state
566  {
567  resA = resB;
569  splitOccurred = false;
570  }
571  else
572  {
573  Interval<double> tmpA, tmpB;
574  if (!carl::set_union(resA, resB, tmpA, tmpB)) {
575  resA = std::move(tmpA);
577  splitOccurred = false;
578  }
579  }
580  } else {
581  #ifdef CONTRACTION_DEBUG
582  std::cout << __func__ << ": result: " << result1 << std::endl;
583  std::cout << __func__ << ": center: " << centerInterval << std::endl;
584  std::cout << __func__ << ": center sub: " << centerInterval.sub(result1) << std::endl;
585  std::cout << __func__ << ": intersecting " << intervals.at(variable) << " and " << centerInterval.sub(result1) << std::endl;
586  #endif
587  resA = carl::set_intersection(intervals.at(variable), centerInterval.sub(result1));
588  if (variable.type() == VariableType::VT_INT) {
589  resA = resA.integral_part();
590  }
591  #ifdef CONTRACTION_DEBUG
592  std::cout << __func__ << ": result after intersection: " << resA << std::endl;
593  #endif
594  }
595  return splitOccurred;
596  }
597  };
598 
599  //typedef Contraction<SimpleNewton, Polynomial> SimpleNewtonContraction;
600 
601 }
#define CARL_LOG_DEBUG(channel, msg)
Definition: carl-logging.h:43
carl is the main namespace for the library.
const T & derivative(const T &t, Variable, std::size_t n=1)
Computes the n'th derivative of a number, which is either the number itself (for n = 0) or zero.
Definition: Derivative.h:23
Number sample(const Interval< Number > &i, bool includingBounds=true)
Searches for some point in this interval, preferably near the midpoint and with a small representatio...
Definition: Sampling.h:30
Number center(const Interval< Number > &i)
Returns the center point of the interval.
Definition: Sampling.h:12
std::uint64_t uint
Definition: numbers.h:16
bool evaluate(const BasicConstraint< Poly > &c, const Assignment< Number > &m)
Definition: Evaluation.h:10
bool set_union(const Interval< Number > &lhs, const Interval< Number > &rhs, Interval< Number > &resA, Interval< Number > &resB)
Computes the union of two intervals (can result in two distinct intervals).
Definition: SetTheory.h:187
Interval< Number > set_intersection(const Interval< Number > &lhs, const Interval< Number > &rhs)
Intersects two intervals in a set-theoretic manner.
Definition: SetTheory.h:99
bool is_linear(const ContextPolynomial< Coeff, Ordering, Policies > &p)
bool is_one(const Interval< Number > &i)
Check if this interval is a point-interval containing 1.
Definition: Interval.h:1462
A Variable represents an algebraic variable that can be used throughout carl.
Definition: Variable.h:85
constexpr VariableType type() const noexcept
Retrieves the type of the variable.
Definition: Variable.h:131
bool div_ext(const Interval< Number > &rhs, Interval< Number > &a, Interval< Number > &b) const
Implements extended interval division with intervals containting zero.
bool is_empty() const
Function which determines, if the interval is empty.
Definition: Interval.h:1056
Interval< Number > root(int deg) const
Calculates the nth root of the interval with respect to natural interval arithmetic.
static Interval< Number > empty_interval()
Method which returns the empty interval rooted at 0.
Definition: Interval.h:813
Interval< Number > convex_hull(const Interval< Number > &interval) const
Interval< Number > sub(const Interval< Number > &rhs) const
Subtracts two intervals according to natural interval arithmetic.
Interval< Number > integral_part() const
Computes the integral part of the given interval.
void addRoot(const Interval< double > &_interv, const Interval< double > &_varInterval, std::vector< Interval< double >> &_result) const
Definition: Contraction.h:144
VarSolutionFormula(const Polynomial &p, Variable::Arg x)
Constructs the solution formula for the given variable x in the equation p = 0, where p is the given ...
Definition: Contraction.h:48
std::shared_ptr< const typename Polynomial::MonomType > mDenominator
Stores the denominator, which is one, if mDenominator == nullptr.
Definition: Contraction.h:32
Variable mVar
The variable, for which to solve.
Definition: Contraction.h:26
Polynomial mNumerator
Stores the numerator.
Definition: Contraction.h:30
uint mRoot
Stores n, if the nth root has to be taken of mNumerator/mDenominator.
Definition: Contraction.h:28
std::vector< Interval< double > > evaluate(const Interval< double >::evalintervalmap &intervals) const
Evaluates this solution formula for the given mapping of the variables occurring in the solution form...
Definition: Contraction.h:196
std::map< Variable, VarSolutionFormula< Polynomial > > mVarSolutionFormulas
Definition: Contraction.h:253
Contraction(const Contraction &)=delete
Contraction(const Polynomial &constraint)
Definition: Contraction.h:258
Contraction & operator=(Contraction &&)=delete
Contraction(Contraction &&_contraction)
Definition: Contraction.h:283
const Polynomial & polynomial() const
Definition: Contraction.h:306
Polynomial * mpOriginal
Definition: Contraction.h:246
Contraction()=delete
std::map< Variable, Polynomial > mDerivatives
Definition: Contraction.h:251
bool operator()(const Interval< double >::evalintervalmap &intervals, Variable::Arg variable, Interval< double > &resA, Interval< double > &resB, bool useNiceCenter=false, bool usePropagation=false)
Definition: Contraction.h:311
Polynomial mConstraint
Definition: Contraction.h:245
Contraction & operator=(const Contraction &)=delete
Contraction(const Polynomial &constraint, const Polynomial &_original)
Definition: Contraction.h:270
std::map< Polynomial, MultivariateHorner< Polynomial, strategy > > mHornerSchemes
Definition: Contraction.h:254
bool contract(const Interval< double >::evalintervalmap &intervals, Variable::Arg variable, const evalType &constraint, const evalType &derivative, Interval< double > &resA, Interval< double > &resB, bool useNiceCenter=false)
Definition: Contraction.h:494