From 8973d12cdae503e0996edd52f8c78879274c0e70 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Tue, 20 Jan 2009 16:37:52 +0000 Subject: * QR: add a rank() method and improve the accuracy of the rank * computation * Array: add a count() method and rename AllAndAny.h file to BooleanRedux.h --- Eigen/Array | 2 +- Eigen/src/Array/AllAndAny.h | 133 ------------------------------------- Eigen/src/Array/BooleanRedux.h | 145 +++++++++++++++++++++++++++++++++++++++++ Eigen/src/Array/Functors.h | 1 - Eigen/src/Core/MatrixBase.h | 1 + Eigen/src/QR/QR.h | 24 ++++++- 6 files changed, 170 insertions(+), 136 deletions(-) delete mode 100644 Eigen/src/Array/AllAndAny.h create mode 100644 Eigen/src/Array/BooleanRedux.h diff --git a/Eigen/Array b/Eigen/Array index dc1cf03c0..fe2a861e4 100644 --- a/Eigen/Array +++ b/Eigen/Array @@ -26,7 +26,7 @@ namespace Eigen { #include "src/Array/CwiseOperators.h" #include "src/Array/Functors.h" -#include "src/Array/AllAndAny.h" +#include "src/Array/BooleanRedux.h" #include "src/Array/Select.h" #include "src/Array/PartialRedux.h" #include "src/Array/Random.h" diff --git a/Eigen/src/Array/AllAndAny.h b/Eigen/src/Array/AllAndAny.h deleted file mode 100644 index ac2760f1a..000000000 --- a/Eigen/src/Array/AllAndAny.h +++ /dev/null @@ -1,133 +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) 2008 Gael Guennebaud -// -// 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_ALLANDANY_H -#define EIGEN_ALLANDANY_H - -template -struct ei_all_unroller -{ - enum { - col = (UnrollCount-1) / Derived::RowsAtCompileTime, - row = (UnrollCount-1) % Derived::RowsAtCompileTime - }; - - inline static bool run(const Derived &mat) - { - return ei_all_unroller::run(mat) && mat.coeff(row, col); - } -}; - -template -struct ei_all_unroller -{ - inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } -}; - -template -struct ei_all_unroller -{ - inline static bool run(const Derived &) { return false; } -}; - -template -struct ei_any_unroller -{ - enum { - col = (UnrollCount-1) / Derived::RowsAtCompileTime, - row = (UnrollCount-1) % Derived::RowsAtCompileTime - }; - - inline static bool run(const Derived &mat) - { - return ei_any_unroller::run(mat) || mat.coeff(row, col); - } -}; - -template -struct ei_any_unroller -{ - inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } -}; - -template -struct ei_any_unroller -{ - inline static bool run(const Derived &) { return false; } -}; - -/** \array_module - * - * \returns true if all coefficients are true - * - * \addexample CwiseAll \label How to check whether a point is inside a box (using operator< and all()) - * - * Example: \include MatrixBase_all.cpp - * Output: \verbinclude MatrixBase_all.out - * - * \sa MatrixBase::any(), Cwise::operator<() - */ -template -inline bool MatrixBase::all(void) const -{ - const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) - <= EIGEN_UNROLLING_LIMIT; - if(unroll) - return ei_all_unroller::run(derived()); - else - { - for(int j = 0; j < cols(); ++j) - for(int i = 0; i < rows(); ++i) - if (!coeff(i, j)) return false; - return true; - } -} - -/** \array_module - * - * \returns true if at least one coefficient is true - * - * \sa MatrixBase::all() - */ -template -inline bool MatrixBase::any(void) const -{ - const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) - <= EIGEN_UNROLLING_LIMIT; - if(unroll) - return ei_any_unroller::run(derived()); - else - { - for(int j = 0; j < cols(); ++j) - for(int i = 0; i < rows(); ++i) - if (coeff(i, j)) return true; - return false; - } -} - -#endif // EIGEN_ALLANDANY_H diff --git a/Eigen/src/Array/BooleanRedux.h b/Eigen/src/Array/BooleanRedux.h new file mode 100644 index 000000000..4e8218327 --- /dev/null +++ b/Eigen/src/Array/BooleanRedux.h @@ -0,0 +1,145 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2008 Gael Guennebaud +// +// 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_ALLANDANY_H +#define EIGEN_ALLANDANY_H + +template +struct ei_all_unroller +{ + enum { + col = (UnrollCount-1) / Derived::RowsAtCompileTime, + row = (UnrollCount-1) % Derived::RowsAtCompileTime + }; + + inline static bool run(const Derived &mat) + { + return ei_all_unroller::run(mat) && mat.coeff(row, col); + } +}; + +template +struct ei_all_unroller +{ + inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } +}; + +template +struct ei_all_unroller +{ + inline static bool run(const Derived &) { return false; } +}; + +template +struct ei_any_unroller +{ + enum { + col = (UnrollCount-1) / Derived::RowsAtCompileTime, + row = (UnrollCount-1) % Derived::RowsAtCompileTime + }; + + inline static bool run(const Derived &mat) + { + return ei_any_unroller::run(mat) || mat.coeff(row, col); + } +}; + +template +struct ei_any_unroller +{ + inline static bool run(const Derived &mat) { return mat.coeff(0, 0); } +}; + +template +struct ei_any_unroller +{ + inline static bool run(const Derived &) { return false; } +}; + +/** \array_module + * + * \returns true if all coefficients are true + * + * \addexample CwiseAll \label How to check whether a point is inside a box (using operator< and all()) + * + * Example: \include MatrixBase_all.cpp + * Output: \verbinclude MatrixBase_all.out + * + * \sa MatrixBase::any(), Cwise::operator<() + */ +template +inline bool MatrixBase::all() const +{ + const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) + <= EIGEN_UNROLLING_LIMIT; + if(unroll) + return ei_all_unroller::run(derived()); + else + { + for(int j = 0; j < cols(); ++j) + for(int i = 0; i < rows(); ++i) + if (!coeff(i, j)) return false; + return true; + } +} + +/** \array_module + * + * \returns true if at least one coefficient is true + * + * \sa MatrixBase::all() + */ +template +inline bool MatrixBase::any() const +{ + const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits::AddCost) + <= EIGEN_UNROLLING_LIMIT; + if(unroll) + return ei_any_unroller::run(derived()); + else + { + for(int j = 0; j < cols(); ++j) + for(int i = 0; i < rows(); ++i) + if (coeff(i, j)) return true; + return false; + } +} + +/** \array_module + * + * \returns the number of coefficients which evaluate to true + * + * \sa MatrixBase::all(), MatrixBase::any() + */ +template +inline int MatrixBase::count() const +{ + return this->cast().cast().sum(); +} + +#endif // EIGEN_ALLANDANY_H diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h index 1e3804311..0aae7fd2c 100644 --- a/Eigen/src/Array/Functors.h +++ b/Eigen/src/Array/Functors.h @@ -200,7 +200,6 @@ template struct ei_functor_traits > { enum { Cost = 2*NumTraits::MulCost, PacketAccess = int(ei_packet_traits::size)>1 }; }; - // default ei_functor_traits for STL functors: template diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 8c755c592..41dd894d7 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -557,6 +557,7 @@ template class MatrixBase bool all(void) const; bool any(void) const; + int count() const; const PartialRedux rowwise() const; const PartialRedux colwise() const; diff --git a/Eigen/src/QR/QR.h b/Eigen/src/QR/QR.h index 7712bfbf2..13d49a4a3 100644 --- a/Eigen/src/QR/QR.h +++ b/Eigen/src/QR/QR.h @@ -57,7 +57,9 @@ template class QR } /** \returns whether or not the matrix is of full rank */ - bool isFullRank() const { return !ei_isMuchSmallerThan(m_qr.diagonal().cwise().abs().minCoeff(), Scalar(1)); } + bool isFullRank() const { return rank() == std::min(m_qr.rows(),m_qr.cols()); } + + int rank() const; /** \returns a read-only expression of the matrix R of the actual the QR decomposition */ const Part, UpperTriangular> @@ -76,13 +78,33 @@ template class QR protected: MatrixType m_qr; VectorType m_hCoeffs; + mutable int m_rank; + mutable bool m_rankIsUptodate; }; +/** \returns the rank of the matrix of which *this is the QR decomposition. */ +template +int QR::rank() const +{ + if (!m_rankIsUptodate) + { + RealScalar maxCoeff = m_qr.diagonal().maxCoeff(); + int n = std::min(m_qr.rows(),m_qr.cols()); + m_rank = n; + for (int i=0; i void QR::_compute(const MatrixType& matrix) { + m_rankIsUptodate = false; m_qr = matrix; int rows = matrix.rows(); int cols = matrix.cols(); -- cgit v1.2.3