10 #ifndef EIGEN_COMPANION_H 11 #define EIGEN_COMPANION_H 21 #ifndef EIGEN_PARSED_BY_DOXYGEN 27 T
radix2(){
return radix<T>()*radix<T>(); }
38 template<
typename _Scalar,
int _Deg >
65 if( m_bl_diag.rows() >
col )
67 if( 0 < row ){
return m_bl_diag[
col]; }
70 else{
return m_monic[
row]; }
74 template<
typename VectorType>
77 const Index deg = poly.size()-1;
78 m_monic = -1/poly[deg] * poly.head(deg);
80 m_bl_diag.setOnes(deg-1);
83 template<
typename VectorType>
85 setPolynomial( poly ); }
90 const Index deg = m_monic.size();
91 const Index deg_1 = deg-1;
92 DenseCompanionMatrixType
companion(deg,deg);
94 ( LeftBlock(deg,deg_1)
95 << LeftBlockFirstRow::Zero(1,deg_1),
96 BottomLeftBlock::Identity(deg-1,deg-1)*m_bl_diag.asDiagonal() ).finished()
110 bool balanced( Scalar colNorm, Scalar rowNorm,
111 bool& isBalanced, Scalar& colB, Scalar& rowB );
119 bool balancedR( Scalar colNorm, Scalar rowNorm,
120 bool& isBalanced, Scalar& colB, Scalar& rowB );
140 template<
typename _Scalar,
int _Deg >
145 if(
Scalar(0) == colNorm ||
Scalar(0) == rowNorm ){
return true; }
153 rowB = rowNorm / radix<Scalar>();
155 const Scalar s = colNorm + rowNorm;
157 while (colNorm < rowB)
159 colB *= radix<Scalar>();
160 colNorm *= radix2<Scalar>();
163 rowB = rowNorm * radix<Scalar>();
165 while (colNorm >= rowB)
167 colB /= radix<Scalar>();
168 colNorm /= radix2<Scalar>();
172 if ((rowNorm + colNorm) <
Scalar(0.95) * s * colB)
183 template<
typename _Scalar,
int _Deg >
188 if(
Scalar(0) == colNorm ||
Scalar(0) == rowNorm ){
return true; }
195 const _Scalar
q = colNorm/rowNorm;
196 if( !isApprox( q, _Scalar(1) ) )
198 rowB =
sqrt( colNorm/rowNorm );
210 template<
typename _Scalar,
int _Deg >
215 const Index deg = m_monic.size();
216 const Index deg_1 = deg-1;
218 bool hasConverged=
false;
219 while( !hasConverged )
227 colNorm =
abs(m_bl_diag[0]);
228 rowNorm =
abs(m_monic[0]);
231 if( !balanced( colNorm, rowNorm, hasConverged, colB, rowB ) )
233 m_bl_diag[0] *= colB;
239 for(
Index i=1; i<deg_1; ++i )
242 colNorm =
abs(m_bl_diag[i]);
245 rowNorm =
abs(m_bl_diag[i-1]) +
abs(m_monic[i]);
248 if( !balanced( colNorm, rowNorm, hasConverged, colB, rowB ) )
250 m_bl_diag[i] *= colB;
251 m_bl_diag[i-1] *= rowB;
258 const Index ebl = m_bl_diag.size()-1;
260 colNorm = headMonic.array().abs().sum();
261 rowNorm =
abs( m_bl_diag[ebl] );
264 if( !balanced( colNorm, rowNorm, hasConverged, colB, rowB ) )
267 m_bl_diag[ebl] *= rowB;
276 #endif // EIGEN_COMPANION_H NumTraits< Scalar >::Real RealScalar
#define EIGEN_STRONG_INLINE
Matrix< Scalar, 1, Deg_1 > LeftBlockFirstRow
BottomLeftDiagonal m_bl_diag
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
#define EIGEN_STATIC_ASSERT(CONDITION, MSG)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
EIGEN_STRONG_INLINE const _Scalar operator()(Index row, Index col) const
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar, Size)
void setPolynomial(const VectorType &poly)
Matrix< Scalar, Deg_1, 1 > BottomLeftDiagonal
Expression of a fixed-size or dynamic-size sub-vector.
EIGEN_DEVICE_FUNC ColXpr col(Index i)
This is the const version of col().
bool balanced(Scalar colNorm, Scalar rowNorm, bool &isBalanced, Scalar &colB, Scalar &rowB)
DenseCompanionMatrixType denseMatrix() const
EIGEN_DEVICE_FUNC RowXpr row(Index i)
This is the const version of row(). */.
EIGEN_DEVICE_FUNC const Scalar & q
Matrix< Scalar, Deg, 1 > RightColumn
companion(const VectorType &poly)
EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex
bool balancedR(Scalar colNorm, Scalar rowNorm, bool &isBalanced, Scalar &colB, Scalar &rowB)
Matrix< Scalar, Deg_1, Deg_1 > BottomLeftBlock
Matrix< Scalar, Deg, Deg > DenseCompanionMatrixType
Matrix< Scalar, _Deg, Deg_1 > LeftBlock