10 #ifndef EIGEN_REAL_QZ_H 11 #define EIGEN_REAL_QZ_H 57 template<
typename _MatrixType>
class RealQZ 68 typedef typename MatrixType::Scalar
Scalar;
70 typedef typename MatrixType::Index
Index;
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());
246 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)
271 m_normOfS +=
m_S.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
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>();
498 Index lr = (std::min)(k+4,dim);
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);
556 template<
typename MatrixType>
560 const Index dim = A_in.cols();
563 && B_in.rows()==dim && B_in.cols()==dim
564 &&
"Need square matrices of the same dimension");
585 if (f>0)
m_S.coeffRef(f,f-1) =
Scalar(0.0);
611 step(f,l, local_iter);
624 #endif //EIGEN_REAL_QZ Matrix< ComplexScalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > EigenvalueType
RealQZ(Index size=RowsAtCompileTime==Dynamic?1:RowsAtCompileTime)
Default constructor.
void pushDownZero(Index z, Index f, Index l)
HouseholderSequenceType householderQ() const
IntermediateState sqrt(const Expression &arg)
Index findSmallSubdiagEntry(Index iu)
std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
void makeGivens(const Scalar &p, const Scalar &q, Scalar *z=0)
A matrix or vector expression mapping an existing array of data.
ComputationInfo info() const
Reports whether previous computation was successful.
Index findSmallDiagEntry(Index f, Index l)
iterative scaling algorithm to equilibrate rows and column norms in matrices
Rotation given by a cosine-sine pair.
const MatrixType & matrixT() const
Returns matrix S in the QZ decomposition.
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_STRONG_INLINE const CwiseUnaryOp< internal::scalar_abs_op< Scalar >, const Derived > abs() const
Index iterations() const
Returns number of performed QR-like iterations.
RealQZ(const MatrixType &A, const MatrixType &B, bool computeQZ=true)
Constructor; computes real QZ decomposition of given matrices.
MatrixType::Scalar Scalar
EIGEN_STRONG_INLINE void resize(Index nbRows, Index nbCols)
Matrix< Scalar, Dynamic, 1 > m_workspace
ColsBlockXpr rightCols(Index n)
Provides a generic way to set and pass user-specified options.
const MatrixType & matrixS() const
Returns matrix S in the QZ decomposition.
JacobiRotation adjoint() const
Matrix< Scalar, 2, 1 > Vector2s
const MatrixType & matrixZ() const
Returns matrix Z in the QZ decomposition.
Matrix< Scalar, ColsAtCompileTime, 1, Options &~RowMajor, MaxColsAtCompileTime, 1 > ColumnVectorType
EIGEN_STRONG_INLINE const Scalar * data() const
Matrix< Scalar, 2, 2 > Matrix2s
RowsBlockXpr topRows(Index n)
void splitOffTwoRows(Index i)
RealQZ & compute(const MatrixType &A, const MatrixType &B, bool computeQZ=true)
Computes QZ decomposition of given matrix.
void hessenbergTriangular()
const MatrixType & matrixQ() const
Returns matrix Q in the QZ decomposition.
Performs a real QZ decomposition of a pair of square matrices.
const MatrixType & matrixQR() const