Give PartialPiv and other solvers an rvalue constructor for owning data
Describe the feature you would like to be implemented.
Most of the solvers have the option for inplace decomposition using Eigen::Ref. it would also be nice if the user passed a temporary to these solvers that the solver would know it could take ownership of the memory.
Would such a feature be useful for other users? Why?
Yes. In particular this is nice for when people know at what point a matrix is no longer needed and we just need its decomposition. For instance if a user had a flag for two different paths where one path needs the matrix and the other does not.
if (need_A_matrix_path) {
Eigen::PartialPivLU<Eigen::MatrixXd>(A);
// Other stuff...
} else {
// Here PartialPivLU would now own A's memory
Eigen::PartialPivLU<Eigen::MatrixXd>(std::move(A));
// Other stuff...
}
Any hints on how to implement the requested feature?
Stan math has a few type traits that can detect if a type inherits from Eigen::EigenBase or Eigen::EigenBase and those could be used to write the constructors using perfect forwarding.
This would require having a derived() && {} method as well. Something like this inside of EigenBase .
EIGEN_DEVICE_FUNC constexpr auto&& derived() && { return std::move(*static_cast<Derived*>(this)); }
The godbolt below has the type traits that are needed with some examples.
https://godbolt.org/z/cdM8eTae6With
the type traits the and derived() && {} member then the PartialPivLU class's constructor would look like the following
template <typename MatrixType, typename PermutationIndex> template <typename InputType, require_eigen_base_t<InputType>* = nullptr>
PartialPivLU<MatrixType,PermutationIndex>::PartialPivLU(InputType&& matrix) :
m_lu(std::forward(matrix).derived()),
m_p(m_lu.rows()),
m_rowsTranspositions(m_lu.rows()),
m_l1_norm(0),
m_det_p(0),
m_isInitialized(false) {
compute();
}
If there is interest in adding this I am happy to make a PR