88 using PolynomialType = Polynomial<Real>;
89 using ExponentType = int;
90 using CoefficientType = Real;
91 using PolynomialPairMap = std::map<ExponentType, CoefficientType>;
92 using iterator =
typename PolynomialPairMap::iterator;
93 using const_iterator =
typename PolynomialPairMap::const_iterator;
105 Real result = Real();
106 ExponentType exponent;
107 CoefficientType coefficient;
109 for (iterator i = polyPairMap_.begin(); i != polyPairMap_.end(); ++i) {
111 coefficient = i->second;
112 result += fastpow(x, exponent) * coefficient;
124 Real result = Real();
125 ExponentType exponent;
126 CoefficientType coefficient;
128 for (iterator i = polyPairMap_.begin(); i != polyPairMap_.end(); ++i) {
130 coefficient = i->second;
131 result += fastpow(x, exponent - 1) * coefficient * exponent;
144 polyPairMap_[exponent] = coefficient;
155 iterator i = polyPairMap_.find(exponent);
158 i->second += coefficient;
172 iterator i = polyPairMap_.find(exponent);
181 iterator begin() {
return polyPairMap_.begin(); }
182 const_iterator begin()
const {
return polyPairMap_.begin(); }
184 iterator end() {
return polyPairMap_.end(); }
185 const_iterator end()
const {
return polyPairMap_.end(); }
187 iterator find(ExponentType exponent) {
return polyPairMap_.find(exponent); }
189 size_t size() {
return polyPairMap_.size(); }
193 for (iterator i = polyPairMap_.begin(); i != polyPairMap_.end(); ++i) {
194 if (i->first > deg) deg = i->first;
199 PolynomialType& operator+=(
const PolynomialType& p) {
200 typename Polynomial<Real>::const_iterator i;
202 for (i = p.begin(); i != p.end(); ++i) {
209 PolynomialType& operator-=(
const PolynomialType& p) {
210 typename Polynomial<Real>::const_iterator i;
211 for (i = p.begin(); i != p.end(); ++i) {
217 PolynomialType& operator*=(
const PolynomialType& p) {
218 typename Polynomial<Real>::const_iterator i;
219 typename Polynomial<Real>::const_iterator j;
220 Polynomial<Real> p2(*
this);
222 polyPairMap_.clear();
223 for (i = p2.begin(); i != p2.end(); ++i) {
224 for (j = p.begin(); j != p.end(); ++j) {
231 PolynomialType& operator*=(
const Real v) {
232 typename Polynomial<Real>::const_iterator i;
235 for (i = this->begin(); i != this->end(); ++i) {
242 PolynomialType& operator+=(
const Real v) {
252 Polynomial<Real>* p =
new Polynomial<Real>();
254 typename Polynomial<Real>::const_iterator i;
255 ExponentType exponent;
256 CoefficientType coefficient;
258 for (i = this->begin(); i != this->end(); ++i) {
260 coefficient = i->second;
272 for (
int i = 0; i < rank; ++i) {
273 for (
int j = 0; j < rank; ++j) {
276 }
else if (j == rank - 1) {
285 std::vector<std::complex<Real>> FindRoots() {
287 DynamicRectMatrix<Real> companion = CreateCompanion();
288 JAMA::Eigenvalue<Real> eig(companion);
289 DynamicVector<Real> reals, imags;
290 eig.getRealEigenvalues(reals);
291 eig.getImagEigenvalues(imags);
293 std::vector<std::complex<Real>> roots;
294 for (
int i = 0; i < rank; i++) {
295 roots.push_back(std::complex<Real>(reals(i), imags(i)));
301 std::vector<Real> FindRealRoots() {
302 const Real fEpsilon = 1.0e-8;
303 std::vector<Real> roots;
306 const int deg = degree();
312 roots.push_back(-fC0 / fC1);
319 Real fDiscr = fC1 * fC1 - 4.0 * fC0 * fC2;
320 if (std::abs(fDiscr) <= fEpsilon) { fDiscr = (Real)0.0; }
322 if (fDiscr < (Real)0.0) {
326 Real fTmp = ((Real)0.5) / fC2;
328 if (fDiscr > (Real)0.0) {
329 fDiscr = std::sqrt(fDiscr);
330 roots.push_back(fTmp * (-fC1 - fDiscr));
331 roots.push_back(fTmp * (-fC1 + fDiscr));
333 roots.push_back(-fTmp * fC1);
344 Real fInvC3 = ((Real)1.0) / fC3;
350 const Real fThird = (Real)1.0 / (Real)3.0;
351 const Real fTwentySeventh = (Real)1.0 / (Real)27.0;
352 Real fOffset = fThird * fC2;
353 Real fA = fC1 - fC2 * fOffset;
354 Real fB = fC0 + fC2 * (((Real)2.0) * fC2 * fC2 - ((Real)9.0) * fC1) *
356 Real fHalfB = ((Real)0.5) * fB;
358 Real fDiscr = fHalfB * fHalfB + fA * fA * fA * fTwentySeventh;
359 if (std::abs(fDiscr) <= fEpsilon) { fDiscr = (Real)0.0; }
361 if (fDiscr > (Real)0.0) {
363 fDiscr = std::sqrt(fDiscr);
364 Real fTemp = -fHalfB + fDiscr;
366 if (fTemp >= (Real)0.0) {
367 root = std::pow(fTemp, fThird);
369 root = -std::pow(-fTemp, fThird);
371 fTemp = -fHalfB - fDiscr;
372 if (fTemp >= (Real)0.0) {
373 root += std::pow(fTemp, fThird);
375 root -= std::pow(-fTemp, fThird);
379 roots.push_back(root);
380 }
else if (fDiscr < (Real)0.0) {
381 const Real fSqrt3 = std::sqrt((Real)3.0);
382 Real fDist = std::sqrt(-fThird * fA);
383 Real fAngle = fThird * std::atan2(std::sqrt(-fDiscr), -fHalfB);
384 Real fCos = cos(fAngle);
385 Real fSin = sin(fAngle);
386 roots.push_back(((Real)2.0) * fDist * fCos - fOffset);
387 roots.push_back(-fDist * (fCos + fSqrt3 * fSin) - fOffset);
388 roots.push_back(-fDist * (fCos - fSqrt3 * fSin) - fOffset);
391 if (fHalfB >= (Real)0.0) {
392 fTemp = -std::pow(fHalfB, fThird);
394 fTemp = std::pow(-fHalfB, fThird);
396 roots.push_back(((Real)2.0) * fTemp - fOffset);
397 roots.push_back(-fTemp - fOffset);
398 roots.push_back(-fTemp - fOffset);
410 Real fInvC4 = ((Real)1.0) / fC4;
417 Real fR0 = -fC3 * fC3 * fC0 + ((Real)4.0) * fC2 * fC0 - fC1 * fC1;
418 Real fR1 = fC3 * fC1 - ((Real)4.0) * fC0;
420 Polynomial<Real> tempCubic;
421 tempCubic.setCoefficient(0, fR0);
422 tempCubic.setCoefficient(1, fR1);
423 tempCubic.setCoefficient(2, fR2);
424 tempCubic.setCoefficient(3, 1.0);
425 std::vector<Real> cubeRoots = tempCubic.FindRealRoots();
431 Real fY = cubeRoots[0];
433 Real fDiscr = ((Real)0.25) * fC3 * fC3 - fC2 + fY;
434 if (std::abs(fDiscr) <= fEpsilon) { fDiscr = (Real)0.0; }
436 if (fDiscr > (Real)0.0) {
437 Real fR = std::sqrt(fDiscr);
438 Real fT1 = ((Real)0.75) * fC3 * fC3 - fR * fR - ((Real)2.0) * fC2;
440 (((Real)4.0) * fC3 * fC2 - ((Real)8.0) * fC1 - fC3 * fC3 * fC3) /
443 Real fTplus = fT1 + fT2;
444 Real fTminus = fT1 - fT2;
445 if (std::abs(fTplus) <= fEpsilon) { fTplus = (Real)0.0; }
446 if (std::abs(fTminus) <= fEpsilon) { fTminus = (Real)0.0; }
448 if (fTplus >= (Real)0.0) {
449 Real fD = std::sqrt(fTplus);
450 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * (fR + fD));
451 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * (fR - fD));
453 if (fTminus >= (Real)0.0) {
454 Real fE = std::sqrt(fTminus);
455 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * (fE - fR));
456 roots.push_back(-((Real)0.25) * fC3 - ((Real)0.5) * (fE + fR));
458 }
else if (fDiscr < (Real)0.0) {
461 Real fT2 = fY * fY - ((Real)4.0) * fC0;
462 if (fT2 >= -fEpsilon) {
463 if (fT2 < (Real)0.0) {
466 fT2 = ((Real)2.0) * std::sqrt(fT2);
467 Real fT1 = ((Real)0.75) * fC3 * fC3 - ((Real)2.0) * fC2;
468 if (fT1 + fT2 >= fEpsilon) {
469 Real fD = std::sqrt(fT1 + fT2);
470 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * fD);
471 roots.push_back(-((Real)0.25) * fC3 - ((Real)0.5) * fD);
473 if (fT1 - fT2 >= fEpsilon) {
474 Real fE = std::sqrt(fT1 - fT2);
475 roots.push_back(-((Real)0.25) * fC3 + ((Real)0.5) * fE);
476 roots.push_back(-((Real)0.25) * fC3 - ((Real)0.5) * fE);
483 DynamicRectMatrix<Real> companion = CreateCompanion();
484 JAMA::Eigenvalue<Real> eig(companion);
485 DynamicVector<Real> reals, imags;
486 eig.getRealEigenvalues(reals);
487 eig.getImagEigenvalues(imags);
489 for (
int i = 0; i < deg; i++) {
490 if (std::abs(imags(i)) < fEpsilon) roots.push_back(reals(i));
498 PolynomialPairMap polyPairMap_;