This commit is contained in:
Mark Borgerding 2010-02-16 21:41:04 -05:00
commit f200c84d9f
157 changed files with 2926 additions and 2523 deletions

View File

@ -56,14 +56,18 @@ if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fexceptions -fno-check-new -fno-common -fstrict-aliasing")
set(CMAKE_CXX_FLAGS_DEBUG "-g3") set(CMAKE_CXX_FLAGS_DEBUG "-g3")
set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2") set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")
check_cxx_compiler_flag("-Wno-variadic-macros" COMPILER_SUPPORT_WNOVARIADICMACRO)
if(COMPILER_SUPPORT_WNOVARIADICMACRO)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-variadic-macros")
endif()
check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA) check_cxx_compiler_flag("-Wextra" COMPILER_SUPPORT_WEXTRA)
if(COMPILER_SUPPORT_WEXTRA) if(COMPILER_SUPPORT_WEXTRA)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra")
endif() endif()
if(NOT EIGEN_TEST_LIB) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic")
endif()
option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF) option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)
if(EIGEN_TEST_SSE2) if(EIGEN_TEST_SSE2)

View File

@ -121,6 +121,10 @@
namespace Eigen { namespace Eigen {
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
// ensure QNX/QCC support
using std::size_t;
/** \defgroup Core_Module Core module /** \defgroup Core_Module Core module
* This is the main module of Eigen providing dense matrix and vector support * This is the main module of Eigen providing dense matrix and vector support
* (both fixed and dynamic size) with all the features corresponding to a BLAS library * (both fixed and dynamic size) with all the features corresponding to a BLAS library
@ -199,12 +203,13 @@ struct Dense {};
#include "src/Core/IO.h" #include "src/Core/IO.h"
#include "src/Core/Swap.h" #include "src/Core/Swap.h"
#include "src/Core/CommaInitializer.h" #include "src/Core/CommaInitializer.h"
#include "src/Core/Flagged.h"
#include "src/Core/ProductBase.h" #include "src/Core/ProductBase.h"
#include "src/Core/Product.h" #include "src/Core/Product.h"
#include "src/Core/TriangularMatrix.h" #include "src/Core/TriangularMatrix.h"
#include "src/Core/SelfAdjointView.h" #include "src/Core/SelfAdjointView.h"
#include "src/Core/SolveTriangular.h" #include "src/Core/SolveTriangular.h"
#include "src/Core/products/GeneralUnrolled.h" #include "src/Core/products/CoeffBasedProduct.h"
#include "src/Core/products/GeneralBlockPanelKernel.h" #include "src/Core/products/GeneralBlockPanelKernel.h"
#include "src/Core/products/GeneralMatrixVector.h" #include "src/Core/products/GeneralMatrixVector.h"
#include "src/Core/products/GeneralMatrixMatrix.h" #include "src/Core/products/GeneralMatrixMatrix.h"
@ -253,6 +258,8 @@ struct Dense {};
} // namespace Eigen } // namespace Eigen
#include "src/Array/GlobalFunctions.h"
#include "src/Core/util/EnableMSVCWarnings.h" #include "src/Core/util/EnableMSVCWarnings.h"
#ifdef EIGEN2_SUPPORT #ifdef EIGEN2_SUPPORT

View File

@ -42,7 +42,6 @@ namespace Eigen {
* *
*/ */
#include "src/Eigen2Support/Flagged.h"
#include "src/Eigen2Support/Lazy.h" #include "src/Eigen2Support/Lazy.h"
#include "src/Eigen2Support/Cwise.h" #include "src/Eigen2Support/Cwise.h"
#include "src/Eigen2Support/CwiseOperators.h" #include "src/Eigen2Support/CwiseOperators.h"

View File

@ -29,6 +29,45 @@
#include "Core" #include "Core"
#include <vector> #include <vector>
// Define the explicit instantiation (e.g. necessary for the Intel compiler)
#if defined(__INTEL_COMPILER) || defined(__GNUC__)
#define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...) template class std::vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> >;
#else
#define EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(...)
#endif
/**
* This section contains a convenience MACRO which allows an easy specialization of
* std::vector such that for data types with alignment issues the correct allocator
* is used automatically.
*/
#define EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(...) \
EIGEN_EXPLICIT_STL_VECTOR_INSTANTIATION(__VA_ARGS__) \
namespace std \
{ \
template<typename _Ay> \
class vector<__VA_ARGS__, _Ay> \
: public vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > \
{ \
typedef vector<__VA_ARGS__, Eigen::aligned_allocator<__VA_ARGS__> > vector_base; \
public: \
typedef __VA_ARGS__ value_type; \
typedef typename vector_base::allocator_type allocator_type; \
typedef typename vector_base::size_type size_type; \
typedef typename vector_base::iterator iterator; \
explicit vector(const allocator_type& a = allocator_type()) : vector_base(a) {} \
template<typename InputIterator> \
vector(InputIterator first, InputIterator last, const allocator_type& a = allocator_type()) : vector_base(first, last, a) {} \
vector(const vector& c) : vector_base(c) {} \
explicit vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
vector(iterator start, iterator end) : vector_base(start, end) {} \
vector& operator=(const vector& x) { \
vector_base::operator=(x); \
return *this; \
} \
}; \
}
namespace Eigen { namespace Eigen {
// This one is needed to prevent reimplementing the whole std::vector. // This one is needed to prevent reimplementing the whole std::vector.

View File

@ -38,7 +38,7 @@ class Array
public: public:
typedef DenseStorageBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Eigen::ArrayBase, _Options> Base; typedef DenseStorageBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Eigen::ArrayBase, _Options> Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(Array) EIGEN_DENSE_PUBLIC_INTERFACE(Array)
enum { Options = _Options }; enum { Options = _Options };
typedef typename Base::PlainMatrixType PlainMatrixType; typedef typename Base::PlainMatrixType PlainMatrixType;

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -36,7 +36,7 @@
*/ */
template<typename ExpressionType> template<typename ExpressionType>
struct ei_traits<ArrayWrapper<ExpressionType> > struct ei_traits<ArrayWrapper<ExpressionType> >
: public ei_traits<ExpressionType> : public ei_traits<typename ei_cleantype<typename ExpressionType::Nested>::type >
{ {
typedef DenseStorageArray DenseStorageType; typedef DenseStorageArray DenseStorageType;
}; };
@ -46,9 +46,11 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
{ {
public: public:
typedef ArrayBase<ArrayWrapper> Base; typedef ArrayBase<ArrayWrapper> Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
typedef typename ei_nested<ExpressionType>::type NestedExpressionType;
inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {} inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
inline int rows() const { return m_expression.rows(); } inline int rows() const { return m_expression.rows(); }
@ -103,7 +105,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
inline void evalTo(Dest& dst) const { dst = m_expression; } inline void evalTo(Dest& dst) const { dst = m_expression; }
protected: protected:
const ExpressionType& m_expression; const NestedExpressionType m_expression;
}; };
/** \class MatrixWrapper /** \class MatrixWrapper
@ -118,7 +120,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
template<typename ExpressionType> template<typename ExpressionType>
struct ei_traits<MatrixWrapper<ExpressionType> > struct ei_traits<MatrixWrapper<ExpressionType> >
: public ei_traits<ExpressionType> : public ei_traits<typename ei_cleantype<typename ExpressionType::Nested>::type >
{ {
typedef DenseStorageMatrix DenseStorageType; typedef DenseStorageMatrix DenseStorageType;
}; };
@ -127,9 +129,12 @@ template<typename ExpressionType>
class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(MatrixWrapper) typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper); EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper);
typedef typename ei_nested<ExpressionType>::type NestedExpressionType;
inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {} inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {}
inline int rows() const { return m_expression.rows(); } inline int rows() const { return m_expression.rows(); }
@ -181,7 +186,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
} }
protected: protected:
const ExpressionType& m_expression; const NestedExpressionType& m_expression;
}; };
#endif // EIGEN_ARRAYWRAPPER_H #endif // EIGEN_ARRAYWRAPPER_H

View File

@ -0,0 +1,55 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2010 Gael Guennebaud <g.gael@free.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_GLOBAL_FUNCTIONS_H
#define EIGEN_GLOBAL_FUNCTIONS_H
#define EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(NAME,FUNCTOR) \
template<typename Derived> \
inline const Eigen::CwiseUnaryOp<Eigen::FUNCTOR<typename Derived::Scalar>, Derived> \
NAME(const Eigen::ArrayBase<Derived>& x) { \
return x.derived(); \
}
namespace std
{
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(sin,ei_scalar_sin_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(cos,ei_scalar_cos_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(exp,ei_scalar_exp_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(log,ei_scalar_log_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(abs,ei_scalar_abs_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(sqrt,ei_scalar_sqrt_op)
}
namespace Eigen
{
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(ei_sin,ei_scalar_sin_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(ei_cos,ei_scalar_cos_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(ei_exp,ei_scalar_exp_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(ei_log,ei_scalar_log_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(ei_abs,ei_scalar_abs_op)
EIGEN_ARRAY_DECLARARE_GLOBAL_UNARY(ei_sqrt,ei_scalar_sqrt_op)
}
#endif // EIGEN_GLOBAL_FUNCTIONS_H

View File

@ -27,7 +27,7 @@
template<typename Scalar> struct ei_scalar_random_op { template<typename Scalar> struct ei_scalar_random_op {
EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_random_op) EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_random_op)
inline const Scalar operator() (int, int) const { return ei_random<Scalar>(); } inline const Scalar operator() (int, int = 0) const { return ei_random<Scalar>(); }
}; };
template<typename Scalar> template<typename Scalar>
struct ei_functor_traits<ei_scalar_random_op<Scalar> > struct ei_functor_traits<ei_scalar_random_op<Scalar> >

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -55,7 +55,7 @@ struct ei_traits<Replicate<MatrixType,RowFactor,ColFactor> >
: ColFactor * MatrixType::ColsAtCompileTime, : ColFactor * MatrixType::ColsAtCompileTime,
MaxRowsAtCompileTime = RowsAtCompileTime, MaxRowsAtCompileTime = RowsAtCompileTime,
MaxColsAtCompileTime = ColsAtCompileTime, MaxColsAtCompileTime = ColsAtCompileTime,
Flags = _MatrixTypeNested::Flags & HereditaryBits, Flags = (_MatrixTypeNested::Flags & HereditaryBits),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost CoeffReadCost = _MatrixTypeNested::CoeffReadCost
}; };
}; };
@ -66,7 +66,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
public: public:
typedef typename MatrixType::template MakeBase< Replicate<MatrixType,RowFactor,ColFactor> >::Type Base; typedef typename MatrixType::template MakeBase< Replicate<MatrixType,RowFactor,ColFactor> >::Type Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Replicate) EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
template<typename OriginalMatrixType> template<typename OriginalMatrixType>
inline explicit Replicate(const OriginalMatrixType& matrix) inline explicit Replicate(const OriginalMatrixType& matrix)

View File

@ -3,7 +3,7 @@
// //
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com> // Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -59,7 +59,7 @@ struct ei_traits<Reverse<MatrixType, Direction> >
LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) ) LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
? LinearAccessBit : 0, ? LinearAccessBit : 0,
Flags = (int(_MatrixTypeNested::Flags) & (HereditaryBits | PacketAccessBit | LinearAccess)), Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | PacketAccessBit | LinearAccess),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost CoeffReadCost = _MatrixTypeNested::CoeffReadCost
}; };
@ -80,7 +80,7 @@ template<typename MatrixType, int Direction> class Reverse
public: public:
typedef typename MatrixType::template MakeBase< Reverse<MatrixType, Direction> >::Type Base; typedef typename MatrixType::template MakeBase< Reverse<MatrixType, Direction> >::Type Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Reverse) EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
protected: protected:
enum { enum {

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -56,9 +56,9 @@ struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime, MaxRowsAtCompileTime = ConditionMatrixType::MaxRowsAtCompileTime,
MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime, MaxColsAtCompileTime = ConditionMatrixType::MaxColsAtCompileTime,
Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits, Flags = (unsigned int)ThenMatrixType::Flags & ElseMatrixType::Flags & HereditaryBits,
CoeffReadCost = ei_traits<typename ei_cleantype<ConditionMatrixNested>::type>::CoeffReadCost CoeffReadCost = ei_traits<typename ei_cleantype<ConditionMatrixNested>::type>::CoeffReadCost
+ EIGEN_ENUM_MAX(ei_traits<typename ei_cleantype<ThenMatrixNested>::type>::CoeffReadCost, + EIGEN_ENUM_MAX(ei_traits<typename ei_cleantype<ThenMatrixNested>::type>::CoeffReadCost,
ei_traits<typename ei_cleantype<ElseMatrixNested>::type>::CoeffReadCost) ei_traits<typename ei_cleantype<ElseMatrixNested>::type>::CoeffReadCost)
}; };
}; };
@ -69,7 +69,7 @@ class Select : ei_no_assignment_operator,
public: public:
typedef typename ThenMatrixType::template MakeBase< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::Type Base; typedef typename ThenMatrixType::template MakeBase< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::Type Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Select) EIGEN_DENSE_PUBLIC_INTERFACE(Select)
Select(const ConditionMatrixType& conditionMatrix, Select(const ConditionMatrixType& conditionMatrix,
const ThenMatrixType& thenMatrix, const ThenMatrixType& thenMatrix,

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
@ -80,7 +80,7 @@ class PartialReduxExpr : ei_no_assignment_operator,
public: public:
typedef typename MatrixType::template MakeBase< PartialReduxExpr<MatrixType, MemberOp, Direction> >::Type Base; typedef typename MatrixType::template MakeBase< PartialReduxExpr<MatrixType, MemberOp, Direction> >::Type Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(PartialReduxExpr) EIGEN_DENSE_PUBLIC_INTERFACE(PartialReduxExpr)
typedef typename ei_traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested; typedef typename ei_traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested;
typedef typename ei_traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested; typedef typename ei_traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested;

View File

@ -206,7 +206,7 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a)
// in "Analysis of the Cholesky Decomposition of a Semi-definite Matrix" by // in "Analysis of the Cholesky Decomposition of a Semi-definite Matrix" by
// Nicholas J. Higham. Also see "Accuracy and Stability of Numerical // Nicholas J. Higham. Also see "Accuracy and Stability of Numerical
// Algorithms" page 217, also by Higham. // Algorithms" page 217, also by Higham.
cutoff = ei_abs(epsilon<Scalar>() * size * biggest_in_corner); cutoff = ei_abs(NumTraits<Scalar>::epsilon() * RealScalar(size) * biggest_in_corner);
m_sign = ei_real(m_matrix.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1; m_sign = ei_real(m_matrix.diagonal().coeff(index_of_biggest_in_corner)) > 0 ? 1 : -1;
} }

View File

@ -100,9 +100,9 @@ template<typename Derived> struct AnyMatrixBase
/** \brief Copies the generic expression \a other into *this. /** \brief Copies the generic expression \a other into *this.
* *
* \details The expression must provide a (templated) evalTo(Derived& dst) const * \details The expression must provide a (templated) evalTo(Derived& dst) const
* function which does the actual job. In practice, this allows any user to write * function which does the actual job. In practice, this allows any user to write
* its own special matrix without having to modify MatrixBase * its own special matrix without having to modify MatrixBase
* *
* \returns a reference to *this. * \returns a reference to *this.
*/ */

View File

@ -378,6 +378,31 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolli
*** Linear vectorization *** *** Linear vectorization ***
***************************/ ***************************/
template <bool IsAligned = false>
struct ei_unaligned_assign_impl
{
template <typename Derived, typename OtherDerived>
static EIGEN_STRONG_INLINE void run(const Derived&, OtherDerived&, int, int) {}
};
template <>
struct ei_unaligned_assign_impl<false>
{
// MSVC must not inline this functions. If it does, it fails to optimize the
// packet access path.
#ifdef _MSC_VER
template <typename Derived, typename OtherDerived>
static EIGEN_DONT_INLINE void run(const Derived& src, OtherDerived& dst, int start, int end)
#else
template <typename Derived, typename OtherDerived>
static EIGEN_STRONG_INLINE void run(const Derived& src, OtherDerived& dst, int start, int end)
#endif
{
for (int index = start; index < end; ++index)
dst.copyCoeff(index, src);
}
};
template<typename Derived1, typename Derived2> template<typename Derived1, typename Derived2>
struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling> struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling>
{ {
@ -389,16 +414,14 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling
: ei_first_aligned(&dst.coeffRef(0), size); : ei_first_aligned(&dst.coeffRef(0), size);
const int alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize; const int alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;
for(int index = 0; index < alignedStart; ++index) ei_unaligned_assign_impl<ei_assign_traits<Derived1,Derived2>::DstIsAligned!=0>::run(src,dst,0,alignedStart);
dst.copyCoeff(index, src);
for(int index = alignedStart; index < alignedEnd; index += packetSize) for(int index = alignedStart; index < alignedEnd; index += packetSize)
{ {
dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::SrcAlignment>(index, src); dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);
} }
for(int index = alignedEnd; index < size; ++index) ei_unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
dst.copyCoeff(index, src);
} }
}; };

View File

@ -77,7 +77,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
? 1 + Supers + Subs ? 1 + Supers + Subs
: Dynamic, : Dynamic,
SizeAtCompileTime = EIGEN_ENUM_MIN(Rows,Cols) SizeAtCompileTime = EIGEN_SIZE_MIN(Rows,Cols)
}; };
typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> DataType; typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> DataType;
@ -136,6 +136,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs
DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic) DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
? Dynamic ? Dynamic
: (ActualIndex<0 : (ActualIndex<0
// we handled Dynamic already, so can use EIGEN_ENUM_MIN safely here.
? EIGEN_ENUM_MIN(ColsAtCompileTime, RowsAtCompileTime + ActualIndex) ? EIGEN_ENUM_MIN(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
: EIGEN_ENUM_MIN(RowsAtCompileTime, ColsAtCompileTime - ActualIndex)) : EIGEN_ENUM_MIN(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
}; };

View File

@ -86,7 +86,7 @@ template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessSta
public: public:
typedef typename MatrixType::template MakeBase< Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >::Type Base; typedef typename MatrixType::template MakeBase< Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(Block) EIGEN_DENSE_PUBLIC_INTERFACE(Block)
class InnerIterator; class InnerIterator;
@ -218,7 +218,7 @@ class Block<MatrixType,BlockRows,BlockCols,HasDirectAccess>
public: public:
typedef MapBase<Block, typename MatrixType::template MakeBase<Block>::Type> Base; typedef MapBase<Block, typename MatrixType::template MakeBase<Block>::Type> Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Block) EIGEN_DENSE_PUBLIC_INTERFACE(Block)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)

View File

