11 #include "../TarskiQuery/TarskiQueryManager.h"
14 #include <eigen3/Eigen/Core>
15 #include <eigen3/Eigen/LU>
24 template<
typename Number>
35 std::list<Polynomial>
mP;
47 template<
typename InputIt>
49 mTaQ(zeroSet_first, zeroSet_last)
83 CARL_LOG_ASSERT(
"carl.thom.sign", alpha.size() == sigma.size(),
"invalid arguments");
85 auto it_alpha = alpha.begin();
86 auto it_sigma = sigma.begin();
87 for(; it_alpha != alpha.end(); ) {
92 else if(*it_sigma ==
Sign::ZERO && *it_alpha != 0) {
100 static Eigen::MatrixXf
adaptedMat(
const std::list<Alpha>& ada,
const std::list<SignCondition>&
signs) {
101 Eigen::MatrixXf res(ada.size(),
signs.size());
104 for (
const auto& alpha : ada) {
105 for (
const auto& sigma :
signs) {
114 static Eigen::MatrixXf
kroneckerProduct(
const Eigen::MatrixXf& m1,
const Eigen::MatrixXf& m2) {
115 Eigen::MatrixXf m3(m1.rows() * m2.rows(), m1.cols() * m2.cols());
116 for(
int i = 0; i < m1.cols(); i++) {
117 for(
int j = 0; j < m1.rows(); j++) {
118 m3.block(i * m2.rows(), j * m2.cols(), m2.rows(), m2.cols()) = m1(i, j) * m2;
124 Eigen::Index numRows =
matrix.rows();
125 Eigen::Index numCols =
matrix.cols()-1;
127 if (colToRemove < numCols) {
128 matrix.block(0, colToRemove, numRows, numCols - colToRemove) =
matrix.block(0, colToRemove + 1 ,numRows, numCols - colToRemove);
130 matrix.conservativeResize(numRows, numCols);
133 Eigen::Index numRows =
matrix.rows()-1;
134 Eigen::Index numCols =
matrix.cols();
136 if (rowToRemove < numRows) {
137 matrix.block(rowToRemove,0,numRows-rowToRemove,numCols) =
matrix.block(rowToRemove+1,0,numRows-rowToRemove,numCols);
140 matrix.conservativeResize(numRows,numCols);
144 std::list<Polynomial> result;
145 for(
const auto& alpha : currAda) {
147 assert(alpha.size() == 1);
148 if(alpha.front() == 0) {
149 result.push_back(prod);
151 else if(alpha.front() == 1) {
152 result.push_back(
mTaQ.reduceProduct(p, prod));
155 assert(alpha.front() == 2);
157 result.push_back(
mTaQ.reduceProduct(psquare, prod));
166 const Eigen::MatrixXf& mat,
167 const std::vector<Alpha>& ada,
169 const uint q)
const {
171 std::vector<uint> lines(ada.size(), 0);
172 assert(n <= ada.size());
173 assert((
uint)mat.rows() == ada.size());
174 for (std::size_t i = 0; i < n; i++) {
179 Eigen::MatrixXf linesMat(n, mat.cols());
180 Eigen::Index row = 0;
181 for(std::size_t i = 0; i < lines.size(); i++) {
182 if (lines[i] == 0)
continue;
183 for (Eigen::Index j = 0; j < mat.cols(); j++) {
184 linesMat(row, j) = mat(Eigen::Index(i), j);
188 Eigen::FullPivLU<Eigen::MatrixXf> dec(linesMat);
189 if (dec.rank() ==
int(n))
break;
192 while(std::prev_permutation(lines.begin(), lines.end()));
195 std::list<Alpha> res;
196 std::vector<Polynomial> newProducts;
197 for(
uint i = 0; i < lines.size(); i++) {
199 res.push_back(ada[i]);
200 newProducts.push_back(
products[q*ada.size() + i]);
203 assert(res.size() == n);
209 std::list<Alpha> newAda =
mAda;
210 for(
auto& alpha : newAda) alpha.push_front(0);
211 std::list<Polynomial> adaptedProducts =
mProducts;
212 adaptedProducts.resize(
mAda.size());
232 std::vector<Alpha>(
mAda.begin(),
mAda.end()),
235 for(
auto& alpha : A_2) {
237 newAda.push_back(alpha);
240 adaptedProducts.push_back(p);
242 if(
mSigns.size() != r1 + r2) {
260 std::vector<Alpha>(
mAda.begin(),
mAda.end()),
263 for(
auto& alpha : A_3) {
265 newAda.push_back(alpha);
268 adaptedProducts.push_back(p);
283 std::list<Alpha>& ada,
284 std::list<uint>& adaHelper,
290 std::list<Polynomial> currProducts;
292 currProducts.push_back(
Polynomial(Number(1)));
294 CARL_LOG_WARN(
"carl.thom.sign",
"doing sign determination on an empty zero set");
300 std::list<SignCondition> currSigns;
301 std::list<Alpha> currAda;
303 currProducts.push_back(p);
306 currProducts.push_back(psquare);
308 int czer = taq0 - taq2;
309 int cpos = (taq1 + taq2) / 2;
310 int cneg = (taq2 - taq1) / 2;
312 if(czer != 0) currSigns.emplace_back(1,
Sign::ZERO);
315 currAda = {{0}, {1}, {2}};
316 currAda.resize(currSigns.size());
317 currProducts.resize(currSigns.size());
318 Eigen::MatrixXf currM =
adaptedMat(currAda, currSigns);
331 Eigen::VectorXf dprime(
long(
products.size()));
334 dprime(index) = float(
mTaQ(prod));
339 CARL_LOG_ASSERT(
"carl.thom.sign", Eigen::FullPivLU<Eigen::MatrixXf>(M_prime).rank() == M_prime.cols(),
"M_prime must be invertible!");
340 Eigen::PartialPivLU<Eigen::MatrixXf> dec(M_prime);
341 Eigen::VectorXf c = dec.solve(dprime);
344 std::list<SignCondition> newSigns;
345 adaHelper = std::list<uint>(
mSigns.size(), 0);
347 for(
long i = 0; i < long(currSigns.size()); i++) {
348 auto helper_it = adaHelper.begin();
349 for(
const auto& sigma :
mSigns) {
351 uint tmp = *helper_it;
352 helper_it = adaHelper.erase(helper_it);
353 helper_it = adaHelper.insert(helper_it, ++tmp);
355 auto it = currSigns.begin();
357 newCond.push_front(it->front());
358 newSigns.push_back(newCond);
363 helper_it = adaHelper.begin();
376 std::list<Polynomial> dummyProducts;
377 std::list<Alpha> dummyAda;
378 std::list<uint> dummyHelper;
379 Eigen::MatrixXf dummyMatrix;
380 std::list<SignCondition> newSigns =
getSigns(p, dummyProducts, dummyAda, dummyHelper, dummyMatrix);
385 std::list<Polynomial> newProducts;
386 std::list<Alpha> newAda;
387 std::list<uint> newHelper;
388 Eigen::MatrixXf newMatrix;
389 std::list<SignCondition> newSigns =
getSigns(p, newProducts, newAda, newHelper, newMatrix);
404 template<
typename InputIt>
413 os <<
"\n---------------------------------------------------------------------" << std::endl;
414 os <<
"Status of sign determination object:" << std::endl;
415 os <<
"---------------------------------------------------------------------" << std::endl;
417 os <<
"sign conditions:\t\t" << rhs.
signs() << std::endl;
418 os <<
"adapted list:\t\t\t" << rhs.
adaptedList() << std::endl;
419 os <<
"products:\t\t\t" << rhs.
products() << std::endl;
420 os <<
"matrix dimension:\t\t" << rhs.
matrix().rows() <<
" x " << rhs.
matrix().cols() << std::endl;
421 os <<
"needs update:\t\t\t" << rhs.
needsUpdate() << std::endl;
422 os <<
"---------------------------------------------------------------------" << std::endl;
#define CARL_LOG_WARN(channel, msg)
#define CARL_LOG_TRACE(channel, msg)
#define CARL_LOG_ASSERT(channel, condition, msg)
#define CARL_LOG_DEBUG(channel, msg)
carl is the main namespace for the library.
Interval< Number > abs(const Interval< Number > &_in)
Method which returns the absolute value of the passed number.
std::ostream & operator<<(std::ostream &os, const BasicConstraint< Poly > &c)
Prints the given constraint on the given stream.
@ NEGATIVE
Indicates that .
@ POSITIVE
Indicates that .
cln::cl_I round(const cln::cl_RA &n)
Round a fraction to next integer.
uint sizeOfZeroSet() const
static Eigen::MatrixXf adaptedMat(const std::list< Alpha > &ada, const std::list< SignCondition > &signs)
static void removeColumn(Eigen::MatrixXf &matrix, Eigen::Index colToRemove)
const auto & signs() const
const auto & products() const
std::list< SignCondition > getSignsAndAddAll(InputIt first, InputIt last)
static void removeRow(Eigen::MatrixXf &matrix, Eigen::Index rowToRemove)
SignDetermination(InputIt zeroSet_first, InputIt zeroSet_last)
std::list< SignCondition > getSigns(const Polynomial &p)
std::list< uint > mAdaHelper
static Eigen::MatrixXf kroneckerProduct(const Eigen::MatrixXf &m1, const Eigen::MatrixXf &m2)
std::list< SignCondition > getSigns(const Polynomial &p, std::list< Polynomial > &products, std::list< Alpha > &ada, std::list< uint > &adaHelper, Eigen::MatrixXf &matrix)
std::list< Polynomial > mProducts
std::list< SignCondition > getSignsAndAdd(const Polynomial &p)
std::list< SignCondition > mSigns
TarskiQueryManager< Number > mTaQ
std::list< Polynomial > computeProducts(const Polynomial &p, const std::list< Alpha > &currAda) const
SignDetermination(const SignDetermination &other)
std::list< Polynomial > mP
std::list< Alpha > firstNLines(const uint n, const Eigen::MatrixXf &mat, const std::vector< Alpha > &ada, std::vector< Polynomial > &products, const uint q) const
const auto & adaptedList() const
const auto & processedPolynomials() const
MultivariatePolynomial< Number > Polynomial
static int sigmaToTheAlpha(const Alpha &alpha, const SignCondition &sigma)
const auto & matrix() const
typename TarskiQueryManager< Number >::QueryResultType TaQResType