From 29184ad27df1b398d4619dea78d0fb8aee445c1f Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Sat, 15 Mar 2008 11:05:38 +0000 Subject: [PATCH] - introduce sum() returning the sum of the coeffs of a vector - reimplement trace() as just diagonal().sum() - apidoc fixes --- Eigen/Core | 2 +- Eigen/src/Core/DiagonalCoeffs.h | 8 ++- Eigen/src/Core/Dot.h | 6 +- Eigen/src/Core/MatrixBase.h | 8 ++- Eigen/src/Core/MatrixStorage.h | 6 +- Eigen/src/Core/SumOfCoeffs.h | 102 ++++++++++++++++++++++++++++++++ Eigen/src/Core/Trace.h | 80 ------------------------- 7 files changed, 121 insertions(+), 91 deletions(-) create mode 100644 Eigen/src/Core/SumOfCoeffs.h delete mode 100644 Eigen/src/Core/Trace.h diff --git a/Eigen/Core b/Eigen/Core index a3dc23b2e..87b4c7766 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -24,7 +24,6 @@ namespace Eigen { #include "src/Core/Block.h" #include "src/Core/Minor.h" #include "src/Core/Transpose.h" -#include "src/Core/Trace.h" #include "src/Core/Dot.h" #include "src/Core/Random.h" #include "src/Core/Zero.h" @@ -32,6 +31,7 @@ namespace Eigen { #include "src/Core/DiagonalMatrix.h" #include "src/Core/DiagonalCoeffs.h" #include "src/Core/Identity.h" +#include "src/Core/SumOfCoeffs.h" #include "src/Core/Fuzzy.h" #include "src/Core/Map.h" #include "src/Core/IO.h" diff --git a/Eigen/src/Core/DiagonalCoeffs.h b/Eigen/src/Core/DiagonalCoeffs.h index 47d24fea4..69fab3066 100644 --- a/Eigen/src/Core/DiagonalCoeffs.h +++ b/Eigen/src/Core/DiagonalCoeffs.h @@ -27,10 +27,12 @@ /** \class DiagonalCoeffs * - * \brief Expression of the main diagonal of a square matrix + * \brief Expression of the main diagonal of a matrix * * \param MatrixType the type of the object in which we are taking the main diagonal * + * The matrix is not required to be square. + * * This class represents an expression of the main diagonal of a square matrix. * It is the return type of MatrixBase::diagonal() and most of the time this is * the only way it is used. @@ -84,7 +86,9 @@ template class DiagonalCoeffs const typename MatrixType::XprCopy m_matrix; }; -/** \returns an expression of the main diagonal of *this, which must be a square matrix. +/** \returns an expression of the main diagonal of the matrix \c *this + * + * \c *this is not required to be square. * * Example: \include MatrixBase_diagonal.cpp * Output: \verbinclude MatrixBase_diagonal.out diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index 4147dee56..33f69f987 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -82,12 +82,12 @@ MatrixBase::dot(const MatrixBase& other) const ei_dot_unroller > - ::run(*static_cast(this), other, res); + ::run(derived(), other, res); else { - res = (*this).coeff(0) * ei_conj(other.coeff(0)); + res = coeff(0) * ei_conj(other.coeff(0)); for(int i = 1; i < size(); i++) - res += (*this).coeff(i)* ei_conj(other.coeff(i)); + res += coeff(i)* ei_conj(other.coeff(i)); } return res; } diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index f51c06d6c..95fc05b8e 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -230,8 +230,7 @@ template class MatrixBase { return matrix*scalar; } //@} - /** \name Matrix product and related notions - * including the trace... + /** \name Matrix product */ //@{ template @@ -244,7 +243,12 @@ template class MatrixBase template Derived& operator*=(const MatrixBase& other); + //@} + /** \name Sums of coefficients + */ + //@{ + Scalar sum() const; Scalar trace() const; //@} diff --git a/Eigen/src/Core/MatrixStorage.h b/Eigen/src/Core/MatrixStorage.h index 4bc0423f2..91290ea59 100644 --- a/Eigen/src/Core/MatrixStorage.h +++ b/Eigen/src/Core/MatrixStorage.h @@ -26,12 +26,12 @@ #ifndef EIGEN_MATRIXSTORAGE_H #define EIGEN_MATRIXSTORAGE_H -/** \class ei_matrix_storage +/** \internal + * + * \class ei_matrix_storage * * \brief Stores the data of a matrix * - * \internal - * * This class stores the data of fixed-size, dynamic-size or mixed matrices * in a way as compact as possible. * diff --git a/Eigen/src/Core/SumOfCoeffs.h b/Eigen/src/Core/SumOfCoeffs.h new file mode 100644 index 000000000..36e75d3e9 --- /dev/null +++ b/Eigen/src/Core/SumOfCoeffs.h @@ -0,0 +1,102 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2006-2008 Benoit Jacob +// +// Eigen is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 3 of the License, or (at your option) any later version. +// +// Alternatively, you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of +// the License, or (at your option) any later version. +// +// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License and a copy of the GNU General Public License along with +// Eigen. If not, see . + +#ifndef EIGEN_SUMOFCOEFFS_H +#define EIGEN_SUMOFCOEFFS_H + +template +struct ei_sumofcoeffs_unroller +{ + static void run(const Derived &v1, typename Derived::Scalar &dot) + { + ei_sumofcoeffs_unroller::run(v1, dot); + dot += v1.coeff(Index); + } +}; + +template +struct ei_sumofcoeffs_unroller<0, Size, Derived> +{ + static void run(const Derived &v1, typename Derived::Scalar &dot) + { + dot = v1.coeff(0); + } +}; + +template +struct ei_sumofcoeffs_unroller +{ + static void run(const Derived&, typename Derived::Scalar&) {} +}; + +// prevent buggy user code from causing an infinite recursion +template +struct ei_sumofcoeffs_unroller +{ + static void run(const Derived&, typename Derived::Scalar&) +{} +}; + +/** \returns the sum of all coefficients of *this + * + * \only_for_vectors + * + * \sa trace() + */ +template +typename ei_traits::Scalar +MatrixBase::sum() const +{ + assert(IsVectorAtCompileTime); + Scalar res; + if(EIGEN_UNROLLED_LOOPS + && SizeAtCompileTime != Dynamic + && SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT) + ei_sumofcoeffs_unroller + ::run(derived(),res); + else + { + res = coeff(0); + for(int i = 1; i < size(); i++) + res += coeff(i); + } + return res; +} + +/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal. + * + * \c *this can be any matrix, not necessarily square. + * + * \sa diagonal(), sum() + */ +template +typename ei_traits::Scalar +MatrixBase::trace() const +{ + return diagonal().sum(); +} + +#endif // EIGEN_SUMOFCOEFFS_H diff --git a/Eigen/src/Core/Trace.h b/Eigen/src/Core/Trace.h deleted file mode 100644 index dcb317de5..000000000 --- a/Eigen/src/Core/Trace.h +++ /dev/null @@ -1,80 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. Eigen itself is part of the KDE project. -// -// Copyright (C) 2006-2008 Benoit Jacob -// -// Eigen is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 3 of the License, or (at your option) any later version. -// -// Alternatively, you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of -// the License, or (at your option) any later version. -// -// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License and a copy of the GNU General Public License along with -// Eigen. If not, see . - -#ifndef EIGEN_TRACE_H -#define EIGEN_TRACE_H - -template struct ei_trace_unroller -{ - static void run(const Derived &mat, typename Derived::Scalar &trace) - { - ei_trace_unroller::run(mat, trace); - trace += mat.coeff(Index, Index); - } -}; - -template struct ei_trace_unroller<0, Rows, Derived> -{ - static void run(const Derived &mat, typename Derived::Scalar &trace) - { - trace = mat.coeff(0, 0); - } -}; - -template struct ei_trace_unroller -{ - static void run(const Derived&, typename Derived::Scalar&) {} -}; - -// prevent buggy user code from causing an infinite recursion -template struct ei_trace_unroller -{ - static void run(const Derived&, typename Derived::Scalar&) {} -}; - -/** \returns the trace of *this, which must be a square matrix. - * - * \sa diagonal() */ -template -typename ei_traits::Scalar -MatrixBase::trace() const -{ - assert(rows() == cols()); - Scalar res; - if(EIGEN_UNROLLED_LOOPS - && RowsAtCompileTime != Dynamic - && RowsAtCompileTime <= EIGEN_UNROLLING_LIMIT) - ei_trace_unroller - ::run(*static_cast(this), res); - else - { - res = coeff(0, 0); - for(int i = 1; i < rows(); i++) - res += coeff(i, i); - } - return res; -} - -#endif // EIGEN_TRACE_H