@ -124,8 +124,11 @@ class CwiseBinaryOp : ei_no_assignment_operator,
EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); } EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); } EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); }
/** \returns the left hand side nested expression */
const _LhsNested& lhs() const { return m_lhs; } const _LhsNested& lhs() const { return m_lhs; }
/** \returns the right hand side nested expression */
const _RhsNested& rhs() const { return m_rhs; } const _RhsNested& rhs() const { return m_rhs; }
/** \returns the functor representing the binary operation */
const BinaryOp& functor() const { return m_functor; } const BinaryOp& functor() const { return m_functor; }
protected: protected:
@ -138,11 +141,11 @@ template<typename BinaryOp, typename Lhs, typename Rhs>
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense> class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
: public Lhs::template MakeBase< CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::Type : public Lhs::template MakeBase< CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::Type
{ {
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
public: public:
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
typedef typename Lhs::template MakeBase< CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::Type Base; typedef typename Lhs::template MakeBase< CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) EIGEN_DENSE_PUBLIC_INTERFACE( Derived )
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{ {

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -60,7 +60,7 @@ class CwiseNullaryOp : ei_no_assignment_operator,
public: public:
typedef typename MatrixType::template MakeBase< CwiseNullaryOp<NullaryOp, MatrixType> >::Type Base; typedef typename MatrixType::template MakeBase< CwiseNullaryOp<NullaryOp, MatrixType> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp) EIGEN_DENSE_PUBLIC_INTERFACE(CwiseNullaryOp)
CwiseNullaryOp(int rows, int cols, const NullaryOp& func = NullaryOp()) CwiseNullaryOp(int rows, int cols, const NullaryOp& func = NullaryOp())
: m_rows(rows), m_cols(cols), m_functor(func) : m_rows(rows), m_cols(cols), m_functor(func)
@ -80,23 +80,20 @@ class CwiseNullaryOp : ei_no_assignment_operator,
} }
template<int LoadMode> template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int, int) const EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{ {
return m_functor.packetOp(); return m_functor.packetOp(row, col);
} }
EIGEN_STRONG_INLINE const Scalar coeff(int index) const EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{ {
if(RowsAtCompileTime == 1) return m_functor(index);
return m_functor(0, index);
else
return m_functor(index, 0);
} }
template<int LoadMode> template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int) const EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{ {
return m_functor.packetOp(); return m_functor.packetOp(index);
} }
protected: protected:
@ -228,6 +225,49 @@ DenseBase<Derived>::Constant(const Scalar& value)
return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_constant_op<Scalar>(value)); return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_constant_op<Scalar>(value));
} }
/**
* \brief Sets a linearly space vector.
*
* The function generates 'size' equally spaced values in the closed interval [low,high].
* This particular version of LinSpaced() uses sequential access, i.e. vector access is
* assumed to be a(0), a(1), ..., a(size). This assumption allows for better vectorization
* and yields faster code than the random access version.
*
* \only_for_vectors
*
* Example: \include DenseBase_LinSpaced_seq.cpp
* Output: \verbinclude DenseBase_LinSpaced_seq.out
*
* \sa setLinSpaced(const Scalar&,const Scalar&,int), LinSpaced(Scalar,Scalar,int), CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high, int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return NullaryExpr(size, ei_linspaced_op<Scalar,false>(low,high,size));
}
/**
* \brief Sets a linearly space vector.
*
* The function generates 'size' equally spaced values in the closed interval [low,high].
*
* \only_for_vectors
*
* Example: \include DenseBase_LinSpaced.cpp
* Output: \verbinclude DenseBase_LinSpaced.out
*
* \sa setLinSpaced(const Scalar&,const Scalar&,int), LinSpaced(Sequential_t,const Scalar&,const Scalar&,int), CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high, int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return NullaryExpr(size, ei_linspaced_op<Scalar,true>(low,high,size));
}
/** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ /** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
template<typename Derived> template<typename Derived>
bool DenseBase<Derived>::isApproxToConstant bool DenseBase<Derived>::isApproxToConstant
@ -305,6 +345,24 @@ DenseStorageBase<Derived,_Base,_Options>::setConstant(int rows, int cols, const
return setConstant(value); return setConstant(value);
} }
/**
* \brief Sets a linearly space vector.
*
* The function generates 'size' equally spaced values in the closed interval [low,high].
*
* \only_for_vectors
*
* Example: \include DenseBase_setLinSpaced.cpp
* Output: \verbinclude DenseBase_setLinSpaced.out
*
* \sa CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high, int size)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return derived() = Derived::NullaryExpr(size, ei_linspaced_op<Scalar,false>(low,high,size));
}
// zero: // zero:

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
@ -49,9 +49,9 @@ struct ei_traits<CwiseUnaryOp<UnaryOp, MatrixType> >
typedef typename MatrixType::Nested MatrixTypeNested; typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum { enum {
Flags = (_MatrixTypeNested::Flags & ( Flags = _MatrixTypeNested::Flags & (
HereditaryBits | LinearAccessBit | AlignedBit HereditaryBits | LinearAccessBit | AlignedBit
| (ei_functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0))), | (ei_functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost
}; };
}; };
@ -74,16 +74,14 @@ class CwiseUnaryOp : ei_no_assignment_operator,
EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); } EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); } EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); }
/** \internal used for introspection */ /** \returns the functor representing the unary operation */
const UnaryOp& _functor() const { return m_functor; } const UnaryOp& functor() const { return m_functor; }
/** \internal used for introspection */
const typename ei_cleantype<typename MatrixType::Nested>::type&
_expression() const { return m_matrix; }
/** \returns the nested expression */
const typename ei_cleantype<typename MatrixType::Nested>::type& const typename ei_cleantype<typename MatrixType::Nested>::type&
nestedExpression() const { return m_matrix; } nestedExpression() const { return m_matrix; }
/** \returns the nested expression */
typename ei_cleantype<typename MatrixType::Nested>::type& typename ei_cleantype<typename MatrixType::Nested>::type&
nestedExpression() { return m_matrix.const_cast_derived(); } nestedExpression() { return m_matrix.const_cast_derived(); }
@ -98,37 +96,33 @@ template<typename UnaryOp, typename MatrixType>
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Dense> class CwiseUnaryOpImpl<UnaryOp,MatrixType,Dense>
: public MatrixType::template MakeBase< CwiseUnaryOp<UnaryOp, MatrixType> >::Type : public MatrixType::template MakeBase< CwiseUnaryOp<UnaryOp, MatrixType> >::Type
{ {
const typename ei_cleantype<typename MatrixType::Nested>::type& nestedExpression() const typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived;
{ return derived().nestedExpression(); }
typename ei_cleantype<typename MatrixType::Nested>::type& nestedExpression()
{ return derived().nestedExpression(); }
public: public:
typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived;
typedef typename MatrixType::template MakeBase< CwiseUnaryOp<UnaryOp, MatrixType> >::Type Base; typedef typename MatrixType::template MakeBase< CwiseUnaryOp<UnaryOp, MatrixType> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{ {
return derived()._functor()(nestedExpression().coeff(row, col)); return derived().functor()(derived().nestedExpression().coeff(row, col));
} }
template<int LoadMode> template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const
{ {
return derived()._functor().packetOp(nestedExpression().template packet<LoadMode>(row, col)); return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(row, col));
} }
EIGEN_STRONG_INLINE const Scalar coeff(int index) const EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{ {
return derived()._functor()(nestedExpression().coeff(index)); return derived().functor()(derived().nestedExpression().coeff(index));
} }
template<int LoadMode> template<int LoadMode>
EIGEN_STRONG_INLINE PacketScalar packet(int index) const EIGEN_STRONG_INLINE PacketScalar packet(int index) const
{ {
return derived()._functor().packetOp(nestedExpression().template packet<LoadMode>(index)); return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
} }
}; };

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -72,12 +72,14 @@ class CwiseUnaryView : ei_no_assignment_operator,
EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); } EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); }
EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); } EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); }
/** \internal used for introspection */ /** \returns the functor representing unary operation */
const ViewOp& _functor() const { return m_functor; } const ViewOp& functor() const { return m_functor; }
/** \returns the nested expression */
const typename ei_cleantype<typename MatrixType::Nested>::type& const typename ei_cleantype<typename MatrixType::Nested>::type&
nestedExpression() const { return m_matrix; } nestedExpression() const { return m_matrix; }
/** \returns the nested expression */
typename ei_cleantype<typename MatrixType::Nested>::type& typename ei_cleantype<typename MatrixType::Nested>::type&
nestedExpression() { return m_matrix.const_cast_derived(); } nestedExpression() { return m_matrix.const_cast_derived(); }
@ -88,36 +90,34 @@ class CwiseUnaryView : ei_no_assignment_operator,
}; };
template<typename ViewOp, typename MatrixType> template<typename ViewOp, typename MatrixType>
class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> : public MatrixBase<CwiseUnaryView<ViewOp, MatrixType> > class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
: public MatrixType::template MakeBase< CwiseUnaryView<ViewOp, MatrixType> >::Type
{ {
const typename ei_cleantype<typename MatrixType::Nested>::type& nestedExpression() const typedef CwiseUnaryView<ViewOp, MatrixType> Derived;
{ return derived().nestedExpression(); }
typename ei_cleantype<typename MatrixType::Nested>::type& nestedExpression()
{ return derived().nestedExpression(); }
public: public:
typedef CwiseUnaryView<ViewOp, MatrixType> Derived; typedef typename MatrixType::template MakeBase< CwiseUnaryView<ViewOp, MatrixType> >::Type Base;
EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const
{ {
return derived()._functor()(nestedExpression().coeff(row, col)); return derived().functor()(derived().nestedExpression().coeff(row, col));
} }
EIGEN_STRONG_INLINE const Scalar coeff(int index) const EIGEN_STRONG_INLINE const Scalar coeff(int index) const
{ {
return derived()._functor()(nestedExpression().coeff(index)); return derived().functor()(derived().nestedExpression().coeff(index));
} }
EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col) EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col)
{ {
return derived()._functor()(nestedExpression().const_cast_derived().coeffRef(row, col)); return derived().functor()(const_cast_derived().nestedExpression().coeffRef(row, col));
} }
EIGEN_STRONG_INLINE Scalar& coeffRef(int index) EIGEN_STRONG_INLINE Scalar& coeffRef(int index)
{ {
return derived()._functor()(nestedExpression().const_cast_derived().coeffRef(index)); return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
} }
}; };

View File

@ -2,7 +2,7 @@
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -192,11 +192,15 @@ template<typename Derived> class DenseBase
/** \internal Represents a matrix with all coefficients equal to one another*/ /** \internal Represents a matrix with all coefficients equal to one another*/
typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType; typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType;
/** \internal Represents a vector with linearly spaced coefficients that allows sequential access only. */
typedef CwiseNullaryOp<ei_linspaced_op<Scalar,false>,Derived> SequentialLinSpacedReturnType;
/** \internal Represents a vector with linearly spaced coefficients that allows random access. */
typedef CwiseNullaryOp<ei_linspaced_op<Scalar,true>,Derived> RandomAccessLinSpacedReturnType;
/** \internal the return type of MatrixBase::eigenvalues() */ /** \internal the return type of MatrixBase::eigenvalues() */
typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType; typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType;
/** \internal expression tyepe of a column */ /** \internal expression type of a column */
typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr; typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr;
/** \internal expression tyepe of a column */ /** \internal expression type of a column */
typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr; typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr;
#endif // not EIGEN_PARSED_BY_DOXYGEN #endif // not EIGEN_PARSED_BY_DOXYGEN
@ -229,6 +233,9 @@ template<typename Derived> class DenseBase
CommaInitializer<Derived> operator<< (const Scalar& s); CommaInitializer<Derived> operator<< (const Scalar& s);
template<unsigned int Added,unsigned int Removed>
const Flagged<Derived, Added, Removed> flagged() const;
template<typename OtherDerived> template<typename OtherDerived>
CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other); CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other);
@ -343,6 +350,11 @@ template<typename Derived> class DenseBase
static const ConstantReturnType static const ConstantReturnType
Constant(const Scalar& value); Constant(const Scalar& value);
static const SequentialLinSpacedReturnType
LinSpaced(Sequential_t, const Scalar& low, const Scalar& high, int size);
static const RandomAccessLinSpacedReturnType
LinSpaced(const Scalar& low, const Scalar& high, int size);
template<typename CustomNullaryOp> template<typename CustomNullaryOp>
static const CwiseNullaryOp<CustomNullaryOp, Derived> static const CwiseNullaryOp<CustomNullaryOp, Derived>
NullaryExpr(int rows, int cols, const CustomNullaryOp& func); NullaryExpr(int rows, int cols, const CustomNullaryOp& func);
@ -362,24 +374,24 @@ template<typename Derived> class DenseBase
void fill(const Scalar& value); void fill(const Scalar& value);
Derived& setConstant(const Scalar& value); Derived& setConstant(const Scalar& value);
Derived& setLinSpaced(const Scalar& low, const Scalar& high, int size);
Derived& setZero(); Derived& setZero();
Derived& setOnes(); Derived& setOnes();
Derived& setRandom(); Derived& setRandom();
template<typename OtherDerived> template<typename OtherDerived>
bool isApprox(const DenseBase<OtherDerived>& other, bool isApprox(const DenseBase<OtherDerived>& other,
RealScalar prec = dummy_precision<Scalar>()) const; RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isMuchSmallerThan(const RealScalar& other, bool isMuchSmallerThan(const RealScalar& other,
RealScalar prec = dummy_precision<Scalar>()) const; RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
template<typename OtherDerived> template<typename OtherDerived>
bool isMuchSmallerThan(const DenseBase<OtherDerived>& other, bool isMuchSmallerThan(const DenseBase<OtherDerived>& other,
RealScalar prec = dummy_precision<Scalar>()) const; RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; bool isConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isZero(RealScalar prec = dummy_precision<Scalar>()) const; bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const; bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
inline Derived& operator*=(const Scalar& other); inline Derived& operator*=(const Scalar& other);
inline Derived& operator/=(const Scalar& other); inline Derived& operator/=(const Scalar& other);
@ -474,6 +486,12 @@ template<typename Derived> class DenseBase
#include EIGEN_DENSEBASE_PLUGIN #include EIGEN_DENSEBASE_PLUGIN
#endif #endif
// disable the use of evalTo for dense objects with a nice compilation error
template<typename Dest> inline void evalTo(Dest& dst) const
{
EIGEN_STATIC_ASSERT((ei_is_same_type<Dest,void>::ret),THE_EVAL_EVALTO_FUNCTION_SHOULD_NEVER_BE_CALLED_FOR_DENSE_OBJECTS);
}
protected: protected:
/** Default constructor. Do nothing. */ /** Default constructor. Do nothing. */
DenseBase() DenseBase()

View File

@ -62,7 +62,7 @@ class DenseStorageBase : public _Base<Derived>
typedef class Eigen::Map<Derived, Aligned> AlignedMapType; typedef class Eigen::Map<Derived, Aligned> AlignedMapType;
protected: protected:
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage; ei_matrix_storage<Scalar, Base::MaxSizeAtCompileTime, Base::RowsAtCompileTime, Base::ColsAtCompileTime, Options> m_storage;
public: public:
enum { NeedsToAlign = (!(Options&DontAlign)) enum { NeedsToAlign = (!(Options&DontAlign))
@ -371,8 +371,7 @@ class DenseStorageBase : public _Base<Derived>
: m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols())
{ {
_check_template_params(); _check_template_params();
resize(other.rows(), other.cols()); Base::operator=(other.derived());
*this = other;
} }
/** \name Map /** \name Map
@ -490,12 +489,8 @@ class DenseStorageBase : public _Base<Derived>
return ei_assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived()); return ei_assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived());
} }
static EIGEN_STRONG_INLINE void _check_template_params() EIGEN_STRONG_INLINE void _check_template_params()
{ {
#ifdef EIGEN_DEBUG_MATRIX_CTOR
EIGEN_DEBUG_MATRIX_CTOR;
#endif
EIGEN_STATIC_ASSERT(((RowsAtCompileTime >= MaxRowsAtCompileTime) EIGEN_STATIC_ASSERT(((RowsAtCompileTime >= MaxRowsAtCompileTime)
&& (ColsAtCompileTime >= MaxColsAtCompileTime) && (ColsAtCompileTime >= MaxColsAtCompileTime)
&& (MaxRowsAtCompileTime >= 0) && (MaxRowsAtCompileTime >= 0)

View File

@ -64,7 +64,7 @@ struct ei_traits<Diagonal<MatrixType,Index> >
}; };
template<typename MatrixType, int Index> class Diagonal template<typename MatrixType, int Index> class Diagonal
: public MatrixBase<Diagonal<MatrixType, Index> > : public MatrixType::template MakeBase< Diagonal<MatrixType,Index> >::Type
{ {
// some compilers may fail to optimize std::max etc in case of compile-time constants... // some compilers may fail to optimize std::max etc in case of compile-time constants...
EIGEN_STRONG_INLINE int absIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); } EIGEN_STRONG_INLINE int absIndex() const { return m_index.value()>0 ? m_index.value() : -m_index.value(); }
@ -73,7 +73,8 @@ template<typename MatrixType, int Index> class Diagonal
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Diagonal) typedef typename MatrixType::template MakeBase<Diagonal>::Type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
inline Diagonal(const MatrixType& matrix, int index = Index) : m_matrix(matrix), m_index(index) {} inline Diagonal(const MatrixType& matrix, int index = Index) : m_matrix(matrix), m_index(index) {}

View File

@ -68,10 +68,10 @@ class DiagonalBase : public AnyMatrixBase<Derived>
const DiagonalProduct<MatrixDerived, Derived, OnTheLeft> const DiagonalProduct<MatrixDerived, Derived, OnTheLeft>
operator*(const MatrixBase<MatrixDerived> &matrix) const; operator*(const MatrixBase<MatrixDerived> &matrix) const;
inline const DiagonalWrapper<NestByValue<CwiseUnaryOp<ei_scalar_inverse_op<Scalar>, DiagonalVectorType> > > inline const DiagonalWrapper<CwiseUnaryOp<ei_scalar_inverse_op<Scalar>, DiagonalVectorType> >
inverse() const inverse() const
{ {
return diagonal().cwiseInverse().nestByValue(); return diagonal().cwiseInverse();
} }
}; };

View File

@ -48,7 +48,8 @@ class DiagonalProduct : ei_no_assignment_operator,
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(DiagonalProduct) typedef MatrixBase<DiagonalProduct> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(DiagonalProduct)
inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal) inline DiagonalProduct(const MatrixType& matrix, const DiagonalType& diagonal)
: m_matrix(matrix), m_diagonal(diagonal) : m_matrix(matrix), m_diagonal(diagonal)

View File

@ -1,55 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_EXPRESSIONMAKER_H
#define EIGEN_EXPRESSIONMAKER_H
// computes the shape of a matrix from its traits flag
template<typename XprType> struct ei_shape_of
{
enum { ret = ei_traits<XprType>::Flags&SparseBit ? IsSparse : IsDense };
};
// Since the Sparse module is completely separated from the Core module, there is
// no way to write the type of a generic expression working for both dense and sparse
// matrix. Unless we change the overall design, here is a workaround.
// There is an example in unsuported/Eigen/src/AutoDiff/AutoDiffScalar.
template<typename Func, typename XprType, int Shape = ei_shape_of<XprType>::ret>
struct MakeCwiseUnaryOp
{
typedef CwiseUnaryOp<Func,XprType> Type;
};
template<typename Func, typename A, typename B, int Shape = ei_shape_of<A>::ret>
struct MakeCwiseBinaryOp
{
typedef CwiseBinaryOp<Func,A,B> Type;
};
// TODO complete the list
#endif // EIGEN_EXPRESSIONMAKER_H

View File

@ -25,9 +25,7 @@
#ifndef EIGEN_FLAGGED_H #ifndef EIGEN_FLAGGED_H
#define EIGEN_FLAGGED_H #define EIGEN_FLAGGED_H
/** \deprecated it is only used by lazy() which is deprecated /** \class Flagged
*
* \class Flagged
* *
* \brief Expression with modified flags * \brief Expression with modified flags
* *
@ -52,7 +50,8 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Flagged) typedef MatrixBase<Flagged> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Flagged)
typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret, typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
ExpressionType, const ExpressionType&>::ret ExpressionTypeNested; ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
typedef typename ExpressionType::InnerIterator InnerIterator; typedef typename ExpressionType::InnerIterator InnerIterator;
@ -119,58 +118,18 @@ template<typename ExpressionType, unsigned int Added, unsigned int Removed> clas
ExpressionTypeNested m_matrix; ExpressionTypeNested m_matrix;
}; };
/** \deprecated it is only used by lazy() which is deprecated /** \returns an expression of *this with added and removed flags
* *
* \returns an expression of *this with added flags * This is mostly for internal use.
* *
* Example: \include MatrixBase_marked.cpp * \sa class Flagged
* Output: \verbinclude MatrixBase_marked.out
*
* \sa class Flagged, extract(), part()
*/ */
template<typename Derived> template<typename Derived>
template<unsigned int Added> template<unsigned int Added,unsigned int Removed>
inline const Flagged<Derived, Added, 0> inline const Flagged<Derived, Added, Removed>
MatrixBase<Derived>::marked() const DenseBase<Derived>::flagged() const
{ {
return derived(); return derived();
} }
/** \deprecated use MatrixBase::noalias()
*
* \returns an expression of *this with the EvalBeforeAssigningBit flag removed.
*
* Example: \include MatrixBase_lazy.cpp
* Output: \verbinclude MatrixBase_lazy.out
*
* \sa class Flagged, marked()
*/
template<typename Derived>
inline const Flagged<Derived, 0, EvalBeforeAssigningBit>
MatrixBase<Derived>::lazy() const
{
return derived();
}
/** \internal
* Overloaded to perform an efficient C += (A*B).lazy() */
template<typename Derived>
template<typename ProductDerived, typename Lhs, typename Rhs>
Derived& MatrixBase<Derived>::operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
EvalBeforeAssigningBit>& other)
{
other._expression().derived().addTo(derived()); return derived();
}
/** \internal
* Overloaded to perform an efficient C -= (A*B).lazy() */
template<typename Derived>
template<typename ProductDerived, typename Lhs, typename Rhs>
Derived& MatrixBase<Derived>::operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
EvalBeforeAssigningBit>& other)
{
other._expression().derived().subTo(derived()); return derived();
}
#endif // EIGEN_FLAGGED_H #endif // EIGEN_FLAGGED_H

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -41,11 +41,12 @@ struct ei_traits<ForceAlignedAccess<ExpressionType> > : public ei_traits<Express
{}; {};
template<typename ExpressionType> class ForceAlignedAccess template<typename ExpressionType> class ForceAlignedAccess
: public MatrixBase<ForceAlignedAccess<ExpressionType> > : public ExpressionType::template MakeBase< ForceAlignedAccess<ExpressionType> >::Type
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(ForceAlignedAccess) typedef typename ExpressionType::template MakeBase<ForceAlignedAccess<ExpressionType> >::Type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(ForceAlignedAccess)
inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {} inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {}

View File

@ -437,7 +437,7 @@ struct ei_scalar_constant_op {
EIGEN_STRONG_INLINE ei_scalar_constant_op(const ei_scalar_constant_op& other) : m_other(other.m_other) { } EIGEN_STRONG_INLINE ei_scalar_constant_op(const ei_scalar_constant_op& other) : m_other(other.m_other) { }
EIGEN_STRONG_INLINE ei_scalar_constant_op(const Scalar& other) : m_other(other) { } EIGEN_STRONG_INLINE ei_scalar_constant_op(const Scalar& other) : m_other(other) { }
EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; } EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; }
EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); } EIGEN_STRONG_INLINE const PacketScalar packetOp(int, int = 0) const { return ei_pset1(m_other); }
const Scalar m_other; const Scalar m_other;
}; };
template<typename Scalar> template<typename Scalar>
@ -452,6 +452,75 @@ template<typename Scalar>
struct ei_functor_traits<ei_scalar_identity_op<Scalar> > struct ei_functor_traits<ei_scalar_identity_op<Scalar> >
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; }; { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
template <typename Scalar, bool RandomAccess> struct ei_linspaced_op_impl;
// linear access for packet ops:
// 1) initialization
// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0])
// 2) each step
// base += [size*step, ..., size*step]
template <typename Scalar>
struct ei_linspaced_op_impl<Scalar,false>
{
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
ei_linspaced_op_impl(Scalar low, Scalar step) :
m_low(low), m_step(step),
m_packetStep(ei_pset1(ei_packet_traits<Scalar>::size*step)),
m_base(ei_padd(ei_pset1(low),ei_pmul(ei_pset1(step),ei_plset<Scalar>(-ei_packet_traits<Scalar>::size)))) {}
EIGEN_STRONG_INLINE const Scalar operator() (int i) const { return m_low+i*m_step; }
EIGEN_STRONG_INLINE const PacketScalar packetOp(int) const { return m_base = ei_padd(m_base,m_packetStep); }
const Scalar m_low;
const Scalar m_step;
const PacketScalar m_packetStep;
mutable PacketScalar m_base;
};
// random access for packet ops:
// 1) each step
// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
template <typename Scalar>
struct ei_linspaced_op_impl<Scalar,true>
{
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
ei_linspaced_op_impl(Scalar low, Scalar step) :
m_low(low), m_step(step),
m_lowPacket(ei_pset1(m_low)), m_stepPacket(ei_pset1(m_step)), m_interPacket(ei_plset<Scalar>(0)) {}
EIGEN_STRONG_INLINE const Scalar operator() (int i) const { return m_low+i*m_step; }
EIGEN_STRONG_INLINE const PacketScalar packetOp(int i) const
{ return ei_padd(m_lowPacket, ei_pmul(m_stepPacket, ei_padd(ei_pset1<Scalar>(i),m_interPacket))); }
const Scalar m_low;
const Scalar m_step;
const PacketScalar m_lowPacket;
const PacketScalar m_stepPacket;
const PacketScalar m_interPacket;
};
// ----- Linspace functor ----------------------------------------------------------------
// Forward declaration (we default to random access which does not really give
// us a speed gain when using packet access but it allows to use the functor in
// nested expressions).
template <typename Scalar, bool RandomAccess = true> struct ei_linspaced_op;
template <typename Scalar, bool RandomAccess> struct ei_functor_traits< ei_linspaced_op<Scalar,RandomAccess> >
{ enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; };
template <typename Scalar, bool RandomAccess> struct ei_linspaced_op
{
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
ei_linspaced_op(Scalar low, Scalar high, int num_steps) : impl(low, (high-low)/(num_steps-1)) {}
EIGEN_STRONG_INLINE const Scalar operator() (int i, int = 0) const { return impl(i); }
EIGEN_STRONG_INLINE const PacketScalar packetOp(int i, int = 0) const { return impl.packetOp(i); }
// This proxy object handles the actual required temporaries, the different
// implementations (random vs. sequential access) as well as the piping
// correct piping to size 2/4 packet operations.
const ei_linspaced_op_impl<Scalar,RandomAccess> impl;
};
// allow to add new functors and specializations of ei_functor_traits from outside Eigen. // allow to add new functors and specializations of ei_functor_traits from outside Eigen.
// this macro is really needed because ei_functor_traits must be specialized after it is declared but before it is used... // this macro is really needed because ei_functor_traits must be specialized after it is declared but before it is used...
#ifdef EIGEN_FUNCTORS_PLUGIN #ifdef EIGEN_FUNCTORS_PLUGIN

View File

@ -157,6 +157,10 @@ ei_ploadu(const Scalar* from) { return *from; }
template<typename Scalar> inline typename ei_packet_traits<Scalar>::type template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
ei_pset1(const Scalar& a) { return a; } ei_pset1(const Scalar& a) { return a; }
/** \internal \brief Returns a packet with coefficients (a,a+1,...,a+packet_size-1). */
template<typename Scalar> inline typename ei_packet_traits<Scalar>::type
ei_plset(const Scalar& a) { return a; }
/** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */ /** \internal copy the packet \a from to \a *to, \a to must be 16 bytes aligned */
template<typename Scalar, typename Packet> inline void ei_pstore(Scalar* to, const Packet& from) template<typename Scalar, typename Packet> inline void ei_pstore(Scalar* to, const Packet& from)
{ (*to) = from; } { (*to) = from; }

View File

@ -143,9 +143,16 @@ std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOForm
} }
else if(fmt.precision == FullPrecision) else if(fmt.precision == FullPrecision)
{ {
explicit_precision = NumTraits<Scalar>::HasFloatingPoint if (NumTraits<Scalar>::HasFloatingPoint)
? std::ceil(-ei_log(epsilon<Scalar>())/ei_log(10.0)) {
: 0; typedef typename NumTraits<Scalar>::Real RealScalar;
RealScalar explicit_precision_fp = std::ceil(-ei_log(NumTraits<Scalar>::epsilon())/ei_log(10.0));
explicit_precision = static_cast<std::streamsize>(explicit_precision_fp);
}
else
{
explicit_precision = 0;
}
} }
else else
{ {

View File

@ -64,7 +64,7 @@ template<typename MatrixType, int Options> class Map
public: public:
typedef MapBase<Map,typename MatrixType::template MakeBase<Map>::Type> Base; typedef MapBase<Map,typename MatrixType::template MakeBase<Map>::Type> Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(Map) EIGEN_DENSE_PUBLIC_INTERFACE(Map)
inline int stride() const { return this->innerSize(); } inline int stride() const { return this->innerSize(); }

View File

@ -88,7 +88,7 @@ template<typename Derived, typename Base> class MapBase
inline const Scalar& coeff(int index) const inline const Scalar& coeff(int index) const
{ {
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit)); ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) ) if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
return m_data[index]; return m_data[index];
else else
return m_data[index*stride()]; return m_data[index*stride()];
@ -97,7 +97,7 @@ template<typename Derived, typename Base> class MapBase
inline Scalar& coeffRef(int index) inline Scalar& coeffRef(int index)
{ {
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit)); ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) ) if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
return const_cast<Scalar*>(m_data)[index]; return const_cast<Scalar*>(m_data)[index];
else else
return const_cast<Scalar*>(m_data)[index*stride()]; return const_cast<Scalar*>(m_data)[index*stride()];
@ -170,7 +170,7 @@ template<typename Derived, typename Base> class MapBase
void checkDataAlignment() const void checkDataAlignment() const
{ {
ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit)) ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit))
|| ((std::size_t(m_data)&0xf)==0)) && "data is not aligned"); || ((size_t(m_data)&0xf)==0)) && "data is not aligned");
} }
const Scalar* EIGEN_RESTRICT m_data; const Scalar* EIGEN_RESTRICT m_data;

View File

@ -25,13 +25,6 @@
#ifndef EIGEN_MATHFUNCTIONS_H #ifndef EIGEN_MATHFUNCTIONS_H
#define EIGEN_MATHFUNCTIONS_H #define EIGEN_MATHFUNCTIONS_H
template<typename T> inline typename NumTraits<T>::Real epsilon()
{
return std::numeric_limits<typename NumTraits<T>::Real>::epsilon();
}
template<typename T> inline typename NumTraits<T>::Real dummy_precision();
template<typename T> inline T ei_random(T a, T b); template<typename T> inline T ei_random(T a, T b);
template<typename T> inline T ei_random(); template<typename T> inline T ei_random();
template<typename T> inline T ei_random_amplitude() template<typename T> inline T ei_random_amplitude()
@ -55,12 +48,11 @@ template<typename T> inline typename NumTraits<T>::Real ei_hypot(T x, T y)
*** int *** *** int ***
**************/ **************/
template<> inline int dummy_precision<int>() { return 0; }
inline int ei_real(int x) { return x; } inline int ei_real(int x) { return x; }
inline int& ei_real_ref(int& x) { return x; } inline int& ei_real_ref(int& x) { return x; }
inline int ei_imag(int) { return 0; } inline int ei_imag(int) { return 0; }
inline int ei_conj(int x) { return x; } inline int ei_conj(int x) { return x; }
inline int ei_abs(int x) { return abs(x); } inline int ei_abs(int x) { return std::abs(x); }
inline int ei_abs2(int x) { return x*x; } inline int ei_abs2(int x) { return x*x; }
inline int ei_sqrt(int) { ei_assert(false); return 0; } inline int ei_sqrt(int) { ei_assert(false); return 0; }
inline int ei_exp(int) { ei_assert(false); return 0; } inline int ei_exp(int) { ei_assert(false); return 0; }
@ -86,21 +78,21 @@ inline int ei_pow(int x, int y)
template<> inline int ei_random(int a, int b) template<> inline int ei_random(int a, int b)
{ {
// We can't just do rand()%n as only the high-order bits are really random // We can't just do rand()%n as only the high-order bits are really random
return a + static_cast<int>((b-a+1) * (rand() / (RAND_MAX + 1.0))); return a + static_cast<int>((b-a+1) * (std::rand() / (RAND_MAX + 1.0)));
} }
template<> inline int ei_random() template<> inline int ei_random()
{ {
return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>()); return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>());
} }
inline bool ei_isMuchSmallerThan(int a, int, int = dummy_precision<int>()) inline bool ei_isMuchSmallerThan(int a, int, int = NumTraits<int>::dummy_precision())
{ {
return a == 0; return a == 0;
} }
inline bool ei_isApprox(int a, int b, int = dummy_precision<int>()) inline bool ei_isApprox(int a, int b, int = NumTraits<int>::dummy_precision())
{ {
return a == b; return a == b;
} }
inline bool ei_isApproxOrLessThan(int a, int b, int = dummy_precision<int>()) inline bool ei_isApproxOrLessThan(int a, int b, int = NumTraits<int>::dummy_precision())
{ {
return a <= b; return a <= b;
} }
@ -109,7 +101,6 @@ inline bool ei_isApproxOrLessThan(int a, int b, int = dummy_precision<int>())
*** float *** *** float ***
**************/ **************/
template<> inline float dummy_precision<float>() { return 1e-5f; }
inline float ei_real(float x) { return x; } inline float ei_real(float x) { return x; }
inline float& ei_real_ref(float& x) { return x; } inline float& ei_real_ref(float& x) { return x; }
inline float ei_imag(float) { return 0.f; } inline float ei_imag(float) { return 0.f; }
@ -140,15 +131,15 @@ template<> inline float ei_random()
{ {
return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>()); return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>());
} }
inline bool ei_isMuchSmallerThan(float a, float b, float prec = dummy_precision<float>()) inline bool ei_isMuchSmallerThan(float a, float b, float prec = NumTraits<float>::dummy_precision())
{ {
return ei_abs(a) <= ei_abs(b) * prec; return ei_abs(a) <= ei_abs(b) * prec;
} }
inline bool ei_isApprox(float a, float b, float prec = dummy_precision<float>()) inline bool ei_isApprox(float a, float b, float prec = NumTraits<float>::dummy_precision())
{ {
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec; return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
} }
inline bool ei_isApproxOrLessThan(float a, float b, float prec = dummy_precision<float>()) inline bool ei_isApproxOrLessThan(float a, float b, float prec = NumTraits<float>::dummy_precision())
{ {
return a <= b || ei_isApprox(a, b, prec); return a <= b || ei_isApprox(a, b, prec);
} }
@ -157,8 +148,6 @@ inline bool ei_isApproxOrLessThan(float a, float b, float prec = dummy_precision
*** double *** *** double ***
**************/ **************/
template<> inline double dummy_precision<double>() { return 1e-12; }
inline double ei_real(double x) { return x; } inline double ei_real(double x) { return x; }
inline double& ei_real_ref(double& x) { return x; } inline double& ei_real_ref(double& x) { return x; }
inline double ei_imag(double) { return 0.; } inline double ei_imag(double) { return 0.; }
@ -189,15 +178,15 @@ template<> inline double ei_random()
{ {
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>()); return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
} }
inline bool ei_isMuchSmallerThan(double a, double b, double prec = dummy_precision<double>()) inline bool ei_isMuchSmallerThan(double a, double b, double prec = NumTraits<double>::dummy_precision())
{ {
return ei_abs(a) <= ei_abs(b) * prec; return ei_abs(a) <= ei_abs(b) * prec;
} }
inline bool ei_isApprox(double a, double b, double prec = dummy_precision<double>()) inline bool ei_isApprox(double a, double b, double prec = NumTraits<double>::dummy_precision())
{ {
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec; return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
} }
inline bool ei_isApproxOrLessThan(double a, double b, double prec = dummy_precision<double>()) inline bool ei_isApproxOrLessThan(double a, double b, double prec = NumTraits<double>::dummy_precision())
{ {
return a <= b || ei_isApprox(a, b, prec); return a <= b || ei_isApprox(a, b, prec);
} }
@ -206,7 +195,6 @@ inline bool ei_isApproxOrLessThan(double a, double b, double prec = dummy_precis
*** complex<float> *** *** complex<float> ***
*********************/ *********************/
template<> inline float dummy_precision<std::complex<float> >() { return dummy_precision<float>(); }
inline float ei_real(const std::complex<float>& x) { return std::real(x); } inline float ei_real(const std::complex<float>& x) { return std::real(x); }
inline float ei_imag(const std::complex<float>& x) { return std::imag(x); } inline float ei_imag(const std::complex<float>& x) { return std::imag(x); }
inline float& ei_real_ref(std::complex<float>& x) { return reinterpret_cast<float*>(&x)[0]; } inline float& ei_real_ref(std::complex<float>& x) { return reinterpret_cast<float*>(&x)[0]; }
@ -225,15 +213,15 @@ template<> inline std::complex<float> ei_random()
{ {
return std::complex<float>(ei_random<float>(), ei_random<float>()); return std::complex<float>(ei_random<float>(), ei_random<float>());
} }
inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>()) inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = NumTraits<float>::dummy_precision())
{ {
return ei_abs2(a) <= ei_abs2(b) * prec * prec; return ei_abs2(a) <= ei_abs2(b) * prec * prec;
} }
inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = dummy_precision<float>()) inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = NumTraits<float>::dummy_precision())
{ {
return ei_abs2(a) <= ei_abs2(b) * prec * prec; return ei_abs2(a) <= ei_abs2(b) * prec * prec;
} }
inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>()) inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = NumTraits<float>::dummy_precision())
{ {
return ei_isApprox(ei_real(a), ei_real(b), prec) return ei_isApprox(ei_real(a), ei_real(b), prec)
&& ei_isApprox(ei_imag(a), ei_imag(b), prec); && ei_isApprox(ei_imag(a), ei_imag(b), prec);
@ -244,7 +232,6 @@ inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>&
*** complex<double> *** *** complex<double> ***
**********************/ **********************/
template<> inline double dummy_precision<std::complex<double> >() { return dummy_precision<double>(); }
inline double ei_real(const std::complex<double>& x) { return std::real(x); } inline double ei_real(const std::complex<double>& x) { return std::real(x); }
inline double ei_imag(const std::complex<double>& x) { return std::imag(x); } inline double ei_imag(const std::complex<double>& x) { return std::imag(x); }
inline double& ei_real_ref(std::complex<double>& x) { return reinterpret_cast<double*>(&x)[0]; } inline double& ei_real_ref(std::complex<double>& x) { return reinterpret_cast<double*>(&x)[0]; }
@ -263,15 +250,15 @@ template<> inline std::complex<double> ei_random()
{ {
return std::complex<double>(ei_random<double>(), ei_random<double>()); return std::complex<double>(ei_random<double>(), ei_random<double>());
} }
inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>()) inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = NumTraits<double>::dummy_precision())
{ {
return ei_abs2(a) <= ei_abs2(b) * prec * prec; return ei_abs2(a) <= ei_abs2(b) * prec * prec;
} }
inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = dummy_precision<double>()) inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = NumTraits<double>::dummy_precision())
{ {
return ei_abs2(a) <= ei_abs2(b) * prec * prec; return ei_abs2(a) <= ei_abs2(b) * prec * prec;
} }
inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>()) inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = NumTraits<double>::dummy_precision())
{ {
return ei_isApprox(ei_real(a), ei_real(b), prec) return ei_isApprox(ei_real(a), ei_real(b), prec)
&& ei_isApprox(ei_imag(a), ei_imag(b), prec); && ei_isApprox(ei_imag(a), ei_imag(b), prec);
@ -283,7 +270,6 @@ inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double
*** long double *** *** long double ***
******************/ ******************/
template<> inline long double dummy_precision<long double>() { return dummy_precision<double>(); }
inline long double ei_real(long double x) { return x; } inline long double ei_real(long double x) { return x; }
inline long double& ei_real_ref(long double& x) { return x; } inline long double& ei_real_ref(long double& x) { return x; }
inline long double ei_imag(long double) { return 0.; } inline long double ei_imag(long double) { return 0.; }
@ -306,15 +292,15 @@ template<> inline long double ei_random()
{ {
return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>()); return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>());
} }
inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = dummy_precision<long double>()) inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = NumTraits<long double>::dummy_precision())
{ {
return ei_abs(a) <= ei_abs(b) * prec; return ei_abs(a) <= ei_abs(b) * prec;
} }
inline bool ei_isApprox(long double a, long double b, long double prec = dummy_precision<long double>()) inline bool ei_isApprox(long double a, long double b, long double prec = NumTraits<long double>::dummy_precision())
{ {
return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec; return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec;
} }
inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = dummy_precision<long double>()) inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = NumTraits<long double>::dummy_precision())
{ {
return a <= b || ei_isApprox(a, b, prec); return a <= b || ei_isApprox(a, b, prec);
} }
@ -323,7 +309,6 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec
*** bool *** *** bool ***
**************/ **************/
template<> inline bool dummy_precision<bool>() { return 0; }
inline bool ei_real(bool x) { return x; } inline bool ei_real(bool x) { return x; }
inline bool& ei_real_ref(bool& x) { return x; } inline bool& ei_real_ref(bool& x) { return x; }
inline bool ei_imag(bool) { return 0; } inline bool ei_imag(bool) { return 0; }
@ -336,15 +321,15 @@ template<> inline bool ei_random()
{ {
return (ei_random<int>(0,1) == 1); return (ei_random<int>(0,1) == 1);
} }
inline bool ei_isMuchSmallerThan(bool a, bool, bool = dummy_precision<bool>()) inline bool ei_isMuchSmallerThan(bool a, bool, bool = NumTraits<bool>::dummy_precision())
{ {
return !a; return !a;
} }
inline bool ei_isApprox(bool a, bool b, bool = dummy_precision<bool>()) inline bool ei_isApprox(bool a, bool b, bool = NumTraits<bool>::dummy_precision())
{ {
return a == b; return a == b;
} }
inline bool ei_isApproxOrLessThan(bool a, bool b, bool = dummy_precision<bool>()) inline bool ei_isApproxOrLessThan(bool a, bool b, bool = NumTraits<bool>::dummy_precision())
{ {
return int(a) <= int(b); return int(a) <= int(b);
} }

View File

@ -134,10 +134,10 @@ class Matrix
* \sa DenseStorageBase * \sa DenseStorageBase
*/ */
typedef DenseStorageBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Eigen::MatrixBase, _Options> Base; typedef DenseStorageBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, Eigen::MatrixBase, _Options> Base;
enum { Options = _Options }; enum { Options = _Options };
_EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) EIGEN_DENSE_PUBLIC_INTERFACE(Matrix)
typedef typename Base::PlainMatrixType PlainMatrixType; typedef typename Base::PlainMatrixType PlainMatrixType;
@ -297,7 +297,7 @@ class Matrix
} }
/** \brief Copy constructor for generic expressions. /** \brief Copy constructor for generic expressions.
* \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) * \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&)
*/ */
template<typename OtherDerived> template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other) EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other)
@ -311,7 +311,7 @@ class Matrix
} }
/** \internal /** \internal
* \brief Override MatrixBase::swap() since for dynamic-sized matrices * \brief Override MatrixBase::swap() since for dynamic-sized matrices
* of same type it is enough to swap the data pointers. * of same type it is enough to swap the data pointers.
*/ */
template<typename OtherDerived> template<typename OtherDerived>

View File

