From b3d381750d347a7a4eecf04052f4e4658ee0d555 Mon Sep 17 00:00:00 2001 From: Andrey Aralov Date: Thu, 8 Aug 2024 17:14:53 +0300 Subject: [PATCH] Add `solveWithFixedDegree` wrapper (#3146) * Add `solveWithFixedDegree` wrapper, that removes leading zeros from the polynomial before passing it to the actual solver. * Fix build. --- source/MRMesh/MRBestFitPolynomial.cpp | 36 +++++++++++++++++++++++++-- source/MRMesh/MRBestFitPolynomial.h | 1 + 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/source/MRMesh/MRBestFitPolynomial.cpp b/source/MRMesh/MRBestFitPolynomial.cpp index caa487a6996c..f1096d1a4823 100644 --- a/source/MRMesh/MRBestFitPolynomial.cpp +++ b/source/MRMesh/MRBestFitPolynomial.cpp @@ -124,6 +124,39 @@ struct Solver }; +template +std::vector> solveWithFixedDegree( auto coeffsBegin, auto coeffsEnd ) +{ + assert( coeffsEnd - coeffsBegin == degree + 1 ); + if constexpr ( degree == 0 ) + { + return {}; + } + else + { + if ( *std::prev( coeffsEnd ) != 0 ) + { + Eigen::Vector c; + for ( size_t i = 0; i < degree + 1; ++i ) + c[i] = *( coeffsBegin + i ); + + Solver s; + auto roots = s( c ); + + std::vector> res; + for ( auto v : roots ) + res.push_back( v ); + return res; + } + else + { + return solveWithFixedDegree( coeffsBegin, std::prev( coeffsEnd ) ); + } + } +} + + + } namespace MR @@ -152,8 +185,7 @@ std::vector Polynomial::solve( T tol ) const if constexpr ( canSolvePolynomial( degree ) ) { #endif - Solver solver; - auto r_c = solver( a ); + auto r_c = solveWithFixedDegree( a.begin(), a.end() ); std::vector r; for ( std::complex c : r_c ) if ( std::abs( c.imag() ) < tol ) diff --git a/source/MRMesh/MRBestFitPolynomial.h b/source/MRMesh/MRBestFitPolynomial.h index 9df0b0022678..fc86ffa77174 100644 --- a/source/MRMesh/MRBestFitPolynomial.h +++ b/source/MRMesh/MRBestFitPolynomial.h @@ -98,6 +98,7 @@ class BestFitPolynomial MRMESH_API void addPoint( T x, T y, T weight ); + /// @note The result might have leading coefficient equal to zero. MRMESH_API Polynomial getBestPolynomial() const; private: