This commit is contained in:
Benoit Jacob
2009-10-15 16:09:43 -04:00
83 changed files with 2390 additions and 768 deletions

View File

@@ -45,14 +45,10 @@ struct ei_traits<Replicate<MatrixType,RowFactor,ColFactor> >
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum {
RowsPlusOne = (MatrixType::RowsAtCompileTime != Dynamic) ?
int(MatrixType::RowsAtCompileTime) + 1 : Dynamic,
ColsPlusOne = (MatrixType::ColsAtCompileTime != Dynamic) ?
int(MatrixType::ColsAtCompileTime) + 1 : Dynamic,
RowsAtCompileTime = RowFactor==Dynamic || MatrixType::RowsAtCompileTime==Dynamic
RowsAtCompileTime = RowFactor==Dynamic || int(MatrixType::RowsAtCompileTime)==Dynamic
? Dynamic
: RowFactor * MatrixType::RowsAtCompileTime,
ColsAtCompileTime = ColFactor==Dynamic || MatrixType::ColsAtCompileTime==Dynamic
ColsAtCompileTime = ColFactor==Dynamic || int(MatrixType::ColsAtCompileTime)==Dynamic
? Dynamic
: ColFactor * MatrixType::ColsAtCompileTime,
MaxRowsAtCompileTime = RowsAtCompileTime,
@@ -69,15 +65,22 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
EIGEN_GENERIC_PUBLIC_INTERFACE(Replicate)
inline Replicate(const MatrixType& matrix)
template<typename OriginalMatrixType>
inline explicit Replicate(const OriginalMatrixType& matrix)
: m_matrix(matrix), m_rowFactor(RowFactor), m_colFactor(ColFactor)
{
EIGEN_STATIC_ASSERT((ei_is_same_type<MatrixType,OriginalMatrixType>::ret),
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
ei_assert(RowFactor!=Dynamic && ColFactor!=Dynamic);
}
inline Replicate(const MatrixType& matrix, int rowFactor, int colFactor)
template<typename OriginalMatrixType>
inline Replicate(const OriginalMatrixType& matrix, int rowFactor, int colFactor)
: m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor)
{}
{
EIGEN_STATIC_ASSERT((ei_is_same_type<MatrixType,OriginalMatrixType>::ret),
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE)
}
inline int rows() const { return m_matrix.rows() * m_rowFactor.value(); }
inline int cols() const { return m_matrix.cols() * m_colFactor.value(); }
@@ -91,6 +94,9 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
const typename MatrixType::Nested m_matrix;
const ei_int_if_dynamic<RowFactor> m_rowFactor;
const ei_int_if_dynamic<ColFactor> m_colFactor;
private:
Replicate& operator=(const Replicate&);
};
/** \nonstableyet
@@ -106,7 +112,7 @@ template<int RowFactor, int ColFactor>
inline const Replicate<Derived,RowFactor,ColFactor>
MatrixBase<Derived>::replicate() const
{
return derived();
return Replicate<Derived,RowFactor,ColFactor>(derived());
}
/** \nonstableyet

View File

@@ -95,6 +95,14 @@ class PartialReduxExpr : ei_no_assignment_operator,
return m_functor(m_matrix.row(i));
}
const Scalar coeff(int index) const
{
if (Direction==Vertical)
return m_functor(m_matrix.col(index));
else
return m_functor(m_matrix.row(index));
}
protected:
const MatrixTypeNested m_matrix;
const MemberOp m_functor;
@@ -442,6 +450,9 @@ template<typename ExpressionType, int Direction> class VectorwiseOp
protected:
ExpressionTypeNested m_matrix;
private:
VectorwiseOp& operator=(const VectorwiseOp&);
};
/** \array_module

View File

@@ -1,35 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 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_EXTERN_INSTANTIATIONS
#define EIGEN_EXTERN_INSTANTIATIONS
#endif
#include "../../Core"
#undef EIGEN_EXTERN_INSTANTIATIONS
#include "../../Cholesky"
namespace Eigen {
EIGEN_CHOLESKY_MODULE_INSTANTIATE();
}

View File

@@ -5,13 +5,6 @@ INSTALL(FILES
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core COMPONENT Devel
)
FILE(GLOB Eigen_Core_Product_SRCS "products/*.h")
INSTALL(FILES
${Eigen_Core_Product_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/products COMPONENT Devel
)
ADD_SUBDIRECTORY(products)
ADD_SUBDIRECTORY(util)
ADD_SUBDIRECTORY(arch)

View File

@@ -116,6 +116,9 @@ struct CommaInitializer
int m_row; // current row id
int m_col; // current col id
int m_currentBlockRows; // current block height
private:
CommaInitializer& operator=(const CommaInitializer&);
};
/** \anchor MatrixBaseCommaInitRef

View File

@@ -1,47 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 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/>.
#ifdef EIGEN_EXTERN_INSTANTIATIONS
#undef EIGEN_EXTERN_INSTANTIATIONS
#endif
#include "../../Core"
namespace Eigen
{
#define EIGEN_INSTANTIATE_PRODUCT(TYPE) \
template static void ei_cache_friendly_product<TYPE>( \
int _rows, int _cols, int depth, \
bool _lhsRowMajor, const TYPE* _lhs, int _lhsStride, \
bool _rhsRowMajor, const TYPE* _rhs, int _rhsStride, \
bool resRowMajor, TYPE* res, int resStride)
EIGEN_INSTANTIATE_PRODUCT(float);
EIGEN_INSTANTIATE_PRODUCT(double);
EIGEN_INSTANTIATE_PRODUCT(int);
EIGEN_INSTANTIATE_PRODUCT(std::complex<float>);
EIGEN_INSTANTIATE_PRODUCT(std::complex<double>);
}

View File

@@ -178,6 +178,9 @@ template<typename ExpressionType> class Cwise
protected:
ExpressionTypeNested m_matrix;
private:
Cwise& operator=(const Cwise&);
};
/** \returns a Cwise wrapper of *this providing additional coefficient-wise operations

View File

@@ -147,7 +147,6 @@ EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived>
MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
ei_assert(IsVectorAtCompileTime);
if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func);
else return CwiseNullaryOp<CustomNullaryOp, Derived>(size, 1, func);
}

View File

@@ -351,6 +351,8 @@ struct ei_scalar_multiple_op {
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
private:
ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_multiple_op<Scalar> >
@@ -378,6 +380,8 @@ struct ei_scalar_quotient1_impl {
EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const
{ return ei_pmul(a, ei_pset1(m_other)); }
const Scalar m_other;
private:
ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> >
@@ -423,6 +427,8 @@ struct ei_scalar_constant_op {
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); }
const Scalar m_other;
private:
ei_scalar_constant_op& operator=(const ei_scalar_constant_op&);
};
template<typename Scalar>
struct ei_functor_traits<ei_scalar_constant_op<Scalar> >

View File

@@ -317,4 +317,34 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec
return a <= b || ei_isApprox(a, b, prec);
}
/**************
*** bool ***
**************/
template<> inline bool precision<bool>() { return 0; }
inline bool ei_real(bool x) { return x; }
inline bool& ei_real_ref(bool& x) { return x; }
inline bool ei_imag(bool) { return 0; }
inline bool ei_conj(bool x) { return x; }
inline bool ei_abs(bool x) { return x; }
inline bool ei_abs2(bool x) { return x; }
inline bool ei_sqrt(bool x) { return x; }
template<> inline bool ei_random()
{
return (ei_random<int>(0,1) == 1);
}
inline bool ei_isMuchSmallerThan(bool a, bool, bool = precision<bool>())
{
return !a;
}
inline bool ei_isApprox(bool a, bool b, bool = precision<bool>())
{
return a == b;
}
inline bool ei_isApproxOrLessThan(bool a, bool b, bool = precision<bool>())
{
return int(a) <= int(b);
}
#endif // EIGEN_MATHFUNCTIONS_H

View File

@@ -538,7 +538,7 @@ class Matrix
* data pointers.
*/
template<typename OtherDerived>
void swap(const MatrixBase<OtherDerived>& other);
void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other);
/** \name Map
* These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects,
@@ -707,6 +707,8 @@ struct ei_conservative_resize_like_impl
{
static void run(MatrixBase<Derived>& _this, const MatrixBase<OtherDerived>& other)
{
if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
// Note: Here is space for improvement. Basically, for conservativeResize(int,int),
// neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the
// dimensions is dynamic, one could use either conservativeResize(int rows, NoChange_t) or
@@ -728,6 +730,8 @@ struct ei_conservative_resize_like_impl<Derived,OtherDerived,true>
{
static void run(MatrixBase<Derived>& _this, const MatrixBase<OtherDerived>& other)
{
if (_this.rows() == other.rows() && _this.cols() == other.cols()) return;
// segment(...) will check whether Derived/OtherDerived are vectors!
typename MatrixBase<Derived>::PlainMatrixType tmp(other);
const int common_size = std::min<int>(_this.size(),tmp.size());
@@ -756,7 +760,7 @@ struct ei_matrix_swap_impl<MatrixType, OtherDerived, true>
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
template<typename OtherDerived>
inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other)
inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
{
enum { SwapPointers = ei_is_same_type<Matrix, OtherDerived>::ret && Base::SizeAtCompileTime==Dynamic };
ei_matrix_swap_impl<Matrix, OtherDerived, bool(SwapPointers)>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));

View File

@@ -592,7 +592,7 @@ template<typename Derived> class MatrixBase
{ return typename ei_eval<Derived>::type(derived()); }
template<typename OtherDerived>
void swap(const MatrixBase<OtherDerived>& other);
void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other);
template<unsigned int Added>
const Flagged<Derived, Added, 0> marked() const;
@@ -702,8 +702,10 @@ template<typename Derived> class MatrixBase
const LU<PlainMatrixType> lu() const;
const PartialLU<PlainMatrixType> partialLu() const;
const PlainMatrixType inverse() const;
void computeInverse(PlainMatrixType *result) const;
bool computeInverseWithCheck( PlainMatrixType *result ) const;
template<typename ResultType>
void computeInverse(ResultType *result) const;
template<typename ResultType>
bool computeInverseWithCheck(ResultType *result ) const;
Scalar determinant() const;
/////////// Cholesky module ///////////

View File

@@ -29,32 +29,38 @@
struct ei_constructor_without_unaligned_array_assert {};
/** \internal
* Static array automatically aligned if the total byte size is a multiple of 16 and the matrix options require auto alignment
* Static array. If the MatrixOptions require auto-alignment, the array will be automatically aligned:
* to 16 bytes boundary if the total size is a multiple of 16 bytes.
*/
template <typename T, int Size, int MatrixOptions,
bool Align = (!(MatrixOptions&DontAlign)) && (((Size*sizeof(T))&0xf)==0)
> struct ei_matrix_array
{
EIGEN_ALIGN_128 T array[Size];
ei_matrix_array()
{
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0
&& "this assertion is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
#endif
}
ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
};
template <typename T, int Size, int MatrixOptions> struct ei_matrix_array<T,Size,MatrixOptions,false>
int Alignment = (MatrixOptions&DontAlign) ? 0
: (((Size*sizeof(T))%16)==0) ? 16
: 0 >
struct ei_matrix_array
{
T array[Size];
ei_matrix_array() {}
ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
};
#ifdef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask)
#else
#define EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(sizemask) \
ei_assert((reinterpret_cast<size_t>(array) & sizemask) == 0 \
&& "this assertion is explained here: " \
"http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html" \
" **** READ THIS WEB PAGE !!! ****");
#endif
template <typename T, int Size, int MatrixOptions>
struct ei_matrix_array<T, Size, MatrixOptions, 16>
{
EIGEN_ALIGN16 T array[Size];
ei_matrix_array() { EIGEN_MAKE_UNALIGNED_ARRAY_ASSERT(0xf) }
ei_matrix_array(ei_constructor_without_unaligned_array_assert) {}
};
/** \internal
*
* \class ei_matrix_storage

View File

@@ -102,6 +102,9 @@ template<typename ExpressionType> class NestByValue
protected:
const ExpressionType m_expression;
private:
NestByValue& operator=(const NestByValue&);
};
/** \returns an expression of the temporary version of *this.

View File

@@ -73,6 +73,9 @@ class NoAlias
protected:
ExpressionType& m_expression;
private:
NoAlias& operator=(const NoAlias&);
};
/** \returns a pseudo expression of \c *this with an operator= assuming

View File

@@ -135,7 +135,7 @@ struct ProductReturnType<Lhs,Rhs,UnrolledProduct>
{
typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
typedef GeneralProduct<Lhs, Rhs, UnrolledProduct> Type;
typedef GeneralProduct<LhsNested, RhsNested, UnrolledProduct> Type;
};
@@ -211,6 +211,9 @@ class GeneralProduct<Lhs, Rhs, OuterProduct>
{
ei_outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha);
}
private:
GeneralProduct& operator=(const GeneralProduct&);
};
template<> struct ei_outer_product_selector<ColMajor> {
@@ -276,6 +279,9 @@ class GeneralProduct<Lhs, Rhs, GemvProduct>
ei_gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
bool(ei_blas_traits<MatrixType>::ActualAccess)>::run(*this, dst, alpha);
}
private:
GeneralProduct& operator=(const GeneralProduct&);
};
// The vector is on the left => transposition

View File

@@ -137,6 +137,8 @@ class ProductBase : public MatrixBase<Derived>
void coeffRef(int,int);
void coeff(int) const;
void coeffRef(int);
ProductBase& operator=(const ProductBase&);
};
template<typename NestedProduct>

View File

@@ -112,6 +112,16 @@ struct ei_redux_novec_unroller<Func, Derived, Start, 1>
}
};
// This is actually dead code and will never be called. It is required
// to prevent false warnings regarding failed inlining though
// for 0 length run() will never be called at all.
template<typename Func, typename Derived, int Start>
struct ei_redux_novec_unroller<Func, Derived, Start, 0>
{
typedef typename Derived::Scalar Scalar;
EIGEN_STRONG_INLINE static Scalar run(const Derived&, const Func&) { return Scalar(); }
};
/*** vectorization ***/
template<typename Func, typename Derived, int Start, int Length>
@@ -297,7 +307,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, CompleteUnrolling>
/** \returns the result of a full redux operation on the whole matrix or vector using \a func
*
* The template parameter \a BinaryOp is the type of the functor \a func which must be
* an assiociative operator. Both current STL and TR1 functor styles are handled.
* an associative operator. Both current STL and TR1 functor styles are handled.
*
* \sa MatrixBase::sum(), MatrixBase::minCoeff(), MatrixBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
*/

View File

@@ -108,21 +108,15 @@ MatrixBase<Derived>::blueNorm() const
iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent
rbig = std::numeric_limits<RealScalar>::max(); // largest floating-point number
// Check the basic machine-dependent constants.
if(iemin > 1 - 2*it || 1+it>iemax || (it==2 && ibeta<5)
|| (it<=4 && ibeta <= 3 ) || it<2)
{
ei_assert(false && "the algorithm cannot be guaranteed on this computer");
}
iexp = -((1-iemin)/2);
b1 = RealScalar(std::pow(double(ibeta),iexp)); // lower boundary of midrange
b1 = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // lower boundary of midrange
iexp = (iemax + 1 - it)/2;
b2 = RealScalar(std::pow(double(ibeta),iexp)); // upper boundary of midrange
b2 = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // upper boundary of midrange
iexp = (2-iemin)/2;
s1m = RealScalar(std::pow(double(ibeta),iexp)); // scaling factor for lower range
s1m = RealScalar(std::pow(RealScalar(ibeta),RealScalar(iexp))); // scaling factor for lower range
iexp = - ((iemax+it)/2);
s2m = RealScalar(std::pow(double(ibeta),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
eps = RealScalar(std::pow(double(ibeta), 1-it));

View File

@@ -117,6 +117,9 @@ template<typename ExpressionType> class SwapWrapper
protected:
ExpressionType& m_expression;
private:
SwapWrapper& operator=(const SwapWrapper&);
};
/** swaps *this with the expression \a other.
@@ -128,15 +131,9 @@ template<typename ExpressionType> class SwapWrapper
*/
template<typename Derived>
template<typename OtherDerived>
void MatrixBase<Derived>::swap(const MatrixBase<OtherDerived>& other)
void MatrixBase<Derived>::swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
{
(SwapWrapper<Derived>(derived())).lazyAssign(other);
}
#endif // EIGEN_SWAP_H

View File

@@ -300,13 +300,13 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView
}
template<typename OtherDerived>
void swap(const TriangularBase<OtherDerived>& other)
void swap(TriangularBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
{
TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived());
}
template<typename OtherDerived>
void swap(const MatrixBase<OtherDerived>& other)
void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
{
TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived());
}

View File

@@ -265,14 +265,14 @@ template<> inline void ei_pstoreu(int* to , const v4i& from )
template<> inline float ei_pfirst(const v4f& a)
{
float EIGEN_ALIGN_128 af[4];
float EIGEN_ALIGN16 af[4];
vec_st(a, 0, af);
return af[0];
}
template<> inline int ei_pfirst(const v4i& a)
{
int EIGEN_ALIGN_128 ai[4];
int EIGEN_ALIGN16 ai[4];
vec_st(a, 0, ai);
return ai[0];
}
@@ -373,7 +373,7 @@ inline float ei_predux_mul(const v4f& a)
inline int ei_predux_mul(const v4i& a)
{
EIGEN_ALIGN_128 int aux[4];
EIGEN_ALIGN16 int aux[4];
ei_pstore(aux, a);
return aux[0] * aux[1] * aux[2] * aux[3];
}

View File

@@ -359,7 +359,7 @@ template<> EIGEN_STRONG_INLINE int ei_predux_mul<Packet4i>(const Packet4i& a)
// after some experiments, it is seems this is the fastest way to implement it
// for GCC (eg., reusing ei_pmul is very slow !)
// TODO try to call _mm_mul_epu32 directly
EIGEN_ALIGN_128 int aux[4];
EIGEN_ALIGN16 int aux[4];
ei_pstore(aux, a);
return (aux[0] * aux[1]) * (aux[2] * aux[3]);;
}
@@ -378,7 +378,7 @@ template<> EIGEN_STRONG_INLINE int ei_predux_min<Packet4i>(const Packet4i& a)
{
// after some experiments, it is seems this is the fastest way to implement it
// for GCC (eg., it does not like using std::min after the ei_pstore !!)
EIGEN_ALIGN_128 int aux[4];
EIGEN_ALIGN16 int aux[4];
ei_pstore(aux, a);
register int aux0 = aux[0]<aux[1] ? aux[0] : aux[1];
register int aux2 = aux[2]<aux[3] ? aux[2] : aux[3];
@@ -399,7 +399,7 @@ template<> EIGEN_STRONG_INLINE int ei_predux_max<Packet4i>(const Packet4i& a)
{
// after some experiments, it is seems this is the fastest way to implement it
// for GCC (eg., it does not like using std::min after the ei_pstore !!)
EIGEN_ALIGN_128 int aux[4];
EIGEN_ALIGN16 int aux[4];
ei_pstore(aux, a);
register int aux0 = aux[0]>aux[1] ? aux[0] : aux[1];
register int aux2 = aux[2]>aux[3] ? aux[2] : aux[3];

View File

@@ -0,0 +1,6 @@
FILE(GLOB Eigen_Core_Product_SRCS "*.h")
INSTALL(FILES
${Eigen_Core_Product_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/Core/products COMPONENT Devel
)

View File

@@ -57,8 +57,7 @@ void ei_cache_friendly_product_colmajor_times_vector(
if(ConjugateRhs)
alpha = ei_conj(alpha);
// std::cerr << "prod " << size << " " << rhs.size() << "\n";
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
@@ -69,9 +68,9 @@ void ei_cache_friendly_product_colmajor_times_vector(
const int PeelAlignedMask = PacketSize*peels-1;
// How many coeffs of the result do we have to skip to be aligned.
// Here we assume data are at least aligned on the base scalar type that is mandatory anyway.
const int alignedStart = ei_alignmentOffset(res,size);
const int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
// Here we assume data are at least aligned on the base scalar type.
int alignedStart = ei_alignmentOffset(res,size);
int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
const int peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
const int alignmentStep = PacketSize>1 ? (PacketSize - lhsStride % PacketSize) & PacketAlignedMask : 0;
@@ -84,12 +83,18 @@ void ei_cache_friendly_product_colmajor_times_vector(
// find how many columns do we have to skip to be aligned with the result (if possible)
int skipColumns = 0;
if (PacketSize>1)
// if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats)
if( (size_t(lhs)%sizeof(RealScalar)) || (size_t(res)%sizeof(RealScalar)) )
{
alignedSize = 0;
alignedStart = 0;
}
else if (PacketSize>1)
{
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
while (skipColumns<PacketSize &&
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
++skipColumns;
if (skipColumns==PacketSize)
{
@@ -263,6 +268,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
ei_conj_helper<ConjugateLhs,ConjugateRhs> cj;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
@@ -274,9 +280,10 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
const int size = rhsSize;
// How many coeffs of the result do we have to skip to be aligned.
// Here we assume data are at least aligned on the base scalar type that is mandatory anyway.
const int alignedStart = ei_alignmentOffset(rhs, size);
const int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
// Here we assume data are at least aligned on the base scalar type
// if that's not the case then vectorization is discarded, see below.
int alignedStart = ei_alignmentOffset(rhs, size);
int alignedSize = PacketSize>1 ? alignedStart + ((size-alignedStart) & ~PacketAlignedMask) : 0;
const int peeledSize = peels>1 ? alignedStart + ((alignedSize-alignedStart) & ~PeelAlignedMask) : alignedStart;
const int alignmentStep = PacketSize>1 ? (PacketSize - lhsStride % PacketSize) & PacketAlignedMask : 0;
@@ -289,7 +296,13 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
// find how many rows do we have to skip to be aligned with rhs (if possible)
int skipRows = 0;
if (PacketSize>1)
// if the data cannot be aligned (TODO add some compile time tests when possible, e.g. for floats)
if( (size_t(lhs)%sizeof(RealScalar)) || (size_t(rhs)%sizeof(RealScalar)) )
{
alignedSize = 0;
alignedStart = 0;
}
else if (PacketSize>1)
{
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);

View File

@@ -38,10 +38,8 @@ struct ei_selfadjoint_rank2_update_selector<Scalar,UType,VType,LowerTriangular>
static void run(Scalar* mat, int stride, const UType& u, const VType& v, Scalar alpha)
{
const int size = u.size();
// std::cerr << "lower \n" << u.transpose() << "\n" << v.transpose() << "\n\n";
for (int i=0; i<size; ++i)
{
// std::cerr <<
Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+i, size-i) +=
(alpha * ei_conj(u.coeff(i))) * v.end(size-i)
+ (alpha * ei_conj(v.coeff(i))) * u.end(size-i);

View File

@@ -29,8 +29,8 @@
#undef minor
#define EIGEN_WORLD_VERSION 2
#define EIGEN_MAJOR_VERSION 0
#define EIGEN_MINOR_VERSION 52
#define EIGEN_MAJOR_VERSION 90
#define EIGEN_MINOR_VERSION 0
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
@@ -202,25 +202,28 @@ using Eigen::ei_cos;
#define EIGEN_ASM_COMMENT(X)
#endif
/* EIGEN_ALIGN_128 forces data to be 16-byte aligned, EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
/* EIGEN_ALIGN_TO_BOUNDARY(n) forces data to be n-byte aligned. This is used to satisfy SIMD requirements.
* However, we do that EVEN if vectorization (EIGEN_VECTORIZE) is disabled,
* so that vectorization doesn't affect binary compatibility.
*
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
* vectorized and non-vectorized code.
*/
#if !EIGEN_ALIGN
#define EIGEN_ALIGN_128
#define EIGEN_ALIGN_TO_BOUNDARY(n)
#elif (defined __GNUC__)
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
#elif (defined _MSC_VER)
#define EIGEN_ALIGN_128 __declspec(align(16))
#define EIGEN_ALIGN_TO_BOUNDARY(n) __declspec(align(n))
#elif (defined __SUNPRO_CC)
// FIXME not sure about this one:
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
#define EIGEN_ALIGN_TO_BOUNDARY(n) __attribute__((aligned(n)))
#else
#error Please tell me what is the equivalent of __attribute__((aligned(16))) for your compiler
#error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler
#endif
#define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16)
#ifdef EIGEN_DONT_USE_RESTRICT_KEYWORD
#define EIGEN_RESTRICT
#endif
@@ -251,6 +254,13 @@ using Eigen::ei_cos;
// needed to define it here as escaping characters in CMake add_definition's argument seems very problematic.
#define EIGEN_DOCS_IO_FORMAT IOFormat(3, 0, " ", "\n", "", "")
// C++0x features
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
#define EIGEN_REF_TO_TEMPORARY &&
#else
#define EIGEN_REF_TO_TEMPORARY const &
#endif
#ifdef _MSC_VER
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \
using Base::operator =; \

View File

@@ -41,7 +41,7 @@
#ifndef EIGEN_NO_STATIC_ASSERT
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && (_MSC_VER >= 1600))
// if native static_assert is enabled, let's use it
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
@@ -77,7 +77,8 @@
THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES,
INVALID_MATRIX_TEMPLATE_PARAMETERS,
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX,
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE
};
};

View File

@@ -1,148 +1,149 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Claire Maurice
// 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_COMPLEX_EIGEN_SOLVER_H
#define EIGEN_COMPLEX_EIGEN_SOLVER_H
/** \eigenvalues_module \ingroup Eigenvalues_Module
* \nonstableyet
*
* \class ComplexEigenSolver
*
* \brief Eigen values/vectors solver for general complex matrices
*
* \param MatrixType the type of the matrix of which we are computing the eigen decomposition
*
* \sa class EigenSolver, class SelfAdjointEigenSolver
*/
template<typename _MatrixType> class ComplexEigenSolver
{
public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef std::complex<RealScalar> Complex;
typedef Matrix<Complex, MatrixType::ColsAtCompileTime,1> EigenvalueType;
typedef Matrix<Complex, MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime> EigenvectorType;
/**
* \brief Default Constructor.
*
* The default constructor is useful in cases in which the user intends to
* perform decompositions via ComplexEigenSolver::compute(const MatrixType&).
*/
ComplexEigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false)
{}
ComplexEigenSolver(const MatrixType& matrix)
: m_eivec(matrix.rows(),matrix.cols()),
m_eivalues(matrix.cols()),
m_isInitialized(false)
{
compute(matrix);
}
EigenvectorType eigenvectors(void) const
{
ei_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
return m_eivec;
}
EigenvalueType eigenvalues() const
{
ei_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
return m_eivalues;
}
void compute(const MatrixType& matrix);
protected:
MatrixType m_eivec;
EigenvalueType m_eivalues;
bool m_isInitialized;
};
template<typename MatrixType>
void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix)
{
// this code is inspired from Jampack
assert(matrix.cols() == matrix.rows());
int n = matrix.cols();
m_eivalues.resize(n,1);
RealScalar eps = epsilon<RealScalar>();
// Reduce to complex Schur form
ComplexSchur<MatrixType> schur(matrix);
m_eivalues = schur.matrixT().diagonal();
m_eivec.setZero();
Scalar d2, z;
RealScalar norm = matrix.norm();
// compute the (normalized) eigenvectors
for(int k=n-1 ; k>=0 ; k--)
{
d2 = schur.matrixT().coeff(k,k);
m_eivec.coeffRef(k,k) = Scalar(1.0,0.0);
for(int i=k-1 ; i>=0 ; i--)
{
m_eivec.coeffRef(i,k) = -schur.matrixT().coeff(i,k);
if(k-i-1>0)
m_eivec.coeffRef(i,k) -= (schur.matrixT().row(i).segment(i+1,k-i-1) * m_eivec.col(k).segment(i+1,k-i-1)).value();
z = schur.matrixT().coeff(i,i) - d2;
if(z==Scalar(0))
ei_real_ref(z) = eps * norm;
m_eivec.coeffRef(i,k) = m_eivec.coeff(i,k) / z;
}
m_eivec.col(k).normalize();
}
m_eivec = schur.matrixU() * m_eivec;
m_isInitialized = true;
// sort the eigenvalues
{
for (int i=0; i<n; i++)
{
int k;
m_eivalues.cwise().abs().end(n-i).minCoeff(&k);
if (k != 0)
{
k += i;
std::swap(m_eivalues[k],m_eivalues[i]);
m_eivec.col(i).swap(m_eivec.col(k));
}
}
}
}
#endif // EIGEN_COMPLEX_EIGEN_SOLVER_H
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Claire Maurice
// 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_COMPLEX_EIGEN_SOLVER_H
#define EIGEN_COMPLEX_EIGEN_SOLVER_H
/** \eigenvalues_module \ingroup Eigenvalues_Module
* \nonstableyet
*
* \class ComplexEigenSolver
*
* \brief Eigen values/vectors solver for general complex matrices
*
* \param MatrixType the type of the matrix of which we are computing the eigen decomposition
*
* \sa class EigenSolver, class SelfAdjointEigenSolver
*/
template<typename _MatrixType> class ComplexEigenSolver
{
public:
typedef _MatrixType MatrixType;
typedef typename MatrixType::Scalar Scalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef std::complex<RealScalar> Complex;
typedef Matrix<Complex, MatrixType::ColsAtCompileTime,1> EigenvalueType;
typedef Matrix<Complex, MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime> EigenvectorType;
/**
* \brief Default Constructor.
*
* The default constructor is useful in cases in which the user intends to
* perform decompositions via ComplexEigenSolver::compute(const MatrixType&).
*/
ComplexEigenSolver() : m_eivec(), m_eivalues(), m_isInitialized(false)
{}
ComplexEigenSolver(const MatrixType& matrix)
: m_eivec(matrix.rows(),matrix.cols()),
m_eivalues(matrix.cols()),
m_isInitialized(false)
{
compute(matrix);
}
EigenvectorType eigenvectors(void) const
{
ei_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
return m_eivec;
}
EigenvalueType eigenvalues() const
{
ei_assert(m_isInitialized && "ComplexEigenSolver is not initialized.");
return m_eivalues;
}
void compute(const MatrixType& matrix);
protected:
MatrixType m_eivec;
EigenvalueType m_eivalues;
bool m_isInitialized;
};
template<typename MatrixType>
void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix)
{
// this code is inspired from Jampack
assert(matrix.cols() == matrix.rows());
int n = matrix.cols();
m_eivalues.resize(n,1);
m_eivec.resize(n,n);
RealScalar eps = epsilon<RealScalar>();
// Reduce to complex Schur form
ComplexSchur<MatrixType> schur(matrix);
m_eivalues = schur.matrixT().diagonal();
m_eivec.setZero();
Scalar d2, z;
RealScalar norm = matrix.norm();
// compute the (normalized) eigenvectors
for(int k=n-1 ; k>=0 ; k--)
{
d2 = schur.matrixT().coeff(k,k);
m_eivec.coeffRef(k,k) = Scalar(1.0,0.0);
for(int i=k-1 ; i>=0 ; i--)
{
m_eivec.coeffRef(i,k) = -schur.matrixT().coeff(i,k);
if(k-i-1>0)
m_eivec.coeffRef(i,k) -= (schur.matrixT().row(i).segment(i+1,k-i-1) * m_eivec.col(k).segment(i+1,k-i-1)).value();
z = schur.matrixT().coeff(i,i) - d2;
if(z==Scalar(0))
ei_real_ref(z) = eps * norm;
m_eivec.coeffRef(i,k) = m_eivec.coeff(i,k) / z;
}
m_eivec.col(k).normalize();
}
m_eivec = schur.matrixU() * m_eivec;
m_isInitialized = true;
// sort the eigenvalues
{
for (int i=0; i<n; i++)
{
int k;
m_eivalues.cwise().abs().end(n-i).minCoeff(&k);
if (k != 0)
{
k += i;
std::swap(m_eivalues[k],m_eivalues[i]);
m_eivec.col(i).swap(m_eivec.col(k));
}
}
}
}
#endif // EIGEN_COMPLEX_EIGEN_SOLVER_H

View File

@@ -194,6 +194,7 @@ EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const MatrixType& matr
assert(matrix.cols() == matrix.rows());
int n = matrix.cols();
m_eivalues.resize(n,1);
m_eivec.resize(n,n);
MatrixType matH = matrix;
RealVectorType ort(n);

View File

@@ -168,6 +168,7 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>::compute(
assert(matrix.cols() == matrix.rows());
int n = matrix.cols();
m_eivalues.resize(n,1);
m_eivec.resize(n,n);
if(n==1)
{

View File

@@ -153,10 +153,12 @@ template<typename VectorsType, typename CoeffsType> class HouseholderSequence
}
protected:
typename VectorsType::Nested m_vectors;
typename CoeffsType::Nested m_coeffs;
bool m_trans;
private:
HouseholderSequence& operator=(const HouseholderSequence&);
};
template<typename VectorsType, typename CoeffsType>

View File

@@ -95,8 +95,8 @@ bool ei_compute_inverse_size3(const XprType& matrix, MatrixType* result)
return true;
}
template<typename MatrixType>
bool ei_compute_inverse_size4_helper(const MatrixType& matrix, MatrixType* result)
template<typename MatrixType, typename ResultType>
bool ei_compute_inverse_size4_helper(const MatrixType& matrix, ResultType* result)
{
/* Let's split M into four 2x2 blocks:
* (P Q)
@@ -195,47 +195,47 @@ bool ei_compute_inverse_size4_with_check(const XprType& matrix, MatrixType* resu
*** Part 2 : selector and MatrixBase methods ***
***********************************************/
template<typename MatrixType, int Size = MatrixType::RowsAtCompileTime>
template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
struct ei_compute_inverse
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const MatrixType& matrix, ResultType* result)
{
result = matrix.partialLu().inverse();
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 1>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 1>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const MatrixType& matrix, ResultType* result)
{
typedef typename MatrixType::Scalar Scalar;
result->coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 2>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 2>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const MatrixType& matrix, ResultType* result)
{
ei_compute_inverse_size2(matrix, result);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 3>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 3>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const MatrixType& matrix, ResultType* result)
{
ei_compute_inverse_size3<false, MatrixType, MatrixType>(matrix, result);
ei_compute_inverse_size3<false, MatrixType, ResultType>(matrix, result);
}
};
template<typename MatrixType>
struct ei_compute_inverse<MatrixType, 4>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse<MatrixType, ResultType, 4>
{
static inline void run(const MatrixType& matrix, MatrixType* result)
static inline void run(const MatrixType& matrix, ResultType* result)
{
ei_compute_inverse_size4_with_check(matrix, result);
}
@@ -256,11 +256,12 @@ struct ei_compute_inverse<MatrixType, 4>
* \sa inverse(), computeInverseWithCheck()
*/
template<typename Derived>
inline void MatrixBase<Derived>::computeInverse(PlainMatrixType *result) const
template<typename ResultType>
inline void MatrixBase<Derived>::computeInverse(ResultType *result) const
{
ei_assert(rows() == cols());
EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)
ei_compute_inverse<PlainMatrixType>::run(eval(), result);
ei_compute_inverse<PlainMatrixType, ResultType>::run(eval(), result);
}
/** \lu_module
@@ -289,10 +290,10 @@ inline const typename MatrixBase<Derived>::PlainMatrixType MatrixBase<Derived>::
* Compute inverse with invertibility check *
*******************************************/
template<typename MatrixType, int Size = MatrixType::RowsAtCompileTime>
template<typename MatrixType, typename ResultType, int Size = MatrixType::RowsAtCompileTime>
struct ei_compute_inverse_with_check
{
static inline bool run(const MatrixType& matrix, MatrixType* result)
static inline bool run(const MatrixType& matrix, ResultType* result)
{
typedef typename MatrixType::Scalar Scalar;
LU<MatrixType> lu( matrix );
@@ -302,10 +303,10 @@ struct ei_compute_inverse_with_check
}
};
template<typename MatrixType>
struct ei_compute_inverse_with_check<MatrixType, 1>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_with_check<MatrixType, ResultType, 1>
{
static inline bool run(const MatrixType& matrix, MatrixType* result)
static inline bool run(const MatrixType& matrix, ResultType* result)
{
typedef typename MatrixType::Scalar Scalar;
if( matrix.coeff(0,0) == Scalar(0) ) return false;
@@ -314,28 +315,28 @@ struct ei_compute_inverse_with_check<MatrixType, 1>
}
};
template<typename MatrixType>
struct ei_compute_inverse_with_check<MatrixType, 2>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_with_check<MatrixType, ResultType, 2>
{
static inline bool run(const MatrixType& matrix, MatrixType* result)
static inline bool run(const MatrixType& matrix, ResultType* result)
{
return ei_compute_inverse_size2_with_check(matrix, result);
}
};
template<typename MatrixType>
struct ei_compute_inverse_with_check<MatrixType, 3>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_with_check<MatrixType, ResultType, 3>
{
static inline bool run(const MatrixType& matrix, MatrixType* result)
static inline bool run(const MatrixType& matrix, ResultType* result)
{
return ei_compute_inverse_size3<true, MatrixType, MatrixType>(matrix, result);
return ei_compute_inverse_size3<true, MatrixType, ResultType>(matrix, result);
}
};
template<typename MatrixType>
struct ei_compute_inverse_with_check<MatrixType, 4>
template<typename MatrixType, typename ResultType>
struct ei_compute_inverse_with_check<MatrixType, ResultType, 4>
{
static inline bool run(const MatrixType& matrix, MatrixType* result)
static inline bool run(const MatrixType& matrix, ResultType* result)
{
return ei_compute_inverse_size4_with_check(matrix, result);
}
@@ -352,11 +353,12 @@ struct ei_compute_inverse_with_check<MatrixType, 4>
* \sa inverse(), computeInverse()
*/
template<typename Derived>
inline bool MatrixBase<Derived>::computeInverseWithCheck(PlainMatrixType *result) const
template<typename ResultType>
inline bool MatrixBase<Derived>::computeInverseWithCheck(ResultType *result) const
{
ei_assert(rows() == cols());
EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)
return ei_compute_inverse_with_check<PlainMatrixType>::run(eval(), result);
return ei_compute_inverse_with_check<PlainMatrixType, ResultType>::run(eval(), result);
}

View File

@@ -62,7 +62,7 @@ template<typename MatrixType> class ColPivotingHouseholderQR
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
typedef Matrix<Scalar, RowsAtCompileTime, 1> ColVectorType;
typedef Matrix<RealScalar, 1, ColsAtCompileTime> RealRowVectorType;
typedef typename HouseholderSequence<MatrixQType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
/**
* \brief Default Constructor.
@@ -351,7 +351,6 @@ bool ColPivotingHouseholderQR<MatrixType>::solve(
}
const int rows = m_qr.rows();
const int cols = b.cols();
ei_assert(b.rows() == rows);
typename OtherDerived::PlainMatrixType c(b);

View File

@@ -59,10 +59,10 @@ template<typename MatrixType> class HouseholderQR
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixQType;
typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, AutoAlign | (ei_traits<MatrixType>::Flags&RowMajorBit ? RowMajor : ColMajor)> MatrixQType;
typedef Matrix<Scalar, DiagSizeAtCompileTime, 1> HCoeffsType;
typedef Matrix<Scalar, 1, ColsAtCompileTime> RowVectorType;
typedef typename HouseholderSequence<MatrixQType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
typedef typename HouseholderSequence<MatrixType,HCoeffsType>::ConjugateReturnType HouseholderSequenceType;
/**
* \brief Default Constructor.
@@ -206,18 +206,22 @@ void HouseholderQR<MatrixType>::solve(
) const
{
ei_assert(m_isInitialized && "HouseholderQR is not initialized.");
result->derived().resize(m_qr.cols(), b.cols());
const int rows = m_qr.rows();
const int cols = b.cols();
const int rank = std::min(m_qr.rows(), m_qr.cols());
ei_assert(b.rows() == rows);
result->resize(rows, cols);
*result = b;
result->applyOnTheLeft(matrixQAsHouseholderSequence().inverse());
typename OtherDerived::PlainMatrixType c(b);
// Note that the matrix Q = H_0^* H_1^*... so its inverse is Q^* = (H_0 H_1 ...)^T
c.applyOnTheLeft(makeHouseholderSequence(m_qr.corner(TopLeft,rows,rank), m_hCoeffs.start(rank)).transpose());
const int rank = std::min(result->rows(), result->cols());
m_qr.corner(TopLeft, rank, rank)
.template triangularView<UpperTriangular>()
.solveInPlace(result->corner(TopLeft, rank, result->cols()));
.solveInPlace(c.corner(TopLeft, rank, c.cols()));
result->corner(TopLeft, rank, c.cols()) = c.corner(TopLeft,rank, c.cols());
result->corner(BottomLeft, result->rows()-rank, c.cols()).setZero();
}
/** \returns the matrix Q */

View File

@@ -1,38 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008 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_EXTERN_INSTANTIATIONS
#define EIGEN_EXTERN_INSTANTIATIONS
#endif
#include "../../Core"
#undef EIGEN_EXTERN_INSTANTIATIONS
#include "../../QR"
namespace Eigen
{
EIGEN_QR_MODULE_INSTANTIATE();
}

View File

@@ -26,8 +26,9 @@
#define EIGEN_JACOBISVD_H
// forward declarations (needed by ICC)
// the empty bodies are required by VC
template<typename MatrixType, unsigned int Options, bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>
struct ei_svd_precondition_2x2_block_to_be_real;
struct ei_svd_precondition_2x2_block_to_be_real {};
template<typename MatrixType, unsigned int Options,
bool PossiblyMoreRowsThanCols = (Options & AtLeastAsManyColsAsRows) == 0

View File

@@ -515,7 +515,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived
{ return typename ei_eval<Derived>::type(derived()); }
// template<typename OtherDerived>
// void swap(const MatrixBase<OtherDerived>& other);
// void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other);
template<unsigned int Added>
const SparseFlagged<Derived, Added, 0> marked() const;