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>
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);
555 template<
typename MatrixType>
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
RealQZ(Index size=RowsAtCompileTime==Dynamic?1:RowsAtCompileTime)
Default constructor.
void pushDownZero(Index z, Index f, Index l)
HouseholderSequenceType householderQ() const
EIGEN_DEVICE_FUNC ColsBlockXpr rightCols(Index n)
This is the const version of rightCols(Index).
std::complex< typename NumTraits< Scalar >::Real > ComplexScalar
void makeGivens(const Scalar &p, const Scalar &q, Scalar *z=0)
Index findSmallSubdiagEntry(Index iu)
A matrix or vector expression mapping an existing array of data.
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
ComputationInfo info() const
Reports whether previous computation was successful.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar * data() const
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
static constexpr size_t size(Tuple< Args... > &)
Provides access to the number of elements in a tuple as a compile-time constant expression.
Rotation given by a cosine-sine pair.
const MatrixType & matrixT() const
Returns matrix S in the QZ decomposition.
EIGEN_DEVICE_FUNC RowsBlockXpr topRows(Index n)
This is the const version of topRows(Index).
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
void step(Index f, Index l, Index iter)
JacobiRotation< Scalar > JRs
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const AbsReturnType abs() const
RealQZ & setMaxIterations(Index maxIters)
JacobiRotation transpose() const
Matrix< Scalar, 3, 1 > Vector3s
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half() max(const half &a, const half &b)
void real_2x2_jacobi_svd(const MatrixType &matrix, Index p, Index q, JacobiRotation< RealScalar > *j_left, JacobiRotation< RealScalar > *j_right)
Index iterations() const
Returns number of performed QR-like iterations.
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
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
const MatrixType & matrixS() const
Returns matrix S in the QZ decomposition.
JacobiRotation adjoint() const
EIGEN_DEVICE_FUNC const Scalar & q
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
const mpreal dim(const mpreal &a, const mpreal &b, mp_rnd_t r=mpreal::get_default_rnd())
TFSIMD_FORCE_INLINE const tfScalar & z() const
Matrix< Scalar, 2, 2 > Matrix2s
void splitOffTwoRows(Index i)
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.
Performs a real QZ decomposition of a pair of square matrices.
const MatrixType & matrixQR() const