20 #ifndef EIGEN_BDCSVD_H
21 #define EIGEN_BDCSVD_H
25 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
26 #undef eigen_internal_assert
27 #define eigen_internal_assert(X) assert(X);
33 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
39 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
40 IOFormat bdcsvdfmt(8, 0,
", ",
"\n",
" [",
"]");
43 template <
typename MatrixType_,
int Options>
48 template <
typename MatrixType_,
int Options>
84 template <
typename MatrixType_,
int Options_>
157 internal::check_svd_options_assertions<MatrixType, Options>(computationOptions,
rows,
cols);
183 internal::check_svd_options_assertions<MatrixType, Options>(computationOptions,
matrix.rows(),
matrix.cols());
206 internal::check_svd_options_assertions<MatrixType, Options>(computationOptions,
matrix.rows(),
matrix.cols());
211 eigen_assert(
s >= 3 &&
"BDCSVD the size of the algo switch has to be at least 3.");
228 template <
typename HouseholderU,
typename HouseholderV,
typename NaiveU,
typename NaiveV>
229 void copyUV(
const HouseholderU& householderU,
const HouseholderV& householderV,
const NaiveU& naiveU,
230 const NaiveV& naivev);
234 template <
typename SVDType>
267 template <
typename MatrixType,
int Options>
269 if (Base::allocate(
rows,
cols, computationOptions))
return;
271 if (
cols < m_algoswap)
275 m_compU = computeV();
276 m_compV = computeU();
278 if (m_isTranspose)
std::swap(m_compU, m_compV);
284 constexpr
Index kMinAspectRatio = 4;
285 constexpr
bool disableQrDecomp =
static_cast<int>(QRDecomposition) ==
static_cast<int>(
DisableQRDecomposition);
286 m_useQrDecomp = !disableQrDecomp && ((
rows / kMinAspectRatio >
cols) || (
cols / kMinAspectRatio >
rows));
289 reducedTriangle =
MatrixX(diagSize(), diagSize());
294 m_useQrDecomp ? diagSize() : copyWorkspace.cols());
303 m_workspace.resize((diagSize() + 1) * (diagSize() + 1) * 3);
304 m_workspaceI.resize(3 * diagSize());
307 template <
typename MatrixType,
int Options>
309 unsigned int computationOptions) {
310 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
311 std::cout <<
"\n\n\n================================================================================================="
312 "=====================\n\n\n";
316 allocate(
matrix.rows(),
matrix.cols(), computationOptions);
321 if (
matrix.cols() < m_algoswap) {
323 m_isInitialized =
true;
324 m_info = smallSvd.info();
326 if (computeU()) m_matrixU = smallSvd.matrixU();
327 if (computeV()) m_matrixV = smallSvd.matrixV();
328 m_singularValues = smallSvd.singularValues();
329 m_nonzeroSingularValues = smallSvd.nonzeroSingularValues();
337 m_isInitialized =
true;
345 copyWorkspace =
matrix.adjoint() / scale;
347 copyWorkspace =
matrix / scale;
354 qrDecomp.compute(copyWorkspace);
355 reducedTriangle = qrDecomp.matrixQR().topRows(diagSize());
356 reducedTriangle.template triangularView<StrictlyLower>().setZero();
357 bid.compute(reducedTriangle);
359 bid.compute(copyWorkspace);
366 m_computed.topRows(diagSize()) = bid.bidiagonal().toDenseMatrix().transpose();
367 m_computed.template bottomRows<1>().setZero();
368 divide(0, diagSize() - 1, 0, 0, 0);
370 m_isInitialized =
true;
375 for (
int i = 0;
i < diagSize();
i++) {
377 m_singularValues.coeffRef(
i) =
a * scale;
378 if (
a < considerZero) {
379 m_nonzeroSingularValues =
i;
380 m_singularValues.tail(diagSize() -
i - 1).setZero();
382 }
else if (
i == diagSize() - 1) {
383 m_nonzeroSingularValues =
i + 1;
390 copyUV(bid.householderV(), bid.householderU(), m_naiveV, m_naiveU);
392 copyUV(bid.householderU(), bid.householderV(), m_naiveU, m_naiveV);
395 if (m_isTranspose && computeV())
396 m_matrixV.applyOnTheLeft(qrDecomp.householderQ());
397 else if (!m_isTranspose && computeU())
398 m_matrixU.applyOnTheLeft(qrDecomp.householderQ());
401 m_isInitialized =
true;
405 template <
typename MatrixType,
int Options>
406 template <
typename HouseholderU,
typename HouseholderV,
typename NaiveU,
typename NaiveV>
408 const NaiveU& naiveU,
const NaiveV& naiveV) {
411 Index Ucols = m_computeThinU ? diagSize() :
rows();
412 m_matrixU = MatrixX::Identity(
rows(), Ucols);
413 m_matrixU.topLeftCorner(diagSize(), diagSize()) =
414 naiveV.template cast<Scalar>().topLeftCorner(diagSize(), diagSize());
417 m_matrixU.topLeftCorner(householderU.cols(), diagSize()).applyOnTheLeft(householderU);
419 m_matrixU.applyOnTheLeft(householderU);
422 Index Vcols = m_computeThinV ? diagSize() :
cols();
423 m_matrixV = MatrixX::Identity(
cols(), Vcols);
424 m_matrixV.topLeftCorner(diagSize(), diagSize()) =
425 naiveU.template cast<Scalar>().topLeftCorner(diagSize(), diagSize());
428 m_matrixV.topLeftCorner(householderV.cols(), diagSize()).applyOnTheLeft(householderV);
430 m_matrixV.applyOnTheLeft(householderV);
442 template <
typename MatrixType,
int Options>
453 Index k1 = 0, k2 = 0;
455 if ((
A.col(
j).head(n1).array() !=
Literal(0)).any()) {
456 A1.col(k1) =
A.col(
j).head(n1);
457 B1.row(k1) =
B.row(
j);
460 if ((
A.col(
j).tail(n2).array() !=
Literal(0)).any()) {
461 A2.col(k2) =
A.col(
j).tail(n2);
462 B2.row(k2) =
B.row(
j);
467 A.topRows(n1).noalias() = A1.leftCols(k1) * B1.topRows(k1);
468 A.bottomRows(n2).noalias() = A2.leftCols(k2) * B2.topRows(k2);
471 tmp.noalias() =
A *
B;
476 template <
typename MatrixType,
int Options>
477 template <
typename SVDType>
480 svd.compute(m_computed.block(firstCol, firstCol,
n + 1,
n));
484 m_naiveU.block(firstCol, firstCol,
n + 1,
n + 1).real() =
svd.matrixU();
486 m_naiveU.row(0).segment(firstCol,
n + 1).real() =
svd.matrixU().row(0);
487 m_naiveU.row(1).segment(firstCol,
n + 1).real() =
svd.matrixU().row(
n);
489 if (m_compV) m_naiveV.block(firstRowW, firstColW,
n,
n).real() =
svd.matrixV();
490 m_computed.block(firstCol + shift, firstCol + shift,
n + 1,
n).setZero();
491 m_computed.diagonal().segment(firstCol + shift,
n) =
svd.singularValues().head(
n);
507 template <
typename MatrixType,
int Options>
513 const Index n = lastCol - firstCol + 1;
523 if (
n < m_algoswap) {
527 computeBaseCase(baseSvd,
n, firstCol, firstRowW, firstColW, shift);
530 computeBaseCase(baseSvd,
n, firstCol, firstRowW, firstColW, shift);
535 alphaK = m_computed(firstCol +
k, firstCol +
k);
536 betaK = m_computed(firstCol +
k + 1, firstCol +
k);
540 divide(
k + 1 + firstCol, lastCol,
k + 1 + firstRowW,
k + 1 + firstColW, shift);
542 divide(firstCol,
k - 1 + firstCol, firstRowW, firstColW + 1, shift + 1);
546 lambda = m_naiveU(firstCol +
k, firstCol +
k);
547 phi = m_naiveU(firstCol +
k + 1, lastCol + 1);
549 lambda = m_naiveU(1, firstCol +
k);
550 phi = m_naiveU(0, lastCol + 1);
554 l = m_naiveU.row(firstCol +
k).segment(firstCol,
k);
555 f = m_naiveU.row(firstCol +
k + 1).segment(firstCol +
k + 1,
n -
k - 1);
557 l = m_naiveU.row(1).segment(firstCol,
k);
558 f = m_naiveU.row(0).segment(firstCol +
k + 1,
n -
k - 1);
560 if (m_compV) m_naiveV(firstRowW +
k, firstColW) =
Literal(1);
561 if (r0 < considerZero) {
565 c0 = alphaK *
lambda / r0;
566 s0 = betaK * phi / r0;
569 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
576 MatrixXr q1(m_naiveU.col(firstCol +
k).segment(firstCol,
k + 1));
578 for (
Index i = firstCol +
k - 1;
i >= firstCol;
i--)
579 m_naiveU.col(
i + 1).segment(firstCol,
k + 1) = m_naiveU.col(
i).segment(firstCol,
k + 1);
581 m_naiveU.col(firstCol).segment(firstCol,
k + 1) = (q1 * c0);
583 m_naiveU.col(lastCol + 1).segment(firstCol,
k + 1) = (q1 * (-s0));
585 m_naiveU.col(firstCol).segment(firstCol +
k + 1,
n -
k) =
586 m_naiveU.col(lastCol + 1).segment(firstCol +
k + 1,
n -
k) * s0;
588 m_naiveU.col(lastCol + 1).segment(firstCol +
k + 1,
n -
k) *= c0;
592 for (
Index i = firstCol +
k - 1;
i >= firstCol;
i--) m_naiveU(0,
i + 1) = m_naiveU(0,
i);
594 m_naiveU(0, firstCol) = (q1 * c0);
596 m_naiveU(0, lastCol + 1) = (q1 * (-s0));
598 m_naiveU(1, firstCol) = m_naiveU(1, lastCol + 1) * s0;
600 m_naiveU(1, lastCol + 1) *= c0;
601 m_naiveU.row(1).segment(firstCol + 1,
k).setZero();
602 m_naiveU.row(0).segment(firstCol +
k + 1,
n -
k - 1).setZero();
605 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
611 m_computed(firstCol + shift, firstCol + shift) = r0;
612 m_computed.col(firstCol + shift).segment(firstCol + shift + 1,
k) = alphaK * l.transpose().real();
613 m_computed.col(firstCol + shift).segment(firstCol + shift +
k + 1,
n -
k - 1) = betaK *
f.transpose().real();
615 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
616 ArrayXr tmp1 = (m_computed.block(firstCol + shift, firstCol + shift,
n,
n)).jacobiSvd().singularValues();
619 deflation(firstCol, lastCol,
k, firstRowW, firstColW, shift);
620 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
621 ArrayXr tmp2 = (m_computed.block(firstCol + shift, firstCol + shift,
n,
n)).jacobiSvd().singularValues();
622 std::cout <<
"\n\nj1 = " << tmp1.transpose().format(bdcsvdfmt) <<
"\n";
623 std::cout <<
"j2 = " << tmp2.transpose().format(bdcsvdfmt) <<
"\n\n";
624 std::cout <<
"err: " << ((tmp1 - tmp2).
abs() > 1
e-12 * tmp2.abs()).
transpose() <<
"\n";
625 static int count = 0;
626 std::cout <<
"# " << ++count <<
"\n\n";
635 computeSVDofM(firstCol + shift,
n, UofSVD, singVals, VofSVD);
637 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
643 structured_update(m_naiveU.block(firstCol, firstCol,
n + 1,
n + 1), UofSVD, (
n + 2) / 2);
646 tmp.noalias() = m_naiveU.middleCols(firstCol,
n + 1) * UofSVD;
647 m_naiveU.middleCols(firstCol,
n + 1) =
tmp;
650 if (m_compV) structured_update(m_naiveV.block(firstRowW, firstColW,
n,
n), VofSVD, (
n + 1) / 2);
652 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
658 m_computed.block(firstCol + shift, firstCol + shift,
n,
n).setZero();
659 m_computed.block(firstCol + shift, firstCol + shift,
n,
n).diagonal() = singVals;
671 template <
typename MatrixType,
int Options>
676 ArrayRef col0 = m_computed.col(firstCol).segment(firstCol,
n);
677 m_workspace.head(
n) = m_computed.block(firstCol, firstCol,
n,
n).diagonal();
683 U.resize(
n + 1,
n + 1);
684 if (m_compV)
V.resize(
n,
n);
686 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
687 if (col0.hasNaN() ||
diag.hasNaN()) std::cout <<
"\n\nHAS NAN\n\n";
700 if (
abs(col0(
k)) > considerZero) m_workspaceI(
m++) =
k;
707 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
708 std::cout <<
"computeSVDofM using:\n";
709 std::cout <<
" z: " << col0.transpose() <<
"\n";
710 std::cout <<
" d: " <<
diag.transpose() <<
"\n";
714 computeSingVals(col0,
diag, perm, singVals, shifts,
mus);
716 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
718 << (m_computed.block(firstCol, firstCol,
n,
n)).jacobiSvd().singularValues().transpose().reverse()
720 std::cout <<
" sing-val: " << singVals.transpose() <<
"\n";
721 std::cout <<
" mu: " <<
mus.transpose() <<
"\n";
722 std::cout <<
" shift: " << shifts.transpose() <<
"\n";
725 std::cout <<
"\n\n mus: " <<
mus.head(
actual_n).transpose() <<
"\n\n";
726 std::cout <<
" check1 (expect0) : "
727 << ((singVals.array() - (shifts +
mus)) / singVals.array()).head(
actual_n).transpose() <<
"\n\n";
729 std::cout <<
" check2 (>0) : " << ((singVals.array() -
diag) / singVals.array()).head(
actual_n).transpose()
735 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
742 perturbCol0(col0,
diag, perm, singVals, shifts,
mus, zhat);
743 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
744 std::cout <<
" zhat: " << zhat.transpose() <<
"\n";
747 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
751 computeSingVecs(zhat,
diag, perm, singVals, shifts,
mus,
U,
V);
753 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
754 std::cout <<
"U^T U: " << (
U.transpose() *
U -
MatrixXr(MatrixXr::Identity(
U.cols(),
U.cols()))).norm() <<
"\n";
755 std::cout <<
"V^T V: " << (
V.transpose() *
V -
MatrixXr(MatrixXr::Identity(
V.cols(),
V.cols()))).norm() <<
"\n";
758 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
772 if (singVals(
i) > singVals(
i + 1)) {
774 swap(singVals(
i), singVals(
i + 1));
775 U.col(
i).swap(
U.col(
i + 1));
776 if (m_compV)
V.col(
i).swap(
V.col(
i + 1));
780 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
782 bool singular_values_sorted =
784 if (!singular_values_sorted)
785 std::cout <<
"Singular values are not sorted: " << singVals.segment(1,
actual_n).transpose() <<
"\n";
792 singVals.head(
actual_n).reverseInPlace();
793 U.leftCols(
actual_n).rowwise().reverseInPlace();
794 if (m_compV)
V.leftCols(
actual_n).rowwise().reverseInPlace();
796 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
798 std::cout <<
" * j: " << jsvd.
singularValues().transpose() <<
"\n\n";
799 std::cout <<
" * sing-val: " << singVals.transpose() <<
"\n";
804 template <
typename MatrixType,
int Options>
814 res += (col0(
j) / (diagShifted(
j) -
mu)) * (col0(
j) / (
diag(
j) + shift +
mu));
819 template <
typename MatrixType,
int Options>
836 singVals(
k) =
k == 0 ? col0(0) :
diag(
k);
838 shifts(
k) =
k == 0 ? col0(0) :
diag(
k);
862 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
863 std::cout <<
"right-left = " << right - left <<
"\n";
867 std::cout <<
" = " << secularEq(left +
RealScalar(0.000001) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
868 << secularEq(left +
RealScalar(0.1) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
869 << secularEq(left +
RealScalar(0.2) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
870 << secularEq(left +
RealScalar(0.3) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
871 << secularEq(left +
RealScalar(0.4) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
872 << secularEq(left +
RealScalar(0.49) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
873 << secularEq(left +
RealScalar(0.5) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
874 << secularEq(left +
RealScalar(0.51) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
875 << secularEq(left +
RealScalar(0.6) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
876 << secularEq(left +
RealScalar(0.7) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
877 << secularEq(left +
RealScalar(0.8) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
878 << secularEq(left +
RealScalar(0.9) * (right - left), col0,
diag, perm,
diag, 0) <<
" "
879 << secularEq(left +
RealScalar(0.999999) * (right - left), col0,
diag, perm,
diag, 0) <<
"\n";
885 diagShifted =
diag - shift;
892 RealScalar fMidShifted = secularEq(midShifted, col0,
diag, perm, diagShifted, shift);
893 if (fMidShifted > 0) {
895 shift = fMidShifted >
Literal(0) ? left : right;
896 diagShifted =
diag - shift;
906 muCur = right - left;
914 RealScalar fPrev = secularEq(muPrev, col0,
diag, perm, diagShifted, shift);
915 RealScalar fCur = secularEq(muCur, col0,
diag, perm, diagShifted, shift);
916 if (
abs(fPrev) <
abs(fCur)) {
923 bool useBisection = fPrev * fCur >
Literal(0);
925 abs(muCur - muPrev) >
935 RealScalar fZero = secularEq(muZero, col0,
diag, perm, diagShifted, shift);
937 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
949 if (
abs(fCur) >
abs(fPrev)) useBisection =
true;
954 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
955 std::cout <<
"useBisection for k = " <<
k <<
", actual_n = " <<
actual_n <<
"\n";
975 leftShifted = -(right - left) *
RealScalar(0.51);
983 RealScalar fLeft = secularEq(leftShifted, col0,
diag, perm, diagShifted, shift);
986 #if defined EIGEN_BDCSVD_DEBUG_VERBOSE || defined EIGEN_BDCSVD_SANITY_CHECKS || defined EIGEN_INTERNAL_DEBUGGING
987 RealScalar fRight = secularEq(rightShifted, col0,
diag, perm, diagShifted, shift);
990 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
992 std::cout <<
"f(" << leftShifted <<
") =" << fLeft <<
" ; " << left <<
" " << shift <<
" " << right <<
"\n";
996 std::cout <<
"f(" << rightShifted <<
") =" << fRight <<
" ; " << left <<
" " << shift <<
" " << right <<
"\n";
1000 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1001 if (!(fLeft * fRight < 0)) {
1002 std::cout <<
"f(leftShifted) using leftShifted=" << leftShifted
1003 <<
" ; diagShifted(1:10):" << diagShifted.head(10).transpose() <<
"\n ; "
1004 <<
"left==shift=" <<
bool(left == shift) <<
" ; left-shift = " << (left - shift) <<
"\n";
1005 std::cout <<
"k=" <<
k <<
", " << fLeft <<
" * " << fRight <<
" == " << fLeft * fRight <<
" ; "
1006 <<
"[" << left <<
" .. " << right <<
"] -> [" << leftShifted <<
" " << rightShifted
1007 <<
"], shift=" << shift <<
" , f(right)=" << secularEq(0, col0,
diag, perm, diagShifted, shift)
1008 <<
" == " << secularEq(right, col0,
diag, perm,
diag, 0) <<
" == " << fRight <<
"\n";
1015 numext::maxi<RealScalar>(
abs(leftShifted),
abs(rightShifted))) {
1017 fMid = secularEq(midShifted, col0,
diag, perm, diagShifted, shift);
1020 if (fLeft * fMid <
Literal(0)) {
1021 rightShifted = midShifted;
1023 leftShifted = midShifted;
1027 muCur = (leftShifted + rightShifted) /
Literal(2);
1039 singVals[
k] = shift + muCur;
1043 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1045 std::cout <<
"found " << singVals[
k] <<
" == " << shift <<
" + " << muCur <<
" from " <<
diag(
k) <<
" .. "
1046 <<
diag(
k + 1) <<
"\n";
1048 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1062 template <
typename MatrixType,
int Options>
1073 Index lastIdx = perm(
m - 1);
1081 RealScalar prod = (singVals(lastIdx) + dk) * (
mus(lastIdx) + (shifts(lastIdx) - dk));
1082 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1084 std::cout <<
"k = " <<
k <<
" ; z(k)=" << col0(
k) <<
", diag(k)=" << dk <<
"\n";
1085 std::cout <<
"prod = "
1086 <<
"(" << singVals(lastIdx) <<
" + " << dk <<
") * (" <<
mus(lastIdx) <<
" + (" << shifts(lastIdx)
1087 <<
" - " << dk <<
"))"
1089 std::cout <<
" = " << singVals(lastIdx) + dk <<
" * " <<
mus(lastIdx) + (shifts(lastIdx) - dk) <<
"\n";
1094 for (
Index l = 0; l <
m; ++l) {
1097 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1098 if (
i >=
k && (l == 0 || l - 1 >=
m)) {
1099 std::cout <<
"Error in perturbCol0\n";
1100 std::cout <<
" " <<
k <<
"/" <<
n <<
" " << l <<
"/" <<
m <<
" " <<
i <<
"/" <<
n <<
" ; " << col0(
k)
1101 <<
" " <<
diag(
k) <<
" "
1103 std::cout <<
" " <<
diag(
i) <<
"\n";
1106 <<
"j=" <<
j <<
"\n";
1109 Index j = i < k ? i : l > 0 ? perm(l - 1) :
i;
1110 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1112 std::cout <<
"k=" <<
k <<
", i=" <<
i <<
", l=" << l <<
", perm.size()=" << perm.size() <<
"\n";
1116 prod *= ((singVals(
j) + dk) / ((
diag(
i) + dk))) * ((
mus(
j) + (shifts(
j) - dk)) / ((
diag(
i) - dk)));
1117 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1120 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1125 << ((singVals(
j) + dk) * (
mus(
j) + (shifts(
j) - dk))) / ((
diag(
i) + dk) * (
diag(
i) - dk))
1126 <<
" == (" << (singVals(
j) + dk) <<
" * " << (
mus(
j) + (shifts(
j) - dk)) <<
") / ("
1127 << (
diag(
i) + dk) <<
" * " << (
diag(
i) - dk) <<
")\n";
1131 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1132 std::cout <<
"zhat(" <<
k <<
") = sqrt( " <<
prod <<
") ; " << (singVals(lastIdx) + dk) <<
" * "
1133 <<
mus(lastIdx) + shifts(lastIdx) <<
" - " << dk <<
"\n";
1136 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1145 template <
typename MatrixType,
int Options>
1154 U.col(
k) = VectorType::Unit(
n + 1,
k);
1155 if (m_compV)
V.col(
k) = VectorType::Unit(
n,
k);
1158 for (
Index l = 0; l <
m; ++l) {
1163 U.col(
k).normalize();
1167 for (
Index l = 1; l <
m; ++l) {
1172 V.col(
k).normalize();
1176 U.col(
n) = VectorType::Unit(
n + 1,
n);
1182 template <
typename MatrixType,
int Options>
1201 m_naiveU.middleRows(firstCol,
size + 1).applyOnTheRight(firstCol, firstCol +
i,
J);
1203 m_naiveU.applyOnTheRight(firstCol, firstCol +
i,
J);
1209 template <
typename MatrixType,
int Options>
1220 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1221 std::cout <<
"deflation 4.4: " <<
i <<
"," <<
j <<
" -> " <<
c <<
" " <<
s <<
" " <<
r <<
" ; "
1222 << m_computed(firstColm +
i - 1, firstColm) <<
" " << m_computed(firstColm +
i, firstColm) <<
" "
1223 << m_computed(firstColm +
i + 1, firstColm) <<
" " << m_computed(firstColm +
i + 2, firstColm) <<
"\n";
1224 std::cout << m_computed(firstColm +
i - 1, firstColm +
i - 1) <<
" " << m_computed(firstColm +
i, firstColm +
i)
1225 <<
" " << m_computed(firstColm +
i + 1, firstColm +
i + 1) <<
" "
1226 << m_computed(firstColm +
i + 2, firstColm +
i + 2) <<
"\n";
1229 m_computed(firstColm +
j, firstColm +
j) = m_computed(firstColm +
i, firstColm +
i);
1234 m_computed(firstColm +
j, firstColm) =
r;
1235 m_computed(firstColm +
j, firstColm +
j) = m_computed(firstColm +
i, firstColm +
i);
1236 m_computed(firstColm +
i, firstColm) =
Literal(0);
1240 m_naiveU.middleRows(firstColu,
size + 1).applyOnTheRight(firstColu +
j, firstColu +
i,
J);
1242 m_naiveU.applyOnTheRight(firstColu +
j, firstColu +
i,
J);
1243 if (m_compV) m_naiveV.middleRows(firstRowW,
size).applyOnTheRight(firstColW +
j, firstColW +
i,
J);
1247 template <
typename MatrixType,
int Options>
1252 const Index length = lastCol + 1 - firstCol;
1264 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1270 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1271 std::cout <<
"\ndeflate:" <<
diag.head(
k + 1).transpose() <<
" | "
1272 <<
diag.segment(
k + 1, length -
k - 1).transpose() <<
"\n";
1276 if (
diag(0) < epsilon_coarse) {
1277 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1278 std::cout <<
"deflation 4.1, because " <<
diag(0) <<
" < " << epsilon_coarse <<
"\n";
1280 diag(0) = epsilon_coarse;
1285 if (
abs(col0(
i)) < epsilon_strict) {
1286 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1287 std::cout <<
"deflation 4.2, set z(" <<
i <<
") to zero because " <<
abs(col0(
i)) <<
" < " << epsilon_strict
1288 <<
" (diag(" <<
i <<
")=" <<
diag(
i) <<
")\n";
1295 if (
diag(
i) < epsilon_coarse) {
1296 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1297 std::cout <<
"deflation 4.3, cancel z(" <<
i <<
")=" << col0(
i) <<
" because diag(" <<
i <<
")=" <<
diag(
i)
1298 <<
" < " << epsilon_coarse <<
"\n";
1300 deflation43(firstCol, shift,
i, length);
1303 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1308 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1309 std::cout <<
"to be sorted: " <<
diag.transpose() <<
"\n\n";
1310 std::cout <<
" : " << col0.transpose() <<
"\n\n";
1315 const bool total_deflation = (col0.tail(length - 1).array().abs() < considerZero).
all();
1319 Index* permutation = m_workspaceI.data();
1326 if (
diag(
i) < considerZero) permutation[
p++] =
i;
1329 for (;
p < length; ++
p) {
1331 permutation[
p] =
j++;
1332 else if (
j >= length)
1333 permutation[
p] =
i++;
1335 permutation[
p] =
j++;
1337 permutation[
p] =
i++;
1342 if (total_deflation) {
1343 for (
Index i = 1;
i < length; ++
i) {
1346 permutation[
i - 1] = permutation[
i];
1348 permutation[
i - 1] = 0;
1355 Index* realInd = m_workspaceI.data() + length;
1356 Index* realCol = m_workspaceI.data() + 2 * length;
1358 for (
int pos = 0; pos < length; pos++) {
1363 for (
Index i = total_deflation ? 0 : 1;
i < length;
i++) {
1364 const Index pi = permutation[length - (total_deflation ?
i + 1 :
i)];
1370 if (
i != 0 &&
J != 0)
swap(col0(
i), col0(
J));
1374 m_naiveU.col(firstCol +
i)
1375 .segment(firstCol, length + 1)
1376 .swap(m_naiveU.col(firstCol +
J).segment(firstCol, length + 1));
1378 m_naiveU.col(firstCol +
i).segment(0, 2).swap(m_naiveU.col(firstCol +
J).segment(0, 2));
1380 m_naiveV.col(firstColW +
i)
1381 .segment(firstRowW, length)
1382 .swap(m_naiveV.col(firstColW +
J).segment(firstRowW, length));
1385 const Index realI = realInd[
i];
1392 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1393 std::cout <<
"sorted: " <<
diag.transpose().format(bdcsvdfmt) <<
"\n";
1394 std::cout <<
" : " << col0.transpose() <<
"\n\n";
1401 while (
i > 0 && (
diag(
i) < considerZero ||
abs(col0(
i)) < considerZero)) --
i;
1404 if ((
diag(
i) -
diag(
i - 1)) < epsilon_strict) {
1405 #ifdef EIGEN_BDCSVD_DEBUG_VERBOSE
1406 std::cout <<
"deflation 4.4 with i = " <<
i <<
" because " <<
diag(
i) <<
" - " <<
diag(
i - 1)
1407 <<
" == " << (
diag(
i) -
diag(
i - 1)) <<
" < " << epsilon_strict <<
"\n";
1410 " diagonal entries are not properly sorted");
1411 deflation44(firstCol, firstCol + shift, firstRowW, firstColW,
i,
i - 1, length);
1415 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1419 #ifdef EIGEN_BDCSVD_SANITY_CHECKS
1432 template <
typename Derived>
1433 template <
int Options>
1444 template <
typename Derived>
1445 template <
int Options>
1447 unsigned int computationOptions)
const {
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar conj(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:133
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
cout<< "The eigenvalues of A are:"<< endl<< ces.eigenvalues()<< endl;cout<< "The matrix of eigenvectors, V, is:"<< endl<< ces.eigenvectors()<< endl<< endl;complex< float > lambda
Definition: ComplexEigenSolver_compute.cpp:9
Array< double, 1, 3 > e(1./3., 0.5, 2.)
MatrixXcd V
Definition: EigenSolver_EigenSolver_MatrixType.cpp:15
cout<< "Here is the matrix m:"<< endl<< m<< endl;JacobiSVD< MatrixXf, ComputeThinU|ComputeThinV > svd(m)
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
#define EIGEN_DEPRECATED
Definition: Macros.h:931
#define eigen_internal_assert(x)
Definition: Macros.h:916
#define eigen_assert(x)
Definition: Macros.h:910
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
Definition: PartialRedux_count.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Scalar * b
Definition: benchVecAdd.cpp:17
NumTraits< Scalar >::Real RealScalar
Definition: bench_gemm.cpp:46
Matrix< SCALARB, Dynamic, Dynamic, opt_B > B
Definition: bench_gemm.cpp:48
class Bidiagonal Divide and Conquer SVD
Definition: BDCSVD.h:85
Index m_nRec
Definition: BDCSVD.h:241
void allocate(Index rows, Index cols, unsigned int computationOptions)
Definition: BDCSVD.h:268
void structured_update(Block< MatrixXr, Dynamic, Dynamic > A, const MatrixXr &B, Index n1)
Definition: BDCSVD.h:443
void copyUV(const HouseholderU &householderU, const HouseholderV &householderV, const NaiveU &naiveU, const NaiveV &naivev)
Definition: BDCSVD.h:407
bool m_isTranspose
Definition: BDCSVD.h:245
Ref< ArrayXi > IndicesRef
Definition: BDCSVD.h:123
Base::MatrixUType MatrixUType
Definition: BDCSVD.h:113
BDCSVD & compute(const MatrixType &matrix)
Method performing the decomposition of given matrix. Computes Thin/Full unitaries U/V if specified us...
Definition: BDCSVD.h:194
ArrayXi m_workspaceI
Definition: BDCSVD.h:243
Base::SingularValuesType SingularValuesType
Definition: BDCSVD.h:115
EIGEN_DEPRECATED BDCSVD(const MatrixType &matrix, unsigned int computationOptions)
Constructor performing the decomposition of given matrix using specified options for computing unitar...
Definition: BDCSVD.h:182
BDCSVD & compute_impl(const MatrixType &matrix, unsigned int computationOptions)
Definition: BDCSVD.h:308
Base::RealScalar RealScalar
Definition: BDCSVD.h:97
void computeBaseCase(SVDType &svd, Index n, Index firstCol, Index firstRowW, Index firstColW, Index shift)
Definition: BDCSVD.h:478
NumTraits< RealScalar >::Literal Literal
Definition: BDCSVD.h:98
bool m_useQrDecomp
Definition: BDCSVD.h:245
Base::Index Index
Definition: BDCSVD.h:99
Array< Index, 1, Dynamic > ArrayXi
Definition: BDCSVD.h:121
void divide(Index firstCol, Index lastCol, Index firstRowW, Index firstColW, Index shift)
Definition: BDCSVD.h:508
void computeSVDofM(Index firstCol, Index n, MatrixXr &U, VectorType &singVals, MatrixXr &V)
Definition: BDCSVD.h:672
@ QRDecomposition
Definition: BDCSVD.h:102
@ DiagSizeAtCompileTime
Definition: BDCSVD.h:106
@ ComputationOptions
Definition: BDCSVD.h:103
@ MaxColsAtCompileTime
Definition: BDCSVD.h:108
@ RowsAtCompileTime
Definition: BDCSVD.h:104
@ ColsAtCompileTime
Definition: BDCSVD.h:105
@ MaxDiagSizeAtCompileTime
Definition: BDCSVD.h:109
@ MatrixOptions
Definition: BDCSVD.h:110
@ MaxRowsAtCompileTime
Definition: BDCSVD.h:107
@ Options
Definition: BDCSVD.h:101
static RealScalar secularEq(RealScalar x, const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, const ArrayRef &diagShifted, RealScalar shift)
Definition: BDCSVD.h:805
MatrixType_ MatrixType
Definition: BDCSVD.h:95
Array< RealScalar, Dynamic, 1 > ArrayXr
Definition: BDCSVD.h:120
void computeSingVecs(const ArrayRef &zhat, const ArrayRef &diag, const IndicesRef &perm, const VectorType &singVals, const ArrayRef &shifts, const ArrayRef &mus, MatrixXr &U, MatrixXr &V)
Definition: BDCSVD.h:1146
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: EigenBase.h:61
Matrix< RealScalar, Dynamic, Dynamic, ColMajor > MatrixXr
Definition: BDCSVD.h:118
BDCSVD(const MatrixType &matrix)
Constructor performing the decomposition of given matrix, using the custom options specified with the...
Definition: BDCSVD.h:166
void setSwitchSize(int s)
Definition: BDCSVD.h:210
SVDBase< BDCSVD > Base
Definition: BDCSVD.h:86
void deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift)
Definition: BDCSVD.h:1248
MatrixX copyWorkspace
Definition: BDCSVD.h:249
JacobiSVD< MatrixType, ComputationOptions > smallSvd
Definition: BDCSVD.h:246
void perturbCol0(const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, const VectorType &singVals, const ArrayRef &shifts, const ArrayRef &mus, ArrayRef zhat)
Definition: BDCSVD.h:1063
MatrixXr m_computed
Definition: BDCSVD.h:240
Matrix< RealScalar, Dynamic, 1 > VectorType
Definition: BDCSVD.h:119
EIGEN_DEPRECATED BDCSVD(Index rows, Index cols, unsigned int computationOptions)
Default Constructor with memory preallocation.
Definition: BDCSVD.h:156
void deflation43(Index firstCol, Index shift, Index i, Index size)
Definition: BDCSVD.h:1183
MatrixXr m_naiveV
Definition: BDCSVD.h:239
int m_numIters
Definition: BDCSVD.h:263
~BDCSVD()
Definition: BDCSVD.h:187
bool m_compU
Definition: BDCSVD.h:245
int m_algoswap
Definition: BDCSVD.h:244
BDCSVD()
Default Constructor.
Definition: BDCSVD.h:130
Matrix< Scalar, Dynamic, Dynamic, ColMajor > MatrixX
Definition: BDCSVD.h:117
MatrixXr m_naiveU
Definition: BDCSVD.h:239
Base::MatrixVType MatrixVType
Definition: BDCSVD.h:114
HouseholderQR< MatrixX > qrDecomp
Definition: BDCSVD.h:247
Base::Scalar Scalar
Definition: BDCSVD.h:96
void computeSingVals(const ArrayRef &col0, const ArrayRef &diag, const IndicesRef &perm, VectorType &singVals, ArrayRef shifts, ArrayRef mus)
Definition: BDCSVD.h:820
bool m_compV
Definition: BDCSVD.h:245
ArrayXr m_workspace
Definition: BDCSVD.h:242
MatrixX reducedTriangle
Definition: BDCSVD.h:250
EIGEN_DEPRECATED BDCSVD & compute(const MatrixType &matrix, unsigned int computationOptions)
Method performing the decomposition of given matrix, as specified by the computationOptions parameter...
Definition: BDCSVD.h:205
void deflation44(Index firstColu, Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size)
Definition: BDCSVD.h:1210
Ref< ArrayXr > ArrayRef
Definition: BDCSVD.h:122
internal::UpperBidiagonalization< MatrixX > bid
Definition: BDCSVD.h:248
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: EigenBase.h:59
BDCSVD(Index rows, Index cols)
Default Constructor with memory preallocation.
Definition: BDCSVD.h:138
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:110
Expression of a diagonal/subdiagonal/superdiagonal in a matrix.
Definition: Diagonal.h:68
Householder QR decomposition of a matrix.
Definition: HouseholderQR.h:59
Rotation given by a cosine-sine pair.
Definition: Jacobi.h:38
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:96
BDCSVD< PlainObject, Options > bdcSvd() const
EIGEN_DEVICE_FUNC constexpr EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
Definition: PlainObjectBase.h:294
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: PlainObjectBase.h:191
A matrix or vector expression mapping an existing expression.
Definition: Ref.h:264
Base class of SVD algorithms.
Definition: SVDBase.h:119
Index cols() const
Definition: SVDBase.h:278
internal::make_proper_matrix_type< Scalar, RowsAtCompileTime, MatrixUColsAtCompileTime, MatrixOptions, MaxRowsAtCompileTime, MatrixUMaxColsAtCompileTime >::type MatrixUType
Definition: SVDBase.h:153
ComputationInfo m_info
Definition: SVDBase.h:334
bool m_computeThinU
Definition: SVDBase.h:336
const SingularValuesType & singularValues() const
Definition: SVDBase.h:200
NumTraits< typename MatrixType::Scalar >::Real RealScalar
Definition: SVDBase.h:126
bool computeV() const
Definition: SVDBase.h:275
bool m_isInitialized
Definition: SVDBase.h:335
unsigned int m_computationOptions
Definition: SVDBase.h:338
MatrixVType m_matrixV
Definition: SVDBase.h:332
bool computeU() const
Definition: SVDBase.h:273
internal::plain_diag_type< MatrixType, RealScalar >::type SingularValuesType
Definition: SVDBase.h:158
internal::make_proper_matrix_type< Scalar, ColsAtCompileTime, MatrixVColsAtCompileTime, MatrixOptions, MaxColsAtCompileTime, MatrixVMaxColsAtCompileTime >::type MatrixVType
Definition: SVDBase.h:156
@ MatrixOptions
Definition: SVDBase.h:141
@ ColsAtCompileTime
Definition: SVDBase.h:136
@ DiagSizeAtCompileTime
Definition: SVDBase.h:137
@ MaxRowsAtCompileTime
Definition: SVDBase.h:138
@ MaxDiagSizeAtCompileTime
Definition: SVDBase.h:140
@ MaxColsAtCompileTime
Definition: SVDBase.h:139
@ RowsAtCompileTime
Definition: SVDBase.h:135
MatrixType::Scalar Scalar
Definition: SVDBase.h:125
Index m_nonzeroSingularValues
Definition: SVDBase.h:339
Index rows() const
Definition: SVDBase.h:277
SingularValuesType m_singularValues
Definition: SVDBase.h:333
bool m_computeThinV
Definition: SVDBase.h:337
Index diagSize() const
Definition: SVDBase.h:279
internal::traits< BDCSVD< MatrixType_, Options_ > >::MatrixType MatrixType
Definition: SVDBase.h:124
MatrixUType m_matrixU
Definition: SVDBase.h:331
Expression of a fixed-size or dynamic-size sub-vector.
Definition: VectorBlock.h:58
Definition: UpperBidiagonalization.h:24
Definition: matrices.h:74
Eigen::Map< Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor >, 0, Eigen::OuterStride<> > matrix(T *data, int rows, int cols, int stride)
Definition: common.h:85
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
static constexpr Eigen::internal::all_t all
Definition: IndexedViewHelper.h:86
@ Aligned
Definition: Constants.h:242
@ DisableQRDecomposition
Definition: Constants.h:429
@ InvalidInput
Definition: Constants.h:447
@ Success
Definition: Constants.h:440
@ NoConvergence
Definition: Constants.h:444
RealScalar s
Definition: level1_cplx_impl.h:130
EIGEN_BLAS_FUNC() swap(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
Definition: level1_impl.h:117
const Scalar * a
Definition: level2_cplx_impl.h:32
int * m
Definition: level2_cplx_impl.h:294
actual_n
Definition: level2_impl.h:445
const char const char const char * diag
Definition: level2_impl.h:86
char char char int int * k
Definition: level2_impl.h:374
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
@ QRPreconditionerBits
Definition: SVDBase.h:27
@ ComputationOptionsBits
Definition: SVDBase.h:29
constexpr int get_computation_options(int options)
Definition: SVDBase.h:34
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool equal_strict(const X &x, const Y &y)
Definition: Meta.h:571
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool() isfinite(const Eigen::bfloat16 &h)
Definition: BFloat16.h:752
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE std::enable_if_t< NumTraits< T >::IsSigned||NumTraits< T >::IsComplex, typename NumTraits< T >::Real > abs(const T &x)
Definition: MathFunctions.h:1355
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bool is_exactly_zero(const X &x)
Definition: Meta.h:592
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
const int Dynamic
Definition: Constants.h:25
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::enable_if_t< std::is_base_of< DenseBase< std::decay_t< DerivedA > >, std::decay_t< DerivedA > >::value &&std::is_base_of< DenseBase< std::decay_t< DerivedB > >, std::decay_t< DerivedB > >::value, void > swap(DerivedA &&a, DerivedB &&b)
Definition: DenseBase.h:655
const Product< Lhs, Rhs > prod(const Lhs &lhs, const Rhs &rhs)
Definition: evaluators.cpp:7
std::complex< double > mu
Definition: time_harmonic_fourier_decomposed_linear_elasticity/cylinder/cylinder.cc:52
double U
Swimming speed.
Definition: two_d_variable_diff_adapt.cc:53
void transpose()
Definition: skew_symmetric_matrix3.cpp:135
int c
Definition: calibrate.py:100
const Mdouble pi
Definition: ExtendedMath.h:23
Definition: Eigen_Colamd.h:49
void start(const unsigned &i)
(Re-)start i-th timer
Definition: oomph_utilities.cc:243
double Zero
Definition: pseudosolid_node_update_elements.cc:35
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43
list x
Definition: plotDoE.py:28
list mus
Definition: plotDoE.py:17
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Definition: EigenBase.h:64
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:217
MatrixType_ MatrixType
Definition: BDCSVD.h:50
Definition: ForwardDeclarations.h:21
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2