10 #ifndef EIGEN_REAL_QZ_H    11 #define EIGEN_REAL_QZ_H    57   template<
typename _MatrixType> 
class RealQZ    68       typedef typename MatrixType::Scalar 
Scalar;
   104       RealQZ(
const MatrixType& A, 
const MatrixType& B, 
bool computeQZ = 
true) :
   105         m_S(A.rows(),A.cols()),
   106         m_T(A.rows(),A.cols()),
   107         m_Q(A.rows(),A.cols()),
   108         m_Z(A.rows(),A.cols()),
   160       RealQZ& 
compute(
const MatrixType& A, 
const MatrixType& B, 
bool computeQZ = 
true);
   211       void step(Index f, Index l, Index iter);
   216   template<
typename MatrixType>
   225       m_T.template triangularView<StrictlyLower>().setZero();
   228       m_S.applyOnTheLeft(
m_Q.adjoint());
   231         m_Z = MatrixType::Identity(dim,dim);
   233       for (
Index j=0; j<=dim-3; j++) {
   234         for (
Index i=dim-1; i>=j+2; i--) {
   237           if(
m_S.coeff(i,j) != 0)
   241             m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.
adjoint());
   242             m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.
adjoint());
   245               m_Q.applyOnTheRight(i-1,i,G);
   252             m_S.applyOnTheRight(i,i-1,G);
   253             m_T.topRows(i).applyOnTheRight(i,i-1,G);
   263   template<
typename MatrixType>
   269       for (
Index j = 0; j < size; ++j)
   272         m_normOfT += 
m_T.row(j).segment(j, size - j).cwiseAbs().sum();
   278   template<
typename MatrixType>
   296   template<
typename MatrixType>
   310   template<
typename MatrixType>
   322         Matrix2s STi = 
m_T.template block<2,2>(i,i).
template triangularView<Upper>().
   323           template solve<OnTheRight>(
m_S.template block<2,2>(i,i));
   325         Scalar q = p*p + STi(1,0)*STi(0,1);
   336           m_S.rightCols(dim-i).applyOnTheLeft(i,i+1,G.
adjoint());
   337           m_T.rightCols(dim-i).applyOnTheLeft(i,i+1,G.
adjoint());
   340             m_Q.applyOnTheRight(i,i+1,G);
   343           m_S.topRows(i+2).applyOnTheRight(i+1,i,G);
   344           m_T.topRows(i+2).applyOnTheRight(i+1,i,G);
   360   template<
typename MatrixType>
   365       for (
Index zz=z; zz<l; zz++)
   368         Index firstColS = zz>f ? (zz-1) : zz;
   370         m_S.rightCols(dim-firstColS).applyOnTheLeft(zz,zz+1,G.
adjoint());
   371         m_T.rightCols(dim-zz).applyOnTheLeft(zz,zz+1,G.
adjoint());
   375           m_Q.applyOnTheRight(zz,zz+1,G);
   380           m_S.topRows(zz+2).applyOnTheRight(zz, zz-1,G);
   381           m_T.topRows(zz+1).applyOnTheRight(zz, zz-1,G);
   390       m_S.applyOnTheRight(l,l-1,G);
   391       m_T.applyOnTheRight(l,l-1,G);
   399   template<
typename MatrixType>
   411           a11=
m_S.coeff(f+0,f+0), a12=
m_S.coeff(f+0,f+1),
   412           a21=
m_S.coeff(f+1,f+0), a22=
m_S.coeff(f+1,f+1), a32=
m_S.coeff(f+2,f+1),
   413           b12=
m_T.coeff(f+0,f+1),
   416           a87=
m_S.coeff(l-1,l-2),
   417           a98=
m_S.coeff(l-0,l-1),
   423         x = ll + a11*a11*b11i*b11i - lpl*a11*b11i + a12*a21*b11i*b22i
   424           - a11*a21*b12*b11i*b11i*b22i;
   425         y = a11*a21*b11i*b11i - lpl*a21*b11i + a21*a22*b11i*b22i 
   426           - a21*a21*b12*b11i*b11i*b22i;
   427         z = a21*a32*b11i*b22i;
   432         x = 
m_S.coeff(f,f)/
m_T.coeff(f,f)-
m_S.coeff(l,l)/
m_T.coeff(l,l) + 
m_S.coeff(l,l-1)*
m_T.coeff(l-1,l) /
   433           (
m_T.coeff(l-1,l-1)*
m_T.coeff(l,l));
   434         y = 
m_S.coeff(f+1,f)/
m_T.coeff(f,f);
   437       else if (iter>23 && !(iter%8))
   440         x = internal::random<Scalar>(-1.0,1.0);
   441         y = internal::random<Scalar>(-1.0,1.0);
   442         z = internal::random<Scalar>(-1.0,1.0);
   453           a11 = 
m_S.coeff(f,f),     a12 = 
m_S.coeff(f,f+1),
   454           a21 = 
m_S.coeff(f+1,f),   a22 = 
m_S.coeff(f+1,f+1),
   455                                     a32 = 
m_S.coeff(f+2,f+1),
   457           a88 = 
m_S.coeff(l-1,l-1), a89 = 
m_S.coeff(l-1,l),
   458           a98 = 
m_S.coeff(l,l-1),   a99 = 
m_S.coeff(l,l),
   460           b11 = 
m_T.coeff(f,f),     b12 = 
m_T.coeff(f,f+1),
   461                                     b22 = 
m_T.coeff(f+1,f+1),
   463           b88 = 
m_T.coeff(l-1,l-1), b89 = 
m_T.coeff(l-1,l),
   464                                     b99 = 
m_T.coeff(l,l);
   466         x = ( (a88/b88 - a11/b11)*(a99/b99 - a11/b11) - (a89/b99)*(a98/b88) + (a98/b88)*(b89/b99)*(a11/b11) ) * (b11/a21)
   467           + a12/b22 - (a11/b11)*(b12/b22);
   468         y = (a22/b22-a11/b11) - (a21/b11)*(b12/b22) - (a88/b88-a11/b11) - (a99/b99-a11/b11) + (a98/b88)*(b89/b99);
   474       for (
Index k=f; k<=l-2; k++)
   483         hr.makeHouseholderInPlace(tau, beta);
   484         essential2 = hr.template bottomRows<2>();
   489           m_Q.template middleCols<3>(k).applyHouseholderOnTheRight(essential2, tau, 
m_workspace.
data());
   491           m_S.coeffRef(k+2,k-1) = 
m_S.coeffRef(k+1,k-1) = 
Scalar(0.0);
   494         hr << 
m_T.coeff(k+2,k+2),
m_T.coeff(k+2,k),
m_T.coeff(k+2,k+1);
   495         hr.makeHouseholderInPlace(tau, beta);
   496         essential2 = hr.template bottomRows<2>();
   501           tmp = 
m_S.template middleCols<2>(k).
topRows(lr) * essential2;
   502           tmp += 
m_S.col(k+2).head(lr);
   503           m_S.col(k+2).head(lr) -= tau*tmp;
   504           m_S.template middleCols<2>(k).
topRows(lr) -= (tau*tmp) * essential2.adjoint();
   506           tmp = 
m_T.template middleCols<2>(k).
topRows(lr) * essential2;
   507           tmp += 
m_T.col(k+2).head(lr);
   508           m_T.col(k+2).head(lr) -= tau*tmp;
   509           m_T.template middleCols<2>(k).
topRows(lr) -= (tau*tmp) * essential2.adjoint();
   515           tmp = essential2.adjoint()*(
m_Z.template middleRows<2>(k));
   517           m_Z.row(k+2) -= tau*tmp;
   518           m_Z.template middleRows<2>(k) -= essential2 * (tau*tmp);
   520         m_T.coeffRef(k+2,k) = 
