* 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
diff --git a/Eigen/Array b/Eigen/Array
index dc1cf03..fe2a861 100644
--- a/Eigen/Array
+++ b/Eigen/Array
@@ -26,7 +26,7 @@
 
 #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/BooleanRedux.h
similarity index 91%
rename from Eigen/src/Array/AllAndAny.h
rename to Eigen/src/Array/BooleanRedux.h
index ac2760f..4e82183 100644
--- a/Eigen/src/Array/AllAndAny.h
+++ b/Eigen/src/Array/BooleanRedux.h
@@ -89,7 +89,7 @@
   * \sa MatrixBase::any(), Cwise::operator<()
   */
 template<typename Derived>
-inline bool MatrixBase<Derived>::all(void) const
+inline bool MatrixBase<Derived>::all() const
 {
   const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost)
                       <= EIGEN_UNROLLING_LIMIT;
@@ -113,7 +113,7 @@
   * \sa MatrixBase::all()
   */
 template<typename Derived>
-inline bool MatrixBase<Derived>::any(void) const
+inline bool MatrixBase<Derived>::any() const
 {
   const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost)
                       <= EIGEN_UNROLLING_LIMIT;
@@ -130,4 +130,16 @@
   }
 }
 
+/** \array_module
+  * 
+  * \returns the number of coefficients which evaluate to true
+  *
+  * \sa MatrixBase::all(), MatrixBase::any()
+  */
+template<typename Derived>
+inline int MatrixBase<Derived>::count() const
+{
+  return this->cast<bool>().cast<int>().sum();
+}
+
 #endif // EIGEN_ALLANDANY_H
diff --git a/Eigen/src/Array/Functors.h b/Eigen/src/Array/Functors.h
index 1e38043..0aae7fd 100644
--- a/Eigen/src/Array/Functors.h
+++ b/Eigen/src/Array/Functors.h
@@ -200,7 +200,6 @@
 struct ei_functor_traits<ei_scalar_cube_op<Scalar> >
 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = int(ei_packet_traits<Scalar>::size)>1 }; };
 
-
 // default ei_functor_traits for STL functors:
 
 template<typename T>
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 8c755c5..41dd894 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -557,6 +557,7 @@
 
     bool all(void) const;
     bool any(void) const;
+    int count() const;
 
     const PartialRedux<Derived,Horizontal> rowwise() const;
     const PartialRedux<Derived,Vertical> colwise() const;
diff --git a/Eigen/src/QR/QR.h b/Eigen/src/QR/QR.h
index 7712bfb..13d49a4 100644
--- a/Eigen/src/QR/QR.h
+++ b/Eigen/src/QR/QR.h
@@ -57,7 +57,9 @@
     }
 
     /** \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<NestByValue<MatrixRBlockType>, UpperTriangular>
@@ -76,13 +78,33 @@
   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<typename MatrixType>
+int QR<MatrixType>::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<n; ++i)
+      if (ei_isMuchSmallerThan(m_qr.diagonal().coeff(i), maxCoeff))
+        --m_rank;
+    m_rankIsUptodate = true;
+  }
+  return m_rank;
+}
+
 #ifndef EIGEN_HIDE_HEAVY_CODE
 
 template<typename MatrixType>
 void QR<MatrixType>::_compute(const MatrixType& matrix)
 {
+  m_rankIsUptodate = false;
   m_qr = matrix;
   int rows = matrix.rows();
   int cols = matrix.cols();