@ -119,8 +119,8 @@ template<typename Derived> class MatrixBase
/** \brief The plain matrix type corresponding to this expression. /** \brief The plain matrix type corresponding to this expression.
* *
* This is not necessarily exactly the return type of eval(). In the case of plain matrices, * This is not necessarily exactly the return type of eval(). In the case of plain matrices,
* the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed * the return type of eval() is a const reference to a matrix, not a matrix! It is however guaranteed
* that the return type of eval() is either PlainMatrixType or const PlainMatrixType&. * that the return type of eval() is either PlainMatrixType or const PlainMatrixType&.
*/ */
typedef Matrix<typename ei_traits<Derived>::Scalar, typedef Matrix<typename ei_traits<Derived>::Scalar,
@ -188,6 +188,10 @@ template<typename Derived> class MatrixBase
const typename ProductReturnType<Derived,OtherDerived>::Type const typename ProductReturnType<Derived,OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const; operator*(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived>
const typename ProductReturnType<Derived,OtherDerived,LazyCoeffBasedProductMode>::Type
lazyProduct(const MatrixBase<OtherDerived> &other) const;
template<typename OtherDerived> template<typename OtherDerived>
Derived& operator*=(const AnyMatrixBase<OtherDerived>& other); Derived& operator*=(const AnyMatrixBase<OtherDerived>& other);
@ -249,16 +253,16 @@ template<typename Derived> class MatrixBase
Derived& setIdentity(); Derived& setIdentity();
Derived& setIdentity(int rows, int cols); Derived& setIdentity(int rows, int cols);
bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const; bool isIdentity(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const; bool isDiagonal(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isUpperTriangular(RealScalar prec = dummy_precision<Scalar>()) const; bool isUpperTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isLowerTriangular(RealScalar prec = dummy_precision<Scalar>()) const; bool isLowerTriangular(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
template<typename OtherDerived> template<typename OtherDerived>
bool isOrthogonal(const MatrixBase<OtherDerived>& other, bool isOrthogonal(const MatrixBase<OtherDerived>& other,
RealScalar prec = dummy_precision<Scalar>()) const; RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const; bool isUnitary(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
/** \returns true if each coefficients of \c *this and \a other are all exactly equal. /** \returns true if each coefficients of \c *this and \a other are all exactly equal.
* \warning When using floating point scalar values you probably should rather use a * \warning When using floating point scalar values you probably should rather use a
@ -278,13 +282,11 @@ template<typename Derived> class MatrixBase
NoAlias<Derived,Eigen::MatrixBase > noalias(); NoAlias<Derived,Eigen::MatrixBase > noalias();
inline const NestByValue<Derived> nestByValue() const;
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const; inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
inline ForceAlignedAccess<Derived> forceAlignedAccess(); inline ForceAlignedAccess<Derived> forceAlignedAccess();
template<bool Enable> inline const typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf() const; template<bool Enable> inline const typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf() const;
template<bool Enable> inline typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf(); template<bool Enable> inline typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf();
Scalar mean() const;
Scalar trace() const; Scalar trace() const;
/////////// Array module /////////// /////////// Array module ///////////
@ -308,13 +310,13 @@ template<typename Derived> class MatrixBase
ResultType& inverse, ResultType& inverse,
typename ResultType::Scalar& determinant, typename ResultType::Scalar& determinant,
bool& invertible, bool& invertible,
const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>() const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
) const; ) const;
template<typename ResultType> template<typename ResultType>
void computeInverseWithCheck( void computeInverseWithCheck(
ResultType& inverse, ResultType& inverse,
bool& invertible, bool& invertible,
const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>() const RealScalar& absDeterminantThreshold = NumTraits<Scalar>::dummy_precision()
) const; ) const;
Scalar determinant() const; Scalar determinant() const;

View File

@ -26,6 +26,12 @@
#ifndef EIGEN_MATRIXSTORAGE_H #ifndef EIGEN_MATRIXSTORAGE_H
#define EIGEN_MATRIXSTORAGE_H #define EIGEN_MATRIXSTORAGE_H
#ifdef EIGEN_DEBUG_MATRIX_CTOR
#define EIGEN_INT_DEBUG_MATRIX_CTOR EIGEN_DEBUG_MATRIX_CTOR;
#else
#define EIGEN_INT_DEBUG_MATRIX_CTOR
#endif
struct ei_constructor_without_unaligned_array_assert {}; struct ei_constructor_without_unaligned_array_assert {};
/** \internal /** \internal
@ -183,7 +189,8 @@ template<typename T, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic,
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert)
: m_data(0), m_rows(0), m_cols(0) {} : m_data(0), m_rows(0), m_cols(0) {}
inline ei_matrix_storage(int size, int rows, int cols) inline ei_matrix_storage(int size, int rows, int cols)
: m_data(ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols) {} : m_data(ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size)), m_rows(rows), m_cols(cols)
{ EIGEN_INT_DEBUG_MATRIX_CTOR }
inline ~ei_matrix_storage() { ei_conditional_aligned_delete<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); } inline ~ei_matrix_storage() { ei_conditional_aligned_delete<T,(_Options&DontAlign)==0>(m_data, m_rows*m_cols); }
inline void swap(ei_matrix_storage& other) inline void swap(ei_matrix_storage& other)
{ std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); }
@ -198,6 +205,7 @@ template<typename T, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic,
m_data = ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size); m_data = ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size);
else else
m_data = 0; m_data = 0;
EIGEN_INT_DEBUG_MATRIX_CTOR
} }
m_rows = rows; m_rows = rows;
m_cols = cols; m_cols = cols;
@ -214,7 +222,8 @@ template<typename T, int _Rows, int _Options> class ei_matrix_storage<T, Dynamic
public: public:
inline explicit ei_matrix_storage() : m_data(0), m_cols(0) {} inline explicit ei_matrix_storage() : m_data(0), m_cols(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {} inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_cols(0) {}
inline ei_matrix_storage(int size, int, int cols) : m_data(ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size)), m_cols(cols) {} inline ei_matrix_storage(int size, int, int cols) : m_data(ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size)), m_cols(cols)
{ EIGEN_INT_DEBUG_MATRIX_CTOR }
inline ~ei_matrix_storage() { ei_conditional_aligned_delete<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); } inline ~ei_matrix_storage() { ei_conditional_aligned_delete<T,(_Options&DontAlign)==0>(m_data, _Rows*m_cols); }
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); }
inline static int rows(void) {return _Rows;} inline static int rows(void) {return _Rows;}
@ -228,6 +237,7 @@ template<typename T, int _Rows, int _Options> class ei_matrix_storage<T, Dynamic
m_data = ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size); m_data = ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size);
else else
m_data = 0; m_data = 0;
EIGEN_INT_DEBUG_MATRIX_CTOR
} }
m_cols = cols; m_cols = cols;
} }
@ -243,7 +253,8 @@ template<typename T, int _Cols, int _Options> class ei_matrix_storage<T, Dynamic
public: public:
inline explicit ei_matrix_storage() : m_data(0), m_rows(0) {} inline explicit ei_matrix_storage() : m_data(0), m_rows(0) {}
inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {} inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(0), m_rows(0) {}
inline ei_matrix_storage(int size, int rows, int) : m_data(ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size)), m_rows(rows) {} inline ei_matrix_storage(int size, int rows, int) : m_data(ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size)), m_rows(rows)
{ EIGEN_INT_DEBUG_MATRIX_CTOR }
inline ~ei_matrix_storage() { ei_conditional_aligned_delete<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); } inline ~ei_matrix_storage() { ei_conditional_aligned_delete<T,(_Options&DontAlign)==0>(m_data, _Cols*m_rows); }
inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); }
inline int rows(void) const {return m_rows;} inline int rows(void) const {return m_rows;}
@ -257,6 +268,7 @@ template<typename T, int _Cols, int _Options> class ei_matrix_storage<T, Dynamic
m_data = ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size); m_data = ei_conditional_aligned_new<T,(_Options&DontAlign)==0>(size);
else else
m_data = 0; m_data = 0;
EIGEN_INT_DEBUG_MATRIX_CTOR
} }
m_rows = rows; m_rows = rows;
} }

View File

@ -64,7 +64,8 @@ template<typename MatrixType> class Minor
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(Minor) typedef MatrixBase<Minor> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Minor)
inline Minor(const MatrixType& matrix, inline Minor(const MatrixType& matrix,
int row, int col) int row, int col)

View File

@ -42,11 +42,12 @@ struct ei_traits<NestByValue<ExpressionType> > : public ei_traits<ExpressionType
{}; {};
template<typename ExpressionType> class NestByValue template<typename ExpressionType> class NestByValue
: public MatrixBase<NestByValue<ExpressionType> > : public ExpressionType::template MakeBase< NestByValue<ExpressionType> >::Type
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(NestByValue) typedef typename ExpressionType::template MakeBase<NestByValue<ExpressionType> >::Type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(NestByValue)
inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {} inline NestByValue(const ExpressionType& matrix) : m_expression(matrix) {}
@ -97,7 +98,7 @@ template<typename ExpressionType> class NestByValue
{ {
m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); m_expression.const_cast_derived().template writePacket<LoadMode>(index, x);
} }
operator const ExpressionType&() const { return m_expression; } operator const ExpressionType&() const { return m_expression; }
protected: protected:
@ -108,7 +109,7 @@ template<typename ExpressionType> class NestByValue
*/ */
template<typename Derived> template<typename Derived>
inline const NestByValue<Derived> inline const NestByValue<Derived>
MatrixBase<Derived>::nestByValue() const DenseBase<Derived>::nestByValue() const
{ {
return NestByValue<Derived>(derived()); return NestByValue<Derived>(derived());
} }

View File

@ -69,6 +69,14 @@ class NoAlias
template<typename ProductDerived, typename Lhs, typename Rhs> template<typename ProductDerived, typename Lhs, typename Rhs>
EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other) EIGEN_STRONG_INLINE ExpressionType& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
{ other.derived().subTo(m_expression); return m_expression; } { other.derived().subTo(m_expression); return m_expression; }
template<typename Lhs, typename Rhs, int NestingFlags>
EIGEN_STRONG_INLINE ExpressionType& operator+=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
{ return m_expression.derived() += CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
template<typename Lhs, typename Rhs, int NestingFlags>
EIGEN_STRONG_INLINE ExpressionType& operator-=(const CoeffBasedProduct<Lhs,Rhs,NestingFlags>& other)
{ return m_expression.derived() -= CoeffBasedProduct<Lhs,Rhs,NestByRefBit>(other.lhs(), other.rhs()); }
#endif #endif
protected: protected:

View File

@ -34,7 +34,7 @@
* \c std::complex<float>, \c std::complex<double>, and \c long \c double (especially * \c std::complex<float>, \c std::complex<double>, and \c long \c double (especially
* useful to enforce x87 arithmetics when SSE is the default). * useful to enforce x87 arithmetics when SSE is the default).
* *
* The provided data consists of: * The provided data consists of everything that is supported by std::numeric_limits, plus:
* \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real, * \li A typedef \a Real, giving the "real part" type of \a T. If \a T is already real,
* then \a Real is just a typedef to \a T. If \a T is \c std::complex<U> then \a Real * then \a Real is just a typedef to \a T. If \a T is \c std::complex<U> then \a Real
* is a typedef to \a U. * is a typedef to \a U.
@ -45,10 +45,29 @@
* type, and to 0 otherwise. * type, and to 0 otherwise.
* \li An enum \a HasFloatingPoint. It is equal to \c 0 if \a T is \c int, * \li An enum \a HasFloatingPoint. It is equal to \c 0 if \a T is \c int,
* and to \c 1 otherwise. * and to \c 1 otherwise.
* \li An epsilon() function which, unlike std::numeric_limits::epsilon(), returns a \a Real instead of a \a T.
* \li A dummy_precision() function returning a weak epsilon value. It is mainly used by the fuzzy comparison operators.
* \li Two highest() and lowest() functions returning the highest and lowest possible values respectively.
*/ */
template<typename T> struct NumTraits; template<typename T> struct NumTraits;
template<typename T> struct ei_default_float_numtraits
: std::numeric_limits<T>
{
inline static T highest() { return std::numeric_limits<T>::max(); }
inline static T lowest() { return -std::numeric_limits<T>::max(); }
};
template<typename T> struct ei_default_integral_numtraits
: std::numeric_limits<T>
{
inline static T dummy_precision() { return T(0); }
inline static T highest() { return std::numeric_limits<T>::max(); }
inline static T lowest() { return std::numeric_limits<T>::min(); }
};
template<> struct NumTraits<int> template<> struct NumTraits<int>
: ei_default_integral_numtraits<int>
{ {
typedef int Real; typedef int Real;
typedef double FloatingPoint; typedef double FloatingPoint;
@ -63,6 +82,7 @@ template<> struct NumTraits<int>
}; };
template<> struct NumTraits<float> template<> struct NumTraits<float>
: ei_default_float_numtraits<float>
{ {
typedef float Real; typedef float Real;
typedef float FloatingPoint; typedef float FloatingPoint;
@ -74,9 +94,12 @@ template<> struct NumTraits<float>
AddCost = 1, AddCost = 1,
MulCost = 1 MulCost = 1
}; };
inline static float dummy_precision() { return 1e-5f; }
}; };
template<> struct NumTraits<double> template<> struct NumTraits<double>
: ei_default_float_numtraits<double>
{ {
typedef double Real; typedef double Real;
typedef double FloatingPoint; typedef double FloatingPoint;
@ -88,9 +111,12 @@ template<> struct NumTraits<double>
AddCost = 1, AddCost = 1,
MulCost = 1 MulCost = 1
}; };
inline static double dummy_precision() { return 1e-12; }
}; };
template<typename _Real> struct NumTraits<std::complex<_Real> > template<typename _Real> struct NumTraits<std::complex<_Real> >
: ei_default_float_numtraits<std::complex<_Real> >
{ {
typedef _Real Real; typedef _Real Real;
typedef std::complex<_Real> FloatingPoint; typedef std::complex<_Real> FloatingPoint;
@ -102,9 +128,13 @@ template<typename _Real> struct NumTraits<std::complex<_Real> >
AddCost = 2 * NumTraits<Real>::AddCost, AddCost = 2 * NumTraits<Real>::AddCost,
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
}; };
inline static Real epsilon() { return std::numeric_limits<Real>::epsilon(); }
inline static Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
}; };
template<> struct NumTraits<long long int> template<> struct NumTraits<long long int>
: ei_default_integral_numtraits<long long int>
{ {
typedef long long int Real; typedef long long int Real;
typedef long double FloatingPoint; typedef long double FloatingPoint;
@ -119,6 +149,7 @@ template<> struct NumTraits<long long int>
}; };
template<> struct NumTraits<long double> template<> struct NumTraits<long double>
: ei_default_float_numtraits<long double>
{ {
typedef long double Real; typedef long double Real;
typedef long double FloatingPoint; typedef long double FloatingPoint;
@ -130,9 +161,12 @@ template<> struct NumTraits<long double>
AddCost = 1, AddCost = 1,
MulCost = 1 MulCost = 1
}; };
static inline long double dummy_precision() { return NumTraits<double>::dummy_precision(); }
}; };
template<> struct NumTraits<bool> template<> struct NumTraits<bool>
: ei_default_integral_numtraits<bool>
{ {
typedef bool Real; typedef bool Real;
typedef float FloatingPoint; typedef float FloatingPoint;

View File

@ -54,8 +54,6 @@ enum {
Small = Dynamic/2 Small = Dynamic/2
}; };
enum { OuterProduct, InnerProduct, UnrolledProduct, GemvProduct, GemmProduct };
template<typename Lhs, typename Rhs> struct ei_product_type template<typename Lhs, typename Rhs> struct ei_product_type
{ {
typedef typename ei_cleantype<Lhs>::type _Lhs; typedef typename ei_cleantype<Lhs>::type _Lhs;
@ -89,9 +87,12 @@ public:
template<int Rows, int Cols> struct ei_product_type_selector<Rows, Cols, 1> { enum { ret = OuterProduct }; }; template<int Rows, int Cols> struct ei_product_type_selector<Rows, Cols, 1> { enum { ret = OuterProduct }; };
template<int Depth> struct ei_product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; }; template<int Depth> struct ei_product_type_selector<1, 1, Depth> { enum { ret = InnerProduct }; };
template<> struct ei_product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; }; template<> struct ei_product_type_selector<1, 1, 1> { enum { ret = InnerProduct }; };
template<> struct ei_product_type_selector<Small,1, Small> { enum { ret = UnrolledProduct }; }; template<> struct ei_product_type_selector<Small,1, Small> { enum { ret = CoeffBasedProductMode }; };
template<> struct ei_product_type_selector<1, Small,Small> { enum { ret = UnrolledProduct }; }; template<> struct ei_product_type_selector<1, Small,Small> { enum { ret = CoeffBasedProductMode }; };
template<> struct ei_product_type_selector<Small,Small,Small> { enum { ret = UnrolledProduct }; }; template<> struct ei_product_type_selector<Small,Small,Small> { enum { ret = CoeffBasedProductMode }; };
template<> struct ei_product_type_selector<Small, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; };
template<> struct ei_product_type_selector<Small, Large, 1> { enum { ret = LazyCoeffBasedProductMode }; };
template<> struct ei_product_type_selector<Large, Small, 1> { enum { ret = LazyCoeffBasedProductMode }; };
template<> struct ei_product_type_selector<1, Large,Small> { enum { ret = GemvProduct }; }; template<> struct ei_product_type_selector<1, Large,Small> { enum { ret = GemvProduct }; };
template<> struct ei_product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; }; template<> struct ei_product_type_selector<1, Large,Large> { enum { ret = GemvProduct }; };
template<> struct ei_product_type_selector<1, Small,Large> { enum { ret = GemvProduct }; }; template<> struct ei_product_type_selector<1, Small,Large> { enum { ret = GemvProduct }; };
@ -133,11 +134,19 @@ struct ProductReturnType
}; };
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,UnrolledProduct> struct ProductReturnType<Lhs,Rhs,CoeffBasedProductMode>
{ {
typedef typename ei_nested<Lhs, Rhs::ColsAtCompileTime, typename ei_plain_matrix_type<Lhs>::type >::type LhsNested; typedef typename ei_nested<Lhs, Rhs::ColsAtCompileTime, typename ei_plain_matrix_type<Lhs>::type >::type LhsNested;
typedef typename ei_nested<Rhs, Lhs::RowsAtCompileTime, typename ei_plain_matrix_type<Rhs>::type >::type RhsNested; typedef typename ei_nested<Rhs, Lhs::RowsAtCompileTime, typename ei_plain_matrix_type<Rhs>::type >::type RhsNested;
typedef GeneralProduct<LhsNested, RhsNested, UnrolledProduct> Type; typedef CoeffBasedProduct<LhsNested, RhsNested, EvalBeforeAssigningBit | EvalBeforeNestingBit> Type;
};
template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,LazyCoeffBasedProductMode>
{
typedef typename ei_nested<Lhs, Rhs::ColsAtCompileTime, typename ei_plain_matrix_type<Lhs>::type >::type LhsNested;
typedef typename ei_nested<Rhs, Lhs::RowsAtCompileTime, typename ei_plain_matrix_type<Rhs>::type >::type RhsNested;
typedef CoeffBasedProduct<LhsNested, RhsNested, NestByRefBit> Type;
}; };
@ -411,7 +420,7 @@ template<> struct ei_gemv_selector<OnTheRight,RowMajor,false>
* *
* \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*(). * \note If instead of the matrix product you want the coefficient-wise product, see Cwise::operator*().
* *
* \sa lazy(), operator*=(const MatrixBase&), Cwise::operator*() * \sa lazyProduct(), operator*=(const MatrixBase&), Cwise::operator*()
*/ */
template<typename Derived> template<typename Derived>
template<typename OtherDerived> template<typename OtherDerived>
@ -436,4 +445,39 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const
return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
} }
/** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation.
*
* The returned product will behave like any other expressions: the coefficients of the product will be
* computed once at a time as requested. This might be useful in some extremely rare cases when only
* a small and no coherent fraction of the result's coefficients have to be computed.
*
* \warning This version of the matrix product can be much much slower. So use it only if you know
* what you are doing and that you measured a true speed improvement.
*
* \sa operator*(const MatrixBase&)
*/
template<typename Derived>
template<typename OtherDerived>
const typename ProductReturnType<Derived,OtherDerived,LazyCoeffBasedProductMode>::Type
MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const
{
enum {
ProductIsValid = Derived::ColsAtCompileTime==Dynamic
|| OtherDerived::RowsAtCompileTime==Dynamic
|| int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
};
// note to the lost user:
// * for a dot product use: v1.dot(v2)
// * for a coeff-wise product use: v1.cwiseProduct(v2)
EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
return typename ProductReturnType<Derived,OtherDerived,LazyCoeffBasedProductMode>::Type(derived(), other.derived());
}
#endif // EIGEN_PRODUCT_H #endif // EIGEN_PRODUCT_H

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -42,21 +42,15 @@ struct ei_traits<ProductBase<Derived,_Lhs,_Rhs> > //: ei_traits<typename ei_clea
ColsAtCompileTime = ei_traits<Rhs>::ColsAtCompileTime, ColsAtCompileTime = ei_traits<Rhs>::ColsAtCompileTime,
MaxRowsAtCompileTime = ei_traits<Lhs>::MaxRowsAtCompileTime, MaxRowsAtCompileTime = ei_traits<Lhs>::MaxRowsAtCompileTime,
MaxColsAtCompileTime = ei_traits<Rhs>::MaxColsAtCompileTime, MaxColsAtCompileTime = ei_traits<Rhs>::MaxColsAtCompileTime,
Flags = EvalBeforeNestingBit | EvalBeforeAssigningBit, Flags = EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit, // Note that EvalBeforeNestingBit and NestByRefBit
// are not used in practice because ei_nested is overloaded for products
CoeffReadCost = 0 // FIXME why is it needed ? CoeffReadCost = 0 // FIXME why is it needed ?
}; };
}; };
// enforce evaluation before nesting
template<typename Derived, typename Lhs, typename Rhs,int N,typename EvalType>
struct ei_nested<ProductBase<Derived,Lhs,Rhs>, N, EvalType>
{
typedef EvalType type;
};
#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \ #define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \
typedef ProductBase<Derived, Lhs, Rhs > Base; \ typedef ProductBase<Derived, Lhs, Rhs > Base; \
_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
typedef typename Base::LhsNested LhsNested; \ typedef typename Base::LhsNested LhsNested; \
typedef typename Base::_LhsNested _LhsNested; \ typedef typename Base::_LhsNested _LhsNested; \
typedef typename Base::LhsBlasTraits LhsBlasTraits; \ typedef typename Base::LhsBlasTraits LhsBlasTraits; \
@ -75,8 +69,8 @@ class ProductBase : public MatrixBase<Derived>
{ {
public: public:
typedef MatrixBase<Derived> Base; typedef MatrixBase<Derived> Base;
_EIGEN_GENERIC_PUBLIC_INTERFACE(ProductBase) EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase)
protected:
typedef typename Lhs::Nested LhsNested; typedef typename Lhs::Nested LhsNested;
typedef typename ei_cleantype<LhsNested>::type _LhsNested; typedef typename ei_cleantype<LhsNested>::type _LhsNested;
typedef ei_blas_traits<_LhsNested> LhsBlasTraits; typedef ei_blas_traits<_LhsNested> LhsBlasTraits;
@ -89,7 +83,11 @@ class ProductBase : public MatrixBase<Derived>
typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType;
using Base::derived; // Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once
typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType;
public:
typedef typename Base::PlainMatrixType PlainMatrixType; typedef typename Base::PlainMatrixType PlainMatrixType;
ProductBase(const Lhs& lhs, const Rhs& rhs) ProductBase(const Lhs& lhs, const Rhs& rhs)
@ -115,17 +113,34 @@ class ProductBase : public MatrixBase<Derived>
template<typename Dest> template<typename Dest>
inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); }
EIGEN_DEPRECATED const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const
{ return *this; }
const _LhsNested& lhs() const { return m_lhs; } const _LhsNested& lhs() const { return m_lhs; }
const _RhsNested& rhs() const { return m_rhs; } const _RhsNested& rhs() const { return m_rhs; }
// Implicit convertion to the nested type (trigger the evaluation of the product)
operator const PlainMatrixType& () const
{
m_result.resize(m_lhs.rows(), m_rhs.cols());
this->evalTo(m_result);
return m_result;
}
const Diagonal<FullyLazyCoeffBaseProductType,0> diagonal() const
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
template<int Index>
const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(int index) const
{ return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); }
protected: protected:
const LhsNested m_lhs; const LhsNested m_lhs;
const RhsNested m_rhs; const RhsNested m_rhs;
mutable PlainMatrixType m_result;
private: private:
// discard coeff methods // discard coeff methods
@ -135,6 +150,14 @@ class ProductBase : public MatrixBase<Derived>
void coeffRef(int); void coeffRef(int);
}; };
// here we need to overload the nested rule for products
// such that the nested type is a const reference to a plain matrix
template<typename Lhs, typename Rhs, int Mode, int N, typename PlainMatrixType>
struct ei_nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainMatrixType>
{
typedef PlainMatrixType const& type;
};
template<typename NestedProduct> template<typename NestedProduct>
class ScaledProduct; class ScaledProduct;

View File

@ -49,7 +49,7 @@ private:
MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit) MightVectorize = (int(Derived::Flags)&ActualPacketAccessBit)
&& (ei_functor_traits<Func>::PacketAccess), && (ei_functor_traits<Func>::PacketAccess),
MayLinearVectorize = MightVectorize && (int(Derived::Flags)&LinearAccessBit), MayLinearVectorize = MightVectorize && (int(Derived::Flags)&LinearAccessBit),
MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize
}; };
public: public:
@ -58,7 +58,7 @@ public:
: int(MaySliceVectorize) ? int(SliceVectorizedTraversal) : int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
: int(DefaultTraversal) : int(DefaultTraversal)
}; };
private: private:
enum { enum {
Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost
@ -123,7 +123,7 @@ struct ei_redux_novec_unroller<Func, Derived, Start, 0>
}; };
/*** vectorization ***/ /*** vectorization ***/
template<typename Func, typename Derived, int Start, int Length> template<typename Func, typename Derived, int Start, int Length>
struct ei_redux_vec_unroller struct ei_redux_vec_unroller
{ {
@ -223,7 +223,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
for(int index = alignedStart + packetSize; index < alignedEnd; index += packetSize) for(int index = alignedStart + packetSize; index < alignedEnd; index += packetSize)
packet_res = func.packetOp(packet_res, mat.template packet<alignment>(index)); packet_res = func.packetOp(packet_res, mat.template packet<alignment>(index));
res = func.predux(packet_res); res = func.predux(packet_res);
for(int index = 0; index < alignedStart; ++index) for(int index = 0; index < alignedStart; ++index)
res = func(res,mat.coeff(index)); res = func(res,mat.coeff(index));
@ -265,7 +265,7 @@ struct ei_redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
for(int i=0; i<packetedInnerSize; i+=int(packetSize)) for(int i=0; i<packetedInnerSize; i+=int(packetSize))
packet_res = func.packetOp(packet_res, mat.template packet<Unaligned> packet_res = func.packetOp(packet_res, mat.template packet<Unaligned>
(isRowMajor?j:i, isRowMajor?i:j)); (isRowMajor?j:i, isRowMajor?i:j));
res = func.predux(packet_res); res = func.predux(packet_res);
for(int j=0; j<outerSize; ++j) for(int j=0; j<outerSize; ++j)
for(int i=packetedInnerSize; i<innerSize; ++i) for(int i=packetedInnerSize; i<innerSize; ++i)
@ -313,10 +313,9 @@ template<typename Func>
inline typename ei_result_of<Func(typename ei_traits<Derived>::Scalar)>::type inline typename ei_result_of<Func(typename ei_traits<Derived>::Scalar)>::type
DenseBase<Derived>::redux(const Func& func) const DenseBase<Derived>::redux(const Func& func) const
{ {
typename Derived::Nested nested(derived());
typedef typename ei_cleantype<typename Derived::Nested>::type ThisNested; typedef typename ei_cleantype<typename Derived::Nested>::type ThisNested;
return ei_redux_impl<Func, ThisNested> return ei_redux_impl<Func, ThisNested>
::run(nested, func); ::run(derived(), func);
} }
/** \returns the minimum of all coefficients of *this /** \returns the minimum of all coefficients of *this
@ -356,7 +355,7 @@ template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar
DenseBase<Derived>::mean() const DenseBase<Derived>::mean() const
{ {
return this->redux(Eigen::ei_scalar_sum_op<Scalar>()) / this->size(); return Scalar(this->redux(Eigen::ei_scalar_sum_op<Scalar>())) / Scalar(this->size());
} }
/** \returns the product of all coefficients of *this /** \returns the product of all coefficients of *this
@ -383,7 +382,7 @@ template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar
MatrixBase<Derived>::trace() const MatrixBase<Derived>::trace() const
{ {
return diagonal().sum(); return derived().diagonal().sum();
} }
#endif // EIGEN_REDUX_H #endif // EIGEN_REDUX_H

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
@ -57,17 +57,31 @@ struct ei_nested<ReturnByValue<Derived>, n, PlainMatrixType>
typedef typename ei_traits<Derived>::ReturnMatrixType type; typedef typename ei_traits<Derived>::ReturnMatrixType type;
}; };
template<typename Derived> template<typename Derived> class ReturnByValue
class ReturnByValue : public MatrixBase<ReturnByValue<Derived> > : public ei_traits<Derived>::ReturnMatrixType::template MakeBase<ReturnByValue<Derived> >::Type
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(ReturnByValue)
typedef typename ei_traits<Derived>::ReturnMatrixType ReturnMatrixType; typedef typename ei_traits<Derived>::ReturnMatrixType ReturnMatrixType;
typedef typename ReturnMatrixType::template MakeBase<ReturnByValue<Derived> >::Type Base;
EIGEN_DENSE_PUBLIC_INTERFACE(ReturnByValue)
template<typename Dest> template<typename Dest>
inline void evalTo(Dest& dst) const inline void evalTo(Dest& dst) const
{ static_cast<const Derived* const>(this)->evalTo(dst); } { static_cast<const Derived* const>(this)->evalTo(dst); }
inline int rows() const { return static_cast<const Derived* const>(this)->rows(); } inline int rows() const { return static_cast<const Derived* const>(this)->rows(); }
inline int cols() const { return static_cast<const Derived* const>(this)->cols(); } inline int cols() const { return static_cast<const Derived* const>(this)->cols(); }
#ifndef EIGEN_PARSED_BY_DOXYGEN
#define Unusable YOU_ARE_TRYING_TO_ACCESS_A_SINGLE_COEFFICIENT_IN_A_SPECIAL_EXPRESSION_WHERE_THAT_IS_NOT_ALLOWED_BECAUSE_THAT_WOULD_BE_INEFFICIENT
class Unusable{
Unusable(const Unusable&) {}
Unusable& operator=(const Unusable&) {return *this;}
};
const Unusable& coeff(int) const { return *reinterpret_cast<const Unusable*>(this); }
const Unusable& coeff(int,int) const { return *reinterpret_cast<const Unusable*>(this); }
Unusable& coeffRef(int) { return *reinterpret_cast<Unusable*>(this); }
Unusable& coeffRef(int,int) { return *reinterpret_cast<Unusable*>(this); }
#endif
}; };
template<typename Derived> template<typename Derived>

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -47,7 +47,7 @@ template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
public: public:
typedef typename MatrixType::template MakeBase< SelfCwiseBinaryOp<BinaryOp, MatrixType> >::Type Base; typedef typename MatrixType::template MakeBase< SelfCwiseBinaryOp<BinaryOp, MatrixType> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp) EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
typedef typename ei_packet_traits<Scalar>::type Packet; typedef typename ei_packet_traits<Scalar>::type Packet;

View File

@ -254,7 +254,7 @@ void TriangularView<MatrixType,Mode>::solveInPlace(const MatrixBase<OtherDerived
OtherCopy otherCopy(other); OtherCopy otherCopy(other);
ei_triangular_solver_selector<MatrixType, typename ei_unref<OtherCopy>::type, ei_triangular_solver_selector<MatrixType, typename ei_unref<OtherCopy>::type,
Side, Mode>::run(_expression(), otherCopy); Side, Mode>::run(nestedExpression(), otherCopy);
if (copy) if (copy)
other = otherCopy; other = otherCopy;

View File

@ -118,10 +118,10 @@ MatrixBase<Derived>::blueNorm() const
iexp = - ((iemax+it)/2); iexp = - ((iemax+it)/2);
s2m = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range s2m = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for upper range
overfl = rbig*s2m; // overfow boundary for abig overfl = rbig*s2m; // overflow boundary for abig
eps = RealScalar(std::pow(double(ibeta), 1-it)); eps = RealScalar(std::pow(double(ibeta), 1-it));
relerr = ei_sqrt(eps); // tolerance for neglecting asml relerr = ei_sqrt(eps); // tolerance for neglecting asml
abig = 1.0/eps - 1.0; abig = RealScalar(1.0/eps - 1.0);
if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n if (RealScalar(nbig)>abig) nmax = int(abig); // largest safe n
else nmax = nbig; else nmax = nbig;
} }

View File

@ -40,7 +40,7 @@ template<typename ExpressionType> class SwapWrapper
public: public:
typedef typename ExpressionType::template MakeBase<SwapWrapper<ExpressionType> >::Type Base; typedef typename ExpressionType::template MakeBase<SwapWrapper<ExpressionType> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper) EIGEN_DENSE_PUBLIC_INTERFACE(SwapWrapper)
typedef typename ei_packet_traits<Scalar>::type Packet; typedef typename ei_packet_traits<Scalar>::type Packet;
inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {} inline SwapWrapper(ExpressionType& xpr) : m_expression(xpr) {}

View File

@ -2,6 +2,7 @@
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -49,7 +50,7 @@ struct ei_traits<Transpose<MatrixType> > : ei_traits<MatrixType>
ColsAtCompileTime = MatrixType::RowsAtCompileTime, ColsAtCompileTime = MatrixType::RowsAtCompileTime,
MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime, MaxRowsAtCompileTime = MatrixType::MaxColsAtCompileTime,
MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime, MaxColsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
Flags = (int(_MatrixTypeNested::Flags) ^ RowMajorBit), Flags = int(_MatrixTypeNested::Flags & ~NestByRefBit) ^ RowMajorBit,
CoeffReadCost = _MatrixTypeNested::CoeffReadCost CoeffReadCost = _MatrixTypeNested::CoeffReadCost
}; };
}; };
@ -71,13 +72,11 @@ template<typename MatrixType> class Transpose
inline int rows() const { return m_matrix.cols(); } inline int rows() const { return m_matrix.cols(); }
inline int cols() const { return m_matrix.rows(); } inline int cols() const { return m_matrix.rows(); }
/** \internal used for introspection */ /** \returns the nested expression */
const typename ei_cleantype<typename MatrixType::Nested>::type&
_expression() const { return m_matrix; }
const typename ei_cleantype<typename MatrixType::Nested>::type& const typename ei_cleantype<typename MatrixType::Nested>::type&
nestedExpression() const { return m_matrix; } nestedExpression() const { return m_matrix; }
/** \returns the nested expression */
typename ei_cleantype<typename MatrixType::Nested>::type& typename ei_cleantype<typename MatrixType::Nested>::type&
nestedExpression() { return m_matrix.const_cast_derived(); } nestedExpression() { return m_matrix.const_cast_derived(); }
@ -89,65 +88,57 @@ template<typename MatrixType> class Transpose
template<typename MatrixType> class TransposeImpl<MatrixType,Dense> template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
: public MatrixType::template MakeBase<Transpose<MatrixType> >::Type : public MatrixType::template MakeBase<Transpose<MatrixType> >::Type
{ {
const typename ei_cleantype<typename MatrixType::Nested>::type& nestedExpression() const
{ return derived().nestedExpression(); }
typename ei_cleantype<typename MatrixType::Nested>::type& nestedExpression()
{ return derived().nestedExpression(); }
public: public:
//EIGEN_DENSE_PUBLpename IC_INTERFACE(TransposeImpl,MatrixBase<Transpose<MatrixType> >)
typedef typename MatrixType::template MakeBase<Transpose<MatrixType> >::Type Base; typedef typename MatrixType::template MakeBase<Transpose<MatrixType> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>) EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
// EIGEN_EXPRESSION_IMPL_COMMON(MatrixBase<Transpose<MatrixType> >) inline int stride() const { return derived().nestedExpression().stride(); }
inline Scalar* data() { return derived().nestedExpression().data(); }
inline int stride() const { return nestedExpression().stride(); } inline const Scalar* data() const { return derived().nestedExpression().data(); }
inline Scalar* data() { return nestedExpression().data(); }
inline const Scalar* data() const { return nestedExpression().data(); }
inline Scalar& coeffRef(int row, int col) inline Scalar& coeffRef(int row, int col)
{ {
return nestedExpression().const_cast_derived().coeffRef(col, row); return const_cast_derived().nestedExpression().coeffRef(col, row);
} }
inline Scalar& coeffRef(int index) inline Scalar& coeffRef(int index)
{ {
return nestedExpression().const_cast_derived().coeffRef(index); return const_cast_derived().nestedExpression().coeffRef(index);
} }
inline const CoeffReturnType coeff(int row, int col) const inline const CoeffReturnType coeff(int row, int col) const
{ {
return nestedExpression().coeff(col, row); return derived().nestedExpression().coeff(col, row);
} }
inline const CoeffReturnType coeff(int index) const inline const CoeffReturnType coeff(int index) const
{ {
return nestedExpression().coeff(index); return derived().nestedExpression().coeff(index);
} }
template<int LoadMode> template<int LoadMode>
inline const PacketScalar packet(int row, int col) const inline const PacketScalar packet(int row, int col) const
{ {
return nestedExpression().template packet<LoadMode>(col, row); return derived().nestedExpression().template packet<LoadMode>(col, row);
} }
template<int LoadMode> template<int LoadMode>
inline void writePacket(int row, int col, const PacketScalar& x) inline void writePacket(int row, int col, const PacketScalar& x)
{ {
nestedExpression().const_cast_derived().template writePacket<LoadMode>(col, row, x); const_cast_derived().nestedExpression().template writePacket<LoadMode>(col, row, x);
} }
template<int LoadMode> template<int LoadMode>
inline const PacketScalar packet(int index) const inline const PacketScalar packet(int index) const
{ {
return nestedExpression().template packet<LoadMode>(index); return derived().nestedExpression().template packet<LoadMode>(index);
} }
template<int LoadMode> template<int LoadMode>
inline void writePacket(int index, const PacketScalar& x) inline void writePacket(int index, const PacketScalar& x)
{ {
nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x); const_cast_derived().nestedExpression().template writePacket<LoadMode>(index, x);
} }
}; };

View File

@ -204,8 +204,8 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
return m_matrix.const_cast_derived().coeffRef(row, col); return m_matrix.const_cast_derived().coeffRef(row, col);
} }
/** \internal */ const MatrixType& nestedExpression() const { return m_matrix; }
const MatrixType& _expression() const { return m_matrix; } MatrixType& nestedExpression() { return const_cast<MatrixType&>(m_matrix); }
/** Assigns a triangular matrix to a triangular part of a dense matrix */ /** Assigns a triangular matrix to a triangular part of a dense matrix */
template<typename OtherDerived> template<typename OtherDerived>
@ -215,7 +215,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
TriangularView& operator=(const MatrixBase<OtherDerived>& other); TriangularView& operator=(const MatrixBase<OtherDerived>& other);
TriangularView& operator=(const TriangularView& other) TriangularView& operator=(const TriangularView& other)
{ return *this = other._expression(); } { return *this = other.nestedExpression(); }
template<typename OtherDerived> template<typename OtherDerived>
void lazyAssign(const TriangularBase<OtherDerived>& other); void lazyAssign(const TriangularBase<OtherDerived>& other);
@ -510,15 +510,15 @@ template<typename OtherDerived>
inline TriangularView<MatrixType, Mode>& inline TriangularView<MatrixType, Mode>&
TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& other) TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& other)
{ {
ei_assert(Mode == OtherDerived::Mode); ei_assert(Mode == int(OtherDerived::Mode));
if(ei_traits<OtherDerived>::Flags & EvalBeforeAssigningBit) if(ei_traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
{ {
typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols()); typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
other_evaluated.template triangularView<Mode>().lazyAssign(other.derived()); other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
lazyAssign(other_evaluated); lazyAssign(other_evaluated);
} }
else else
lazyAssign(other.derived()); lazyAssign(other.derived().nestedExpression());
return *this; return *this;
} }
@ -534,7 +534,7 @@ void TriangularView<MatrixType, Mode>::lazyAssign(const TriangularBase<OtherDeri
<MatrixType, OtherDerived, int(Mode), <MatrixType, OtherDerived, int(Mode),
unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic, unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
false // preserve the opposite triangular part false // preserve the opposite triangular part
>::run(m_matrix.const_cast_derived(), other.derived()._expression()); >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
} }
/*************************************************************************** /***************************************************************************
@ -571,7 +571,7 @@ void TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
<DenseDerived, typename ei_traits<Derived>::ExpressionType, Derived::Mode, <DenseDerived, typename ei_traits<Derived>::ExpressionType, Derived::Mode,
unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic, unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
true // clear the opposite triangular part true // clear the opposite triangular part
>::run(other.derived(), derived()._expression()); >::run(other.derived(), derived().nestedExpression());
} }
/*************************************************************************** /***************************************************************************

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
@ -75,7 +75,7 @@ template<typename VectorType, int Size> class VectorBlock
IsColVector = ei_traits<VectorType>::ColsAtCompileTime==1 IsColVector = ei_traits<VectorType>::ColsAtCompileTime==1
}; };
public: public:
_EIGEN_GENERIC_PUBLIC_INTERFACE(VectorBlock) EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock)
using Base::operator=; using Base::operator=;

View File

@ -91,6 +91,10 @@ template<> EIGEN_STRONG_INLINE Packet2d ei_pset1<double>(const double& from) { r
#endif #endif
template<> EIGEN_STRONG_INLINE Packet4i ei_pset1<int>(const int& from) { return _mm_set1_epi32(from); } template<> EIGEN_STRONG_INLINE Packet4i ei_pset1<int>(const int& from) { return _mm_set1_epi32(from); }
template<> EIGEN_STRONG_INLINE Packet4f ei_plset<float>(const float& a) { return _mm_add_ps(ei_pset1(a), _mm_set_ps(3,2,1,0)); }
template<> EIGEN_STRONG_INLINE Packet2d ei_plset<double>(const double& a) { return _mm_add_pd(ei_pset1(a),_mm_set_pd(1,0)); }
template<> EIGEN_STRONG_INLINE Packet4i ei_plset<int>(const int& a) { return _mm_add_epi32(ei_pset1(a),_mm_set_epi32(3,2,1,0)); }
template<> EIGEN_STRONG_INLINE Packet4f ei_padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_add_ps(a,b); } template<> EIGEN_STRONG_INLINE Packet4f ei_padd<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_add_ps(a,b); }
template<> EIGEN_STRONG_INLINE Packet2d ei_padd<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_add_pd(a,b); } template<> EIGEN_STRONG_INLINE Packet2d ei_padd<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_add_pd(a,b); }
template<> EIGEN_STRONG_INLINE Packet4i ei_padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_add_epi32(a,b); } template<> EIGEN_STRONG_INLINE Packet4i ei_padd<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_add_epi32(a,b); }

View File

@ -2,7 +2,7 @@
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -23,11 +23,14 @@
// License and a copy of the GNU General Public License along with // License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>. // Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_GENERAL_UNROLLED_PRODUCT_H #ifndef EIGEN_COEFFBASED_PRODUCT_H
#define EIGEN_GENERAL_UNROLLED_PRODUCT_H #define EIGEN_COEFFBASED_PRODUCT_H
/********************************************************************************* /*********************************************************************************
* Specialization of GeneralProduct<> for products with small fixed sizes * Coefficient based product implementation.
* It is designed for the following use cases:
* - small fixed sizes
* - lazy products
*********************************************************************************/ *********************************************************************************/
/* Since the all the dimensions of the product are small, here we can rely /* Since the all the dimensions of the product are small, here we can rely
@ -42,8 +45,8 @@ struct ei_product_coeff_impl;
template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode> template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode>
struct ei_product_packet_impl; struct ei_product_packet_impl;
template<typename LhsNested, typename RhsNested> template<typename LhsNested, typename RhsNested, int NestingFlags>
struct ei_traits<GeneralProduct<LhsNested,RhsNested,UnrolledProduct> > struct ei_traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> >
{ {
typedef DenseStorageMatrix DenseStorageType; typedef DenseStorageMatrix DenseStorageType;
typedef typename ei_cleantype<LhsNested>::type _LhsNested; typedef typename ei_cleantype<LhsNested>::type _LhsNested;
@ -79,8 +82,7 @@ struct ei_traits<GeneralProduct<LhsNested,RhsNested,UnrolledProduct> >
RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit),
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| EvalBeforeAssigningBit | NestingFlags
| EvalBeforeNestingBit
| (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0) | (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0)
| (LhsFlags & RhsFlags & AlignedBit), | (LhsFlags & RhsFlags & AlignedBit),
@ -98,34 +100,43 @@ struct ei_traits<GeneralProduct<LhsNested,RhsNested,UnrolledProduct> >
}; };
}; };
template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,RhsNested,UnrolledProduct> template<typename LhsNested, typename RhsNested, int NestingFlags>
class CoeffBasedProduct
: ei_no_assignment_operator, : ei_no_assignment_operator,
public MatrixBase<GeneralProduct<LhsNested, RhsNested, UnrolledProduct> > public MatrixBase<CoeffBasedProduct<LhsNested, RhsNested, NestingFlags> >
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(GeneralProduct) typedef MatrixBase<CoeffBasedProduct> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(CoeffBasedProduct)
typedef typename Base::PlainMatrixType PlainMatrixType;
private: private:
typedef typename ei_traits<GeneralProduct>::_LhsNested _LhsNested; typedef typename ei_traits<CoeffBasedProduct>::_LhsNested _LhsNested;
typedef typename ei_traits<GeneralProduct>::_RhsNested _RhsNested; typedef typename ei_traits<CoeffBasedProduct>::_RhsNested _RhsNested;
enum { enum {
PacketSize = ei_packet_traits<Scalar>::size, PacketSize = ei_packet_traits<Scalar>::size,
InnerSize = ei_traits<GeneralProduct>::InnerSize, InnerSize = ei_traits<CoeffBasedProduct>::InnerSize,
Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT, Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
CanVectorizeInner = ei_traits<GeneralProduct>::CanVectorizeInner CanVectorizeInner = ei_traits<CoeffBasedProduct>::CanVectorizeInner
}; };
typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal, typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,
Unroll ? InnerSize-1 : Dynamic, Unroll ? InnerSize-1 : Dynamic,
_LhsNested, _RhsNested, Scalar> ScalarCoeffImpl; _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl;
typedef CoeffBasedProduct<LhsNested,RhsNested,NestByRefBit> LazyCoeffBasedProductType;
public: public:
inline CoeffBasedProduct(const CoeffBasedProduct& other)
: Base(), m_lhs(other.m_lhs), m_rhs(other.m_rhs)
{}
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
inline GeneralProduct(const Lhs& lhs, const Rhs& rhs) inline CoeffBasedProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs) : m_lhs(lhs), m_rhs(rhs)
{ {
// we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable. // we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable.
@ -170,11 +181,40 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested,
return res; return res;
} }
// Implicit convertion to the nested type (trigger the evaluation of the product)
operator const PlainMatrixType& () const
{
m_result.lazyAssign(*this);
return m_result;
}
const _LhsNested& lhs() const { return m_lhs; }
const _RhsNested& rhs() const { return m_rhs; }
const Diagonal<LazyCoeffBasedProductType,0> diagonal() const
{ return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); }
template<int Index>
const Diagonal<LazyCoeffBasedProductType,Index> diagonal() const
{ return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); }
const Diagonal<LazyCoeffBasedProductType,Dynamic> diagonal(int index) const
{ return reinterpret_cast<const LazyCoeffBasedProductType&>(*this).diagonal(index); }
protected: protected:
const LhsNested m_lhs; const LhsNested m_lhs;
const RhsNested m_rhs; const RhsNested m_rhs;
mutable PlainMatrixType m_result;
}; };
// here we need to overload the nested rule for products
// such that the nested type is a const reference to a plain matrix
template<typename Lhs, typename Rhs, int N, typename PlainMatrixType>
struct ei_nested<CoeffBasedProduct<Lhs,Rhs,EvalBeforeNestingBit|EvalBeforeAssigningBit>, N, PlainMatrixType>
{
typedef PlainMatrixType const& type;
};
/*************************************************************************** /***************************************************************************
* Normal product .coeff() implementation (with meta-unrolling) * Normal product .coeff() implementation (with meta-unrolling)
@ -385,4 +425,4 @@ struct ei_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, PacketScalar, LoadMod
} }
}; };
#endif // EIGEN_GENERAL_UNROLLED_PRODUCT_H #endif // EIGEN_COEFFBASED_PRODUCT_H

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -185,8 +185,8 @@ struct ei_blas_traits<CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestedXpr> >
IsComplex = NumTraits<Scalar>::IsComplex, IsComplex = NumTraits<Scalar>::IsComplex,
NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex NeedToConjugate = Base::NeedToConjugate ? 0 : IsComplex
}; };
static inline ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
static inline Scalar extractScalarFactor(const XprType& x) { return ei_conj(Base::extractScalarFactor(x._expression())); } static inline Scalar extractScalarFactor(const XprType& x) { return ei_conj(Base::extractScalarFactor(x.nestedExpression())); }
}; };
// pop scalar multiple // pop scalar multiple
@ -197,9 +197,9 @@ struct ei_blas_traits<CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, NestedXpr> >
typedef ei_blas_traits<NestedXpr> Base; typedef ei_blas_traits<NestedXpr> Base;
typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, NestedXpr> XprType; typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, NestedXpr> XprType;
typedef typename Base::ExtractType ExtractType; typedef typename Base::ExtractType ExtractType;
static inline ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
static inline Scalar extractScalarFactor(const XprType& x) static inline Scalar extractScalarFactor(const XprType& x)
{ return x._functor().m_other * Base::extractScalarFactor(x._expression()); } { return x.functor().m_other * Base::extractScalarFactor(x.nestedExpression()); }
}; };
// pop opposite // pop opposite
@ -210,9 +210,9 @@ struct ei_blas_traits<CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, NestedXpr> >
typedef ei_blas_traits<NestedXpr> Base; typedef ei_blas_traits<NestedXpr> Base;
typedef CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, NestedXpr> XprType; typedef CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, NestedXpr> XprType;
typedef typename Base::ExtractType ExtractType; typedef typename Base::ExtractType ExtractType;
static inline ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
static inline Scalar extractScalarFactor(const XprType& x) static inline Scalar extractScalarFactor(const XprType& x)
{ return - Base::extractScalarFactor(x._expression()); } { return - Base::extractScalarFactor(x.nestedExpression()); }
}; };
// pop/push transpose // pop/push transpose
@ -232,8 +232,8 @@ struct ei_blas_traits<Transpose<NestedXpr> >
enum { enum {
IsTransposed = Base::IsTransposed ? 0 : 1 IsTransposed = Base::IsTransposed ? 0 : 1
}; };
static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline const ExtractType extract(const XprType& x) { return Base::extract(x.nestedExpression()); }
static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); } static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x.nestedExpression()); }
}; };
#endif // EIGEN_BLASUTIL_H #endif // EIGEN_BLASUTIL_H

View File

@ -35,7 +35,7 @@
* - It should be smaller than the sqrt of INT_MAX. Indeed, we often multiply a number of rows with a number * - It should be smaller than the sqrt of INT_MAX. Indeed, we often multiply a number of rows with a number
* of columns in order to compute a number of coefficients. Even if we guard that with an "if" checking whether * of columns in order to compute a number of coefficients. Even if we guard that with an "if" checking whether
* the values are Dynamic, we still get a compiler warning "integer overflow". So the only way to get around * the values are Dynamic, we still get a compiler warning "integer overflow". So the only way to get around
* it would be a meta-selector. Doing this everywhere would reduce code readability and lenghten compilation times. * it would be a meta-selector. Doing this everywhere would reduce code readability and lengthen compilation times.
* Also, disabling compiler warnings for integer overflow, sounds like a bad idea. * Also, disabling compiler warnings for integer overflow, sounds like a bad idea.
* - It should be a prime number, because for example the old value 10000 led to bugs with 100x100 matrices. * - It should be a prime number, because for example the old value 10000 led to bugs with 100x100 matrices.
* *
@ -76,7 +76,7 @@ const unsigned int EvalBeforeNestingBit = 0x2;
/** \ingroup flags /** \ingroup flags
* *
* means the expression should be evaluated before any assignement */ * means the expression should be evaluated before any assignment */
const unsigned int EvalBeforeAssigningBit = 0x4; const unsigned int EvalBeforeAssigningBit = 0x4;
/** \ingroup flags /** \ingroup flags
@ -97,6 +97,8 @@ const unsigned int EvalBeforeAssigningBit = 0x4;
*/ */
const unsigned int PacketAccessBit = 0x8; const unsigned int PacketAccessBit = 0x8;
const unsigned int NestByRefBit = 0x100;
#ifdef EIGEN_VECTORIZE #ifdef EIGEN_VECTORIZE
/** \ingroup flags /** \ingroup flags
* *
@ -224,6 +226,11 @@ namespace {
EIGEN_UNUSED NoChange_t NoChange; EIGEN_UNUSED NoChange_t NoChange;
} }
struct Sequential_t {};
namespace {
EIGEN_UNUSED Sequential_t Sequential;
}
struct Default_t {}; struct Default_t {};
namespace { namespace {
EIGEN_UNUSED Default_t Default; EIGEN_UNUSED Default_t Default;
@ -262,4 +269,6 @@ namespace Architecture
enum DenseStorageMatrix {}; enum DenseStorageMatrix {};
enum DenseStorageArray {}; enum DenseStorageArray {};
enum { CoeffBasedProductMode, LazyCoeffBasedProductMode, OuterProduct, InnerProduct, GemvProduct, GemmProduct };
#endif // EIGEN_CONSTANTS_H #endif // EIGEN_CONSTANTS_H

View File

@ -49,8 +49,10 @@ template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp;
template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp; template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp;
template<typename ViewOp, typename MatrixType> class CwiseUnaryView; template<typename ViewOp, typename MatrixType> class CwiseUnaryView;
template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp;
template<typename BinOp, typename MatrixType> class SelfCwiseBinaryOp; template<typename BinOp, typename MatrixType> class SelfCwiseBinaryOp;
template<typename Derived, typename Lhs, typename Rhs> class ProductBase; template<typename Derived, typename Lhs, typename Rhs> class ProductBase;
template<typename Lhs, typename Rhs, int Mode> class GeneralProduct;
template<typename Lhs, typename Rhs, int NestingFlags> class CoeffBasedProduct;
template<typename Derived> class DiagonalBase; template<typename Derived> class DiagonalBase;
template<typename _DiagonalVectorType> class DiagonalWrapper; template<typename _DiagonalVectorType> class DiagonalWrapper;

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
@ -281,50 +281,30 @@ using Eigen::ei_cos;
* Just a side note. Commenting within defines works only by documenting * Just a side note. Commenting within defines works only by documenting
* behind the object (via '!<'). Comments cannot be multi-line and thus * behind the object (via '!<'). Comments cannot be multi-line and thus
* we have these extra long lines. What is confusing doxygen over here is * we have these extra long lines. What is confusing doxygen over here is
* that we use '\' and basically have a bunch of typedefs with their * that we use '\' and basically have a bunch of typedefs with their
* documentation in a single line. * documentation in a single line.
**/ **/
#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ #define EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(Derived) \
typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \
typedef typename Eigen::ei_nested<Derived>::type Nested; \
enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
Flags = Eigen::ei_traits<Derived>::Flags, \
CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \
SizeAtCompileTime = Base::SizeAtCompileTime, \
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \ typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; /*!< \brief Numeric type, e.g. float, double, int or std::complex<float>. */ \
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \ typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; /*!< \brief The underlying numeric type for composed scalar types. \details In cases where Scalar is e.g. std::complex<T>, T were corresponding to RealScalar. */ \
typedef typename Base::PacketScalar PacketScalar; \ typedef typename Base::PacketScalar PacketScalar; \
typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \ typedef typename Base::CoeffReturnType CoeffReturnType; /*!< \brief The return type for coefficient access. \details Depending on whether the object allows direct coefficient access (e.g. for a MatrixXd), this type is either 'const Scalar&' or simply 'Scalar' for objects that do not allow direct coefficient access. */ \
typedef typename Eigen::ei_nested<Derived>::type Nested; \ typedef typename Eigen::ei_nested<Derived>::type Nested; \
enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \
MaxColsAtCompileTime = Eigen::ei_traits<Derived>::MaxColsAtCompileTime, \
Flags = Eigen::ei_traits<Derived>::Flags, \
CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \
SizeAtCompileTime = Base::SizeAtCompileTime, \
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \
typedef Eigen::MatrixBase<Derived> Base; \
_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived)
#define EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(Derived) \
typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \
typedef typename Base::CoeffReturnType CoeffReturnType; \
typedef typename Eigen::ei_nested<Derived>::type Nested; \
enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
Flags = Eigen::ei_traits<Derived>::Flags, \
CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \
SizeAtCompileTime = Base::SizeAtCompileTime, \
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
IsVectorAtCompileTime = Base::IsVectorAtCompileTime };
#define _EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \
typedef typename Base::PacketScalar PacketScalar; \
typedef typename Base::CoeffReturnType CoeffReturnType; \
typedef typename Eigen::ei_nested<Derived>::type Nested; \
enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \
MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \ MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \
@ -334,11 +314,8 @@ using Eigen::ei_cos;
SizeAtCompileTime = Base::SizeAtCompileTime, \ SizeAtCompileTime = Base::SizeAtCompileTime, \
MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \
IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
using Base::derived; using Base::derived; \
using Base::const_cast_derived;
#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
typedef Eigen::MatrixBase<Derived> Base; \
_EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) #define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)

View File

@ -61,7 +61,7 @@
*/ */
inline void* ei_handmade_aligned_malloc(size_t size) inline void* ei_handmade_aligned_malloc(size_t size)
{ {
void *original = malloc(size+16); void *original = std::malloc(size+16);
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16); void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16);
*(reinterpret_cast<void**>(aligned) - 1) = original; *(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned; return aligned;
@ -71,7 +71,7 @@ inline void* ei_handmade_aligned_malloc(size_t size)
inline void ei_handmade_aligned_free(void *ptr) inline void ei_handmade_aligned_free(void *ptr)
{ {
if(ptr) if(ptr)
free(*(reinterpret_cast<void**>(ptr) - 1)); std::free(*(reinterpret_cast<void**>(ptr) - 1));
} }
/** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment. /** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
@ -119,7 +119,7 @@ template<> inline void* ei_conditional_aligned_malloc<false>(size_t size)
ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
#endif #endif
void *result = malloc(size); void *result = std::malloc(size);
#ifdef EIGEN_EXCEPTIONS #ifdef EIGEN_EXCEPTIONS
if(!result) throw std::bad_alloc(); if(!result) throw std::bad_alloc();
#endif #endif
@ -179,7 +179,7 @@ template<bool Align> inline void ei_conditional_aligned_free(void *ptr)
template<> inline void ei_conditional_aligned_free<false>(void *ptr) template<> inline void ei_conditional_aligned_free<false>(void *ptr)
{ {
free(ptr); std::free(ptr);
} }
/** \internal destruct the elements of an array. /** \internal destruct the elements of an array.
@ -341,7 +341,7 @@ class aligned_allocator
{ {
public: public:
typedef size_t size_type; typedef size_t size_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef T* pointer; typedef T* pointer;
typedef const T* const_pointer; typedef const T* const_pointer;
typedef T& reference; typedef T& reference;

View File

@ -61,6 +61,7 @@
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE, THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE, THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
YOU_MADE_A_PROGRAMMING_MISTAKE, YOU_MADE_A_PROGRAMMING_MISTAKE,
EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE,
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR, YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR, YOU_CALLED_A_DYNAMIC_SIZE_METHOD_ON_A_FIXED_SIZE_MATRIX_OR_VECTOR,
UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC, UNALIGNED_LOAD_AND_STORE_OPERATIONS_UNIMPLEMENTED_ON_ALTIVEC,

View File

@ -97,7 +97,7 @@ class ei_compute_matrix_flags
}; };
public: public:
enum { ret = LinearAccessBit | DirectAccessBit | packet_access_bit | row_major_bit | aligned_bit }; enum { ret = LinearAccessBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit };
}; };
template<int _Rows, int _Cols> struct ei_size_at_compile_time template<int _Rows, int _Cols> struct ei_size_at_compile_time
@ -142,7 +142,7 @@ template<typename T> struct ei_plain_matrix_type_dense<T,DenseStorageArray>
* in order to avoid a useless copy * in order to avoid a useless copy
*/ */
template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_eval; template<typename T, typename StorageType = typename ei_traits<T>::StorageType> struct ei_eval;
template<typename T> struct ei_eval<T,Dense> template<typename T> struct ei_eval<T,Dense>
{ {
@ -209,23 +209,11 @@ template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
template <typename T> template <typename T>
struct ei_ref_selector struct ei_ref_selector
{ {
typedef T type; typedef typename ei_meta_if<
}; bool(ei_traits<T>::Flags & NestByRefBit),
T const&,
/** T
* Matrices on the other hand side should only be copied, when it is sure >::ret type;
* we gain by copying (see arithmetic cost check and eval before nesting flag).
* Note: This is an optimization measure that comprises potential (though little)
* to create erroneous code. Any user, utilizing ei_nested outside of
* Eigen needs to take care that no references to temporaries are
* stored or that this potential danger is at least communicated
* to the user.
**/
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
{
typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType;
typedef MatrixType const& type;
}; };
/** \internal Determines how a given expression should be nested into another one. /** \internal Determines how a given expression should be nested into another one.

View File

@ -0,0 +1,82 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_LAZY_H
#define EIGEN_LAZY_H
/** \deprecated it is only used by lazy() which is deprecated
*
* \returns an expression of *this with added flags
*
* Example: \include MatrixBase_marked.cpp
* Output: \verbinclude MatrixBase_marked.out
*
* \sa class Flagged, extract(), part()
*/
template<typename Derived>
template<unsigned int Added>
inline const Flagged<Derived, Added, 0>
MatrixBase<Derived>::marked() const
{
return derived();
}
/** \deprecated use MatrixBase::noalias()
*
* \returns an expression of *this with the EvalBeforeAssigningBit flag removed.
*
* Example: \include MatrixBase_lazy.cpp
* Output: \verbinclude MatrixBase_lazy.out
*
* \sa class Flagged, marked()
*/
template<typename Derived>
inline const Flagged<Derived, 0, EvalBeforeAssigningBit>
MatrixBase<Derived>::lazy() const
{
return derived();
}
/** \internal
* Overloaded to perform an efficient C += (A*B).lazy() */
template<typename Derived>
template<typename ProductDerived, typename Lhs, typename Rhs>
Derived& MatrixBase<Derived>::operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
EvalBeforeAssigningBit>& other)
{
other._expression().derived().addTo(derived()); return derived();
}
/** \internal
* Overloaded to perform an efficient C -= (A*B).lazy() */
template<typename Derived>
template<typename ProductDerived, typename Lhs, typename Rhs>
Derived& MatrixBase<Derived>::operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0,
EvalBeforeAssigningBit>& other)
{
other._expression().derived().subTo(derived()); return derived();
}
#endif // EIGEN_LAZY_H

View File

@ -94,7 +94,7 @@ void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix)
m_eivalues.resize(n,1); m_eivalues.resize(n,1);
m_eivec.resize(n,n); m_eivec.resize(n,n);
RealScalar eps = epsilon<RealScalar>(); RealScalar eps = NumTraits<RealScalar>::epsilon();
// Reduce to complex Schur form // Reduce to complex Schur form
ComplexSchur<MatrixType> schur(matrix); ComplexSchur<MatrixType> schur(matrix);

View File

@ -159,7 +159,7 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU)
RealScalar d,sd,sf; RealScalar d,sd,sf;
Complex c,b,disc,r1,r2,kappa; Complex c,b,disc,r1,r2,kappa;
RealScalar eps = epsilon<RealScalar>(); RealScalar eps = NumTraits<RealScalar>::epsilon();
int iter = 0; int iter = 0;
while(true) while(true)

View File

@ -43,37 +43,70 @@ class AlignedBox
public: public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
enum { AmbientDimAtCompileTime = _AmbientDim }; enum { AmbientDimAtCompileTime = _AmbientDim };
typedef _Scalar Scalar; typedef _Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar; typedef NumTraits<Scalar> ScalarTraits;
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType; typedef typename ScalarTraits::Real RealScalar;
typedef typename ScalarTraits::FloatingPoint FloatingPoint;
typedef Matrix<Scalar,AmbientDimAtCompileTime,1> VectorType;
/** Define constants to name the corners of a 1D, 2D or 3D axis aligned bounding box */
enum CornerType
{
/** 1D names */
Min=0, Max=1,
/** Added names for 2D */
BottomLeft=0, BottomRight=1,
TopLeft=2, TopRight=3,
/** Added names for 3D */
BottomLeftFloor=0, BottomRightFloor=1,
TopLeftFloor=2, TopRightFloor=3,
BottomLeftCeil=4, BottomRightCeil=5,
TopLeftCeil=6, TopRightCeil=7
};
/** Default constructor initializing a null box. */ /** Default constructor initializing a null box. */
inline explicit AlignedBox() inline explicit AlignedBox()
{ if (AmbientDimAtCompileTime!=Dynamic) setNull(); } { if (AmbientDimAtCompileTime!=Dynamic) setEmpty(); }
/** Constructs a null box with \a _dim the dimension of the ambient space. */ /** Constructs a null box with \a _dim the dimension of the ambient space. */
inline explicit AlignedBox(int _dim) : m_min(_dim), m_max(_dim) inline explicit AlignedBox(int _dim) : m_min(_dim), m_max(_dim)
{ setNull(); } { setEmpty(); }
/** Constructs a box with extremities \a _min and \a _max. */ /** Constructs a box with extremities \a _min and \a _max. */
inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_min(_min), m_max(_max) {} template<typename OtherVectorType1, typename OtherVectorType2>
inline AlignedBox(const OtherVectorType1& _min, const OtherVectorType2& _max) : m_min(_min), m_max(_max) {}
/** Constructs a box containing a single point \a p. */ /** Constructs a box containing a single point \a p. */
inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {} template<typename Derived>
inline explicit AlignedBox(const MatrixBase<Derived>& a_p)
{
const typename ei_nested<Derived,2>::type p(a_p.derived());
m_min = p;
m_max = p;
}
~AlignedBox() {} ~AlignedBox() {}
/** \returns the dimension in which the box holds */ /** \returns the dimension in which the box holds */
inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; } inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; }
/** \returns true if the box is null, i.e, empty. */ /** \deprecated use isEmpty */
inline bool isNull() const { return (m_min.array() > m_max.array()).any(); } inline bool isNull() const { return isEmpty(); }
/** Makes \c *this a null/empty box. */ /** \deprecated use setEmpty */
inline void setNull() inline void setNull() { setEmpty(); }
/** \returns true if the box is empty. */
inline bool isEmpty() const { return (m_min.array() > m_max.array()).any(); }
/** Makes \c *this an empty box. */
inline void setEmpty()
{ {
m_min.setConstant( std::numeric_limits<Scalar>::max()); m_min.setConstant( ScalarTraits::highest() );
m_max.setConstant(-std::numeric_limits<Scalar>::max()); m_max.setConstant( ScalarTraits::lowest() );
} }
/** \returns the minimal corner */ /** \returns the minimal corner */
@ -86,45 +119,135 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
inline VectorType& max() { return m_max; } inline VectorType& max() { return m_max; }
/** \returns the center of the box */ /** \returns the center of the box */
inline VectorType center() const { return (m_min + m_max) / 2; } inline const CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>,
CwiseBinaryOp<ei_scalar_sum_op<Scalar>, VectorType, VectorType> >
center() const
{ return (m_min+m_max)/2; }
/** \returns the lengths of the sides of the bounding box.
* Note that this function does not get the same
* result for integral or floating scalar types: see
*/
inline const CwiseBinaryOp< ei_scalar_difference_op<Scalar>, VectorType, VectorType> sizes() const
{ return m_max - m_min; }
/** \returns the volume of the bounding box */
inline Scalar volume() const
{ return sizes().prod(); }
/** \returns an expression for the bounding box diagonal vector
* if the length of the diagonal is needed: diagonal().norm()
* will provide it.
*/
inline CwiseBinaryOp< ei_scalar_difference_op<Scalar>, VectorType, VectorType> diagonal() const
{ return sizes(); }
/** \returns the vertex of the bounding box at the corner defined by
* the corner-id corner. It works only for a 1D, 2D or 3D bounding box.
* For 1D bounding boxes corners are named by 2 enum constants:
* BottomLeft and BottomRight.
* For 2D bounding boxes, corners are named by 4 enum constants:
* BottomLeft, BottomRight, TopLeft, TopRight.
* For 3D bounding boxes, the following names are added:
* BottomLeftCeil, BottomRightCeil, TopLeftCeil, TopRightCeil.
*/
inline VectorType corner(CornerType corner) const
{
EIGEN_STATIC_ASSERT(_AmbientDim <= 3, THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE);
VectorType res;
int mult = 1;
for(int d=0; d<dim(); ++d)
{
if( mult & corner ) res[d] = m_max[d];
else res[d] = m_min[d];
mult *= 2;
}
return res;
}
/** \returns a random point inside the bounding box sampled with
* a uniform distribution */
inline VectorType sample() const
{
VectorType r;
for(int d=0; d<dim(); ++d)
{
if(ScalarTraits::HasFloatingPoint)
{
r[d] = m_min[d] + (m_max[d]-m_min[d])
* (ei_random<Scalar>() + ei_random_amplitude<Scalar>())
/ (Scalar(2)*ei_random_amplitude<Scalar>() );
}
else
r[d] = ei_random(m_min[d], m_max[d]);
}
return r;
}
/** \returns true if the point \a p is inside the box \c *this. */ /** \returns true if the point \a p is inside the box \c *this. */
inline bool contains(const VectorType& p) const template<typename Derived>
{ return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all(); } inline bool contains(const MatrixBase<Derived>& a_p) const
{
const typename ei_nested<Derived,2>::type p(a_p.derived());
return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all();
}
/** \returns true if the box \a b is entirely inside the box \c *this. */ /** \returns true if the box \a b is entirely inside the box \c *this. */
inline bool contains(const AlignedBox& b) const inline bool contains(const AlignedBox& b) const
{ return (m_min.array()<=b.min().array()).all() && (b.max().array()<=m_max.array()).all(); } { return (m_min.array()<=b.min().array()).all() && (b.max().array()<=m_max.array()).all(); }
/** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */ /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */
inline AlignedBox& extend(const VectorType& p) template<typename Derived>
{ m_min = m_min.cwiseMin(p); m_max = m_max.cwiseMax(p); return *this; } inline AlignedBox& extend(const MatrixBase<Derived>& a_p)
{
const typename ei_nested<Derived,2>::type p(a_p.derived());
m_min = m_min.cwiseMin(p);
m_max = m_max.cwiseMax(p);
return *this;
}
/** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */ /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */
inline AlignedBox& extend(const AlignedBox& b) inline AlignedBox& extend(const AlignedBox& b)
{ m_min = m_min.cwiseMin(b.m_min); m_max = m_max.cwiseMax(b.m_max); return *this; } {
m_min = m_min.cwiseMin(b.m_min);
m_max = m_max.cwiseMax(b.m_max);
return *this;
}
/** Clamps \c *this by the box \a b and returns a reference to \c *this. */ /** Clamps \c *this by the box \a b and returns a reference to \c *this. */
inline AlignedBox& clamp(const AlignedBox& b) inline AlignedBox& clamp(const AlignedBox& b)
{ m_min = m_min.cwiseMax(b.m_min); m_max = m_max.cwiseMin(b.m_max); return *this; } {
m_min = m_min.cwiseMax(b.m_min);
m_max = m_max.cwiseMin(b.m_max);
return *this;
}
/** Returns an AlignedBox that is the intersection of \a b and \c *this */ /** Returns an AlignedBox that is the intersection of \a b and \c *this */
inline AlignedBox intersection(const AlignedBox &b) const inline AlignedBox intersection(const AlignedBox& b) const
{ return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); } {return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); }
/** Returns an AlignedBox that is the union of \a b and \c *this */ /** Returns an AlignedBox that is the union of \a b and \c *this */
inline AlignedBox merged(const AlignedBox &b) const inline AlignedBox merged(const AlignedBox& b) const
{ return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); } { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); }
/** Translate \c *this by the vector \a t and returns a reference to \c *this. */ /** Translate \c *this by the vector \a t and returns a reference to \c *this. */
inline AlignedBox& translate(const VectorType& t) template<typename Derived>
{ m_min += t; m_max += t; return *this; } inline AlignedBox& translate(const MatrixBase<Derived>& a_t)
{
const typename ei_nested<Derived,2>::type t(a_t.derived());
m_min += t;
m_max += t;
return *this;
}
/** \returns the squared distance between the point \a p and the box \c *this, /** \returns the squared distance between the point \a p and the box \c *this,
* and zero if \a p is inside the box. * and zero if \a p is inside the box.
* \sa exteriorDistance() * \sa exteriorDistance()
*/ */
inline Scalar squaredExteriorDistance(const VectorType& p) const; template<typename Derived>
inline Scalar squaredExteriorDistance(const MatrixBase<Derived>& a_p) const;
/** \returns the squared distance between the boxes \a b and \c *this, /** \returns the squared distance between the boxes \a b and \c *this,
* and zero if the boxes intersect. * and zero if the boxes intersect.
@ -136,15 +259,16 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
* and zero if \a p is inside the box. * and zero if \a p is inside the box.
* \sa squaredExteriorDistance() * \sa squaredExteriorDistance()
*/ */
inline Scalar exteriorDistance(const VectorType& p) const template<typename Derived>
{ return ei_sqrt(squaredExteriorDistance(p)); } inline FloatingPoint exteriorDistance(const MatrixBase<Derived>& p) const
{ return ei_sqrt(FloatingPoint(squaredExteriorDistance(p))); }
/** \returns the distance between the boxes \a b and \c *this, /** \returns the distance between the boxes \a b and \c *this,
* and zero if the boxes intersect. * and zero if the boxes intersect.
* \sa squaredExteriorDistance() * \sa squaredExteriorDistance()
*/ */
inline Scalar exteriorDistance(const AlignedBox& b) const inline FloatingPoint exteriorDistance(const AlignedBox& b) const
{ return ei_sqrt(squaredExteriorDistance(b)); } { return ei_sqrt(FloatingPoint(squaredExteriorDistance(b))); }
/** \returns \c *this with scalar type casted to \a NewScalarType /** \returns \c *this with scalar type casted to \a NewScalarType
* *
@ -171,7 +295,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim)
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const AlignedBox& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const AlignedBox& other, RealScalar prec = ScalarTraits::dummy_precision()) const
{ return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); } { return m_min.isApprox(other.m_min, prec) && m_max.isApprox(other.m_max, prec); }
protected: protected:
@ -179,32 +303,48 @@ protected:
VectorType m_min, m_max; VectorType m_min, m_max;
}; };
template<typename Scalar,int AmbiantDim>
inline Scalar AlignedBox<Scalar,AmbiantDim>::squaredExteriorDistance(const VectorType& p) const
template<typename Scalar,int AmbientDim>
template<typename Derived>
inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const MatrixBase<Derived>& a_p) const
{ {
const typename ei_nested<Derived,2*AmbientDim>::type p(a_p.derived());
Scalar dist2 = 0.; Scalar dist2 = 0.;
Scalar aux; Scalar aux;
for (int k=0; k<dim(); ++k) for (int k=0; k<dim(); ++k)
{ {
if ((aux = (p[k]-m_min[k]))<Scalar(0)) if( m_min[k] > p[k] )
{
aux = m_min[k] - p[k];
dist2 += aux*aux; dist2 += aux*aux;
else if ( (aux = (m_max[k]-p[k]))<Scalar(0) ) }
else if( p[k] > m_max[k] )
{
aux = p[k] - m_max[k];
dist2 += aux*aux; dist2 += aux*aux;
}
} }
return dist2; return dist2;
} }
template<typename Scalar,int AmbiantDim> template<typename Scalar,int AmbientDim>
inline Scalar AlignedBox<Scalar,AmbiantDim>::squaredExteriorDistance(const AlignedBox& b) const inline Scalar AlignedBox<Scalar,AmbientDim>::squaredExteriorDistance(const AlignedBox& b) const
{ {
Scalar dist2 = 0.; Scalar dist2 = 0.;
Scalar aux; Scalar aux;
for (int k=0; k<dim(); ++k) for (int k=0; k<dim(); ++k)
{ {
if ((aux = (b.m_min[k]-m_max[k]))>0.) if( m_min[k] > b.m_max[k] )
{
aux = m_min[k] - b.m_max[k];
dist2 += aux*aux; dist2 += aux*aux;
else if ( (aux = (m_min[k]-b.m_max[k]))>0. ) }
else if( b.m_min[k] > m_max[k] )
{
aux = b.m_min[k] - m_max[k];
dist2 += aux*aux; dist2 += aux*aux;
}
} }
return dist2; return dist2;
} }

View File

@ -146,7 +146,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const AngleAxis& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); } { return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
}; };
@ -165,7 +165,7 @@ template<typename QuatDerived>
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q) AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
{ {
Scalar n2 = q.vec().squaredNorm(); Scalar n2 = q.vec().squaredNorm();
if (n2 < dummy_precision<Scalar>()*dummy_precision<Scalar>()) if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
{ {
m_angle = 0; m_angle = 0;
m_axis << 1, 0, 0; m_axis << 1, 0, 0;
@ -189,6 +189,16 @@ AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const MatrixBase<Derived>& mat)
return *this = QuaternionType(mat); return *this = QuaternionType(mat);
} }
/**
* \brief Sets \c *this from a 3x3 rotation matrix.
**/
template<typename Scalar>
template<typename Derived>
AngleAxis<Scalar>& AngleAxis<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
{
return *this = QuaternionType(mat);
}
/** Constructs and \returns an equivalent 3x3 rotation matrix. /** Constructs and \returns an equivalent 3x3 rotation matrix.
*/ */
template<typename Scalar> template<typename Scalar>

View File

@ -50,7 +50,7 @@ MatrixBase<Derived>::eulerAngles(int a0, int a1, int a2) const
Matrix<Scalar,3,1> res; Matrix<Scalar,3,1> res;
typedef Matrix<typename Derived::Scalar,2,1> Vector2; typedef Matrix<typename Derived::Scalar,2,1> Vector2;
const Scalar epsilon = dummy_precision<Scalar>(); const Scalar epsilon = NumTraits<Scalar>::dummy_precision();
const int odd = ((a0+1)%3 == a1) ? 0 : 1; const int odd = ((a0+1)%3 == a1) ? 0 : 1;
const int i = a0; const int i = a0;

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2009-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -70,7 +70,8 @@ template<typename MatrixType,int _Direction> class Homogeneous
enum { Direction = _Direction }; enum { Direction = _Direction };
EIGEN_GENERIC_PUBLIC_INTERFACE(Homogeneous) typedef MatrixBase<Homogeneous> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(Homogeneous)
inline Homogeneous(const MatrixType& matrix) inline Homogeneous(const MatrixType& matrix)
: m_matrix(matrix) : m_matrix(matrix)

View File

@ -257,7 +257,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const Hyperplane& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); } { return m_coeffs.isApprox(other.m_coeffs, prec); }
protected: protected:

View File

@ -123,7 +123,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const ParametrizedLine& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); } { return m_origin.isApprox(other.m_origin, prec) && m_direction.isApprox(other.m_direction, prec); }
protected: protected:

View File

@ -163,7 +163,7 @@ public:
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
template<class OtherDerived> template<class OtherDerived>
bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = dummy_precision<Scalar>()) const bool isApprox(const QuaternionBase<OtherDerived>& other, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
{ return coeffs().isApprox(other.coeffs(), prec); } { return coeffs().isApprox(other.coeffs(), prec); }
/** return the result vector of \a v through the rotation*/ /** return the result vector of \a v through the rotation*/
@ -377,7 +377,8 @@ template <class Derived>
template <class OtherDerived> template <class OtherDerived>
EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other) EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator*= (const QuaternionBase<OtherDerived>& other)
{ {
return (derived() = derived() * other.derived()); derived() = derived() * other.derived();
return derived();
} }
/** Rotation of a vector by a quaternion. /** Rotation of a vector by a quaternion.
@ -507,7 +508,7 @@ inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Deri
// under the constraint: // under the constraint:
// ||x|| = 1 // ||x|| = 1
// which yields a singular value problem // which yields a singular value problem
if (c < Scalar(-1)+dummy_precision<Scalar>()) if (c < Scalar(-1)+NumTraits<Scalar>::dummy_precision())
{ {
c = std::max<Scalar>(c,-1); c = std::max<Scalar>(c,-1);
Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose(); Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
@ -572,7 +573,7 @@ QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& oth
double d = ei_abs(this->dot(other)); double d = ei_abs(this->dot(other));
if (d>=1.0) if (d>=1.0)
return Scalar(0); return Scalar(0);
return Scalar(2) * std::acos(d); return static_cast<Scalar>(2 * std::acos(d));
} }
/** \returns the spherical linear interpolation between the two quaternions /** \returns the spherical linear interpolation between the two quaternions
@ -583,7 +584,7 @@ template <class OtherDerived>
Quaternion<typename ei_traits<Derived>::Scalar> Quaternion<typename ei_traits<Derived>::Scalar>
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
{ {
static const Scalar one = Scalar(1) - epsilon<Scalar>(); static const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
Scalar d = this->dot(other); Scalar d = this->dot(other);
Scalar absD = ei_abs(d); Scalar absD = ei_abs(d);

View File

@ -121,7 +121,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const Rotation2D& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return ei_isApprox(m_angle,other.m_angle, prec); } { return ei_isApprox(m_angle,other.m_angle, prec); }
}; };

View File

@ -107,7 +107,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const UniformScaling& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return ei_isApprox(m_factor, other.factor(), prec); } { return ei_isApprox(m_factor, other.factor(), prec); }
}; };

View File

@ -345,9 +345,14 @@ public:
/** \sa MatrixBase::setIdentity() */ /** \sa MatrixBase::setIdentity() */
void setIdentity() { m_matrix.setIdentity(); } void setIdentity() { m_matrix.setIdentity(); }
static const typename MatrixType::IdentityReturnType Identity()
/**
* \brief Returns an identity transformation.
* \todo In the future this function should be returning a Transform expression.
*/
static const Transform Identity()
{ {
return MatrixType::Identity(); return Transform(MatrixType::Identity());
} }
template<typename OtherDerived> template<typename OtherDerived>
@ -424,7 +429,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const Transform& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_matrix.isApprox(other.m_matrix, prec); } { return m_matrix.isApprox(other.m_matrix, prec); }
/** Sets the last row to [0 ... 0 1] /** Sets the last row to [0 ... 0 1]

View File

@ -154,7 +154,7 @@ public:
* determined by \a prec. * determined by \a prec.
* *
* \sa MatrixBase::isApprox() */ * \sa MatrixBase::isApprox() */
bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = dummy_precision<Scalar>()) const bool isApprox(const Translation& other, typename NumTraits<Scalar>::Real prec = NumTraits<Scalar>::dummy_precision()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); } { return m_coeffs.isApprox(other.m_coeffs, prec); }
}; };

View File

@ -45,10 +45,10 @@ namespace
struct ei_umeyama_transform_matrix_type struct ei_umeyama_transform_matrix_type
{ {
enum { enum {
MinRowsAtCompileTime = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime, OtherMatrixType::RowsAtCompileTime), MinRowsAtCompileTime = EIGEN_SIZE_MIN(MatrixType::RowsAtCompileTime, OtherMatrixType::RowsAtCompileTime),
// When possible we want to choose some small fixed size value since the result // When possible we want to choose some small fixed size value since the result
// is likely to fit on the stack. // is likely to fit on the stack. Here EIGEN_ENUM_MIN is really what we want.
HomogeneousDimension = EIGEN_ENUM_MIN(MinRowsAtCompileTime+1, Dynamic) HomogeneousDimension = EIGEN_ENUM_MIN(MinRowsAtCompileTime+1, Dynamic)
}; };
@ -114,7 +114,7 @@ umeyama(const MatrixBase<Derived>& src, const MatrixBase<OtherDerived>& dst, boo
EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename ei_traits<OtherDerived>::Scalar>::ret), EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename ei_traits<OtherDerived>::Scalar>::ret),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
enum { Dimension = EIGEN_ENUM_MIN(Derived::RowsAtCompileTime, OtherDerived::RowsAtCompileTime) }; enum { Dimension = EIGEN_SIZE_MIN(Derived::RowsAtCompileTime, OtherDerived::RowsAtCompileTime) };
typedef Matrix<Scalar, Dimension, 1> VectorType; typedef Matrix<Scalar, Dimension, 1> VectorType;
typedef Matrix<Scalar, Dimension, Dimension> MatrixType; typedef Matrix<Scalar, Dimension, Dimension> MatrixType;

View File

@ -45,7 +45,7 @@ void makeTrivialHouseholder(
template<typename Derived> template<typename Derived>
void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta) void MatrixBase<Derived>::makeHouseholderInPlace(Scalar& tau, RealScalar& beta)
{ {
VectorBlock<Derived, ei_decrement_size<SizeAtCompileTime>::ret> essentialPart(derived(), 1, size()-1); VectorBlock<Derived, ei_decrement_size<Base::SizeAtCompileTime>::ret> essentialPart(derived(), 1, size()-1);
makeHouseholder(essentialPart, tau, beta); makeHouseholder(essentialPart, tau, beta);
} }
@ -99,7 +99,7 @@ void MatrixBase<Derived>::applyHouseholderOnTheLeft(
const Scalar& tau, const Scalar& tau,
Scalar* workspace) Scalar* workspace)
{ {
Map<Matrix<Scalar, 1, ColsAtCompileTime, PlainMatrixType::Options, 1, MaxColsAtCompileTime> > tmp(workspace,cols()); Map<Matrix<Scalar, 1, Base::ColsAtCompileTime, PlainMatrixType::Options, 1, Base::MaxColsAtCompileTime> > tmp(workspace,cols());
Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols()); Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols());
tmp.noalias() = essential.adjoint() * bottom; tmp.noalias() = essential.adjoint() * bottom;
tmp += this->row(0); tmp += this->row(0);
@ -114,7 +114,7 @@ void MatrixBase<Derived>::applyHouseholderOnTheRight(
const Scalar& tau, const Scalar& tau,
Scalar* workspace) Scalar* workspace)
{ {
Map<Matrix<Scalar, RowsAtCompileTime, 1, PlainMatrixType::Options, MaxRowsAtCompileTime, 1> > tmp(workspace,rows()); Map<Matrix<Scalar, Base::RowsAtCompileTime, 1, PlainMatrixType::Options, Base::MaxRowsAtCompileTime, 1> > tmp(workspace,rows());
Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1); Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1);
tmp.noalias() = right * essential.conjugate(); tmp.noalias() = right * essential.conjugate();
tmp += this->col(0); tmp += this->col(0);

View File

@ -99,7 +99,7 @@ template<typename Derived>
inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
{ {
assert(rows() == cols()); assert(rows() == cols());
typedef typename ei_nested<Derived,RowsAtCompileTime>::type Nested; typedef typename ei_nested<Derived,Base::RowsAtCompileTime>::type Nested;
Nested nested(derived()); Nested nested(derived());
return ei_determinant_impl<typename ei_cleantype<Nested>::type>::run(nested); return ei_determinant_impl<typename ei_cleantype<Nested>::type>::run(nested);
} }

View File

@ -276,7 +276,7 @@ template<typename _MatrixType> class FullPivLU
return m_usePrescribedThreshold ? m_prescribedThreshold return m_usePrescribedThreshold ? m_prescribedThreshold
// this formula comes from experimenting (see "LU precision tuning" thread on the list) // this formula comes from experimenting (see "LU precision tuning" thread on the list)
// and turns out to be identical to Higham's formula used already in LDLt. // and turns out to be identical to Higham's formula used already in LDLt.
: epsilon<Scalar>() * m_lu.diagonalSize(); : NumTraits<Scalar>::epsilon() * m_lu.diagonalSize();
} }
/** \returns the rank of the matrix of which *this is the LU decomposition. /** \returns the rank of the matrix of which *this is the LU decomposition.
@ -476,7 +476,7 @@ typename ei_traits<MatrixType>::Scalar FullPivLU<MatrixType>::determinant() cons
{ {
ei_assert(m_isInitialized && "LU is not initialized."); ei_assert(m_isInitialized && "LU is not initialized.");
ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!"); ei_assert(m_lu.rows() == m_lu.cols() && "You can't take the determinant of a non-square matrix!");
return Scalar(m_det_pq) * m_lu.diagonal().prod(); return Scalar(m_det_pq) * Scalar(m_lu.diagonal().prod());
} }
/********* Implementation of kernel() **************************************************/ /********* Implementation of kernel() **************************************************/
@ -487,7 +487,7 @@ struct ei_kernel_retval<FullPivLU<_MatrixType> >
{ {
EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>) EIGEN_MAKE_KERNEL_HELPERS(FullPivLU<_MatrixType>)
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN( enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime,
MatrixType::MaxRowsAtCompileTime) MatrixType::MaxRowsAtCompileTime)
}; };
@ -572,7 +572,7 @@ struct ei_image_retval<FullPivLU<_MatrixType> >
{ {
EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>) EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>)
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN( enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime,
MatrixType::MaxRowsAtCompileTime) MatrixType::MaxRowsAtCompileTime)
}; };

View File

@ -67,7 +67,7 @@ template<typename _MatrixType> class PartialPivLU
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> PermutationVectorType; typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> PermutationVectorType;
typedef PermutationMatrix<MatrixType::RowsAtCompileTime> PermutationType; typedef PermutationMatrix<MatrixType::RowsAtCompileTime> PermutationType;
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN( enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime,
MatrixType::MaxRowsAtCompileTime) MatrixType::MaxRowsAtCompileTime)
}; };

View File

@ -158,8 +158,8 @@ struct ei_compute_inverse_size4<Architecture::SSE, double, MatrixType, ResultTyp
{ {
static void run(const MatrixType& matrix, ResultType& result) static void run(const MatrixType& matrix, ResultType& result)
{ {
const EIGEN_ALIGN16 long long int _Sign_NP[2] = { 0x8000000000000000, 0x0000000000000000 }; const EIGEN_ALIGN16 long long int _Sign_NP[2] = { 0x8000000000000000ll, 0x0000000000000000ll };
const EIGEN_ALIGN16 long long int _Sign_PN[2] = { 0x0000000000000000, 0x8000000000000000 }; const EIGEN_ALIGN16 long long int _Sign_PN[2] = { 0x0000000000000000ll, 0x8000000000000000ll };
// The inverse is calculated using "Divide and Conquer" technique. The // The inverse is calculated using "Divide and Conquer" technique. The
// original matrix is divide into four 2x2 sub-matrices. Since each // original matrix is divide into four 2x2 sub-matrices. Since each

View File

@ -51,7 +51,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
RowsAtCompileTime = MatrixType::RowsAtCompileTime, RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime,
Options = MatrixType::Options, Options = MatrixType::Options,
DiagSizeAtCompileTime = EIGEN_ENUM_MIN(ColsAtCompileTime,RowsAtCompileTime) DiagSizeAtCompileTime = EIGEN_SIZE_MIN(ColsAtCompileTime,RowsAtCompileTime)
}; };
typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::RealScalar RealScalar;
@ -282,7 +282,7 @@ template<typename _MatrixType> class ColPivHouseholderQR
return m_usePrescribedThreshold ? m_prescribedThreshold return m_usePrescribedThreshold ? m_prescribedThreshold
// this formula comes from experimenting (see "LU precision tuning" thread on the list) // this formula comes from experimenting (see "LU precision tuning" thread on the list)
// and turns out to be identical to Higham's formula used already in LDLt. // and turns out to be identical to Higham's formula used already in LDLt.
: epsilon<Scalar>() * m_qr.diagonalSize(); : NumTraits<Scalar>::epsilon() * m_qr.diagonalSize();
} }
/** \returns the number of nonzero pivots in the QR decomposition. /** \returns the number of nonzero pivots in the QR decomposition.
@ -350,7 +350,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const
for(int k = 0; k < cols; ++k) for(int k = 0; k < cols; ++k)
colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm(); colSqNorms.coeffRef(k) = m_qr.col(k).squaredNorm();
RealScalar threshold_helper = colSqNorms.maxCoeff() * ei_abs2(epsilon<Scalar>()) / rows; RealScalar threshold_helper = colSqNorms.maxCoeff() * ei_abs2(NumTraits<Scalar>::epsilon()) / rows;
m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case) m_nonzero_pivots = size; // the generic case is that in which all pivots are nonzero (invertible case)
m_maxpivot = RealScalar(0); m_maxpivot = RealScalar(0);

View File

@ -51,7 +51,7 @@ template<typename _MatrixType> class FullPivHouseholderQR
RowsAtCompileTime = MatrixType::RowsAtCompileTime, RowsAtCompileTime = MatrixType::RowsAtCompileTime,
ColsAtCompileTime = MatrixType::ColsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime,
Options = MatrixType::Options, Options = MatrixType::Options,
DiagSizeAtCompileTime = EIGEN_ENUM_MIN(ColsAtCompileTime,RowsAtCompileTime) DiagSizeAtCompileTime = EIGEN_SIZE_MIN(ColsAtCompileTime,RowsAtCompileTime)
}; };
typedef typename MatrixType::Scalar Scalar; typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar; typedef typename MatrixType::RealScalar RealScalar;
@ -270,7 +270,7 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons
RowVectorType temp(cols); RowVectorType temp(cols);
m_precision = epsilon<Scalar>() * size; m_precision = NumTraits<Scalar>::epsilon() * size;
m_rows_transpositions.resize(matrix.rows()); m_rows_transpositions.resize(matrix.rows());
IntRowVectorType cols_transpositions(matrix.cols()); IntRowVectorType cols_transpositions(matrix.cols());
@ -370,7 +370,7 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs>
RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwiseAbs().maxCoeff(); RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwiseAbs().maxCoeff();
RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwiseAbs().maxCoeff(); RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwiseAbs().maxCoeff();
// FIXME brain dead // FIXME brain dead
const RealScalar m_precision = epsilon<Scalar>() * std::min(rows,cols); const RealScalar m_precision = NumTraits<Scalar>::epsilon() * std::min(rows,cols);
if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision)) if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision))
return; return;
} }

View File

@ -295,7 +295,7 @@ JacobiSVD<MatrixType, Options>& JacobiSVD<MatrixType, Options>::compute(const Ma
int cols = matrix.cols(); int cols = matrix.cols();
int diagSize = std::min(rows, cols); int diagSize = std::min(rows, cols);
m_singularValues.resize(diagSize); m_singularValues.resize(diagSize);
const RealScalar precision = 2 * epsilon<Scalar>(); const RealScalar precision = 2 * NumTraits<Scalar>::epsilon();
if(!ei_svd_precondition_if_more_rows_than_cols<MatrixType, Options>::run(matrix, work_matrix, *this) if(!ei_svd_precondition_if_more_rows_than_cols<MatrixType, Options>::run(matrix, work_matrix, *this)
&& !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, work_matrix, *this)) && !ei_svd_precondition_if_more_cols_than_rows<MatrixType, Options>::run(matrix, work_matrix, *this))

View File

@ -52,7 +52,7 @@ template<typename _MatrixType> class SVD
ColsAtCompileTime = MatrixType::ColsAtCompileTime, ColsAtCompileTime = MatrixType::ColsAtCompileTime,
PacketSize = ei_packet_traits<Scalar>::size, PacketSize = ei_packet_traits<Scalar>::size,
AlignmentMask = int(PacketSize)-1, AlignmentMask = int(PacketSize)-1,
MinSize = EIGEN_ENUM_MIN(RowsAtCompileTime, ColsAtCompileTime) MinSize = EIGEN_SIZE_MIN(RowsAtCompileTime, ColsAtCompileTime)
}; };
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVector; typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVector;
@ -193,7 +193,7 @@ SVD<MatrixType>& SVD<MatrixType>::compute(const MatrixType& matrix)
int i=0,its=0,j=0,k=0,l=0,nm=0; int i=0,its=0,j=0,k=0,l=0,nm=0;
Scalar anorm, c, f, g, h, s, scale, x, y, z; Scalar anorm, c, f, g, h, s, scale, x, y, z;
bool convergence = true; bool convergence = true;
Scalar eps = dummy_precision<Scalar>(); Scalar eps = NumTraits<Scalar>::dummy_precision();
Matrix<Scalar,Dynamic,1> rv1(n); Matrix<Scalar,Dynamic,1> rv1(n);
g = scale = anorm = 0; g = scale = anorm = 0;

View File

@ -296,7 +296,7 @@ class AmbiVector<_Scalar>::Iterator
* In practice, all coefficients having a magnitude smaller than \a epsilon * In practice, all coefficients having a magnitude smaller than \a epsilon
* are skipped. * are skipped.
*/ */
Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*dummy_precision<RealScalar>()) Iterator(const AmbiVector& vec, RealScalar epsilon = RealScalar(0.1)*NumTraits<RealScalar>::dummy_precision())
: m_vector(vec) : m_vector(vec)
{ {
m_epsilon = epsilon; m_epsilon = epsilon;

View File

@ -185,7 +185,7 @@ class CompressedStorage
return m_values[id]; return m_values[id];
} }
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
{ {
size_t k = 0; size_t k = 0;
size_t n = size(); size_t n = size();

View File

@ -52,19 +52,12 @@ struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags> >
ColsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic,
MaxRowsAtCompileTime = Dynamic, MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic,
Flags = _Flags, Flags = _Flags | NestByRefBit,
CoeffReadCost = NumTraits<Scalar>::ReadCost, CoeffReadCost = NumTraits<Scalar>::ReadCost,
SupportedAccessPatterns = OuterRandomAccessPattern SupportedAccessPatterns = OuterRandomAccessPattern
}; };
}; };
template<typename _Scalar, int _Options>
struct ei_ref_selector< DynamicSparseMatrix<_Scalar, _Options> >
{
typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
typedef MatrixType const& type;
};
template<typename _Scalar, int _Flags> template<typename _Scalar, int _Flags>
class DynamicSparseMatrix class DynamicSparseMatrix
: public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> > : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> >
@ -216,7 +209,7 @@ class DynamicSparseMatrix
inline void finalize() {} inline void finalize() {}
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
{ {
for (int j=0; j<outerSize(); ++j) for (int j=0; j<outerSize(); ++j)
m_data[j].prune(reference,epsilon); m_data[j].prune(reference,epsilon);

View File

@ -1,8 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -406,98 +405,4 @@ template<typename Derived>
const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(int outerStart, int outerSize) const const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(int outerStart, int outerSize) const
{ return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); } { return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
# if 0
template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess>
class Block<MatrixType,BlockRows,BlockCols,PacketAccess,IsSparse>
: public SparseMatrixBase<Block<MatrixType,BlockRows,BlockCols,PacketAccess,IsSparse> >
{
public:
_EIGEN_GENERIC_PUBLIC_INTERFACE(Block, SparseMatrixBase<Block>)
class InnerIterator;
/** Column or Row constructor
*/
inline Block(const MatrixType& matrix, int i)
: m_matrix(matrix),
// It is a row if and only if BlockRows==1 and BlockCols==MatrixType::ColsAtCompileTime,
// and it is a column if and only if BlockRows==MatrixType::RowsAtCompileTime and BlockCols==1,
// all other cases are invalid.
// The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
m_startRow( (BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0),
m_startCol( (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
m_blockRows(matrix.rows()), // if it is a row, then m_blockRows has a fixed-size of 1, so no pb to try to overwrite it
m_blockCols(matrix.cols()) // same for m_blockCols
{
ei_assert( (i>=0) && (
((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
}
/** Fixed-size constructor
*/
inline Block(const MatrixType& matrix, int startRow, int startCol)
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
{
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
}
/** Dynamic-size constructor
*/
inline Block(const MatrixType& matrix,
int startRow, int startCol,
int blockRows, int blockCols)
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
m_blockRows(blockRows), m_blockCols(blockCols)
{
ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
&& (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
&& startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
}
inline int rows() const { return m_blockRows.value(); }
inline int cols() const { return m_blockCols.value(); }
inline int stride(void) const { return m_matrix.stride(); }
inline Scalar& coeffRef(int row, int col)
{
return m_matrix.const_cast_derived()
.coeffRef(row + m_startRow.value(), col + m_startCol.value());
}
inline const Scalar coeff(int row, int col) const
{
return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
}
inline Scalar& coeffRef(int index)
{
return m_matrix.const_cast_derived()
.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
}
inline const Scalar coeff(int index) const
{
return m_matrix
.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
}
protected:
const typename MatrixType::Nested m_matrix;
const ei_int_if_dynamic<MatrixType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
const ei_int_if_dynamic<MatrixType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
const ei_int_if_dynamic<RowsAtCompileTime> m_blockRows;
const ei_int_if_dynamic<ColsAtCompileTime> m_blockCols;
};
#endif
#endif // EIGEN_SPARSE_BLOCK_H #endif // EIGEN_SPARSE_BLOCK_H

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -60,7 +60,7 @@ class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator
public: public:
EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, int outer) EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, int outer)
: m_iter(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived()._functor()) : m_iter(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
{} {}
EIGEN_STRONG_INLINE InnerIterator& operator++() EIGEN_STRONG_INLINE InnerIterator& operator++()
@ -101,7 +101,7 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator
public: public:
EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryView, int outer) EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryView, int outer)
: m_iter(unaryView.derived().nestedExpression(),outer), m_functor(unaryView.derived()._functor()) : m_iter(unaryView.derived().nestedExpression(),outer), m_functor(unaryView.derived().functor())
{} {}
EIGEN_STRONG_INLINE InnerIterator& operator++() EIGEN_STRONG_INLINE InnerIterator& operator++()

View File

@ -1,42 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>
//
// 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 <http://www.gnu.org/licenses/>.
#ifndef EIGEN_SPARSE_EXPRESSIONMAKER_H
#define EIGEN_SPARSE_EXPRESSIONMAKER_H
template<typename Func, typename XprType>
struct MakeCwiseUnaryOp<Func,XprType,IsSparse>
{
typedef SparseCwiseUnaryOp<Func,XprType> Type;
};
template<typename Func, typename A, typename B>
struct MakeCwiseBinaryOp<Func,A,B,IsSparse>
{
typedef SparseCwiseBinaryOp<Func,A,B> Type;
};
// TODO complete the list
#endif // EIGEN_SPARSE_EXPRESSIONMAKER_H

View File

@ -94,7 +94,7 @@ class SparseLDLT
: m_flags(flags), m_status(0) : m_flags(flags), m_status(0)
{ {
ei_assert((MatrixType::Flags&RowMajorBit)==0); ei_assert((MatrixType::Flags&RowMajorBit)==0);
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>(); m_precision = RealScalar(0.1) * Eigen::NumTraits<RealScalar>::dummy_precision();
} }
/** Creates a LDLT object and compute the respective factorization of \a matrix using /** Creates a LDLT object and compute the respective factorization of \a matrix using
@ -103,7 +103,7 @@ class SparseLDLT
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0) : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
{ {
ei_assert((MatrixType::Flags&RowMajorBit)==0); ei_assert((MatrixType::Flags&RowMajorBit)==0);
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>(); m_precision = RealScalar(0.1) * Eigen::NumTraits<RealScalar>::dummy_precision();
compute(matrix); compute(matrix);
} }

View File

@ -54,7 +54,7 @@ class SparseLLT
SparseLLT(int flags = 0) SparseLLT(int flags = 0)
: m_flags(flags), m_status(0) : m_flags(flags), m_status(0)
{ {
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>(); m_precision = RealScalar(0.1) * Eigen::NumTraits<RealScalar>::dummy_precision();
} }
/** Creates a LLT object and compute the respective factorization of \a matrix using /** Creates a LLT object and compute the respective factorization of \a matrix using
@ -62,7 +62,7 @@ class SparseLLT
SparseLLT(const MatrixType& matrix, int flags = 0) SparseLLT(const MatrixType& matrix, int flags = 0)
: m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0) : m_matrix(matrix.rows(), matrix.cols()), m_flags(flags), m_status(0)
{ {
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>(); m_precision = RealScalar(0.1) * Eigen::NumTraits<RealScalar>::dummy_precision();
compute(matrix); compute(matrix);
} }

View File

@ -59,7 +59,7 @@ class SparseLU
SparseLU(int flags = 0) SparseLU(int flags = 0)
: m_flags(flags), m_status(0) : m_flags(flags), m_status(0)
{ {
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>(); m_precision = RealScalar(0.1) * Eigen::NumTraits<RealScalar>::dummy_precision();
} }
/** Creates a LU object and compute the respective factorization of \a matrix using /** Creates a LU object and compute the respective factorization of \a matrix using
@ -67,7 +67,7 @@ class SparseLU
SparseLU(const MatrixType& matrix, int flags = 0) SparseLU(const MatrixType& matrix, int flags = 0)
: /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0) : /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0)
{ {
m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar>(); m_precision = RealScalar(0.1) * Eigen::NumTraits<RealScalar>::dummy_precision();
compute(matrix); compute(matrix);
} }

View File

@ -51,19 +51,12 @@ struct ei_traits<SparseMatrix<_Scalar, _Options> >
ColsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic,
MaxRowsAtCompileTime = Dynamic, MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic,
Flags = _Options, Flags = _Options | NestByRefBit,
CoeffReadCost = NumTraits<Scalar>::ReadCost, CoeffReadCost = NumTraits<Scalar>::ReadCost,
SupportedAccessPatterns = InnerRandomAccessPattern SupportedAccessPatterns = InnerRandomAccessPattern
}; };
}; };
template<typename _Scalar, int _Options>
struct ei_ref_selector<SparseMatrix<_Scalar, _Options> >
{
typedef SparseMatrix<_Scalar, _Options> MatrixType;
typedef MatrixType const& type;
};
template<typename _Scalar, int _Options> template<typename _Scalar, int _Options>
class SparseMatrix class SparseMatrix
: public SparseMatrixBase<SparseMatrix<_Scalar, _Options> > : public SparseMatrixBase<SparseMatrix<_Scalar, _Options> >
@ -357,7 +350,7 @@ class SparseMatrix
} }
} }
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
{ {
int k = 0; int k = 0;
for (int j=0; j<m_outerSize; ++j) for (int j=0; j<m_outerSize; ++j)

View File

@ -513,32 +513,32 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
template<typename OtherDerived> template<typename OtherDerived>
bool isApprox(const SparseMatrixBase<OtherDerived>& other, bool isApprox(const SparseMatrixBase<OtherDerived>& other,
RealScalar prec = dummy_precision<Scalar>()) const RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
{ return toDense().isApprox(other.toDense(),prec); } { return toDense().isApprox(other.toDense(),prec); }
template<typename OtherDerived> template<typename OtherDerived>
bool isApprox(const MatrixBase<OtherDerived>& other, bool isApprox(const MatrixBase<OtherDerived>& other,
RealScalar prec = dummy_precision<Scalar>()) const RealScalar prec = NumTraits<Scalar>::dummy_precision()) const
{ return toDense().isApprox(other,prec); } { return toDense().isApprox(other,prec); }
// bool isMuchSmallerThan(const RealScalar& other, // bool isMuchSmallerThan(const RealScalar& other,
// RealScalar prec = dummy_precision<Scalar>()) const; // RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// template<typename OtherDerived> // template<typename OtherDerived>
// bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other, // bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other,
// RealScalar prec = dummy_precision<Scalar>()) const; // RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; // bool isApproxToConstant(const Scalar& value, RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isZero(RealScalar prec = dummy_precision<Scalar>()) const; // bool isZero(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const; // bool isOnes(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const; // bool isIdentity(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const; // bool isDiagonal(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isUpper(RealScalar prec = dummy_precision<Scalar>()) const; // bool isUpper(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isLower(RealScalar prec = dummy_precision<Scalar>()) const; // bool isLower(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// template<typename OtherDerived> // template<typename OtherDerived>
// bool isOrthogonal(const MatrixBase<OtherDerived>& other, // bool isOrthogonal(const MatrixBase<OtherDerived>& other,
// RealScalar prec = dummy_precision<Scalar>()) const; // RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const; // bool isUnitary(RealScalar prec = NumTraits<Scalar>::dummy_precision()) const;
// template<typename OtherDerived> // template<typename OtherDerived>
// inline bool operator==(const MatrixBase<OtherDerived>& other) const // inline bool operator==(const MatrixBase<OtherDerived>& other) const

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // for linear algebra.
// //
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@ -93,7 +93,8 @@ class SparseProduct : ei_no_assignment_operator,
{ {
public: public:
EIGEN_GENERIC_PUBLIC_INTERFACE(SparseProduct) typedef typename ei_traits<SparseProduct<LhsNested, RhsNested> >::Base Base;
EIGEN_DENSE_PUBLIC_INTERFACE(SparseProduct)
private: private:

View File

@ -46,19 +46,12 @@ struct ei_traits<SparseVector<_Scalar, _Options> >
ColsAtCompileTime = IsColVector ? 1 : Dynamic, ColsAtCompileTime = IsColVector ? 1 : Dynamic,
MaxRowsAtCompileTime = RowsAtCompileTime, MaxRowsAtCompileTime = RowsAtCompileTime,
MaxColsAtCompileTime = ColsAtCompileTime, MaxColsAtCompileTime = ColsAtCompileTime,
Flags = _Options, Flags = _Options | NestByRefBit,
CoeffReadCost = NumTraits<Scalar>::ReadCost, CoeffReadCost = NumTraits<Scalar>::ReadCost,
SupportedAccessPatterns = InnerRandomAccessPattern SupportedAccessPatterns = InnerRandomAccessPattern
}; };
}; };
template<typename _Scalar, int _Options>
struct ei_ref_selector< SparseVector<_Scalar, _Options> >
{
typedef SparseVector<_Scalar, _Options> MatrixType;
typedef MatrixType const& type;
};
template<typename _Scalar, int _Options> template<typename _Scalar, int _Options>
class SparseVector class SparseVector
: public SparseMatrixBase<SparseVector<_Scalar, _Options> > : public SparseMatrixBase<SparseVector<_Scalar, _Options> >
@ -209,7 +202,7 @@ class SparseVector
EIGEN_DEPRECATED void endFill() {} EIGEN_DEPRECATED void endFill() {}
inline void finalize() {} inline void finalize() {}
void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
{ {
m_data.prune(reference,epsilon); m_data.prune(reference,epsilon);
} }

View File

@ -75,7 +75,7 @@ cwiseInverse() const { return derived(); }
* \sa cwiseEqual(const MatrixBase<OtherDerived> &) const * \sa cwiseEqual(const MatrixBase<OtherDerived> &) const
*/ */
inline const CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,Derived> inline const CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,Derived>
cwiseEqual(Scalar s) const cwiseEqual(const Scalar& s) const
{ {
return CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,Derived> return CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,Derived>
(derived(), std::bind1st(std::equal_to<Scalar>(), s)); (derived(), std::bind1st(std::equal_to<Scalar>(), s));

Some files were not shown because too many files have changed in this diff Show More