m_T.coeffRef(k+2,k+1) = 
Scalar(0.0);
   524         m_S.applyOnTheRight(k+1,k,G);
   525         m_T.applyOnTheRight(k+1,k,G);
   532         x = 
m_S.coeff(k+1,k);
   533         y = 
m_S.coeff(k+2,k);
   535           z = 
m_S.coeff(k+3,k);
   543         m_Q.applyOnTheRight(l-1,l,G);
   548       m_S.applyOnTheRight(l,l-1,G);
   549       m_T.applyOnTheRight(l,l-1,G);
   555   template<
typename MatrixType>
   559       const Index dim = A_in.cols();
   562           && B_in.rows()==dim && B_in.cols()==dim 
   563           && 
"Need square matrices of the same dimension");
   584         if (f>0) 
m_S.coeffRef(f,f-1) = 
Scalar(0.0);
   610             step(f,l, local_iter);
   625         for(
Index i=0; i<dim-1; ++i)
   633             m_S.applyOnTheLeft(i,i+1,j_left);
   634             m_S.applyOnTheRight(i,i+1,j_right);
   635             m_T.applyOnTheLeft(i,i+1,j_left);
   636             m_T.applyOnTheRight(i,i+1,j_right);
   654 #endif //EIGEN_REAL_QZ 
Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > EigenvalueType
void pushDownZero(Index z, Index f, Index l)
const MatrixType & matrixS() const
Returns matrix S in the QZ decomposition. 
std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
void makeGivens(const Scalar &p, const Scalar &q, Scalar *z=0)
Index iterations() const
Returns number of performed QR-like iterations. 
Index findSmallSubdiagEntry(Index iu)
EIGEN_DEVICE_FUNC ColsBlockXpr rightCols(Index n)
This is the const version of rightCols(Index). 
A matrix or vector expression mapping an existing array of data. 
const MatrixType & matrixQR() const
RealQZ(Index size=RowsAtCompileTime==Dynamic ? 1 :RowsAtCompileTime)
Default constructor. 
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Rotation given by a cosine-sine pair. 
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
void step(Index f, Index l, Index iter)
JacobiRotation< Scalar > JRs
RealQZ & setMaxIterations(Index maxIters)
Matrix< Scalar, 3, 1 > Vector3s
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
void real_2x2_jacobi_svd(const MatrixType &matrix, Index p, Index q, JacobiRotation< RealScalar > *j_left, JacobiRotation< RealScalar > *j_right)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
EIGEN_DEVICE_FUNC RowsBlockXpr topRows(Index n)
This is the const version of topRows(Index). 
RealQZ(const MatrixType &A, const MatrixType &B, bool computeQZ=true)
Constructor; computes real QZ decomposition of given matrices. 
MatrixType::Scalar Scalar
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API. 
Matrix< Scalar, Dynamic, 1 > m_workspace
HouseholderSequenceType householderQ() const
Matrix< Scalar, 2, 1 > Vector2s
const MatrixType & matrixZ() const
Returns matrix Z in the QZ decomposition. 
ComputationInfo info() const
Reports whether previous computation was successful. 
Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ColumnVectorType
Matrix< Scalar, 2, 2 > Matrix2s
int64_t max(int64_t a, const int b)
const MatrixType & matrixT() const
Returns matrix S in the QZ decomposition. 
void splitOffTwoRows(Index i)
JacobiRotation transpose() const
RealQZ & compute(const MatrixType &A, const MatrixType &B, bool computeQZ=true)
Computes QZ decomposition of given matrix. 
Index findSmallDiagEntry(Index f, Index l)
void hessenbergTriangular()
const MatrixType & matrixQ() const
Returns matrix Q in the QZ decomposition. 
JacobiRotation adjoint() const
Performs a real QZ decomposition of a pair of square matrices.