From 924b55e9a92cc30f6caf9e53ea6c5ec96f275dc3 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Sat, 26 Sep 2009 22:48:16 -0400 Subject: [PATCH] when copying a ReturnByValue into a MatrixBase, first eval it to a PlainMatrixType. This allows to limit the number of instantiations of the big template method evalTo. Also allows to get rid of the dummy MatrixBase::resize(). See "TODO" comment. --- Eigen/src/Core/MatrixBase.h | 13 ------------- Eigen/src/Core/ReturnByValue.h | 18 ++++++++++++++++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 2c25576a9..4817f4773 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -190,19 +190,6 @@ template class MatrixBase * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */ int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } - /** Only plain matrices, not expressions may be resized; therefore the only useful resize method is - * Matrix::resize(). The present method only asserts that the new size equals the old size, and does - * nothing else. - */ - void resize(int size) - { ei_assert(size == this->size() && "MatrixBase::resize() does not actually allow to resize."); } - /** Only plain matrices, not expressions may be resized; therefore the only useful resize method is - * Matrix::resize(). The present method only asserts that the new size equals the old size, and does - * nothing else. - */ - void resize(int rows, int cols) - { ei_assert(rows == this->rows() && cols == this->cols() && "MatrixBase::resize() does not actually allow to resize."); } - #ifndef EIGEN_PARSED_BY_DOXYGEN /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h index 55652db48..297ed2456 100644 --- a/Eigen/src/Core/ReturnByValue.h +++ b/Eigen/src/Core/ReturnByValue.h @@ -65,8 +65,22 @@ template template Derived& MatrixBase::operator=(const ReturnByValue& other) { - other.evalTo(derived()); - return derived(); + // Here we evaluate to a temporary matrix tmp, which we then copy. The main purpose + // of this is to limit the number of instantiations of the template method evalTo(): + // we only instantiate for PlainMatrixType. + // Notice that this behaviour is specific to this operator in MatrixBase. The corresponding operator in class Matrix + // does not evaluate into a temporary first. + // TODO find a way to avoid evaluating into a temporary in the cases that matter. At least Block<> matters + // for the implementation of blocked algorithms. + // Should we: + // - try a trick like for the products, where the destination is abstracted as an array with stride? + // - or just add an operator in class Block, so we get a separate instantiation there (bad) but at least not more + // than that, and at least that's easy to make work? + // - or, since here we're talking about a compromise between code size and performance, let the user choose? + // Not obvious: many users will never find out about this feature, and it's hard to find a good API. + PlainMatrixType tmp; + other.evalTo(tmp); + return derived() = tmp; } #endif // EIGEN_RETURNBYVALUE_H