21 throw std::invalid_argument(
"epsrel must be non-negative");
24 const Eigen::Index nr = J.rows();
25 const Eigen::Index nc = J.cols();
26 if ((nc == 0) || (nr == 0))
27 return Eigen::MatrixXd{};
30 Eigen::ColPivHouseholderQR<Eigen::MatrixXd> qr(J);
33 Eigen::MatrixXd R = qr.matrixR().topLeftCorner(nc, nc).template triangularView<Eigen::Upper>().toDenseMatrix();
36 const double r11 = std::abs(R(0, 0));
37 Eigen::Index rank = 0;
39 for (Eigen::Index k = 0; k < nc; ++k) {
40 if (std::abs(R(k, k)) > epsrel * r11) {
52 Eigen::MatrixXd cov_pivot = Eigen::MatrixXd::Zero(nc, nc);
56 const Eigen::MatrixXd R1 = R.topLeftCorner(rank, rank).template triangularView<Eigen::Upper>();
57 Eigen::MatrixXd invR1 = R1.inverse();
58 Eigen::MatrixXd cov1 = invR1 * invR1.transpose();
59 cov_pivot.topLeftCorner(rank, rank) = cov1;
64 const Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> P = qr.colsPermutation();
65 Eigen::MatrixXd cov = P * cov_pivot * P.transpose();