3 #include <gsPolynomial/gsMonomialPoly.h>
25 root.conservativeResize(root.rows() - 1, 3);
37 gsMonomialPoly<T> copyPoly = poly;
39 int degree = copyPoly.basis().size() - 1;
44 while (!copyPoly.isNull() && copyPoly.coefs()(0) == 0)
46 rootIntervals(rootIntervals.rows() - 1, 0) = 0;
47 rootIntervals(rootIntervals.rows() - 1, 1) = 0;
48 rootIntervals(rootIntervals.rows() - 1, 2) += 1;
53 gsMonomialPoly<T> x(monomialBasis, coefs);
60 rootIntervals.conservativeResize(rootIntervals.rows() + 1, 3);
64 if (! copyPoly.isConstant() )
70 if (sturmSeq.bottomRows(1).isZero())
73 gsMonomialPoly<T >poly(copyPoly.basis(), vec);
80 eps, sturmSeq, rootIntervals);
92 int roots = SignChanges(
HornerEval(sturmSeq, leftBound)) - SignChanges(
HornerEval(sturmSeq, rightBound));
95 if (roots == 0) {
return; }
98 else if (roots == 1 && rightBound - leftBound <= 0.01)
100 rootIntervals(rootIntervals.rows() - 1, 0) = leftBound;
101 rootIntervals(rootIntervals.rows() - 1, 1) = rightBound;
102 rootIntervals(rootIntervals.rows() - 1, 2) = 1;
103 rootIntervals.conservativeResize(rootIntervals.rows() + 1, 3);
106 else if (roots > 1 && rightBound - leftBound < eps)
108 rootIntervals(rootIntervals.rows() - 1, 0) = leftBound;
109 rootIntervals(rootIntervals.rows() - 1, 1) = rightBound;
110 rootIntervals(rootIntervals.rows() - 1, 2) = roots;
111 rootIntervals.conservativeResize(rootIntervals.rows() + 1, 3);
117 T bound = (rightBound + leftBound) / 2;
124 roots = SignChanges(
HornerEval(sturmSeq, T(bound - eps/2)))
125 - SignChanges(
HornerEval(sturmSeq, T(bound + eps/2)));
128 rootIntervals(rootIntervals.rows() - 1, 0) = bound - eps / 2;
129 rootIntervals(rootIntervals.rows() - 1, 1) = bound + eps / 2;
130 rootIntervals(rootIntervals.rows() - 1, 2) = roots;
131 rootIntervals.conservativeResize(rootIntervals.rows() + 1, 3);
135 rootIntervals(rootIntervals.rows() - 1, 0) = bound;
136 rootIntervals(rootIntervals.rows() - 1, 1) = bound;
137 rootIntervals(rootIntervals.rows() - 1, 2) = 1;
138 rootIntervals.conservativeResize(rootIntervals.rows() + 1, 3);
140 RootIsolation(leftBound, T(bound - eps/2), eps, sturmSeq, rootIntervals);
141 RootIsolation(T(bound + eps/2), rightBound, eps, sturmSeq, rootIntervals);
146 RootIsolation(leftBound, bound, eps, sturmSeq, rootIntervals);
147 RootIsolation(bound, rightBound, eps, sturmSeq, rootIntervals);
160 int lead = vec.size() - 1;
161 for (
int i = vec.size() - 1; i >= 0; i--)
169 return 1 + (vec/vec[lead]).array().abs().maxCoeff();
176 int deg = poly.basis().size() - 1;
181 sturm.row(0) = poly.coefs().transpose();
188 sturm.conservativeResize(2, sturm.cols());
197 for (
int i = 2; i <= deg; i++)
199 dividend = sturm.row(i - 2);
200 divisor = sturm.row(i - 1);
201 gsMonomialPoly<T> poly1(poly.basis(), dividend);
202 gsMonomialPoly<T> poly2(poly.basis(), divisor);
203 gsMonomialPoly<T> poly3 =
PolyDivision(poly1, poly2, 2);
205 if ( poly3.isNull() )
207 sturm.conservativeResize(i + 1, sturm.cols());
212 for (
int j = 0; j < poly3.coefs().size(); j++)
214 sturm(i, j) -= poly3.coefs()(j);
217 if ( poly3.isConstant() )
219 sturm.conservativeResize(i + 1, sturm.cols());
238 for (
int i = 0; i < deriv.size() - 1; i++)
240 deriv(i) = poly.coefs()(i + 1)*(i + 1);
242 deriv(deriv.size() - 1) = 0;
243 return gsMonomialPoly<T>(poly.basis(), deriv);
253 const gsMonomialPoly<T> & divisorPoly,
int num)
255 if (num != 1 && num != 2)
257 std::cout <<
"ERROR: The number is not in the corresponding range. The dividend will be returned" << std::endl;
260 gsMonomialPoly<T> dividendCopy = dividendPoly;
261 gsMonomialPoly<T> divisorCopy = divisorPoly;
264 gsMatrix<T> dividend = dividendCopy.coefs().transpose();
268 for (
int i = 0; i < divisorCopy.coefs().size(); i++)
270 divisor(i) = divisorCopy.coefs()(i);
275 int deg_dividend = dividend.size() - 1;
277 while (dividend(deg_dividend) == 0)
283 int deg_divisor = divisor.size() - 1;
285 while (divisor(deg_divisor) == 0)
290 if (deg_divisor > deg_dividend)
292 std::cout <<
"Error, the division is not possible. The degree of the divisor is greater than the degree of the dividend. The dividend will be returned";
302 rem = dividend.transpose();
303 int deg_rem = deg_dividend;
309 while (!(rem.maxCoeff() == 0 && rem.minCoeff() == 0) && deg_rem >= deg_divisor)
311 lead = deg_rem - deg_divisor;
312 lead_coeff = rem(deg_rem) / divisor(deg_divisor);
313 quot(lead) = quot(lead) + lead_coeff;
315 rem = rem - dummy * lead_coeff;
316 deg_rem = deg_dividend;
318 while (rem(deg_rem) == 0 && deg_rem > 0)
328 gsMonomialPoly<T> polyQuot(monomial_basis, quot.head(deg_dividend - deg_divisor + 1));
335 gsMonomialPoly<T> polyRem(monomial_basis, rem.head(deg_rem + 1));
345 template <
typename T>
349 shift_vec.topRows(num).setZero();
350 const index_t b = vec.size()-num;
351 shift_vec.bottomRows(b) = vec.topRows(b);
357 template <
typename T>
358 int SignChanges(
const gsVector<T> & vec)
365 gsVector<T> vec_copy = vec;
366 for (
int i = 0; i < vec.size(); i++)
368 vec_copy(i) = vec(i) /
math::abs(vec(i));
372 for (
int i = 0; i < vec_copy.size() - 1; i++)
374 if (
math::abs(vec_copy(i) + vec_copy(i + 1)) < 2) { result++; }
383 template <
typename T>
386 int col = mat.cols();
388 eval = mat.col(col - 1);
390 for (
int i = 2; i <= mat.cols(); i++)
392 eval = eval*num + mat.col(col - i);
400 template <
typename T>
403 T eval = vec(vec.size() - 1);
405 for (
int i = 2; i <= vec.size(); i++)
407 eval = eval*num + vec(vec.size() - i);
423 for (
int i = 0; i < unsort.rows(); i++)
426 min = unsort.col(0).minCoeff();
427 for (
int j = 0; j < unsort.rows(); j++)
429 if (min == unsort(j, 0)){
435 sort.row(i) = unsort.row(position);
436 unsort(position, 0) = INT_MAX;
439 for (
int i = 0; i < sort.rows()-1; i++)
442 if ((sort(i, 0) == sort(i + 1, 0) && sort(i, 1) <= sort(i + 1, 1)) ||
443 (sort(i, 0) <= sort(i + 1, 0) && sort(i, 1) == sort(i + 1, 1)))
446 for (
int j = i+1; j < sort.rows()-1; j++){
447 sort.row(j) = sort.row(j + 1);
450 sort.conservativeResize(sort.rows()- 1, 3);
void RootIsolation(T leftBound, T rightBound, T eps, gsMatrix< T > &sturmSeq, gsMatrix< T > &rootIntervals)
Algorithm for the isolation of the roots.
Definition: gsSturmSolver.h:90
T CauchyBound(gsMonomialPoly< T > &poly)
returns the Cauchy Bound of a Polynomial, which is 1+max(abs(a_i/a_n))
Definition: gsSturmSolver.h:156
gsMonomialPoly< T > PolyDivision(const gsMonomialPoly< T > ÷ndPoly, const gsMonomialPoly< T > &divisorPoly, int num)
Definition: gsSturmSolver.h:252
gsMatrix< T > CalcIntervals(const gsMonomialPoly< T > &poly, T eps, gsMatrix< T > rootIntervals)
Definition: gsSturmSolver.h:35
#define index_t
Definition: gsConfig.h:32
gsVector< T > ShiftRight(const gsVector< T > &vec, int num)
Definition: gsSturmSolver.h:346
An univariate monomial polynomial basis. If the degree is p the basis is given by: [ 1...
Definition: gsMonomialBasis.h:23
gsMonomialPoly< T > PolyDerivWithSameDegree(const gsMonomialPoly< T > &poly)
Definition: gsSturmSolver.h:231
gsMatrix< T > SortRoots(gsMatrix< T > &unsort)
Definition: gsSturmSolver.h:416
T HornerEvalPoly(const gsVector< T > &vec, T num)
evaluates a gsVector (which represents the coefficients of a polynomial) at value num ...
Definition: gsSturmSolver.h:401
gsMatrix< T > SturmSequence(gsMonomialPoly< T > &poly)
returns the sturm sequence in a gsMatrix
Definition: gsSturmSolver.h:174
EIGEN_STRONG_INLINE abs_expr< E > abs(const E &u)
Absolute value.
Definition: gsExpressions.h:4486
gsMatrix< T > FindRootIntervals(gsMonomialPoly< T > &poly, T eps)
Definition: gsSturmSolver.h:19
gsVector< T > HornerEval(gsMatrix< T > &mat, T num)
Definition: gsSturmSolver.h:384