Patch from Oleg Shirokobrod to extend polynomial solver to complexes

This commit is contained in:
Gael Guennebaud 2016-11-23 15:42:26 +01:00
parent e340866c81
commit 9246587122
2 changed files with 27 additions and 27 deletions

View File

@ -75,7 +75,7 @@ class companion
void setPolynomial( const VectorType& poly )
{
const Index deg = poly.size()-1;
m_monic = -1/poly[deg] * poly.head(deg);
m_monic = Scalar(-1)/poly[deg] * poly.head(deg);
//m_bl_diag.setIdentity( deg-1 );
m_bl_diag.setOnes(deg-1);
}
@ -107,8 +107,8 @@ class companion
* colB and rowB are repectively the multipliers for
* the column and the row in order to balance them.
* */
bool balanced( Scalar colNorm, Scalar rowNorm,
bool& isBalanced, Scalar& colB, Scalar& rowB );
bool balanced( RealScalar colNorm, RealScalar rowNorm,
bool& isBalanced, RealScalar& colB, RealScalar& rowB );
/** Helper function for the balancing algorithm.
* \returns true if the row and the column, having colNorm and rowNorm
@ -116,8 +116,8 @@ class companion
* colB and rowB are repectively the multipliers for
* the column and the row in order to balance them.
* */
bool balancedR( Scalar colNorm, Scalar rowNorm,
bool& isBalanced, Scalar& colB, Scalar& rowB );
bool balancedR( RealScalar colNorm, RealScalar rowNorm,
bool& isBalanced, RealScalar& colB, RealScalar& rowB );
public:
/**
@ -139,10 +139,10 @@ class companion
template< typename _Scalar, int _Deg >
inline
bool companion<_Scalar,_Deg>::balanced( Scalar colNorm, Scalar rowNorm,
bool& isBalanced, Scalar& colB, Scalar& rowB )
bool companion<_Scalar,_Deg>::balanced( RealScalar colNorm, RealScalar rowNorm,
bool& isBalanced, RealScalar& colB, RealScalar& rowB )
{
if( Scalar(0) == colNorm || Scalar(0) == rowNorm ){ return true; }
if( RealScalar(0) == colNorm || RealScalar(0) == rowNorm ){ return true; }
else
{
//To find the balancing coefficients, if the radix is 2,
@ -150,29 +150,29 @@ bool companion<_Scalar,_Deg>::balanced( Scalar colNorm, Scalar rowNorm,
// \f$ 2^{2\sigma-1} < rowNorm / colNorm \le 2^{2\sigma+1} \f$
// then the balancing coefficient for the row is \f$ 1/2^{\sigma} \f$
// and the balancing coefficient for the column is \f$ 2^{\sigma} \f$
rowB = rowNorm / radix<Scalar>();
colB = Scalar(1);
const Scalar s = colNorm + rowNorm;
rowB = rowNorm / radix<RealScalar>();
colB = RealScalar(1);
const RealScalar s = colNorm + rowNorm;
while (colNorm < rowB)
{
colB *= radix<Scalar>();
colNorm *= radix2<Scalar>();
colB *= radix<RealScalar>();
colNorm *= radix2<RealScalar>();
}
rowB = rowNorm * radix<Scalar>();
rowB = rowNorm * radix<RealScalar>();
while (colNorm >= rowB)
{
colB /= radix<Scalar>();
colNorm /= radix2<Scalar>();
colB /= radix<RealScalar>();
colNorm /= radix2<RealScalar>();
}
//This line is used to avoid insubstantial balancing
if ((rowNorm + colNorm) < Scalar(0.95) * s * colB)
if ((rowNorm + colNorm) < RealScalar(0.95) * s * colB)
{
isBalanced = false;
rowB = Scalar(1) / colB;
rowB = RealScalar(1) / colB;
return false;
}
else{
@ -182,21 +182,21 @@ bool companion<_Scalar,_Deg>::balanced( Scalar colNorm, Scalar rowNorm,
template< typename _Scalar, int _Deg >
inline
bool companion<_Scalar,_Deg>::balancedR( Scalar colNorm, Scalar rowNorm,
bool& isBalanced, Scalar& colB, Scalar& rowB )
bool companion<_Scalar,_Deg>::balancedR( RealScalar colNorm, RealScalar rowNorm,
bool& isBalanced, RealScalar& colB, RealScalar& rowB )
{
if( Scalar(0) == colNorm || Scalar(0) == rowNorm ){ return true; }
if( RealScalar(0) == colNorm || RealScalar(0) == rowNorm ){ return true; }
else
{
/**
* Set the norm of the column and the row to the geometric mean
* of the row and column norm
*/
const _Scalar q = colNorm/rowNorm;
const RealScalar q = colNorm/rowNorm;
if( !isApprox( q, _Scalar(1) ) )
{
rowB = sqrt( colNorm/rowNorm );
colB = Scalar(1)/rowB;
colB = RealScalar(1)/rowB;
isBalanced = false;
return false;
@ -219,8 +219,8 @@ void companion<_Scalar,_Deg>::balance()
while( !hasConverged )
{
hasConverged = true;
Scalar colNorm,rowNorm;
Scalar colB,rowB;
RealScalar colNorm,rowNorm;
RealScalar colB,rowB;
//First row, first column excluding the diagonal
//==============================================

View File

@ -327,7 +327,7 @@ class PolynomialSolverBase
* However, almost always, correct accuracy is reached even in these cases for 64bit
* (double) floating types and small polynomial degree (<20).
*/
template< typename _Scalar, int _Deg >
template< typename _Scalar, int _Deg , typename EigenSolverType = EigenSolver<Matrix<_Scalar,_Deg,_Deg> > >
class PolynomialSolver : public PolynomialSolverBase<_Scalar,_Deg>
{
public:
@ -337,7 +337,7 @@ class PolynomialSolver : public PolynomialSolverBase<_Scalar,_Deg>
EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( PS_Base )
typedef Matrix<Scalar,_Deg,_Deg> CompanionMatrixType;
typedef EigenSolver<CompanionMatrixType> EigenSolverType;
//typedef EigenSolver<CompanionMatrixType> EigenSolverType;
public:
/** Computes the complex roots of a new polynomial. */