34 : m_Qs(mat.rows(), decomposition_size)
35 , m_Ts(decomposition_size)
36 , m_A_times_q(mat.rows())
39 PINOCCHIO_CHECK_INPUT_ARGUMENT(mat.rows() == mat.cols(),
"The input matrix is not square.");
40 PINOCCHIO_CHECK_INPUT_ARGUMENT(
41 decomposition_size >= 1,
"The size of the decomposition should be greater than one.");
42 PINOCCHIO_CHECK_INPUT_ARGUMENT(
43 decomposition_size <= mat.rows(),
44 "The size of the decomposition should not be larger than the number of rows.");
69 PINOCCHIO_CHECK_INPUT_ARGUMENT(A.rows() == A.cols(),
"The input matrix is not square.");
70 PINOCCHIO_CHECK_INPUT_ARGUMENT(
71 A.rows() == m_Qs.rows(),
"The input matrix is of correct size.");
73 const Eigen::DenseIndex decomposition_size = m_Ts.cols();
74 auto & alphas = m_Ts.diagonal();
75 auto & betas = m_Ts.subDiagonal();
77 m_Qs.col(0).fill(Scalar(1) / math::sqrt(Scalar(m_Qs.rows())));
80 for (k = 0; k < decomposition_size; ++k)
82 const auto q = m_Qs.col(k);
83 m_A_times_q.noalias() = A * q;
84 alphas[k] = q.dot(m_A_times_q);
86 if (k < decomposition_size - 1)
88 auto q_next = m_Qs.col(k + 1);
89 m_A_times_q -= alphas[k] * q;
92 m_A_times_q -= betas[k - 1] * m_Qs.col(k - 1);
100 betas[k] = m_A_times_q.norm();
101 if (betas[k] <= 1e2 * Eigen::NumTraits<Scalar>::epsilon())
107 q_next.noalias() = m_A_times_q / betas[k];
111 m_rank = math::max(Eigen::DenseIndex(1), k);
125 const Eigen::DenseIndex last_col_id = m_Ts.cols() - 1;
126 const auto & alphas = m_Ts.diagonal();
127 const auto & betas = m_Ts.subDiagonal();
129 PlainMatrix residual = A * m_Qs;
130 residual -= (m_Qs * m_Ts).eval();
132 const auto & q = m_Qs.col(last_col_id);
134 auto & tmp_vec = m_A_times_q;
135 tmp_vec.noalias() = A * q;
136 tmp_vec -= alphas[last_col_id] * q;
138 tmp_vec -= betas[last_col_id - 1] * m_Qs.col(last_col_id - 1);
140 residual.col(last_col_id) -= tmp_vec;