aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/SolveTriangular.h
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2011-02-01 17:21:20 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2011-02-01 17:21:20 +0100
commit8915d5bd2217d4ebbf8fe54ebd2dfbf3f0c420c4 (patch)
tree55266bf06b395a0d0bcea81f6dd4e3ea0e5d85e5 /Eigen/src/Core/SolveTriangular.h
parent59af20b390b5d55961e6bdc6c1dcc0733ac393d6 (diff)
fix 168 : now TriangularView::solve returns by value making TriangularView::solveInPlace less important.
Also fix the very outdated documentation of this function.
Diffstat (limited to 'Eigen/src/Core/SolveTriangular.h')
-rw-r--r--Eigen/src/Core/SolveTriangular.h71
1 files changed, 47 insertions, 24 deletions
diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h
index d186b5a4b..b59cdbf85 100644
--- a/Eigen/src/Core/SolveTriangular.h
+++ b/Eigen/src/Core/SolveTriangular.h
@@ -174,8 +174,6 @@ struct triangular_solver_selector<Lhs,Rhs,OnTheRight,Mode,CompleteUnrolling,1> {
/** "in-place" version of TriangularView::solve() where the result is written in \a other
*
- *
- *
* \warning The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
* This function will const_cast it, so constness isn't honored here.
*
@@ -205,43 +203,68 @@ void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived
/** \returns the product of the inverse of \c *this with \a other, \a *this being triangular.
*
+ * This function computes the inverse-matrix matrix product inverse(\c *this) * \a other if
+ * \a Side==OnTheLeft (the default), or the right-inverse-multiply \a other * inverse(\c *this) if
+ * \a Side==OnTheRight.
*
- *
- * This function computes the inverse-matrix matrix product inverse(\c *this) * \a other.
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the
* diagonal must be non zero). It works as a forward (resp. backward) substitution if \c *this
* is an upper (resp. lower) triangular matrix.
*
- * It is required that \c *this be marked as either an upper or a lower triangular matrix, which
- * can be done by marked(), and that is automatically the case with expressions such as those returned
- * by extract().
- *
* Example: \include MatrixBase_marked.cpp
* Output: \verbinclude MatrixBase_marked.out
*
- * This function is essentially a wrapper to the faster solveTriangularInPlace() function creating
- * a temporary copy of \a other, calling solveTriangularInPlace() on the copy and returning it.
- * Therefore, if \a other is not needed anymore, it is quite faster to call solveTriangularInPlace()
- * instead of solveTriangular().
+ * This function returns an expression of the inverse-multiply and can works in-place if it is assigned
+ * to the same matrix or vector \a other.
*
- * For users coming from BLAS, this function (and more specifically solveTriangularInPlace()) offer
+ * For users coming from BLAS, this function (and more specifically solveInPlace()) offer
* all the operations supported by the \c *TRSV and \c *TRSM BLAS routines.
*
- * \b Tips: to perform a \em "right-inverse-multiply" you can simply transpose the operation, e.g.:
- * \code
- * M * T^1 <=> T.transpose().solveInPlace(M.transpose());
- * \endcode
- *
* \sa TriangularView::solveInPlace()
*/
template<typename Derived, unsigned int Mode>
-template<int Side, typename RhsDerived>
-typename internal::plain_matrix_type_column_major<RhsDerived>::type
-TriangularView<Derived,Mode>::solve(const MatrixBase<RhsDerived>& rhs) const
+template<int Side, typename Other>
+const internal::triangular_solve_retval<Side,TriangularView<Derived,Mode>,Other>
+TriangularView<Derived,Mode>::solve(const MatrixBase<Other>& other) const
{
- typename internal::plain_matrix_type_column_major<RhsDerived>::type res(rhs);
- solveInPlace<Side>(res);
- return res;
+ return internal::triangular_solve_retval<Side,TriangularView,Other>(*this, other.derived());
}
+namespace internal {
+
+
+template<int Side, typename TriangularType, typename Rhs>
+struct traits<triangular_solve_retval<Side, TriangularType, Rhs> >
+{
+ typedef typename internal::plain_matrix_type_column_major<Rhs>::type ReturnType;
+};
+
+template<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval
+ : public ReturnByValue<triangular_solve_retval<Side, TriangularType, Rhs> >
+{
+ typedef typename remove_all<typename Rhs::Nested>::type RhsNestedCleaned;
+ typedef ReturnByValue<triangular_solve_retval> Base;
+ typedef typename Base::Index Index;
+
+ triangular_solve_retval(const TriangularType& tri, const Rhs& rhs)
+ : m_triangularMatrix(tri), m_rhs(rhs)
+ {}
+
+ inline Index rows() const { return m_rhs.rows(); }
+ inline Index cols() const { return m_rhs.cols(); }
+
+ template<typename Dest> inline void evalTo(Dest& dst) const
+ {
+ if(!(is_same<RhsNestedCleaned,Dest>::value && extract_data(dst) == extract_data(m_rhs)))
+ dst = m_rhs;
+ m_triangularMatrix.template solveInPlace<Side>(dst);
+ }
+
+ protected:
+ const TriangularType& m_triangularMatrix;
+ const typename Rhs::Nested m_rhs;
+};
+
+} // namespace internal
+
#endif // EIGEN_SOLVETRIANGULAR_H