50 itkAssertOrThrowMacro(A.rows() > 0 && A.cols() > 0,
"QRDecomposition requires a non-empty matrix");
51 using RowMajor = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
52 using ColMajor = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic>;
53 const unsigned int rows = A.rows();
54 const unsigned int cols = A.cols();
56 Eigen::Map<const RowMajor> aMap(A.data_block(), rows, cols);
57 const Eigen::HouseholderQR<ColMajor> qr(aMap);
59 const ColMajor qFull = qr.householderQ();
60 const ColMajor rFull = qr.matrixQR().template triangularView<Eigen::Upper>();
62 m_Q.set_size(rows, rows);
63 Eigen::Map<RowMajor>(
m_Q.data_block(), rows, rows) = qFull;
64 m_R.set_size(rows, cols);
65 Eigen::Map<RowMajor>(
m_R.data_block(), rows, cols) = rFull;
90 using RowMajor = Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
91 using Vector = Eigen::Matrix<T, Eigen::Dynamic, 1>;
92 const unsigned int rows =
m_Q.rows();
93 const unsigned int cols =
m_R.cols();
94 itkAssertOrThrowMacro(b.size() == rows,
"QRDecomposition::Solve requires b length to match the row count");
97 itkGenericExceptionMacro(
"QRDecomposition::Solve supports square or overdetermined systems only (rows >= cols)");
100 Eigen::Map<const RowMajor> qMap(
m_Q.data_block(), rows, rows);
101 Eigen::Map<const RowMajor> rMap(
m_R.data_block(), rows, cols);
102 Eigen::Map<const Vector> bMap(b.data_block(), rows);
104 const Vector qtb = qMap.adjoint() * bMap;
105 const Vector x = rMap.topLeftCorner(cols, cols).template triangularView<Eigen::Upper>().solve(qtb.head(cols));
108 Eigen::Map<Vector>(out.data_block(), cols) = x;