86 using ExponentType = int;
87 using CoefficientType = Real;
88 using PolynomialPairMap = std::map<ExponentType, CoefficientType>;
89 using iterator =
typename PolynomialPairMap::iterator;
90 using const_iterator =
typename PolynomialPairMap::const_iterator;
102 Real result = Real();
103 ExponentType exponent;
104 CoefficientType coefficient;
106 for (iterator i = polyPairMap_.begin(); i != polyPairMap_.end(); ++i) {
108 coefficient = i->second;
109 result += fastpow(x, exponent) * coefficient;
121 Real result = Real();
122 ExponentType exponent;
123 CoefficientType coefficient;
125 for (iterator i = polyPairMap_.begin(); i != polyPairMap_.end(); ++i) {
127 coefficient = i->second;
128 result += fastpow(x, exponent - 1) * coefficient * exponent;
141 polyPairMap_[exponent] = coefficient;
152 iterator i = polyPairMap_.find(exponent);
155 i->second += coefficient;
169 iterator i = polyPairMap_.find(exponent);
178 iterator begin() {
return polyPairMap_.begin(); }
179 const_iterator begin()
const {
return polyPairMap_.begin(); }
181 iterator end() {
return polyPairMap_.end(); }
182 const_iterator end()
const {
return polyPairMap_.end(); }
184 iterator find(ExponentType exponent) {
return polyPairMap_.find(exponent); }
186 size_t size() {
return polyPairMap_.size(); }
190 for (iterator i = polyPairMap_.begin(); i != polyPairMap_.end(); ++i) {
191 if (i->first > deg) deg = i->first;
196 PolynomialType& operator+=(
const PolynomialType& p) {
197 typename Polynomial<Real>::const_iterator i;
199 for (i = p.begin(); i != p.end(); ++i) {
206 PolynomialType& operator-=(
const PolynomialType& p) {
207 typename Polynomial<Real>::const_iterator i;
208 for (i = p.begin(); i != p.end(); ++i) {
214 PolynomialType& operator*=(
const PolynomialType& p) {
215 typename Polynomial<Real>::const_iterator i;
216 typename Polynomial<Real>::const_iterator j;
219 polyPairMap_.clear();
220 for (i = p2.begin(); i != p2.end(); ++i) {
221 for (j = p.begin(); j != p.end(); ++j) {
228 PolynomialType& operator*=(
const Real v) {
229 typename Polynomial<Real>::const_iterator i;
232 for (i = this->begin(); i != this->end(); ++i) {
239 PolynomialType& operator+=(
const Real v) {
251 typename Polynomial<Real>::const_iterator i;
252 ExponentType exponent;
253 CoefficientType coefficient;
255 for (i = this->begin(); i != this->end(); ++i) {
257 coefficient = i->second;
269 for (
int i = 0; i < rank; ++i) {
270 for (
int j = 0; j < rank; ++j) {
273 }
else if (j == rank - 1) {
282 std::vector<complex<Real>> FindRoots() {
287 eig.getRealEigenvalues(reals);
288 eig.getImagEigenvalues(imags);
290 std::vector<complex<Real>> roots;
291 for (
int i = 0; i < rank; i++) {
292 roots.push_back(complex<Real>(reals(i), imags(i)));
298 std::vector<Real> FindRealRoots() {
299 const Real fEpsilon = 1.0e-8;
300 std::vector<Real> roots;
303 const int deg = degree();
309 roots.push_back(-fC0 / fC1);
316 Real fDiscr = fC1 * fC1 - 4.0 * fC0 * fC2;
317 if (abs(fDiscr) <= fEpsilon) { fDiscr = (Real)0.0; }
319 if (fDiscr < (Real)0.0) {
323 Real fTmp = ((Real)0.5) / fC2;
325 if (fDiscr > (Real)0.0) {
326 fDiscr = sqrt(fDiscr);
327 roots.push_back(fTmp * (-fC1 - fDiscr));
328 roots.push_back(fTmp * (-fC1 + fDiscr));
330 roots.push_back(-fTmp * fC1);
341 Real fInvC3 = ((Real)1.0) / fC3;
347 const Real fThird = (Real)1.0 / (Real)3.0;
348 const Real fTwentySeventh = (Real)1.0 / (Real)27.0;
349 Real fOffset = fThird * fC2;
350 Real fA = fC1 - fC2 * fOffset;
351 Real fB = fC0 + fC2 * (((Real)2.0) * fC2 * fC2 - ((Real)9.0) * fC1) *
353 Real fHalfB = ((Real)0.5) * fB;
355 Real fDiscr = fHalfB * fHalfB + fA * fA * fA * fTwentySeventh;
356 if (fabs(fDiscr) <= fEpsilon) { fDiscr = (Real)0.0; }
358 if (fDiscr > (Real)0.0) {
360 fDiscr = sqrt(fDiscr);
361 Real fTemp = -fHalfB + fDiscr;
363 if (fTemp >= (Real)0.0) {
364 root = pow(fTemp, fThird);
366 root = -pow(-fTemp, fThird);
368 fTemp = -fHalfB - fDiscr;
369 if (fTemp >= (Real)0.0) {
370 root += pow(fTemp, fThird);
372 root -= pow(-fTemp, fThird);
376 roots.push_back(root);
377 }
else if (fDiscr < (Real)0.0) {
378 const Real fSqrt3 = sqrt((Real)3.0);
379 Real fDist = sqrt(-fThird * fA);
380 Real fAngle = fThird * atan2(sqrt(-fDiscr), -fHalfB);
381 Real fCos = cos(fAngle);
382 Real fSin = sin(fAngle);
383 roots.push_back(((Real)2.0) * fDist * fCos - fOffset);
384 roots.push_back(-fDist * (fCos + fSqrt3 * fSin) - fOffset);
385 roots.push_back(-fDist * (fCos - fSqrt3 * fSin) - fOffset);
388 if (fHalfB >= (Real)0.0) {
389 fTemp = -pow(fHalfB, fThird);
391 fTemp = pow(-fHalfB, fThird);
393 roots.push_back(((Real)2.0) * fTemp - fOffset);
394 roots.push_back(-fTemp - fOffset);
395 roots.push_back(-fTemp - fOffset);
407 Real fInvC4 = ((Real)1.0) / fC4;
414 Real fR0 = -fC3 * fC3 * fC0 + ((Real)4.0) * fC2 * fC0 - fC1 * fC1;
415 Real fR1 = fC3 * fC1 - ((Real)4.0) * fC0;
422 std::vector<Real> cubeRoots = tempCubic.FindRealRoots();
428 Real fY = cubeRoots[0];
430 Real fDiscr = ((Real)0.25) * fC3 * fC3 - fC2 + fY;
431 if (fabs(fDiscr) <= fEpsilon) { fDiscr = (Real)0.0; }
433 if (fDiscr > (Real)0.0) {
434 Real fR = sqrt(fDiscr);
435 Real fT1 = ((Real)0.75) * fC3 * fC3 - fR * fR - ((Real)2.0) * fC2;
437 (((Real)4.0) * fC3 * fC2 - ((Real)8.0) * fC1 - fC3 * fC3 * fC3) /
440 Real fTplus = fT1 + fT2;
441 Real fTminus = fT1 - fT2;
442 if (fabs(fTplus) <= fEpsilon) { fTplus = (Real)0.0; }
443 if (fabs(fTminus) <= fEpsilon) { fTminus = (Real)0.0; }
445 if (fTplus >= (Real)0.0) {
446 Real fD = sqrt(fTplus);
447 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * (fR + fD));
448 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * (fR - fD));
450 if (fTminus >= (Real)0.0) {
451 Real fE = sqrt(fTminus);
452 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * (fE - fR));
453 roots.push_back(-((Real)0.25) * fC3 - ((Real)0.5) * (fE + fR));
455 }
else if (fDiscr < (Real)0.0) {
458 Real fT2 = fY * fY - ((Real)4.0) * fC0;
459 if (fT2 >= -fEpsilon) {
460 if (fT2 < (Real)0.0) {
463 fT2 = ((Real)2.0) * sqrt(fT2);
464 Real fT1 = ((Real)0.75) * fC3 * fC3 - ((Real)2.0) * fC2;
465 if (fT1 + fT2 >= fEpsilon) {
466 Real fD = sqrt(fT1 + fT2);
467 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * fD);
468 roots.push_back(-((Real)0.25) * fC3 - ((Real)0.5) * fD);
470 if (fT1 - fT2 >= fEpsilon) {
471 Real fE = sqrt(fT1 - fT2);
472 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * fE);
473 roots.push_back(-((Real)0.25) * fC3 - ((Real)0.5) * fE);
483 eig.getRealEigenvalues(reals);
484 eig.getImagEigenvalues(imags);
486 for (
int i = 0; i < deg; i++) {
487 if (fabs(imags(i)) < fEpsilon) roots.push_back(reals(i));
495 PolynomialPairMap polyPairMap_;