2 * @file MultivariateHorner.tpp
12 template< typename PolynomialType, class strategy >
13 MultivariateHorner< PolynomialType, strategy>::MultivariateHorner (const PolynomialType& inPut) {
15 std::cout << __func__ << " (GreedyI constr) P: " << inPut << std::endl;
18 size_t arithmeticOperationsCounter = 0;
19 if (strategy::use_arithmeticOperationsCounter)
22 arithmeticOperationsCounter = inPut.nr_terms() - 1;
24 typename PolynomialType::TermsType::const_iterator polynomialIt;
25 for (polynomialIt = inPut.begin(); polynomialIt != inPut.end(); polynomialIt++)
27 arithmeticOperationsCounter += polynomialIt->num_variables() - 1;
28 arithmeticOperationsCounter += polynomialIt->tdeg() - polynomialIt->num_variables();
29 if (polynomialIt->coeff() > 1) arithmeticOperationsCounter++;
30 if (polynomialIt->is_constant()) arithmeticOperationsCounter++;
36 //static_assert(!(strategy::variableSelectionHeurisics == variableSelectionHeurisics::GREEDY_II)&&!(strategy::variableSelectionHeurisics == variableSelectionHeurisics::GREEDY_IIs), "Strategy requires Interval map");
38 if (strategy::selectionType == variableSelectionHeurisics::GREEDY_II || strategy::selectionType == variableSelectionHeurisics::GREEDY_IIs){
39 auto allVariablesinPolynome = carl::variables(inPut);
40 carl::carlVariables::iterator variableIt;
42 for (variableIt = allVariablesinPolynome.begin(); variableIt != allVariablesinPolynome.end(); variableIt++)
44 typename std::map<Variable, Interval<double>>::const_iterator const_iterator_map = mMap.find(*variableIt);
45 if ( const_iterator_map == mMap.end() )
47 const_iterator_map = mMap.emplace(*variableIt, Interval<double>((-1) * strategy::targetDiameter, strategy::targetDiameter)).first;
52 int arithmeticOperationsReductionCounter = 0;
54 //Create Horner Scheme Recursivly
55 MultivariateHorner< PolynomialType, strategy > root ( std::move(inPut), mMap, arithmeticOperationsReductionCounter );
57 //Part after recursion
58 if (strategy::selectionType == variableSelectionHeurisics::GREEDY_Is || strategy::selectionType == variableSelectionHeurisics::GREEDY_IIs)
60 auto root_ptr =std::make_shared<MultivariateHorner< PolynomialType, strategy > >(root);
61 root_ptr = simplify( root_ptr );
68 if (strategy::use_arithmeticOperationsCounter)
70 std::cout <<"Total AO: "<< arithmeticOperationsCounter << " rAO: " << arithmeticOperationsReductionCounter << " inPut: " << inPut << " Output: " << root << std::endl;
72 if (arithmeticOperationsReductionCounter > 0)
74 std::cout << "\n\n\n\n\n IT WORKED !!! \n\n\n\n\n" << std::endl;
80 //Constructor for Greedy II and Greedy I
81 template< typename PolynomialType, typename strategy >
82 MultivariateHorner< PolynomialType, strategy>::MultivariateHorner (const PolynomialType& inPut, const std::map<Variable, Interval<double>>& map) {
84 std::cout << __func__ << " (GreedyII constr) P: " << inPut << std::endl;
87 //Create Horner Scheme Recursivly
88 MultivariateHorner< PolynomialType, strategy > root (std::move(inPut), true, map);
90 //Part after recursion
91 if (strategy::selectionType == variableSelectionHeurisics::GREEDY_Is || strategy::selectionType == variableSelectionHeurisics::GREEDY_IIs)
93 auto root_ptr =std::make_shared<MultivariateHorner< PolynomialType, strategy > >(root);
94 root_ptr = simplify( root_ptr );
103 //Constructor for Greedy I/II creates recursive Datastruckture
104 template< typename PolynomialType, typename strategy >
105 MultivariateHorner< PolynomialType, strategy>::MultivariateHorner (const PolynomialType& inPut, const std::map<Variable, Interval<double>>& map, int& counter)
107 int s = strategy::selectionType;
109 carl::carlVariables::iterator variableIt;
110 carl::carlVariables::iterator selectedVariable;
111 auto allVariablesinPolynome = carl::variables(inPut);
113 Interval<double> currentInterval(0);
114 CoeffType delta = constant_zero<CoeffType>::get();
115 CoeffType bestDelta = constant_zero<CoeffType>::get();
117 unsigned int monomials_containingChoosenVar = 0;
119 if (!allVariablesinPolynome.empty())
121 //Detecting amounts of Variables in Monomials
122 for (variableIt = allVariablesinPolynome.begin(); variableIt != allVariablesinPolynome.end(); variableIt++)
124 if (s == variableSelectionHeurisics::GREEDY_I || s == variableSelectionHeurisics::GREEDY_Is)
126 unsigned int monomialCounter = 0;
127 typename PolynomialType::TermsType::const_iterator polynomialIt;
128 for (polynomialIt = inPut.begin(); polynomialIt != inPut.end(); polynomialIt++)
130 if (polynomialIt->has(*variableIt))
136 //saving most promising Variable for later
137 if ( monomialCounter >= monomials_containingChoosenVar ) {
138 monomials_containingChoosenVar = monomialCounter;
139 selectedVariable = variableIt;
143 if (s == variableSelectionHeurisics::GREEDY_II || s == variableSelectionHeurisics::GREEDY_IIs)
145 typename PolynomialType::TermsType::const_iterator polynomialIt;
146 CoeffType accMonomEval = constant_zero<CoeffType>::get();
147 CoeffType accMonomDivEval = constant_zero<CoeffType>::get();
149 for (polynomialIt = inPut.begin(); polynomialIt != inPut.end(); polynomialIt++)
151 if (polynomialIt->has(*variableIt))
153 Term< typename PolynomialType::CoeffType > currentTerm = *polynomialIt;
154 Term< typename PolynomialType::CoeffType > currentTerm_div = *polynomialIt;
156 currentTerm_div.divide(*variableIt, currentTerm_div);
158 currentInterval = carl::evaluate( currentTerm_div, map );
160 accMonomEval += carl::rationalize<CoeffType>(carl::evaluate( currentTerm, map ).diameter());
161 accMonomDivEval += carl::rationalize<CoeffType>(currentInterval.diameter());
165 accMonomDivEval *= carl::rationalize<CoeffType>(map.find(*variableIt)->second.diameter());
166 delta = accMonomDivEval - accMonomEval;
168 if (delta > bestDelta )
171 std::cout << "update Delta...";
175 selectedVariable = variableIt;
177 //std::cout << *variableIt << " D: "<< delta << " BD: "<< bestDelta << "\n" << std::endl;
181 //Setting the choosen Variable for the current Hornerscheme iterartion
183 if ((*selectedVariable == NULL && (strategy::selectionType == variableSelectionHeurisics::GREEDY_Is || strategy::selectionType == variableSelectionHeurisics::GREEDY_I))
184 || (bestDelta == constant_zero<CoeffType>::get() && (strategy::selectionType == variableSelectionHeurisics::GREEDY_IIs || strategy::selectionType == variableSelectionHeurisics::GREEDY_II)) )
186 selectedVariable = allVariablesinPolynome.begin();
188 this->setVariable(*selectedVariable);
191 std::cout << __func__ << " Polynome: " << inPut << std::endl;
192 std::cout << "Choosen Var: " << *selectedVariable << std::endl;
195 typename PolynomialType::TermsType::const_iterator polynomialIt;
196 typename PolynomialType::TermType tempTerm;
198 typename PolynomialType::PolyType h_independentPart;
199 typename PolynomialType::PolyType h_dependentPart;
201 //Choose Terms from Polynome denpending on dependency on choosen Variable
202 for (polynomialIt = inPut.begin(); polynomialIt != inPut.end(); polynomialIt++)
204 if (polynomialIt->has(*selectedVariable))
206 //divide dependent terms by choosen Variable
208 polynomialIt->divide(*selectedVariable, tempTerm);
210 h_dependentPart.addTerm( tempTerm );
214 h_independentPart.addTerm( *polynomialIt );
218 counter = counter - 1;
220 //If Dependent Polynome contains Variables - continue with recursive Horner
221 if ( !h_dependentPart.is_number() )
224 std::cout << __func__ << " DEP->new Horner " << h_dependentPart << std::endl;
226 std::shared_ptr<MultivariateHorner<PolynomialType, strategy>> new_dependent (new MultivariateHorner< PolynomialType, strategy >(std::move(h_dependentPart), map, counter));
227 setDependent(new_dependent);
228 mConst_dependent = constant_zero<CoeffType>::get();
231 //Dependent Polynome is a Constant (Number) - save to memberVar
235 mConst_dependent = h_dependentPart.constant_part();
238 //If independent Polynome contains Variables - continue with recursive Horner
239 if ( !h_independentPart.is_number() )
242 std::cout << __func__ << " INDEP->new Horner " << h_independentPart << std::endl;
244 std::shared_ptr<MultivariateHorner<PolynomialType, strategy>> new_independent ( new MultivariateHorner< PolynomialType, strategy >(std::move(h_independentPart) ,map, counter));
245 setIndependent(new_independent);
246 mConst_independent = constant_zero<CoeffType>::get();
248 //Independent Polynome is a Constant (Number) - save to memberVar
252 mConst_independent = h_independentPart.constant_part();
256 //If there are no Variables in the polynome
260 std::cout << __func__ << " [CONSTANT TERM w/o Variables] " << inPut << std::endl;
264 mConst_independent = inPut.constant_part();
265 this->setVariable( Variable::NO_VARIABLE );
272 * Streaming operator for multivariate HornerSchemes.
273 * @param os Output stream.
274 * @param rhs HornerScheme.
277 template< typename PolynomialType, typename strategy >
278 std::ostream& operator<<(std::ostream& os,const MultivariateHorner<PolynomialType, strategy>& mvH)
280 if (mvH.getDependent() && mvH.getIndependent())
282 if (mvH.getExponent() != 1)
284 return (os << mvH.getVariable() <<"^"<< mvH.getExponent() << " * (" << *mvH.getDependent() << ") + " << *mvH.getIndependent());
288 return (os << mvH.getVariable() << " * (" << *mvH.getDependent() << ") + " << *mvH.getIndependent());
292 else if (mvH.getDependent() && !mvH.getIndependent())
294 if (mvH.getIndepConstant() == 0)
296 if (mvH.getExponent() != 1)
298 return (os << mvH.getVariable() <<"^"<< mvH.getExponent() << " * (" << *mvH.getDependent() << ")" );
302 return (os << mvH.getVariable() << " * (" << *mvH.getDependent() << ")" );
307 if (mvH.getExponent() != 1)
309 return (os << mvH.getVariable() <<"^"<< mvH.getExponent() << " * (" << *mvH.getDependent() << ") + " << mvH.getIndepConstant());
313 return (os << mvH.getVariable() << " * (" << *mvH.getDependent() << ") + " << mvH.getIndepConstant());
317 else if (!mvH.getDependent() && mvH.getIndependent())
319 if (mvH.getDepConstant() == 1)
321 if (mvH.getExponent() != 1)
323 return (os << mvH.getVariable() <<"^"<< mvH.getExponent() << " + " << *mvH.getIndependent() );
327 return (os << mvH.getVariable() << " + " << *mvH.getIndependent() );
332 if (mvH.getExponent() != 1)
334 return (os << mvH.getDepConstant() << mvH.getVariable() <<"^"<< mvH.getExponent() << " + " << *mvH.getIndependent() );
338 return (os << mvH.getDepConstant() << mvH.getVariable() <<" + " << *mvH.getIndependent() );
342 else //if (mvH.getDependent() == NULL && mvH.getIndependent() == NULL)
344 if (mvH.getVariable() == Variable::NO_VARIABLE)
346 return (os << mvH.getIndepConstant());
349 else if (mvH.getIndepConstant() == 0)
351 if (mvH.getDepConstant() == 1)
353 if (mvH.getExponent() != 1)
355 return (os << mvH.getVariable() <<"^"<< mvH.getExponent() );
359 return (os << mvH.getVariable());
365 if (mvH.getExponent() != 1)
367 return (os << mvH.getDepConstant() << mvH.getVariable() <<"^"<< mvH.getExponent());
371 return (os << mvH.getDepConstant() << mvH.getVariable());
377 if (mvH.getExponent() != 1)
379 return (os << mvH.getDepConstant() << mvH.getVariable() <<"^"<< mvH.getExponent() << " + " << mvH.getIndepConstant());
383 return (os << mvH.getDepConstant() << mvH.getVariable() <<" + " << mvH.getIndepConstant());
390 template<typename PolynomialType, typename strategy>
391 std::shared_ptr<MultivariateHorner<PolynomialType, strategy>> simplify( std::shared_ptr<MultivariateHorner<PolynomialType, strategy>> mvH)
395 std::cout << __func__ << " Polynome: " << *mvH << std::endl;
398 if (mvH->getDependent() && (mvH->getDependent()->getDependent() || mvH->getDependent()->getDepConstant() != 0) && !mvH->getDependent()->getIndependent() && mvH->getDependent()->getIndepConstant() == 0 )
401 if (mvH->getVariable() == mvH->getDependent()->getVariable())
403 mvH->setExponent (mvH->getExponent() + mvH->getDependent()->getExponent()) ;
405 if (mvH->getDependent()->getDependent())
407 mvH->setDependent( simplify( mvH->getDependent()->getDependent()) );
409 else if (mvH->getDependent()->getDepConstant() != 0)
411 mvH->setDepConstant(mvH->getDependent()->getDepConstant() );
412 mvH->removeDependent();
415 if (mvH->getIndependent())
417 mvH->setIndependent( simplify( mvH->getIndependent() ));
420 return ( simplify(mvH));
424 else if (!mvH->getDependent() && mvH->getIndependent())
426 mvH->setIndependent(simplify ( mvH->getIndependent() ));
427 mvH->removeDependent();
431 else if (mvH->getDependent() && !mvH->getIndependent() )
433 mvH->setDependent( simplify ( mvH->getDependent()));
434 mvH->removeIndepenent();
438 else if (mvH->getDependent() && mvH->getIndependent() )
440 mvH->setDependent( simplify( mvH->getDependent()));
441 mvH->setIndependent( simplify ( mvH->getIndependent()));