34 #include <Eigen/Eigenvalues>
35 #include <Eigen/Householder>
46 assert(U.rows() == 2 && U.cols() == 2);
88 double z = (p / scale) * p + (bc_max / scale) * bc_mis;
95 T(1, 1) = d - (bc_max / z) * bc_mis;
110 double sigma =
b +
c;
113 double u_sin = -(p / (tau * u_cos)) *
util::sign(1, sigma);
119 T = U.transpose() * T * U;
121 double temp = 0.5 * (T(0, 0) + T(1, 1));
146 double cos1 = sab * tau;
147 double sin1 = sac * tau;
149 temp = U(0, 0) * cos1 - U(1, 0) * sin1;
150 U(1, 0) = U(0, 0) * sin1 + U(1, 0) * cos1;
174 assert(p > 0 && p < 3);
175 assert(
q > 0 &&
q < 3);
176 assert(ra11 + p +
q <= T.rows());
180 Eigen::MatrixXd BACKUP = T;
182 const int na = p +
q;
208 const double gamma = 1e3 * std::numeric_limits<double>::epsilon() * T.block(ra11, ra11, na, na).norm();
211 if (!
SylvesterContinuous::solve(T.block(ra11, ra11, p, p), -T.block(ra22, ra22,
q,
q), -gamma * T.block(ra11, ra22, p,
q),
X))
return false;
213 Eigen::MatrixXd G(p +
q,
q);
214 G.block(0, 0, p,
q) = -
X;
215 G.block(p, 0,
q,
q).setIdentity();
216 G.block(p, 0,
q,
q) *= gamma;
219 double A_infnorm = T.block(ra11, ra11, na, na).lpNorm<
Eigen::Infinity>();
231 T.block(ra11, ra11, na, T.cols() - ra11).applyOnTheLeft(qr_dec.householderQ().transpose());
232 T.block(0, ra11, ra22 +
q, na).applyOnTheRight(qr_dec.householderQ());
233 Q.block(0, ra11, Q.rows(), na).applyOnTheRight(qr_dec.householderQ());
238 constexpr
const double threshold = std::numeric_limits<double>::epsilon() * 2;
239 const double stability_crit = 10.0 * threshold * A_infnorm;
241 if (A21_norm < stability_crit)
244 T.block(ra22, ra11, p,
q).setZero();
249 PRINT_WARNING(
"swap_blocks_schur_form(): numerical instability detected: " << A21_norm <<
"/" << stability_crit <<
",\nA21:\n"
250 << T.block(ra22, ra11,
q, p));
262 T.block(ra11, ra22,
q, T.cols() - ra22).applyOnTheLeft(U.transpose());
265 for (
int i = 0; i < ra11; ++i)
270 map.applyOnTheLeft(U.transpose());
274 for (
int i = 0; i < Q.rows(); ++i)
277 map.applyOnTheLeft(U.transpose());
288 if (T.cols() > ra22 + p) T.block(ra22, ra22 + p, p, T.cols() - ra22 - p).applyOnTheLeft(U.transpose());
291 for (
int i = 0; i < ra22; ++i)
296 map.applyOnTheLeft(U.transpose());
300 for (
int i = 0; i < Q.rows(); ++i)
303 map.applyOnTheLeft(U.transpose());