This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
View | Details | Raw Unified | Return to bug 314
Collapse All | Expand All

(-)a/Eigen/src/Cholesky/LDLT.h (+1 lines)
Lines 243-258 namespace internal { Link Here
243
243
244
template<int UpLo> struct ldlt_inplace;
244
template<int UpLo> struct ldlt_inplace;
245
245
246
template<> struct ldlt_inplace<Lower>
246
template<> struct ldlt_inplace<Lower>
247
{
247
{
248
  template<typename MatrixType, typename TranspositionType, typename Workspace>
248
  template<typename MatrixType, typename TranspositionType, typename Workspace>
249
  static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
249
  static bool unblocked(MatrixType& mat, TranspositionType& transpositions, Workspace& temp, int* sign=0)
250
  {
250
  {
251
    using std::abs;
251
    typedef typename MatrixType::Scalar Scalar;
252
    typedef typename MatrixType::Scalar Scalar;
252
    typedef typename MatrixType::RealScalar RealScalar;
253
    typedef typename MatrixType::RealScalar RealScalar;
253
    typedef typename MatrixType::Index Index;
254
    typedef typename MatrixType::Index Index;
254
    eigen_assert(mat.rows()==mat.cols());
255
    eigen_assert(mat.rows()==mat.cols());
255
    const Index size = mat.rows();
256
    const Index size = mat.rows();
256
257
257
    if (size <= 1)
258
    if (size <= 1)
258
    {
259
    {
(-)a/Eigen/src/Cholesky/LLT.h (+2 lines)
Lines 185-200 template<typename _MatrixType, int _UpLo Link Here
185
185
186
namespace internal {
186
namespace internal {
187
187
188
template<typename Scalar, int UpLo> struct llt_inplace;
188
template<typename Scalar, int UpLo> struct llt_inplace;
189
189
190
template<typename MatrixType, typename VectorType>
190
template<typename MatrixType, typename VectorType>
191
static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma)
191
static typename MatrixType::Index llt_rank_update_lower(MatrixType& mat, const VectorType& vec, const typename MatrixType::RealScalar& sigma)
192
{
192
{
193
  using std::sqrt;
193
  typedef typename MatrixType::Scalar Scalar;
194
  typedef typename MatrixType::Scalar Scalar;
194
  typedef typename MatrixType::RealScalar RealScalar;
195
  typedef typename MatrixType::RealScalar RealScalar;
195
  typedef typename MatrixType::Index Index;
196
  typedef typename MatrixType::Index Index;
196
  typedef typename MatrixType::ColXpr ColXpr;
197
  typedef typename MatrixType::ColXpr ColXpr;
197
  typedef typename internal::remove_all<ColXpr>::type ColXprCleaned;
198
  typedef typename internal::remove_all<ColXpr>::type ColXprCleaned;
198
  typedef typename ColXprCleaned::SegmentReturnType ColXprSegment;
199
  typedef typename ColXprCleaned::SegmentReturnType ColXprSegment;
199
  typedef Matrix<Scalar,Dynamic,1> TempVectorType;
200
  typedef Matrix<Scalar,Dynamic,1> TempVectorType;
200
  typedef typename TempVectorType::SegmentReturnType TempVecSegment;
201
  typedef typename TempVectorType::SegmentReturnType TempVecSegment;
Lines 258-273 static typename MatrixType::Index llt_ra Link Here
258
}
259
}
259
260
260
template<typename Scalar> struct llt_inplace<Scalar, Lower>
261
template<typename Scalar> struct llt_inplace<Scalar, Lower>
261
{
262
{
262
  typedef typename NumTraits<Scalar>::Real RealScalar;
263
  typedef typename NumTraits<Scalar>::Real RealScalar;
263
  template<typename MatrixType>
264
  template<typename MatrixType>
264
  static typename MatrixType::Index unblocked(MatrixType& mat)
265
  static typename MatrixType::Index unblocked(MatrixType& mat)
265
  {
266
  {
267
    using std::sqrt;
266
    typedef typename MatrixType::Index Index;
268
    typedef typename MatrixType::Index Index;
267
    
269
    
268
    eigen_assert(mat.rows()==mat.cols());
270
    eigen_assert(mat.rows()==mat.cols());
269
    const Index size = mat.rows();
271
    const Index size = mat.rows();
270
    for(Index k = 0; k < size; ++k)
272
    for(Index k = 0; k < size; ++k)
271
    {
273
    {
272
      Index rs = size-k-1; // remaining size
274
      Index rs = size-k-1; // remaining size
273
275
(-)a/Eigen/src/Core/DiagonalMatrix.h (-1 / +2 lines)
Lines 281-301 MatrixBase<Derived>::asDiagonal() const Link Here
281
  * Example: \include MatrixBase_isDiagonal.cpp
281
  * Example: \include MatrixBase_isDiagonal.cpp
282
  * Output: \verbinclude MatrixBase_isDiagonal.out
282
  * Output: \verbinclude MatrixBase_isDiagonal.out
283
  *
283
  *
284
  * \sa asDiagonal()
284
  * \sa asDiagonal()
285
  */
285
  */
286
template<typename Derived>
286
template<typename Derived>
287
bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
287
bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const
288
{
288
{
289
  using std::abs;
289
  if(cols() != rows()) return false;
290
  if(cols() != rows()) return false;
290
  RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
291
  RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1);
291
  for(Index j = 0; j < cols(); ++j)
292
  for(Index j = 0; j < cols(); ++j)
292
  {
293
  {
293
    RealScalar absOnDiagonal = internal::abs(coeff(j,j));
294
    RealScalar absOnDiagonal = abs(coeff(j,j));
294
    if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
295
    if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal;
295
  }
296
  }
296
  for(Index j = 0; j < cols(); ++j)
297
  for(Index j = 0; j < cols(); ++j)
297
    for(Index i = 0; i < j; ++i)
298
    for(Index i = 0; i < j; ++i)
298
    {
299
    {
299
      if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
300
      if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false;
300
      if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
301
      if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false;
301
    }
302
    }
(-)a/Eigen/src/Core/Dot.h (-1 / +2 lines)
Lines 119-135 EIGEN_STRONG_INLINE typename NumTraits<t Link Here
119
  * In both cases, it consists in the square root of the sum of the square of all the matrix entries.
119
  * In both cases, it consists in the square root of the sum of the square of all the matrix entries.
120
  * For vectors, this is also equals to the square root of the dot product of \c *this with itself.
120
  * For vectors, this is also equals to the square root of the dot product of \c *this with itself.
121
  *
121
  *
122
  * \sa dot(), squaredNorm()
122
  * \sa dot(), squaredNorm()
123
  */
123
  */
124
template<typename Derived>
124
template<typename Derived>
125
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
125
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
126
{
126
{
127
  return internal::sqrt(squaredNorm());
127
  using std::sqrt;
128
  return sqrt(squaredNorm());
128
}
129
}
129
130
130
/** \returns an expression of the quotient of *this by its own norm.
131
/** \returns an expression of the quotient of *this by its own norm.
131
  *
132
  *
132
  * \only_for_vectors
133
  * \only_for_vectors
133
  *
134
  *
134
  * \sa norm(), normalize()
135
  * \sa norm(), normalize()
135
  */
136
  */
(-)a/Eigen/src/Core/Functors.h (-9 / +9 lines)
Lines 282-298 struct functor_traits<scalar_opposite_op Link Here
282
/** \internal
282
/** \internal
283
  * \brief Template functor to compute the absolute value of a scalar
283
  * \brief Template functor to compute the absolute value of a scalar
284
  *
284
  *
285
  * \sa class CwiseUnaryOp, Cwise::abs
285
  * \sa class CwiseUnaryOp, Cwise::abs
286
  */
286
  */
287
template<typename Scalar> struct scalar_abs_op {
287
template<typename Scalar> struct scalar_abs_op {
288
  EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
288
  EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
289
  typedef typename NumTraits<Scalar>::Real result_type;
289
  typedef typename NumTraits<Scalar>::Real result_type;
290
  EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return internal::abs(a); }
290
  EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); }
291
  template<typename Packet>
291
  template<typename Packet>
292
  EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
292
  EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
293
  { return internal::pabs(a); }
293
  { return internal::pabs(a); }
294
};
294
};
295
template<typename Scalar>
295
template<typename Scalar>
296
struct functor_traits<scalar_abs_op<Scalar> >
296
struct functor_traits<scalar_abs_op<Scalar> >
297
{
297
{
298
  enum {
298
  enum {
Lines 416-448 struct functor_traits<scalar_imag_ref_op Link Here
416
/** \internal
416
/** \internal
417
  *
417
  *
418
  * \brief Template functor to compute the exponential of a scalar
418
  * \brief Template functor to compute the exponential of a scalar
419
  *
419
  *
420
  * \sa class CwiseUnaryOp, Cwise::exp()
420
  * \sa class CwiseUnaryOp, Cwise::exp()
421
  */
421
  */
422
template<typename Scalar> struct scalar_exp_op {
422
template<typename Scalar> struct scalar_exp_op {
423
  EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
423
  EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
424
  inline const Scalar operator() (const Scalar& a) const { return internal::exp(a); }
424
  inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); }
425
  typedef typename packet_traits<Scalar>::type Packet;
425
  typedef typename packet_traits<Scalar>::type Packet;
426
  inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
426
  inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
427
};
427
};
428
template<typename Scalar>
428
template<typename Scalar>
429
struct functor_traits<scalar_exp_op<Scalar> >
429
struct functor_traits<scalar_exp_op<Scalar> >
430
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
430
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
431
431
432
/** \internal
432
/** \internal
433
  *
433
  *
434
  * \brief Template functor to compute the logarithm of a scalar
434
  * \brief Template functor to compute the logarithm of a scalar
435
  *
435
  *
436
  * \sa class CwiseUnaryOp, Cwise::log()
436
  * \sa class CwiseUnaryOp, Cwise::log()
437
  */
437
  */
438
template<typename Scalar> struct scalar_log_op {
438
template<typename Scalar> struct scalar_log_op {
439
  EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
439
  EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
440
  inline const Scalar operator() (const Scalar& a) const { return internal::log(a); }
440
  inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); }
441
  typedef typename packet_traits<Scalar>::type Packet;
441
  typedef typename packet_traits<Scalar>::type Packet;
442
  inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
442
  inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
443
};
443
};
444
template<typename Scalar>
444
template<typename Scalar>
445
struct functor_traits<scalar_log_op<Scalar> >
445
struct functor_traits<scalar_log_op<Scalar> >
446
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
446
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
447
447
448
/** \internal
448
/** \internal
Lines 669-685 struct functor_traits<scalar_add_op<Scal Link Here
669
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
669
{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
670
670
671
/** \internal
671
/** \internal
672
  * \brief Template functor to compute the square root of a scalar
672
  * \brief Template functor to compute the square root of a scalar
673
  * \sa class CwiseUnaryOp, Cwise::sqrt()
673
  * \sa class CwiseUnaryOp, Cwise::sqrt()
674
  */
674
  */
675
template<typename Scalar> struct scalar_sqrt_op {
675
template<typename Scalar> struct scalar_sqrt_op {
676
  EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
676
  EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
677
  inline const Scalar operator() (const Scalar& a) const { return internal::sqrt(a); }
677
  inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); }
678
  typedef typename packet_traits<Scalar>::type Packet;
678
  typedef typename packet_traits<Scalar>::type Packet;
679
  inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
679
  inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
680
};
680
};
681
template<typename Scalar>
681
template<typename Scalar>
682
struct functor_traits<scalar_sqrt_op<Scalar> >
682
struct functor_traits<scalar_sqrt_op<Scalar> >
683
{ enum {
683
{ enum {
684
    Cost = 5 * NumTraits<Scalar>::MulCost,
684
    Cost = 5 * NumTraits<Scalar>::MulCost,
685
    PacketAccess = packet_traits<Scalar>::HasSqrt
685
    PacketAccess = packet_traits<Scalar>::HasSqrt
Lines 687-703 struct functor_traits<scalar_sqrt_op<Sca Link Here
687
};
687
};
688
688
689
/** \internal
689
/** \internal
690
  * \brief Template functor to compute the cosine of a scalar
690
  * \brief Template functor to compute the cosine of a scalar
691
  * \sa class CwiseUnaryOp, ArrayBase::cos()
691
  * \sa class CwiseUnaryOp, ArrayBase::cos()
692
  */
692
  */
693
template<typename Scalar> struct scalar_cos_op {
693
template<typename Scalar> struct scalar_cos_op {
694
  EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
694
  EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
695
  inline Scalar operator() (const Scalar& a) const { return internal::cos(a); }
695
  inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); }
696
  typedef typename packet_traits<Scalar>::type Packet;
696
  typedef typename packet_traits<Scalar>::type Packet;
697
  inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
697
  inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
698
};
698
};
699
template<typename Scalar>
699
template<typename Scalar>
700
struct functor_traits<scalar_cos_op<Scalar> >
700
struct functor_traits<scalar_cos_op<Scalar> >
701
{
701
{
702
  enum {
702
  enum {
703
    Cost = 5 * NumTraits<Scalar>::MulCost,
703
    Cost = 5 * NumTraits<Scalar>::MulCost,
Lines 706-722 struct functor_traits<scalar_cos_op<Scal Link Here
706
};
706
};
707
707
708
/** \internal
708
/** \internal
709
  * \brief Template functor to compute the sine of a scalar
709
  * \brief Template functor to compute the sine of a scalar
710
  * \sa class CwiseUnaryOp, ArrayBase::sin()
710
  * \sa class CwiseUnaryOp, ArrayBase::sin()
711
  */
711
  */
712
template<typename Scalar> struct scalar_sin_op {
712
template<typename Scalar> struct scalar_sin_op {
713
  EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
713
  EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
714
  inline const Scalar operator() (const Scalar& a) const { return internal::sin(a); }
714
  inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); }
715
  typedef typename packet_traits<Scalar>::type Packet;
715
  typedef typename packet_traits<Scalar>::type Packet;
716
  inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
716
  inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
717
};
717
};
718
template<typename Scalar>
718
template<typename Scalar>
719
struct functor_traits<scalar_sin_op<Scalar> >
719
struct functor_traits<scalar_sin_op<Scalar> >
720
{
720
{
721
  enum {
721
  enum {
722
    Cost = 5 * NumTraits<Scalar>::MulCost,
722
    Cost = 5 * NumTraits<Scalar>::MulCost,
Lines 726-742 struct functor_traits<scalar_sin_op<Scal Link Here
726
726
727
727
728
/** \internal
728
/** \internal
729
  * \brief Template functor to compute the tan of a scalar
729
  * \brief Template functor to compute the tan of a scalar
730
  * \sa class CwiseUnaryOp, ArrayBase::tan()
730
  * \sa class CwiseUnaryOp, ArrayBase::tan()
731
  */
731
  */
732
template<typename Scalar> struct scalar_tan_op {
732
template<typename Scalar> struct scalar_tan_op {
733
  EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
733
  EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
734
  inline const Scalar operator() (const Scalar& a) const { return internal::tan(a); }
734
  inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); }
735
  typedef typename packet_traits<Scalar>::type Packet;
735
  typedef typename packet_traits<Scalar>::type Packet;
736
  inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
736
  inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
737
};
737
};
738
template<typename Scalar>
738
template<typename Scalar>
739
struct functor_traits<scalar_tan_op<Scalar> >
739
struct functor_traits<scalar_tan_op<Scalar> >
740
{
740
{
741
  enum {
741
  enum {
742
    Cost = 5 * NumTraits<Scalar>::MulCost,
742
    Cost = 5 * NumTraits<Scalar>::MulCost,
Lines 745-761 struct functor_traits<scalar_tan_op<Scal Link Here
745
};
745
};
746
746
747
/** \internal
747
/** \internal
748
  * \brief Template functor to compute the arc cosine of a scalar
748
  * \brief Template functor to compute the arc cosine of a scalar
749
  * \sa class CwiseUnaryOp, ArrayBase::acos()
749
  * \sa class CwiseUnaryOp, ArrayBase::acos()
750
  */
750
  */
751
template<typename Scalar> struct scalar_acos_op {
751
template<typename Scalar> struct scalar_acos_op {
752
  EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
752
  EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
753
  inline const Scalar operator() (const Scalar& a) const { return internal::acos(a); }
753
  inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); }
754
  typedef typename packet_traits<Scalar>::type Packet;
754
  typedef typename packet_traits<Scalar>::type Packet;
755
  inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
755
  inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
756
};
756
};
757
template<typename Scalar>
757
template<typename Scalar>
758
struct functor_traits<scalar_acos_op<Scalar> >
758
struct functor_traits<scalar_acos_op<Scalar> >
759
{
759
{
760
  enum {
760
  enum {
761
    Cost = 5 * NumTraits<Scalar>::MulCost,
761
    Cost = 5 * NumTraits<Scalar>::MulCost,
Lines 764-780 struct functor_traits<scalar_acos_op<Sca Link Here
764
};
764
};
765
765
766
/** \internal
766
/** \internal
767
  * \brief Template functor to compute the arc sine of a scalar
767
  * \brief Template functor to compute the arc sine of a scalar
768
  * \sa class CwiseUnaryOp, ArrayBase::asin()
768
  * \sa class CwiseUnaryOp, ArrayBase::asin()
769
  */
769
  */
770
template<typename Scalar> struct scalar_asin_op {
770
template<typename Scalar> struct scalar_asin_op {
771
  EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
771
  EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
772
  inline const Scalar operator() (const Scalar& a) const { return internal::asin(a); }
772
  inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); }
773
  typedef typename packet_traits<Scalar>::type Packet;
773
  typedef typename packet_traits<Scalar>::type Packet;
774
  inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
774
  inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
775
};
775
};
776
template<typename Scalar>
776
template<typename Scalar>
777
struct functor_traits<scalar_asin_op<Scalar> >
777
struct functor_traits<scalar_asin_op<Scalar> >
778
{
778
{
779
  enum {
779
  enum {
780
    Cost = 5 * NumTraits<Scalar>::MulCost,
780
    Cost = 5 * NumTraits<Scalar>::MulCost,
(-)a/Eigen/src/Core/GlobalFunctions.h (-28 / +16 lines)
Lines 1-22 Link Here
1
// This file is part of Eigen, a lightweight C++ template library
1
// This file is part of Eigen, a lightweight C++ template library
2
// for linear algebra.
2
// for linear algebra.
3
//
3
//
4
// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
4
// Copyright (C) 2010-2012 Gael Guennebaud <gael.guennebaud@inria.fr>
5
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5
// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6
//
6
//
7
// This Source Code Form is subject to the terms of the Mozilla
7
// This Source Code Form is subject to the terms of the Mozilla
8
// Public License v. 2.0. If a copy of the MPL was not distributed
8
// Public License v. 2.0. If a copy of the MPL was not distributed
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
10
11
#ifndef EIGEN_GLOBAL_FUNCTIONS_H
11
#ifndef EIGEN_GLOBAL_FUNCTIONS_H
12
#define EIGEN_GLOBAL_FUNCTIONS_H
12
#define EIGEN_GLOBAL_FUNCTIONS_H
13
13
14
#define EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(NAME,FUNCTOR) \
14
#define EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(NAME,FUNCTOR) \
15
  template<typename Derived> \
15
  template<typename Derived> \
16
  inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \
16
  inline const Eigen::CwiseUnaryOp<Eigen::internal::FUNCTOR<typename Derived::Scalar>, const Derived> \
17
  NAME(const Eigen::ArrayBase<Derived>& x) { \
17
  NAME(const Eigen::ArrayBase<Derived>& x) { \
18
    return x.derived(); \
18
    return x.derived(); \
19
  }
19
  }
20
20
21
#define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \
21
#define EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(NAME,FUNCTOR) \
22
  \
22
  \
Lines 30-78 Link Here
30
  { \
30
  { \
31
    static inline typename NAME##_retval<ArrayBase<Derived> >::type run(const Eigen::ArrayBase<Derived>& x) \
31
    static inline typename NAME##_retval<ArrayBase<Derived> >::type run(const Eigen::ArrayBase<Derived>& x) \
32
    { \
32
    { \
33
      return x.derived(); \
33
      return x.derived(); \
34
    } \
34
    } \
35
  };
35
  };
36
36
37
37
38
namespace std
38
namespace Eigen
39
{
39
{
40
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(real,scalar_real_op)
40
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op)
41
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op)
41
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op)
42
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op)
42
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op)
43
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op)
43
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op)
44
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(asin,scalar_asin_op)
44
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op)
45
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(acos,scalar_acos_op)
45
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op)
46
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op)
46
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op)
47
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op)
47
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op)
48
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op)
48
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op)
49
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(abs,scalar_abs_op)
49
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op)
50
  EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sqrt,scalar_sqrt_op)
50
  EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op)
51
51
  
52
  template<typename Derived>
52
  template<typename Derived>
53
  inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived>
53
  inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived>
54
  pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) {
54
  pow(const Eigen::ArrayBase<Derived>& x, const typename Derived::Scalar& exponent) {
55
    return x.derived().pow(exponent);
55
    return x.derived().pow(exponent);
56
  }
56
  }
57
57
58
  template<typename Derived>
58
  template<typename Derived>
59
  inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>
59
  inline const Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>
60
  pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<Derived>& exponents) 
60
  pow(const Eigen::ArrayBase<Derived>& x, const Eigen::ArrayBase<Derived>& exponents) 
61
  {
61
  {
62
    return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>(
62
    return Eigen::CwiseBinaryOp<Eigen::internal::scalar_binary_pow_op<typename Derived::Scalar, typename Derived::Scalar>, const Derived, const Derived>(
63
      x.derived(),
63
      x.derived(),
64
      exponents.derived()
64
      exponents.derived()
65
    );
65
    );
66
  }
66
  }
67
}
67
  
68
69
namespace Eigen
70
{
71
  /**
68
  /**
72
  * \brief Component-wise division of a scalar by array elements.
69
  * \brief Component-wise division of a scalar by array elements.
73
  **/
70
  **/
74
  template <typename Derived>
71
  template <typename Derived>
75
  inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>
72
  inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>
76
    operator/(typename Derived::Scalar s, const Eigen::ArrayBase<Derived>& a)
73
    operator/(typename Derived::Scalar s, const Eigen::ArrayBase<Derived>& a)
77
  {
74
  {
78
    return Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>(
75
    return Eigen::CwiseUnaryOp<Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>, const Derived>(
Lines 80-103 namespace Eigen Link Here
80
      Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>(s)  
77
      Eigen::internal::scalar_inverse_mult_op<typename Derived::Scalar>(s)  
81
    );
78
    );
82
  }
79
  }
83
80
84
  namespace internal
81
  namespace internal
85
  {
82
  {
86
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op)
83
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(real,scalar_real_op)
87
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op)
84
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op)
88
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op)
89
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op)
90
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(asin,scalar_asin_op)
91
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(acos,scalar_acos_op)
92
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op)
93
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op)
94
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op)
95
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs,scalar_abs_op)
96
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op)
85
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(abs2,scalar_abs2_op)
97
    EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sqrt,scalar_sqrt_op)
98
  }
86
  }
99
}
87
}
100
88
101
// TODO: cleanly disable those functions that are not supported on Array (internal::real_ref, internal::random, internal::isApprox...)
89
// TODO: cleanly disable those functions that are not supported on Array (internal::real_ref, internal::random, internal::isApprox...)
102
90
103
#endif // EIGEN_GLOBAL_FUNCTIONS_H
91
#endif // EIGEN_GLOBAL_FUNCTIONS_H
(-)a/Eigen/src/Core/MathFunctions.h (-142 lines)
Lines 246-288 struct conj_retval Link Here
246
246
247
template<typename Scalar>
247
template<typename Scalar>
248
inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
248
inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
249
{
249
{
250
  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
250
  return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
251
}
251
}
252
252
253
/****************************************************************************
253
/****************************************************************************
254
* Implementation of abs                                                  *
255
****************************************************************************/
256
257
template<typename Scalar>
258
struct abs_impl
259
{
260
  typedef typename NumTraits<Scalar>::Real RealScalar;
261
  static inline RealScalar run(const Scalar& x)
262
  {
263
    using std::abs;
264
    return abs(x);
265
  }
266
};
267
268
template<typename Scalar>
269
struct abs_retval
270
{
271
  typedef typename NumTraits<Scalar>::Real type;
272
};
273
274
template<typename Scalar>
275
inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x)
276
{
277
  return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x);
278
}
279
280
/****************************************************************************
281
* Implementation of abs2                                                 *
254
* Implementation of abs2                                                 *
282
****************************************************************************/
255
****************************************************************************/
283
256
284
template<typename Scalar>
257
template<typename Scalar>
285
struct abs2_impl
258
struct abs2_impl
286
{
259
{
287
  typedef typename NumTraits<Scalar>::Real RealScalar;
260
  typedef typename NumTraits<Scalar>::Real RealScalar;
288
  static inline RealScalar run(const Scalar& x)
261
  static inline RealScalar run(const Scalar& x)
Lines 400-530 struct cast_impl Link Here
400
373
401
template<typename OldType, typename NewType>
374
template<typename OldType, typename NewType>
402
inline NewType cast(const OldType& x)
375
inline NewType cast(const OldType& x)
403
{
376
{
404
  return cast_impl<OldType, NewType>::run(x);
377
  return cast_impl<OldType, NewType>::run(x);
405
}
378
}
406
379
407
/****************************************************************************
380
/****************************************************************************
408
* Implementation of sqrt                                                 *
409
****************************************************************************/
410
411
template<typename Scalar, bool IsInteger>
412
struct sqrt_default_impl
413
{
414
  static inline Scalar run(const Scalar& x)
415
  {
416
    using std::sqrt;
417
    return sqrt(x);
418
  }
419
};
420
421
template<typename Scalar>
422
struct sqrt_default_impl<Scalar, true>
423
{
424
  static inline Scalar run(const Scalar&)
425
  {
426
#ifdef EIGEN2_SUPPORT
427
    eigen_assert(!NumTraits<Scalar>::IsInteger);
428
#else
429
    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
430
#endif
431
    return Scalar(0);
432
  }
433
};
434
435
template<typename Scalar>
436
struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
437
438
template<typename Scalar>
439
struct sqrt_retval
440
{
441
  typedef Scalar type;
442
};
443
444
template<typename Scalar>
445
inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
446
{
447
  return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
448
}
449
450
/****************************************************************************
451
* Implementation of standard unary real functions (exp, log, sin, cos, ...  *
452
****************************************************************************/
453
454
// This macro instanciate all the necessary template mechanism which is common to all unary real functions.
455
#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
456
  template<typename Scalar, bool IsInteger> struct NAME##_default_impl {            \
457
    static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); }  \
458
  };                                                                                \
459
  template<typename Scalar> struct NAME##_default_impl<Scalar, true> {              \
460
    static inline Scalar run(const Scalar&) {                                       \
461
      EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)                                       \
462
      return Scalar(0);                                                             \
463
    }                                                                               \
464
  };                                                                                \
465
  template<typename Scalar> struct NAME##_impl                                      \
466
    : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger>                     \
467
  {};                                                                               \
468
  template<typename Scalar> struct NAME##_retval { typedef Scalar type; };          \
469
  template<typename Scalar>                                                         \
470
  inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) {                \
471
    return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x);                               \
472
  }
473
474
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
475
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
476
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
477
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
478
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
479
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
480
EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
481
482
/****************************************************************************
483
* Implementation of atan2                                                *
484
****************************************************************************/
485
486
template<typename Scalar, bool IsInteger>
487
struct atan2_default_impl
488
{
489
  typedef Scalar retval;
490
  static inline Scalar run(const Scalar& x, const Scalar& y)
491
  {
492
    using std::atan2;
493
    return atan2(x, y);
494
  }
495
};
496
497
template<typename Scalar>
498
struct atan2_default_impl<Scalar, true>
499
{
500
  static inline Scalar run(const Scalar&, const Scalar&)
501
  {
502
    EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
503
    return Scalar(0);
504
  }
505
};
506
507
template<typename Scalar>
508
struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
509
510
template<typename Scalar>
511
struct atan2_retval
512
{
513
  typedef Scalar type;
514
};
515
516
template<typename Scalar>
517
inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
518
{
519
  return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
520
}
521
522
/****************************************************************************
523
* Implementation of atanh2                                                *
381
* Implementation of atanh2                                                *
524
****************************************************************************/
382
****************************************************************************/
525
383
526
template<typename Scalar, bool IsInteger>
384
template<typename Scalar, bool IsInteger>
527
struct atanh2_default_impl
385
struct atanh2_default_impl
528
{
386
{
529
  typedef Scalar retval;
387
  typedef Scalar retval;
530
  typedef typename NumTraits<Scalar>::Real RealScalar;
388
  typedef typename NumTraits<Scalar>::Real RealScalar;
(-)a/Eigen/src/Core/StableNorm.h (-10 / +13 lines)
Lines 39-68 inline void stable_norm_kernel(const Exp Link Here
39
  *
39
  *
40
  * \sa norm(), blueNorm(), hypotNorm()
40
  * \sa norm(), blueNorm(), hypotNorm()
41
  */
41
  */
42
template<typename Derived>
42
template<typename Derived>
43
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
43
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
44
MatrixBase<Derived>::stableNorm() const
44
MatrixBase<Derived>::stableNorm() const
45
{
45
{
46
  using std::min;
46
  using std::min;
47
  using std::sqrt;
47
  const Index blockSize = 4096;
48
  const Index blockSize = 4096;
48
  RealScalar scale(0);
49
  RealScalar scale(0);
49
  RealScalar invScale(1);
50
  RealScalar invScale(1);
50
  RealScalar ssq(0); // sum of square
51
  RealScalar ssq(0); // sum of square
51
  enum {
52
  enum {
52
    Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0
53
    Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0
53
  };
54
  };
54
  Index n = size();
55
  Index n = size();
55
  Index bi = internal::first_aligned(derived());
56
  Index bi = internal::first_aligned(derived());
56
  if (bi>0)
57
  if (bi>0)
57
    internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
58
    internal::stable_norm_kernel(this->head(bi), ssq, scale, invScale);
58
  for (; bi<n; bi+=blockSize)
59
  for (; bi<n; bi+=blockSize)
59
    internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
60
    internal::stable_norm_kernel(this->segment(bi,(min)(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale);
60
  return scale * internal::sqrt(ssq);
61
  return scale * sqrt(ssq);
61
}
62
}
62
63
63
/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
64
/** \returns the \em l2 norm of \c *this using the Blue's algorithm.
64
  * A Portable Fortran Program to Find the Euclidean Norm of a Vector,
65
  * A Portable Fortran Program to Find the Euclidean Norm of a Vector,
65
  * ACM TOMS, Vol 4, Issue 1, 1978.
66
  * ACM TOMS, Vol 4, Issue 1, 1978.
66
  *
67
  *
67
  * For architecture/scalar types without vectorization, this version
68
  * For architecture/scalar types without vectorization, this version
68
  * is much faster than stableNorm(). Otherwise the stableNorm() is faster.
69
  * is much faster than stableNorm(). Otherwise the stableNorm() is faster.
Lines 71-86 MatrixBase<Derived>::stableNorm() const Link Here
71
  */
72
  */
72
template<typename Derived>
73
template<typename Derived>
73
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
74
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
74
MatrixBase<Derived>::blueNorm() const
75
MatrixBase<Derived>::blueNorm() const
75
{
76
{
76
  using std::pow;
77
  using std::pow;
77
  using std::min;
78
  using std::min;
78
  using std::max;
79
  using std::max;
80
  using std::sqrt;
81
  using std::abs;
79
  static Index nmax = -1;
82
  static Index nmax = -1;
80
  static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
83
  static RealScalar b1, b2, s1m, s2m, overfl, rbig, relerr;
81
  if(nmax <= 0)
84
  if(nmax <= 0)
82
  {
85
  {
83
    int nbig, ibeta, it, iemin, iemax, iexp;
86
    int nbig, ibeta, it, iemin, iemax, iexp;
84
    RealScalar abig, eps;
87
    RealScalar abig, eps;
85
    // This program calculates the machine-dependent constants
88
    // This program calculates the machine-dependent constants
86
    // bl, b2, slm, s2m, relerr overfl, nmax
89
    // bl, b2, slm, s2m, relerr overfl, nmax
Lines 104-169 MatrixBase<Derived>::blueNorm() const Link Here
104
107
105
    iexp  = (2-iemin)/2;
108
    iexp  = (2-iemin)/2;
106
    s1m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // scaling factor for lower range
109
    s1m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // scaling factor for lower range
107
    iexp  = - ((iemax+it)/2);
110
    iexp  = - ((iemax+it)/2);
108
    s2m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // scaling factor for upper range
111
    s2m   = RealScalar(pow(RealScalar(ibeta),RealScalar(iexp)));   // scaling factor for upper range
109
112
110
    overfl  = rbig*s2m;             // overflow boundary for abig
113
    overfl  = rbig*s2m;             // overflow boundary for abig
111
    eps     = RealScalar(pow(double(ibeta), 1-it));
114
    eps     = RealScalar(pow(double(ibeta), 1-it));
112
    relerr  = internal::sqrt(eps);         // tolerance for neglecting asml
115
    relerr  = sqrt(eps);         // tolerance for neglecting asml
113
    abig    = RealScalar(1.0/eps - 1.0);
116
    abig    = RealScalar(1.0/eps - 1.0);
114
    if (RealScalar(nbig)>abig)  nmax = int(abig);  // largest safe n
117
    if (RealScalar(nbig)>abig)  nmax = int(abig);  // largest safe n
115
    else                        nmax = nbig;
118
    else                        nmax = nbig;
116
  }
119
  }
117
  Index n = size();
120
  Index n = size();
118
  RealScalar ab2 = b2 / RealScalar(n);
121
  RealScalar ab2 = b2 / RealScalar(n);
119
  RealScalar asml = RealScalar(0);
122
  RealScalar asml = RealScalar(0);
120
  RealScalar amed = RealScalar(0);
123
  RealScalar amed = RealScalar(0);
121
  RealScalar abig = RealScalar(0);
124
  RealScalar abig = RealScalar(0);
122
  for(Index j=0; j<n; ++j)
125
  for(Index j=0; j<n; ++j)
123
  {
126
  {
124
    RealScalar ax = internal::abs(coeff(j));
127
    RealScalar ax = abs(coeff(j));
125
    if(ax > ab2)     abig += internal::abs2(ax*s2m);
128
    if(ax > ab2)     abig += internal::abs2(ax*s2m);
126
    else if(ax < b1) asml += internal::abs2(ax*s1m);
129
    else if(ax < b1) asml += internal::abs2(ax*s1m);
127
    else             amed += internal::abs2(ax);
130
    else             amed += internal::abs2(ax);
128
  }
131
  }
129
  if(abig > RealScalar(0))
132
  if(abig > RealScalar(0))
130
  {
133
  {
131
    abig = internal::sqrt(abig);
134
    abig = sqrt(abig);
132
    if(abig > overfl)
135
    if(abig > overfl)
133
    {
136
    {
134
      return rbig;
137
      return rbig;
135
    }
138
    }
136
    if(amed > RealScalar(0))
139
    if(amed > RealScalar(0))
137
    {
140
    {
138
      abig = abig/s2m;
141
      abig = abig/s2m;
139
      amed = internal::sqrt(amed);
142
      amed = sqrt(amed);
140
    }
143
    }
141
    else
144
    else
142
      return abig/s2m;
145
      return abig/s2m;
143
  }
146
  }
144
  else if(asml > RealScalar(0))
147
  else if(asml > RealScalar(0))
145
  {
148
  {
146
    if (amed > RealScalar(0))
149
    if (amed > RealScalar(0))
147
    {
150
    {
148
      abig = internal::sqrt(amed);
151
      abig = sqrt(amed);
149
      amed = internal::sqrt(asml) / s1m;
152
      amed = sqrt(asml) / s1m;
150
    }
153
    }
151
    else
154
    else
152
      return internal::sqrt(asml)/s1m;
155
      return sqrt(asml)/s1m;
153
  }
156
  }
154
  else
157
  else
155
    return internal::sqrt(amed);
158
    return sqrt(amed);
156
  asml = (min)(abig, amed);
159
  asml = (min)(abig, amed);
157
  abig = (max)(abig, amed);
160
  abig = (max)(abig, amed);
158
  if(asml <= abig*relerr)
161
  if(asml <= abig*relerr)
159
    return abig;
162
    return abig;
160
  else
163
  else
161
    return abig * internal::sqrt(RealScalar(1) + internal::abs2(asml/abig));
164
    return abig * sqrt(RealScalar(1) + internal::abs2(asml/abig));
162
}
165
}
163
166
164
/** \returns the \em l2 norm of \c *this avoiding undeflow and overflow.
167
/** \returns the \em l2 norm of \c *this avoiding undeflow and overflow.
165
  * This version use a concatenation of hypot() calls, and it is very slow.
168
  * This version use a concatenation of hypot() calls, and it is very slow.
166
  *
169
  *
167
  * \sa norm(), stableNorm()
170
  * \sa norm(), stableNorm()
168
  */
171
  */
169
template<typename Derived>
172
template<typename Derived>
(-)a/Eigen/src/Core/TriangularMatrix.h (-4 / +6 lines)
Lines 776-828 MatrixBase<Derived>::triangularView() co Link Here
776
/** \returns true if *this is approximately equal to an upper triangular matrix,
776
/** \returns true if *this is approximately equal to an upper triangular matrix,
777
  *          within the precision given by \a prec.
777
  *          within the precision given by \a prec.
778
  *
778
  *
779
  * \sa isLowerTriangular()
779
  * \sa isLowerTriangular()
780
  */
780
  */
781
template<typename Derived>
781
template<typename Derived>
782
bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
782
bool MatrixBase<Derived>::isUpperTriangular(const RealScalar& prec) const
783
{
783
{
784
  using std::abs;
784
  RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
785
  RealScalar maxAbsOnUpperPart = static_cast<RealScalar>(-1);
785
  for(Index j = 0; j < cols(); ++j)
786
  for(Index j = 0; j < cols(); ++j)
786
  {
787
  {
787
    Index maxi = (std::min)(j, rows()-1);
788
    Index maxi = (std::min)(j, rows()-1);
788
    for(Index i = 0; i <= maxi; ++i)
789
    for(Index i = 0; i <= maxi; ++i)
789
    {
790
    {
790
      RealScalar absValue = internal::abs(coeff(i,j));
791
      RealScalar absValue = abs(coeff(i,j));
791
      if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
792
      if(absValue > maxAbsOnUpperPart) maxAbsOnUpperPart = absValue;
792
    }
793
    }
793
  }
794
  }
794
  RealScalar threshold = maxAbsOnUpperPart * prec;
795
  RealScalar threshold = maxAbsOnUpperPart * prec;
795
  for(Index j = 0; j < cols(); ++j)
796
  for(Index j = 0; j < cols(); ++j)
796
    for(Index i = j+1; i < rows(); ++i)
797
    for(Index i = j+1; i < rows(); ++i)
797
      if(internal::abs(coeff(i, j)) > threshold) return false;
798
      if(abs(coeff(i, j)) > threshold) return false;
798
  return true;
799
  return true;
799
}
800
}
800
801
801
/** \returns true if *this is approximately equal to a lower triangular matrix,
802
/** \returns true if *this is approximately equal to a lower triangular matrix,
802
  *          within the precision given by \a prec.
803
  *          within the precision given by \a prec.
803
  *
804
  *
804
  * \sa isUpperTriangular()
805
  * \sa isUpperTriangular()
805
  */
806
  */
806
template<typename Derived>
807
template<typename Derived>
807
bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
808
bool MatrixBase<Derived>::isLowerTriangular(const RealScalar& prec) const
808
{
809
{
810
  using std::abs;
809
  RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
811
  RealScalar maxAbsOnLowerPart = static_cast<RealScalar>(-1);
810
  for(Index j = 0; j < cols(); ++j)
812
  for(Index j = 0; j < cols(); ++j)
811
    for(Index i = j; i < rows(); ++i)
813
    for(Index i = j; i < rows(); ++i)
812
    {
814
    {
813
      RealScalar absValue = internal::abs(coeff(i,j));
815
      RealScalar absValue = abs(coeff(i,j));
814
      if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
816
      if(absValue > maxAbsOnLowerPart) maxAbsOnLowerPart = absValue;
815
    }
817
    }
816
  RealScalar threshold = maxAbsOnLowerPart * prec;
818
  RealScalar threshold = maxAbsOnLowerPart * prec;
817
  for(Index j = 1; j < cols(); ++j)
819
  for(Index j = 1; j < cols(); ++j)
818
  {
820
  {
819
    Index maxi = (std::min)(j, rows()-1);
821
    Index maxi = (std::min)(j, rows()-1);
820
    for(Index i = 0; i < maxi; ++i)
822
    for(Index i = 0; i < maxi; ++i)
821
      if(internal::abs(coeff(i, j)) > threshold) return false;
823
      if(abs(coeff(i, j)) > threshold) return false;
822
  }
824
  }
823
  return true;
825
  return true;
824
}
826
}
825
827
826
} // end namespace Eigen
828
} // end namespace Eigen
827
829
828
#endif // EIGEN_TRIANGULARMATRIX_H
830
#endif // EIGEN_TRIANGULARMATRIX_H
(-)a/Eigen/src/Eigen2Support/MathFunctions.h (-7 / +7 lines)
Lines 10-33 Link Here
10
#ifndef EIGEN2_MATH_FUNCTIONS_H
10
#ifndef EIGEN2_MATH_FUNCTIONS_H
11
#define EIGEN2_MATH_FUNCTIONS_H
11
#define EIGEN2_MATH_FUNCTIONS_H
12
12
13
namespace Eigen { 
13
namespace Eigen { 
14
14
15
template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return internal::real(x); }
15
template<typename T> inline typename NumTraits<T>::Real ei_real(const T& x) { return internal::real(x); }
16
template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return internal::imag(x); }
16
template<typename T> inline typename NumTraits<T>::Real ei_imag(const T& x) { return internal::imag(x); }
17
template<typename T> inline T ei_conj(const T& x) { return internal::conj(x); }
17
template<typename T> inline T ei_conj(const T& x) { return internal::conj(x); }
18
template<typename T> inline typename NumTraits<T>::Real ei_abs (const T& x) { return internal::abs(x); }
18
template<typename T> inline typename NumTraits<T>::Real ei_abs (const T& x) { using std::abs; return abs(x); }
19
template<typename T> inline typename NumTraits<T>::Real ei_abs2(const T& x) { return internal::abs2(x); }
19
template<typename T> inline typename NumTraits<T>::Real ei_abs2(const T& x) { return internal::abs2(x); }
20
template<typename T> inline T ei_sqrt(const T& x) { return internal::sqrt(x); }
20
template<typename T> inline T ei_sqrt(const T& x) { using std::sqrt; return sqrt(x); }
21
template<typename T> inline T ei_exp (const T& x) { return internal::exp(x); }
21
template<typename T> inline T ei_exp (const T& x) { using std::exp;  return exp(x); }
22
template<typename T> inline T ei_log (const T& x) { return internal::log(x); }
22
template<typename T> inline T ei_log (const T& x) { using std::log;  return log(x); }
23
template<typename T> inline T ei_sin (const T& x) { return internal::sin(x); }
23
template<typename T> inline T ei_sin (const T& x) { using std::sin;  return sin(x); }
24
template<typename T> inline T ei_cos (const T& x) { return internal::cos(x); }
24
template<typename T> inline T ei_cos (const T& x) { using std::cos;  return cos(x); }
25
template<typename T> inline T ei_atan2(const T& x,const T& y) { return internal::atan2(x,y); }
25
template<typename T> inline T ei_atan2(const T& x,const T& y) { using std::atan2; return atan2(x,y); }
26
template<typename T> inline T ei_pow (const T& x,const T& y) { return internal::pow(x,y); }
26
template<typename T> inline T ei_pow (const T& x,const T& y) { return internal::pow(x,y); }
27
template<typename T> inline T ei_random () { return internal::random<T>(); }
27
template<typename T> inline T ei_random () { return internal::random<T>(); }
28
template<typename T> inline T ei_random (const T& x, const T& y) { return internal::random(x, y); }
28
template<typename T> inline T ei_random (const T& x, const T& y) { return internal::random(x, y); }
29
29
30
template<typename T> inline T precision () { return NumTraits<T>::dummy_precision(); }
30
template<typename T> inline T precision () { return NumTraits<T>::dummy_precision(); }
31
template<typename T> inline T machine_epsilon () { return NumTraits<T>::epsilon(); }
31
template<typename T> inline T machine_epsilon () { return NumTraits<T>::epsilon(); }
32
32
33
33
(-)a/Eigen/src/Eigenvalues/ComplexSchur.h (-1 / +2 lines)
Lines 253-272 inline bool ComplexSchur<MatrixType>::su Link Here
253
  return false;
253
  return false;
254
}
254
}
255
255
256
256
257
/** Compute the shift in the current QR iteration. */
257
/** Compute the shift in the current QR iteration. */
258
template<typename MatrixType>
258
template<typename MatrixType>
259
typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(Index iu, Index iter)
259
typename ComplexSchur<MatrixType>::ComplexScalar ComplexSchur<MatrixType>::computeShift(Index iu, Index iter)
260
{
260
{
261
  using std::abs;
261
  if (iter == 10 || iter == 20) 
262
  if (iter == 10 || iter == 20) 
262
  {
263
  {
263
    // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
264
    // exceptional shift, taken from http://www.netlib.org/eispack/comqr.f
264
    return internal::abs(internal::real(m_matT.coeff(iu,iu-1))) + internal::abs(internal::real(m_matT.coeff(iu-1,iu-2)));
265
    return abs(internal::real(m_matT.coeff(iu,iu-1))) + abs(internal::real(m_matT.coeff(iu-1,iu-2)));
265
  }
266
  }
266
267
267
  // compute the shift as one of the eigenvalues of t, the 2x2
268
  // compute the shift as one of the eigenvalues of t, the 2x2
268
  // diagonal block on the bottom of the active submatrix
269
  // diagonal block on the bottom of the active submatrix
269
  Matrix<ComplexScalar,2,2> t = m_matT.template block<2,2>(iu-1,iu-1);
270
  Matrix<ComplexScalar,2,2> t = m_matT.template block<2,2>(iu-1,iu-1);
270
  RealScalar normt = t.cwiseAbs().sum();
271
  RealScalar normt = t.cwiseAbs().sum();
271
  t /= normt;     // the normalization by sf is to avoid under/overflow
272
  t /= normt;     // the normalization by sf is to avoid under/overflow
272
273
(-)a/Eigen/src/Eigenvalues/EigenSolver.h (-8 / +12 lines)
Lines 359-374 typename EigenSolver<MatrixType>::Eigenv Link Here
359
  }
359
  }
360
  return matV;
360
  return matV;
361
}
361
}
362
362
363
template<typename MatrixType>
363
template<typename MatrixType>
364
EigenSolver<MatrixType>& 
364
EigenSolver<MatrixType>& 
365
EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
365
EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors)
366
{
366
{
367
  using std::sqrt;
368
  using std::abs;
367
  assert(matrix.cols() == matrix.rows());
369
  assert(matrix.cols() == matrix.rows());
368
370
369
  // Reduce to real Schur form.
371
  // Reduce to real Schur form.
370
  m_realSchur.compute(matrix, computeEigenvectors);
372
  m_realSchur.compute(matrix, computeEigenvectors);
371
373
372
  if (m_realSchur.info() == Success)
374
  if (m_realSchur.info() == Success)
373
  {
375
  {
374
    m_matT = m_realSchur.matrixT();
376
    m_matT = m_realSchur.matrixT();
Lines 383-399 EigenSolver<MatrixType>::compute(const M Link Here
383
      if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0)) 
385
      if (i == matrix.cols() - 1 || m_matT.coeff(i+1, i) == Scalar(0)) 
384
      {
386
      {
385
        m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
387
        m_eivalues.coeffRef(i) = m_matT.coeff(i, i);
386
        ++i;
388
        ++i;
387
      }
389
      }
388
      else
390
      else
389
      {
391
      {
390
        Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i+1, i+1));
392
        Scalar p = Scalar(0.5) * (m_matT.coeff(i, i) - m_matT.coeff(i+1, i+1));
391
        Scalar z = internal::sqrt(internal::abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
393
        Scalar z = sqrt(abs(p * p + m_matT.coeff(i+1, i) * m_matT.coeff(i, i+1)));
392
        m_eivalues.coeffRef(i)   = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
394
        m_eivalues.coeffRef(i)   = ComplexScalar(m_matT.coeff(i+1, i+1) + p, z);
393
        m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
395
        m_eivalues.coeffRef(i+1) = ComplexScalar(m_matT.coeff(i+1, i+1) + p, -z);
394
        i += 2;
396
        i += 2;
395
      }
397
      }
396
    }
398
    }
397
    
399
    
398
    // Compute eigenvectors.
400
    // Compute eigenvectors.
399
    if (computeEigenvectors)
401
    if (computeEigenvectors)
Lines 405-422 EigenSolver<MatrixType>::compute(const M Link Here
405
407
406
  return *this;
408
  return *this;
407
}
409
}
408
410
409
// Complex scalar division.
411
// Complex scalar division.
410
template<typename Scalar>
412
template<typename Scalar>
411
std::complex<Scalar> cdiv(Scalar xr, Scalar xi, Scalar yr, Scalar yi)
413
std::complex<Scalar> cdiv(Scalar xr, Scalar xi, Scalar yr, Scalar yi)
412
{
414
{
415
  using std::abs;
413
  Scalar r,d;
416
  Scalar r,d;
414
  if (internal::abs(yr) > internal::abs(yi))
417
  if (abs(yr) > abs(yi))
415
  {
418
  {
416
      r = yi/yr;
419
      r = yi/yr;
417
      d = yr + r*yi;
420
      d = yr + r*yi;
418
      return std::complex<Scalar>((xr + r*xi)/d, (xi - r*xr)/d);
421
      return std::complex<Scalar>((xr + r*xi)/d, (xi - r*xr)/d);
419
  }
422
  }
420
  else
423
  else
421
  {
424
  {
422
      r = yr/yi;
425
      r = yr/yi;
Lines 424-439 std::complex<Scalar> cdiv(Scalar xr, Sca Link Here
424
      return std::complex<Scalar>((r*xr + xi)/d, (r*xi - xr)/d);
427
      return std::complex<Scalar>((r*xr + xi)/d, (r*xi - xr)/d);
425
  }
428
  }
426
}
429
}
427
430
428
431
429
template<typename MatrixType>
432
template<typename MatrixType>
430
void EigenSolver<MatrixType>::doComputeEigenvectors()
433
void EigenSolver<MatrixType>::doComputeEigenvectors()
431
{
434
{
435
  using std::abs;
432
  const Index size = m_eivec.cols();
436
  const Index size = m_eivec.cols();
433
  const Scalar eps = NumTraits<Scalar>::epsilon();
437
  const Scalar eps = NumTraits<Scalar>::epsilon();
434
438
435
  // inefficient! this is already computed in RealSchur
439
  // inefficient! this is already computed in RealSchur
436
  Scalar norm(0);
440
  Scalar norm(0);
437
  for (Index j = 0; j < size; ++j)
441
  for (Index j = 0; j < size; ++j)
438
  {
442
  {
439
    norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
443
    norm += m_matT.row(j).segment((std::max)(j-1,Index(0)), size-(std::max)(j-1,Index(0))).cwiseAbs().sum();
Lines 479-514 void EigenSolver<MatrixType>::doComputeE Link Here
479
          }
483
          }
480
          else // Solve real equations
484
          else // Solve real equations
481
          {
485
          {
482
            Scalar x = m_matT.coeff(i,i+1);
486
            Scalar x = m_matT.coeff(i,i+1);
483
            Scalar y = m_matT.coeff(i+1,i);
487
            Scalar y = m_matT.coeff(i+1,i);
484
            Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
488
            Scalar denom = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag();
485
            Scalar t = (x * lastr - lastw * r) / denom;
489
            Scalar t = (x * lastr - lastw * r) / denom;
486
            m_matT.coeffRef(i,n) = t;
490
            m_matT.coeffRef(i,n) = t;
487
            if (internal::abs(x) > internal::abs(lastw))
491
            if (abs(x) > abs(lastw))
488
              m_matT.coeffRef(i+1,n) = (-r - w * t) / x;
492
              m_matT.coeffRef(i+1,n) = (-r - w * t) / x;
489
            else
493
            else
490
              m_matT.coeffRef(i+1,n) = (-lastr - y * t) / lastw;
494
              m_matT.coeffRef(i+1,n) = (-lastr - y * t) / lastw;
491
          }
495
          }
492
496
493
          // Overflow control
497
          // Overflow control
494
          Scalar t = internal::abs(m_matT.coeff(i,n));
498
          Scalar t = abs(m_matT.coeff(i,n));
495
          if ((eps * t) * t > Scalar(1))
499
          if ((eps * t) * t > Scalar(1))
496
            m_matT.col(n).tail(size-i) /= t;
500
            m_matT.col(n).tail(size-i) /= t;
497
        }
501
        }
498
      }
502
      }
499
    }
503
    }
500
    else if (q < Scalar(0) && n > 0) // Complex vector
504
    else if (q < Scalar(0) && n > 0) // Complex vector
501
    {
505
    {
502
      Scalar lastra(0), lastsa(0), lastw(0);
506
      Scalar lastra(0), lastsa(0), lastw(0);
503
      Index l = n-1;
507
      Index l = n-1;
504
508
505
      // Last vector component imaginary so matrix is triangular
509
      // Last vector component imaginary so matrix is triangular
506
      if (internal::abs(m_matT.coeff(n,n-1)) > internal::abs(m_matT.coeff(n-1,n)))
510
      if (abs(m_matT.coeff(n,n-1)) > abs(m_matT.coeff(n-1,n)))
507
      {
511
      {
508
        m_matT.coeffRef(n-1,n-1) = q / m_matT.coeff(n,n-1);
512
        m_matT.coeffRef(n-1,n-1) = q / m_matT.coeff(n,n-1);
509
        m_matT.coeffRef(n-1,n) = -(m_matT.coeff(n,n) - p) / m_matT.coeff(n,n-1);
513
        m_matT.coeffRef(n-1,n) = -(m_matT.coeff(n,n) - p) / m_matT.coeff(n,n-1);
510
      }
514
      }
511
      else
515
      else
512
      {
516
      {
513
        std::complex<Scalar> cc = cdiv<Scalar>(0.0,-m_matT.coeff(n-1,n),m_matT.coeff(n-1,n-1)-p,q);
517
        std::complex<Scalar> cc = cdiv<Scalar>(0.0,-m_matT.coeff(n-1,n),m_matT.coeff(n-1,n-1)-p,q);
514
        m_matT.coeffRef(n-1,n-1) = internal::real(cc);
518
        m_matT.coeffRef(n-1,n-1) = internal::real(cc);
Lines 540-576 void EigenSolver<MatrixType>::doComputeE Link Here
540
          else
544
          else
541
          {
545
          {
542
            // Solve complex equations
546
            // Solve complex equations
543
            Scalar x = m_matT.coeff(i,i+1);
547
            Scalar x = m_matT.coeff(i,i+1);
544
            Scalar y = m_matT.coeff(i+1,i);
548
            Scalar y = m_matT.coeff(i+1,i);
545
            Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
549
            Scalar vr = (m_eivalues.coeff(i).real() - p) * (m_eivalues.coeff(i).real() - p) + m_eivalues.coeff(i).imag() * m_eivalues.coeff(i).imag() - q * q;
546
            Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
550
            Scalar vi = (m_eivalues.coeff(i).real() - p) * Scalar(2) * q;
547
            if ((vr == 0.0) && (vi == 0.0))
551
            if ((vr == 0.0) && (vi == 0.0))
548
              vr = eps * norm * (internal::abs(w) + internal::abs(q) + internal::abs(x) + internal::abs(y) + internal::abs(lastw));
552
              vr = eps * norm * (abs(w) + abs(q) + abs(x) + abs(y) + abs(lastw));
549
553
550
            std::complex<Scalar> cc = cdiv(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra,vr,vi);
554
            std::complex<Scalar> cc = cdiv(x*lastra-lastw*ra+q*sa,x*lastsa-lastw*sa-q*ra,vr,vi);
551
            m_matT.coeffRef(i,n-1) = internal::real(cc);
555
            m_matT.coeffRef(i,n-1) = internal::real(cc);
552
            m_matT.coeffRef(i,n) = internal::imag(cc);
556
            m_matT.coeffRef(i,n) = internal::imag(cc);
553
            if (internal::abs(x) > (internal::abs(lastw) + internal::abs(q)))
557
            if (abs(x) > (abs(lastw) + abs(q)))
554
            {
558
            {
555
              m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x;
559
              m_matT.coeffRef(i+1,n-1) = (-ra - w * m_matT.coeff(i,n-1) + q * m_matT.coeff(i,n)) / x;
556
              m_matT.coeffRef(i+1,n) = (-sa - w * m_matT.coeff(i,n) - q * m_matT.coeff(i,n-1)) / x;
560
              m_matT.coeffRef(i+1,n) = (-sa - w * m_matT.coeff(i,n) - q * m_matT.coeff(i,n-1)) / x;
557
            }
561
            }
558
            else
562
            else
559
            {
563
            {
560
              cc = cdiv(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n),lastw,q);
564
              cc = cdiv(-lastra-y*m_matT.coeff(i,n-1),-lastsa-y*m_matT.coeff(i,n),lastw,q);
561
              m_matT.coeffRef(i+1,n-1) = internal::real(cc);
565
              m_matT.coeffRef(i+1,n-1) = internal::real(cc);
562
              m_matT.coeffRef(i+1,n) = internal::imag(cc);
566
              m_matT.coeffRef(i+1,n) = internal::imag(cc);
563
            }
567
            }
564
          }
568
          }
565
569
566
          // Overflow control
570
          // Overflow control
567
          using std::max;
571
          using std::max;
568
          Scalar t = (max)(internal::abs(m_matT.coeff(i,n-1)),internal::abs(m_matT.coeff(i,n)));
572
          Scalar t = (max)(abs(m_matT.coeff(i,n-1)),abs(m_matT.coeff(i,n)));
569
          if ((eps * t) * t > Scalar(1))
573
          if ((eps * t) * t > Scalar(1))
570
            m_matT.block(i, n-1, size-i, 2) /= t;
574
            m_matT.block(i, n-1, size-i, 2) /= t;
571
575
572
        }
576
        }
573
      }
577
      }
574
      
578
      
575
      // We handled a pair of complex conjugate eigenvalues, so need to skip them both
579
      // We handled a pair of complex conjugate eigenvalues, so need to skip them both
576
      n--;
580
      n--;
(-)a/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h (-1 / +3 lines)
Lines 285-300 template<typename _MatrixType> class Gen Link Here
285
//  // TODO
285
//  // TODO
286
//  return matV;
286
//  return matV;
287
//}
287
//}
288
288
289
template<typename MatrixType>
289
template<typename MatrixType>
290
GeneralizedEigenSolver<MatrixType>&
290
GeneralizedEigenSolver<MatrixType>&
291
GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors)
291
GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors)
292
{
292
{
293
  using std::sqrt;
294
  using std::abs;
293
  eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
295
  eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
294
296
295
  // Reduce to generalized real Schur form:
297
  // Reduce to generalized real Schur form:
296
  // A = Q S Z and B = Q T Z
298
  // A = Q S Z and B = Q T Z
297
  m_realQZ.compute(A, B, computeEigenvectors);
299
  m_realQZ.compute(A, B, computeEigenvectors);
298
300
299
  if (m_realQZ.info() == Success)
301
  if (m_realQZ.info() == Success)
300
  {
302
  {
Lines 312-328 GeneralizedEigenSolver<MatrixType>::comp Link Here
312
      {
314
      {
313
        m_alphas.coeffRef(i) = m_matS.coeff(i, i);
315
        m_alphas.coeffRef(i) = m_matS.coeff(i, i);
314
        m_betas.coeffRef(i)  = m_realQZ.matrixT().coeff(i,i);
316
        m_betas.coeffRef(i)  = m_realQZ.matrixT().coeff(i,i);
315
        ++i;
317
        ++i;
316
      }
318
      }
317
      else
319
      else
318
      {
320
      {
319
        Scalar p = Scalar(0.5) * (m_matS.coeff(i, i) - m_matS.coeff(i+1, i+1));
321
        Scalar p = Scalar(0.5) * (m_matS.coeff(i, i) - m_matS.coeff(i+1, i+1));
320
        Scalar z = internal::sqrt(internal::abs(p * p + m_matS.coeff(i+1, i) * m_matS.coeff(i, i+1)));
322
        Scalar z = sqrt(abs(p * p + m_matS.coeff(i+1, i) * m_matS.coeff(i, i+1)));
321
        m_alphas.coeffRef(i)   = ComplexScalar(m_matS.coeff(i+1, i+1) + p, z);
323
        m_alphas.coeffRef(i)   = ComplexScalar(m_matS.coeff(i+1, i+1) + p, z);
322
        m_alphas.coeffRef(i+1) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, -z);
324
        m_alphas.coeffRef(i+1) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, -z);
323
325
324
        m_betas.coeffRef(i)   = m_realQZ.matrixT().coeff(i,i);
326
        m_betas.coeffRef(i)   = m_realQZ.matrixT().coeff(i,i);
325
        m_betas.coeffRef(i+1) = m_realQZ.matrixT().coeff(i,i);
327
        m_betas.coeffRef(i+1) = m_realQZ.matrixT().coeff(i,i);
326
        i += 2;
328
        i += 2;
327
      }
329
      }
328
    }
330
    }
(-)a/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h (-1 / +2 lines)
Lines 116-135 SelfAdjointView<MatrixType, UpLo>::eigen Link Here
116
  * Output: \verbinclude MatrixBase_operatorNorm.out
116
  * Output: \verbinclude MatrixBase_operatorNorm.out
117
  *
117
  *
118
  * \sa SelfAdjointView::eigenvalues(), SelfAdjointView::operatorNorm()
118
  * \sa SelfAdjointView::eigenvalues(), SelfAdjointView::operatorNorm()
119
  */
119
  */
120
template<typename Derived>
120
template<typename Derived>
121
inline typename MatrixBase<Derived>::RealScalar
121
inline typename MatrixBase<Derived>::RealScalar
122
MatrixBase<Derived>::operatorNorm() const
122
MatrixBase<Derived>::operatorNorm() const
123
{
123
{
124
  using std::sqrt;
124
  typename Derived::PlainObject m_eval(derived());
125
  typename Derived::PlainObject m_eval(derived());
125
  // FIXME if it is really guaranteed that the eigenvalues are already sorted,
126
  // FIXME if it is really guaranteed that the eigenvalues are already sorted,
126
  // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
127
  // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough.
127
  return internal::sqrt((m_eval*m_eval.adjoint())
128
  return sqrt((m_eval*m_eval.adjoint())
128
                 .eval()
129
                 .eval()
129
		 .template selfadjointView<Lower>()
130
		 .template selfadjointView<Lower>()
130
		 .eigenvalues()
131
		 .eigenvalues()
131
		 .maxCoeff()
132
		 .maxCoeff()
132
		 );
133
		 );
133
}
134
}
134
135
135
/** \brief Computes the L2 operator norm
136
/** \brief Computes the L2 operator norm
(-)a/Eigen/src/Eigenvalues/RealQZ.h (-7 / +13 lines)
Lines 273-331 namespace Eigen { Link Here
273
      }
273
      }
274
    }
274
    }
275
275
276
276
277
  /** \internal Look for single small sub-diagonal element S(res, res-1) and return res (or 0) */
277
  /** \internal Look for single small sub-diagonal element S(res, res-1) and return res (or 0) */
278
  template<typename MatrixType>
278
  template<typename MatrixType>
279
    inline typename MatrixType::Index RealQZ<MatrixType>::findSmallSubdiagEntry(Index iu)
279
    inline typename MatrixType::Index RealQZ<MatrixType>::findSmallSubdiagEntry(Index iu)
280
    {
280
    {
281
      using std::abs;
281
      Index res = iu;
282
      Index res = iu;
282
      while (res > 0)
283
      while (res > 0)
283
      {
284
      {
284
        Scalar s = internal::abs(m_S.coeff(res-1,res-1)) + internal::abs(m_S.coeff(res,res));
285
        Scalar s = abs(m_S.coeff(res-1,res-1)) + abs(m_S.coeff(res,res));
285
        if (s == Scalar(0.0))
286
        if (s == Scalar(0.0))
286
          s = m_normOfS;
287
          s = m_normOfS;
287
        if (internal::abs(m_S.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
288
        if (abs(m_S.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
288
          break;
289
          break;
289
        res--;
290
        res--;
290
      }
291
      }
291
      return res;
292
      return res;
292
    }
293
    }
293
294
294
  /** \internal Look for single small diagonal element T(res, res) for res between f and l, and return res (or f-1)  */
295
  /** \internal Look for single small diagonal element T(res, res) for res between f and l, and return res (or f-1)  */
295
  template<typename MatrixType>
296
  template<typename MatrixType>
296
    inline typename MatrixType::Index RealQZ<MatrixType>::findSmallDiagEntry(Index f, Index l)
297
    inline typename MatrixType::Index RealQZ<MatrixType>::findSmallDiagEntry(Index f, Index l)
297
    {
298
    {
299
      using std::abs;
298
      Index res = l;
300
      Index res = l;
299
      while (res >= f) {
301
      while (res >= f) {
300
        if (internal::abs(m_T.coeff(res,res)) <= NumTraits<Scalar>::epsilon() * m_normOfT)
302
        if (abs(m_T.coeff(res,res)) <= NumTraits<Scalar>::epsilon() * m_normOfT)
301
          break;
303
          break;
302
        res--;
304
        res--;
303
      }
305
      }
304
      return res;
306
      return res;
305
    }
307
    }
306
308
307
  /** \internal decouple 2x2 diagonal block in rows i, i+1 if eigenvalues are real */
309
  /** \internal decouple 2x2 diagonal block in rows i, i+1 if eigenvalues are real */
308
  template<typename MatrixType>
310
  template<typename MatrixType>
309
    inline void RealQZ<MatrixType>::splitOffTwoRows(Index i)
311
    inline void RealQZ<MatrixType>::splitOffTwoRows(Index i)
310
    {
312
    {
313
      using std::abs;
314
      using std::sqrt;
311
      const Index dim=m_S.cols();
315
      const Index dim=m_S.cols();
312
      if (internal::abs(m_S.coeff(i+1,i)==Scalar(0)))
316
      if (abs(m_S.coeff(i+1,i)==Scalar(0)))
313
        return;
317
        return;
314
      Index z = findSmallDiagEntry(i,i+1);
318
      Index z = findSmallDiagEntry(i,i+1);
315
      if (z==i-1)
319
      if (z==i-1)
316
      {
320
      {
317
        // block of (S T^{-1})
321
        // block of (S T^{-1})
318
        Matrix2s STi = m_T.template block<2,2>(i,i).template triangularView<Upper>().
322
        Matrix2s STi = m_T.template block<2,2>(i,i).template triangularView<Upper>().
319
          template solve<OnTheRight>(m_S.template block<2,2>(i,i));
323
          template solve<OnTheRight>(m_S.template block<2,2>(i,i));
320
        Scalar p = Scalar(0.5)*(STi(0,0)-STi(1,1));
324
        Scalar p = Scalar(0.5)*(STi(0,0)-STi(1,1));
321
        Scalar q = p*p + STi(1,0)*STi(0,1);
325
        Scalar q = p*p + STi(1,0)*STi(0,1);
322
        if (q>=0) {
326
        if (q>=0) {
323
          Scalar z = internal::sqrt(q);
327
          Scalar z = sqrt(q);
324
          // one QR-like iteration for ABi - lambda I
328
          // one QR-like iteration for ABi - lambda I
325
          // is enough - when we know exact eigenvalue in advance,
329
          // is enough - when we know exact eigenvalue in advance,
326
          // convergence is immediate
330
          // convergence is immediate
327
          JRs G;
331
          JRs G;
328
          if (p>=0)
332
          if (p>=0)
329
            G.makeGivens(p + z, STi(1,0));
333
            G.makeGivens(p + z, STi(1,0));
330
          else
334
          else
331
            G.makeGivens(p - z, STi(1,0));
335
            G.makeGivens(p - z, STi(1,0));
Lines 388-404 namespace Eigen { Link Here
388
      m_S.coeffRef(l,l-1)=Scalar(0.0);
392
      m_S.coeffRef(l,l-1)=Scalar(0.0);
389
      // update Z
393
      // update Z
390
      if (m_computeQZ)
394
      if (m_computeQZ)
391
        m_Z.applyOnTheLeft(l,l-1,G.adjoint());
395
        m_Z.applyOnTheLeft(l,l-1,G.adjoint());
392
    }
396
    }
393
397
394
  /** \internal QR-like iterative step for block f..l */
398
  /** \internal QR-like iterative step for block f..l */
395
  template<typename MatrixType>
399
  template<typename MatrixType>
396
    inline void RealQZ<MatrixType>::step(Index f, Index l, Index iter) {
400
    inline void RealQZ<MatrixType>::step(Index f, Index l, Index iter)
401
    {
402
      using std::abs;
397
      const Index dim = m_S.cols();
403
      const Index dim = m_S.cols();
398
404
399
      // x, y, z
405
      // x, y, z
400
      Scalar x, y, z;
406
      Scalar x, y, z;
401
      if (iter==10)
407
      if (iter==10)
402
      {
408
      {
403
        // Wilkinson ad hoc shift
409
        // Wilkinson ad hoc shift
404
        const Scalar
410
        const Scalar
Lines 406-422 namespace Eigen { Link Here
406
          a21=m_S.coeff(f+1,f+0), a22=m_S.coeff(f+1,f+1), a32=m_S.coeff(f+2,f+1),
412
          a21=m_S.coeff(f+1,f+0), a22=m_S.coeff(f+1,f+1), a32=m_S.coeff(f+2,f+1),
407
          b12=m_T.coeff(f+0,f+1),
413
          b12=m_T.coeff(f+0,f+1),
408
          b11i=Scalar(1.0)/m_T.coeff(f+0,f+0),
414
          b11i=Scalar(1.0)/m_T.coeff(f+0,f+0),
409
          b22i=Scalar(1.0)/m_T.coeff(f+1,f+1),
415
          b22i=Scalar(1.0)/m_T.coeff(f+1,f+1),
410
          a87=m_S.coeff(l-1,l-2),
416
          a87=m_S.coeff(l-1,l-2),
411
          a98=m_S.coeff(l-0,l-1),
417
          a98=m_S.coeff(l-0,l-1),
412
          b77i=Scalar(1.0)/m_T.coeff(l-2,l-2),
418
          b77i=Scalar(1.0)/m_T.coeff(l-2,l-2),
413
          b88i=Scalar(1.0)/m_T.coeff(l-1,l-1);
419
          b88i=Scalar(1.0)/m_T.coeff(l-1,l-1);
414
        Scalar ss = internal::abs(a87*b77i) + internal::abs(a98*b88i),
420
        Scalar ss = abs(a87*b77i) + abs(a98*b88i),
415
               lpl = Scalar(1.5)*ss,
421
               lpl = Scalar(1.5)*ss,
416
               ll = ss*ss;
422
               ll = ss*ss;
417
        x = ll + a11*a11*b11i*b11i - lpl*a11*b11i + a12*a21*b11i*b22i
423
        x = ll + a11*a11*b11i*b11i - lpl*a11*b11i + a12*a21*b11i*b22i
418
          - a11*a21*b12*b11i*b11i*b22i;
424
          - a11*a21*b12*b11i*b11i*b22i;
419
        y = a11*a21*b11i*b11i - lpl*a21*b11i + a21*a22*b11i*b22i 
425
        y = a11*a21*b11i*b11i - lpl*a21*b11i + a21*a22*b11i*b22i 
420
          - a21*a21*b12*b11i*b11i*b22i;
426
          - a21*a21*b12*b11i*b11i*b22i;
421
        z = a21*a32*b11i*b22i;
427
        z = a21*a32*b11i*b22i;
422
      }
428
      }
(-)a/Eigen/src/Eigenvalues/RealSchur.h (-8 / +14 lines)
Lines 309-353 inline typename MatrixType::Scalar RealS Link Here
309
    norm += m_matT.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
309
    norm += m_matT.col(j).segment(0, (std::min)(size,j+2)).cwiseAbs().sum();
310
  return norm;
310
  return norm;
311
}
311
}
312
312
313
/** \internal Look for single small sub-diagonal element and returns its index */
313
/** \internal Look for single small sub-diagonal element and returns its index */
314
template<typename MatrixType>
314
template<typename MatrixType>
315
inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, Scalar norm)
315
inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, Scalar norm)
316
{
316
{
317
  using std::abs;
317
  Index res = iu;
318
  Index res = iu;
318
  while (res > 0)
319
  while (res > 0)
319
  {
320
  {
320
    Scalar s = internal::abs(m_matT.coeff(res-1,res-1)) + internal::abs(m_matT.coeff(res,res));
321
    Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res));
321
    if (s == 0.0)
322
    if (s == 0.0)
322
      s = norm;
323
      s = norm;
323
    if (internal::abs(m_matT.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
324
    if (abs(m_matT.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)
324
      break;
325
      break;
325
    res--;
326
    res--;
326
  }
327
  }
327
  return res;
328
  return res;
328
}
329
}
329
330
330
/** \internal Update T given that rows iu-1 and iu decouple from the rest. */
331
/** \internal Update T given that rows iu-1 and iu decouple from the rest. */
331
template<typename MatrixType>
332
template<typename MatrixType>
332
inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, Scalar exshift)
333
inline void RealSchur<MatrixType>::splitOffTwoRows(Index iu, bool computeU, Scalar exshift)
333
{
334
{
335
  using std::sqrt;
336
  using std::abs;
334
  const Index size = m_matT.cols();
337
  const Index size = m_matT.cols();
335
338
336
  // The eigenvalues of the 2x2 matrix [a b; c d] are 
339
  // The eigenvalues of the 2x2 matrix [a b; c d] are 
337
  // trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc
340
  // trace +/- sqrt(discr/4) where discr = tr^2 - 4*det, tr = a + d, det = ad - bc
338
  Scalar p = Scalar(0.5) * (m_matT.coeff(iu-1,iu-1) - m_matT.coeff(iu,iu));
341
  Scalar p = Scalar(0.5) * (m_matT.coeff(iu-1,iu-1) - m_matT.coeff(iu,iu));
339
  Scalar q = p * p + m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);   // q = tr^2 / 4 - det = discr/4
342
  Scalar q = p * p + m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);   // q = tr^2 / 4 - det = discr/4
340
  m_matT.coeffRef(iu,iu) += exshift;
343
  m_matT.coeffRef(iu,iu) += exshift;
341
  m_matT.coeffRef(iu-1,iu-1) += exshift;
344
  m_matT.coeffRef(iu-1,iu-1) += exshift;
342
345
343
  if (q >= Scalar(0)) // Two real eigenvalues
346
  if (q >= Scalar(0)) // Two real eigenvalues
344
  {
347
  {
345
    Scalar z = internal::sqrt(internal::abs(q));
348
    Scalar z = sqrt(abs(q));
346
    JacobiRotation<Scalar> rot;
349
    JacobiRotation<Scalar> rot;
347
    if (p >= Scalar(0))
350
    if (p >= Scalar(0))
348
      rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
351
      rot.makeGivens(p + z, m_matT.coeff(iu, iu-1));
349
    else
352
    else
350
      rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
353
      rot.makeGivens(p - z, m_matT.coeff(iu, iu-1));
351
354
352
    m_matT.rightCols(size-iu+1).applyOnTheLeft(iu-1, iu, rot.adjoint());
355
    m_matT.rightCols(size-iu+1).applyOnTheLeft(iu-1, iu, rot.adjoint());
353
    m_matT.topRows(iu+1).applyOnTheRight(iu-1, iu, rot);
356
    m_matT.topRows(iu+1).applyOnTheRight(iu-1, iu, rot);
Lines 359-430 inline void RealSchur<MatrixType>::split Link Here
359
  if (iu > 1) 
362
  if (iu > 1) 
360
    m_matT.coeffRef(iu-1, iu-2) = Scalar(0);
363
    m_matT.coeffRef(iu-1, iu-2) = Scalar(0);
361
}
364
}
362
365
363
/** \internal Form shift in shiftInfo, and update exshift if an exceptional shift is performed. */
366
/** \internal Form shift in shiftInfo, and update exshift if an exceptional shift is performed. */
364
template<typename MatrixType>
367
template<typename MatrixType>
365
inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo)
368
inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo)
366
{
369
{
370
  using std::sqrt;
371
  using std::abs;
367
  shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu);
372
  shiftInfo.coeffRef(0) = m_matT.coeff(iu,iu);
368
  shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1);
373
  shiftInfo.coeffRef(1) = m_matT.coeff(iu-1,iu-1);
369
  shiftInfo.coeffRef(2) = m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);
374
  shiftInfo.coeffRef(2) = m_matT.coeff(iu,iu-1) * m_matT.coeff(iu-1,iu);
370
375
371
  // Wilkinson's original ad hoc shift
376
  // Wilkinson's original ad hoc shift
372
  if (iter == 10)
377
  if (iter == 10)
373
  {
378
  {
374
    exshift += shiftInfo.coeff(0);
379
    exshift += shiftInfo.coeff(0);
375
    for (Index i = 0; i <= iu; ++i)
380
    for (Index i = 0; i <= iu; ++i)
376
      m_matT.coeffRef(i,i) -= shiftInfo.coeff(0);
381
      m_matT.coeffRef(i,i) -= shiftInfo.coeff(0);
377
    Scalar s = internal::abs(m_matT.coeff(iu,iu-1)) + internal::abs(m_matT.coeff(iu-1,iu-2));
382
    Scalar s = abs(m_matT.coeff(iu,iu-1)) + abs(m_matT.coeff(iu-1,iu-2));
378
    shiftInfo.coeffRef(0) = Scalar(0.75) * s;
383
    shiftInfo.coeffRef(0) = Scalar(0.75) * s;
379
    shiftInfo.coeffRef(1) = Scalar(0.75) * s;
384
    shiftInfo.coeffRef(1) = Scalar(0.75) * s;
380
    shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s;
385
    shiftInfo.coeffRef(2) = Scalar(-0.4375) * s * s;
381
  }
386
  }
382
387
383
  // MATLAB's new ad hoc shift
388
  // MATLAB's new ad hoc shift
384
  if (iter == 30)
389
  if (iter == 30)
385
  {
390
  {
386
    Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
391
    Scalar s = (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
387
    s = s * s + shiftInfo.coeff(2);
392
    s = s * s + shiftInfo.coeff(2);
388
    if (s > Scalar(0))
393
    if (s > Scalar(0))
389
    {
394
    {
390
      s = internal::sqrt(s);
395
      s = sqrt(s);
391
      if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
396
      if (shiftInfo.coeff(1) < shiftInfo.coeff(0))
392
        s = -s;
397
        s = -s;
393
      s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
398
      s = s + (shiftInfo.coeff(1) - shiftInfo.coeff(0)) / Scalar(2.0);
394
      s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s;
399
      s = shiftInfo.coeff(0) - shiftInfo.coeff(2) / s;
395
      exshift += s;
400
      exshift += s;
396
      for (Index i = 0; i <= iu; ++i)
401
      for (Index i = 0; i <= iu; ++i)
397
        m_matT.coeffRef(i,i) -= s;
402
        m_matT.coeffRef(i,i) -= s;
398
      shiftInfo.setConstant(Scalar(0.964));
403
      shiftInfo.setConstant(Scalar(0.964));
399
    }
404
    }
400
  }
405
  }
401
}
406
}
402
407
403
/** \internal Compute index im at which Francis QR step starts and the first Householder vector. */
408
/** \internal Compute index im at which Francis QR step starts and the first Householder vector. */
404
template<typename MatrixType>
409
template<typename MatrixType>
405
inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector)
410
inline void RealSchur<MatrixType>::initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector)
406
{
411
{
412
  using std::abs;
407
  Vector3s& v = firstHouseholderVector; // alias to save typing
413
  Vector3s& v = firstHouseholderVector; // alias to save typing
408
414
409
  for (im = iu-2; im >= il; --im)
415
  for (im = iu-2; im >= il; --im)
410
  {
416
  {
411
    const Scalar Tmm = m_matT.coeff(im,im);
417
    const Scalar Tmm = m_matT.coeff(im,im);
412
    const Scalar r = shiftInfo.coeff(0) - Tmm;
418
    const Scalar r = shiftInfo.coeff(0) - Tmm;
413
    const Scalar s = shiftInfo.coeff(1) - Tmm;
419
    const Scalar s = shiftInfo.coeff(1) - Tmm;
414
    v.coeffRef(0) = (r * s - shiftInfo.coeff(2)) / m_matT.coeff(im+1,im) + m_matT.coeff(im,im+1);
420
    v.coeffRef(0) = (r * s - shiftInfo.coeff(2)) / m_matT.coeff(im+1,im) + m_matT.coeff(im,im+1);
415
    v.coeffRef(1) = m_matT.coeff(im+1,im+1) - Tmm - r - s;
421
    v.coeffRef(1) = m_matT.coeff(im+1,im+1) - Tmm - r - s;
416
    v.coeffRef(2) = m_matT.coeff(im+2,im+1);
422
    v.coeffRef(2) = m_matT.coeff(im+2,im+1);
417
    if (im == il) {
423
    if (im == il) {
418
      break;
424
      break;
419
    }
425
    }
420
    const Scalar lhs = m_matT.coeff(im,im-1) * (internal::abs(v.coeff(1)) + internal::abs(v.coeff(2)));
426
    const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2)));
421
    const Scalar rhs = v.coeff(0) * (internal::abs(m_matT.coeff(im-1,im-1)) + internal::abs(Tmm) + internal::abs(m_matT.coeff(im+1,im+1)));
427
    const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1)));
422
    if (internal::abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
428
    if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)
423
    {
429
    {
424
      break;
430
      break;
425
    }
431
    }
426
  }
432
  }
427
}
433
}
428
434
429
/** \internal Perform a Francis QR step involving rows il:iu and columns im:iu. */
435
/** \internal Perform a Francis QR step involving rows il:iu and columns im:iu. */
430
template<typename MatrixType>
436
template<typename MatrixType>
(-)a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h (-1 / +4 lines)
Lines 379-394 namespace internal { Link Here
379
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
379
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
380
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
380
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n);
381
}
381
}
382
382
383
template<typename MatrixType>
383
template<typename MatrixType>
384
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
384
SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType>
385
::compute(const MatrixType& matrix, int options)
385
::compute(const MatrixType& matrix, int options)
386
{
386
{
387
  using std::abs;
387
  eigen_assert(matrix.cols() == matrix.rows());
388
  eigen_assert(matrix.cols() == matrix.rows());
388
  eigen_assert((options&~(EigVecMask|GenEigMask))==0
389
  eigen_assert((options&~(EigVecMask|GenEigMask))==0
389
          && (options&EigVecMask)!=EigVecMask
390
          && (options&EigVecMask)!=EigVecMask
390
          && "invalid option parameter");
391
          && "invalid option parameter");
391
  bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
392
  bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
392
  Index n = matrix.cols();
393
  Index n = matrix.cols();
393
  m_eivalues.resize(n,1);
394
  m_eivalues.resize(n,1);
394
395
Lines 416-432 SelfAdjointEigenSolver<MatrixType>& Self Link Here
416
  
417
  
417
  Index end = n-1;
418
  Index end = n-1;
418
  Index start = 0;
419
  Index start = 0;
419
  Index iter = 0; // total number of iterations
420
  Index iter = 0; // total number of iterations
420
421
421
  while (end>0)
422
  while (end>0)
422
  {
423
  {
423
    for (Index i = start; i<end; ++i)
424
    for (Index i = start; i<end; ++i)
424
      if (internal::isMuchSmallerThan(internal::abs(m_subdiag[i]),(internal::abs(diag[i])+internal::abs(diag[i+1]))))
425
      if (internal::isMuchSmallerThan(abs(m_subdiag[i]),(abs(diag[i])+abs(diag[i+1]))))
425
        m_subdiag[i] = 0;
426
        m_subdiag[i] = 0;
426
427
427
    // find the largest unreduced block
428
    // find the largest unreduced block
428
    while (end>0 && m_subdiag[end-1]==0)
429
    while (end>0 && m_subdiag[end-1]==0)
429
    {
430
    {
430
      end--;
431
      end--;
431
    }
432
    }
432
    if (end<=0)
433
    if (end<=0)
Lines 670-685 template<typename SolverType> struct dir Link Here
670
    const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
671
    const Scalar t0 = Scalar(0.5) * sqrt( abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));
671
    const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1));
672
    const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1));
672
    roots(0) = t1 - t0;
673
    roots(0) = t1 - t0;
673
    roots(1) = t1 + t0;
674
    roots(1) = t1 + t0;
674
  }
675
  }
675
  
676
  
676
  static inline void run(SolverType& solver, const MatrixType& mat, int options)
677
  static inline void run(SolverType& solver, const MatrixType& mat, int options)
677
  {
678
  {
679
    using std::sqrt;
678
    eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
680
    eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows());
679
    eigen_assert((options&~(EigVecMask|GenEigMask))==0
681
    eigen_assert((options&~(EigVecMask|GenEigMask))==0
680
            && (options&EigVecMask)!=EigVecMask
682
            && (options&EigVecMask)!=EigVecMask
681
            && "invalid option parameter");
683
            && "invalid option parameter");
682
    bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
684
    bool computeEigenvectors = (options&ComputeEigenvectors)==ComputeEigenvectors;
683
    
685
    
684
    MatrixType& eivecs = solver.m_eivec;
686
    MatrixType& eivecs = solver.m_eivec;
685
    VectorType& eivals = solver.m_eivalues;
687
    VectorType& eivals = solver.m_eivalues;
Lines 731-746 SelfAdjointEigenSolver<MatrixType>& Self Link Here
731
  internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>::run(*this,matrix,options);
733
  internal::direct_selfadjoint_eigenvalues<SelfAdjointEigenSolver,Size,NumTraits<Scalar>::IsComplex>::run(*this,matrix,options);
732
  return *this;
734
  return *this;
733
}
735
}
734
736
735
namespace internal {
737
namespace internal {
736
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
738
template<int StorageOrder,typename RealScalar, typename Scalar, typename Index>
737
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
739
static void tridiagonal_qr_step(RealScalar* diag, RealScalar* subdiag, Index start, Index end, Scalar* matrixQ, Index n)
738
{
740
{
741
  using std::abs;
739
  RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
742
  RealScalar td = (diag[end-1] - diag[end])*RealScalar(0.5);
740
  RealScalar e = subdiag[end-1];
743
  RealScalar e = subdiag[end-1];
741
  // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still
744
  // Note that thanks to scaling, e^2 or td^2 cannot overflow, however they can still
742
  // underflow thus leading to inf/NaN values when using the following commented code:
745
  // underflow thus leading to inf/NaN values when using the following commented code:
743
//   RealScalar e2 = abs2(subdiag[end-1]);
746
//   RealScalar e2 = abs2(subdiag[end-1]);
744
//   RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
747
//   RealScalar mu = diag[end] - e2 / (td + (td>0 ? 1 : -1) * sqrt(td*td + e2));
745
  // This explain the following, somewhat more complicated, version:
748
  // This explain the following, somewhat more complicated, version:
746
  RealScalar mu = diag[end];
749
  RealScalar mu = diag[end];
(-)a/Eigen/src/Eigenvalues/Tridiagonalization.h (+1 lines)
Lines 462-477 template<typename MatrixType> Link Here
462
struct tridiagonalization_inplace_selector<MatrixType,3,false>
462
struct tridiagonalization_inplace_selector<MatrixType,3,false>
463
{
463
{
464
  typedef typename MatrixType::Scalar Scalar;
464
  typedef typename MatrixType::Scalar Scalar;
465
  typedef typename MatrixType::RealScalar RealScalar;
465
  typedef typename MatrixType::RealScalar RealScalar;
466
466
467
  template<typename DiagonalType, typename SubDiagonalType>
467
  template<typename DiagonalType, typename SubDiagonalType>
468
  static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
468
  static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
469
  {
469
  {
470
    using std::sqrt;
470
    diag[0] = mat(0,0);
471
    diag[0] = mat(0,0);
471
    RealScalar v1norm2 = abs2(mat(2,0));
472
    RealScalar v1norm2 = abs2(mat(2,0));
472
    if(v1norm2 == RealScalar(0))
473
    if(v1norm2 == RealScalar(0))
473
    {
474
    {
474
      diag[1] = mat(1,1);
475
      diag[1] = mat(1,1);
475
      diag[2] = mat(2,2);
476
      diag[2] = mat(2,2);
476
      subdiag[0] = mat(1,0);
477
      subdiag[0] = mat(1,0);
477
      subdiag[1] = mat(2,1);
478
      subdiag[1] = mat(2,1);
(-)a/Eigen/src/Geometry/AlignedBox.h (-2 / +2 lines)
Lines 243-266 EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTO Link Here
243
  inline Scalar squaredExteriorDistance(const AlignedBox& b) const;
243
  inline Scalar squaredExteriorDistance(const AlignedBox& b) const;
244
244
245
  /** \returns the distance between the point \a p and the box \c *this,
245
  /** \returns the distance between the point \a p and the box \c *this,
246
    * and zero if \a p is inside the box.
246
    * and zero if \a p is inside the box.
247
    * \sa squaredExteriorDistance()
247
    * \sa squaredExteriorDistance()
248
    */
248
    */
249
  template<typename Derived>
249
  template<typename Derived>
250
  inline NonInteger exteriorDistance(const MatrixBase<Derived>& p) const
250
  inline NonInteger exteriorDistance(const MatrixBase<Derived>& p) const
251
  { return internal::sqrt(NonInteger(squaredExteriorDistance(p))); }
251
  { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(p))); }
252
252
253
  /** \returns the distance between the boxes \a b and \c *this,
253
  /** \returns the distance between the boxes \a b and \c *this,
254
    * and zero if the boxes intersect.
254
    * and zero if the boxes intersect.
255
    * \sa squaredExteriorDistance()
255
    * \sa squaredExteriorDistance()
256
    */
256
    */
257
  inline NonInteger exteriorDistance(const AlignedBox& b) const
257
  inline NonInteger exteriorDistance(const AlignedBox& b) const
258
  { return internal::sqrt(NonInteger(squaredExteriorDistance(b))); }
258
  { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(b))); }
259
259
260
  /** \returns \c *this with scalar type casted to \a NewScalarType
260
  /** \returns \c *this with scalar type casted to \a NewScalarType
261
    *
261
    *
262
    * Note that if \a NewScalarType is equal to the current scalar type of \c *this
262
    * Note that if \a NewScalarType is equal to the current scalar type of \c *this
263
    * then this function smartly returns a const reference to \c *this.
263
    * then this function smartly returns a const reference to \c *this.
264
    */
264
    */
265
  template<typename NewScalarType>
265
  template<typename NewScalarType>
266
  inline typename internal::cast_return_type<AlignedBox,
266
  inline typename internal::cast_return_type<AlignedBox,
(-)a/Eigen/src/Geometry/AngleAxis.h (-3 / +6 lines)
Lines 156-181 typedef AngleAxis<double> AngleAxisd; Link Here
156
  */
156
  */
157
template<typename Scalar>
157
template<typename Scalar>
158
template<typename QuatDerived>
158
template<typename QuatDerived>
159
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
159
AngleAxis<Scalar>& AngleAxis<Scalar>::operator=(const QuaternionBase<QuatDerived>& q)
160
{
160
{
161
  using std::acos;
161
  using std::acos;
162
  using std::min;
162
  using std::min;
163
  using std::max;
163
  using std::max;
164
  using std::sqrt;
164
  Scalar n2 = q.vec().squaredNorm();
165
  Scalar n2 = q.vec().squaredNorm();
165
  if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
166
  if (n2 < NumTraits<Scalar>::dummy_precision()*NumTraits<Scalar>::dummy_precision())
166
  {
167
  {
167
    m_angle = 0;
168
    m_angle = 0;
168
    m_axis << 1, 0, 0;
169
    m_axis << 1, 0, 0;
169
  }
170
  }
170
  else
171
  else
171
  {
172
  {
172
    m_angle = Scalar(2)*acos((min)((max)(Scalar(-1),q.w()),Scalar(1)));
173
    m_angle = Scalar(2)*acos((min)((max)(Scalar(-1),q.w()),Scalar(1)));
173
    m_axis = q.vec() / internal::sqrt(n2);
174
    m_axis = q.vec() / sqrt(n2);
174
  }
175
  }
175
  return *this;
176
  return *this;
176
}
177
}
177
178
178
/** Set \c *this from a 3x3 rotation matrix \a mat.
179
/** Set \c *this from a 3x3 rotation matrix \a mat.
179
  */
180
  */
180
template<typename Scalar>
181
template<typename Scalar>
181
template<typename Derived>
182
template<typename Derived>
Lines 197-215 AngleAxis<Scalar>& AngleAxis<Scalar>::fr Link Here
197
}
198
}
198
199
199
/** Constructs and \returns an equivalent 3x3 rotation matrix.
200
/** Constructs and \returns an equivalent 3x3 rotation matrix.
200
  */
201
  */
201
template<typename Scalar>
202
template<typename Scalar>
202
typename AngleAxis<Scalar>::Matrix3
203
typename AngleAxis<Scalar>::Matrix3
203
AngleAxis<Scalar>::toRotationMatrix(void) const
204
AngleAxis<Scalar>::toRotationMatrix(void) const
204
{
205
{
206
  using std::sin;
207
  using std::cos;
205
  Matrix3 res;
208
  Matrix3 res;
206
  Vector3 sin_axis  = internal::sin(m_angle) * m_axis;
209
  Vector3 sin_axis  = sin(m_angle) * m_axis;
207
  Scalar c = internal::cos(m_angle);
210
  Scalar c = cos(m_angle);
208
  Vector3 cos1_axis = (Scalar(1)-c) * m_axis;
211
  Vector3 cos1_axis = (Scalar(1)-c) * m_axis;
209
212
210
  Scalar tmp;
213
  Scalar tmp;
211
  tmp = cos1_axis.x() * m_axis.y();
214
  tmp = cos1_axis.x() * m_axis.y();
212
  res.coeffRef(0,1) = tmp - sin_axis.z();
215
  res.coeffRef(0,1) = tmp - sin_axis.z();
213
  res.coeffRef(1,0) = tmp + sin_axis.z();
216
  res.coeffRef(1,0) = tmp + sin_axis.z();
214
217
215
  tmp = cos1_axis.x() * m_axis.z();
218
  tmp = cos1_axis.x() * m_axis.z();
(-)a/Eigen/src/Geometry/EulerAngles.h (-8 / +9 lines)
Lines 27-82 namespace Eigen { Link Here
27
  *      * AngleAxisf(ea[1], Vector3f::UnitX())
27
  *      * AngleAxisf(ea[1], Vector3f::UnitX())
28
  *      * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode
28
  *      * AngleAxisf(ea[2], Vector3f::UnitZ()); \endcode
29
  * This corresponds to the right-multiply conventions (with right hand side frames).
29
  * This corresponds to the right-multiply conventions (with right hand side frames).
30
  */
30
  */
31
template<typename Derived>
31
template<typename Derived>
32
inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
32
inline Matrix<typename MatrixBase<Derived>::Scalar,3,1>
33
MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const
33
MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const
34
{
34
{
35
  using std::atan2;
35
  /* Implemented from Graphics Gems IV */
36
  /* Implemented from Graphics Gems IV */
36
  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)
37
  EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived,3,3)
37
38
38
  Matrix<Scalar,3,1> res;
39
  Matrix<Scalar,3,1> res;
39
  typedef Matrix<typename Derived::Scalar,2,1> Vector2;
40
  typedef Matrix<typename Derived::Scalar,2,1> Vector2;
40
  const Scalar epsilon = NumTraits<Scalar>::dummy_precision();
41
  const Scalar epsilon = NumTraits<Scalar>::dummy_precision();
41
42
42
  const Index odd = ((a0+1)%3 == a1) ? 0 : 1;
43
  const Index odd = ((a0+1)%3 == a1) ? 0 : 1;
43
  const Index i = a0;
44
  const Index i = a0;
44
  const Index j = (a0 + 1 + odd)%3;
45
  const Index j = (a0 + 1 + odd)%3;
45
  const Index k = (a0 + 2 - odd)%3;
46
  const Index k = (a0 + 2 - odd)%3;
46
47
47
  if (a0==a2)
48
  if (a0==a2)
48
  {
49
  {
49
    Scalar s = Vector2(coeff(j,i) , coeff(k,i)).norm();
50
    Scalar s = Vector2(coeff(j,i) , coeff(k,i)).norm();
50
    res[1] = internal::atan2(s, coeff(i,i));
51
    res[1] = atan2(s, coeff(i,i));
51
    if (s > epsilon)
52
    if (s > epsilon)
52
    {
53
    {
53
      res[0] = internal::atan2(coeff(j,i), coeff(k,i));
54
      res[0] = atan2(coeff(j,i), coeff(k,i));
54
      res[2] = internal::atan2(coeff(i,j),-coeff(i,k));
55
      res[2] = atan2(coeff(i,j),-coeff(i,k));
55
    }
56
    }
56
    else
57
    else
57
    {
58
    {
58
      res[0] = Scalar(0);
59
      res[0] = Scalar(0);
59
      res[2] = (coeff(i,i)>0?1:-1)*internal::atan2(-coeff(k,j), coeff(j,j));
60
      res[2] = (coeff(i,i)>0?1:-1)*atan2(-coeff(k,j), coeff(j,j));
60
    }
61
    }
61
  }
62
  }
62
  else
63
  else
63
  {
64
  {
64
    Scalar c = Vector2(coeff(i,i) , coeff(i,j)).norm();
65
    Scalar c = Vector2(coeff(i,i) , coeff(i,j)).norm();
65
    res[1] = internal::atan2(-coeff(i,k), c);
66
    res[1] = atan2(-coeff(i,k), c);
66
    if (c > epsilon)
67
    if (c > epsilon)
67
    {
68
    {
68
      res[0] = internal::atan2(coeff(j,k), coeff(k,k));
69
      res[0] = atan2(coeff(j,k), coeff(k,k));
69
      res[2] = internal::atan2(coeff(i,j), coeff(i,i));
70
      res[2] = atan2(coeff(i,j), coeff(i,i));
70
    }
71
    }
71
    else
72
    else
72
    {
73
    {
73
      res[0] = Scalar(0);
74
      res[0] = Scalar(0);
74
      res[2] = (coeff(i,k)>0?1:-1)*internal::atan2(-coeff(k,j), coeff(j,j));
75
      res[2] = (coeff(i,k)>0?1:-1)*atan2(-coeff(k,j), coeff(j,j));
75
    }
76
    }
76
  }
77
  }
77
  if (!odd)
78
  if (!odd)
78
    res = -res;
79
    res = -res;
79
  return res;
80
  return res;
80
}
81
}
81
82
82
} // end namespace Eigen
83
} // end namespace Eigen
(-)a/Eigen/src/Geometry/Hyperplane.h (-2 / +3 lines)
Lines 130-146 public: Link Here
130
  /** \returns the signed distance between the plane \c *this and a point \a p.
130
  /** \returns the signed distance between the plane \c *this and a point \a p.
131
    * \sa absDistance()
131
    * \sa absDistance()
132
    */
132
    */
133
  inline Scalar signedDistance(const VectorType& p) const { return normal().dot(p) + offset(); }
133
  inline Scalar signedDistance(const VectorType& p) const { return normal().dot(p) + offset(); }
134
134
135
  /** \returns the absolute distance between the plane \c *this and a point \a p.
135
  /** \returns the absolute distance between the plane \c *this and a point \a p.
136
    * \sa signedDistance()
136
    * \sa signedDistance()
137
    */
137
    */
138
  inline Scalar absDistance(const VectorType& p) const { return internal::abs(signedDistance(p)); }
138
  inline Scalar absDistance(const VectorType& p) const { using std::abs; return abs(signedDistance(p)); }
139
139
140
  /** \returns the projection of a point \a p onto the plane \c *this.
140
  /** \returns the projection of a point \a p onto the plane \c *this.
141
    */
141
    */
142
  inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); }
142
  inline VectorType projection(const VectorType& p) const { return p - signedDistance(p) * normal(); }
143
143
144
  /** \returns a constant reference to the unit normal vector of the plane, which corresponds
144
  /** \returns a constant reference to the unit normal vector of the plane, which corresponds
145
    * to the linear part of the implicit equation.
145
    * to the linear part of the implicit equation.
146
    */
146
    */
Lines 173-195 public: Link Here
173
  /** \returns the intersection of *this with \a other.
173
  /** \returns the intersection of *this with \a other.
174
    *
174
    *
175
    * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines.
175
    * \warning The ambient space must be a plane, i.e. have dimension 2, so that \c *this and \a other are lines.
176
    *
176
    *
177
    * \note If \a other is approximately parallel to *this, this method will return any point on *this.
177
    * \note If \a other is approximately parallel to *this, this method will return any point on *this.
178
    */
178
    */
179
  VectorType intersection(const Hyperplane& other) const
179
  VectorType intersection(const Hyperplane& other) const
180
  {
180
  {
181
    using std::abs;
181
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
182
    EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(VectorType, 2)
182
    Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
183
    Scalar det = coeffs().coeff(0) * other.coeffs().coeff(1) - coeffs().coeff(1) * other.coeffs().coeff(0);
183
    // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests
184
    // since the line equations ax+by=c are normalized with a^2+b^2=1, the following tests
184
    // whether the two lines are approximately parallel.
185
    // whether the two lines are approximately parallel.
185
    if(internal::isMuchSmallerThan(det, Scalar(1)))
186
    if(internal::isMuchSmallerThan(det, Scalar(1)))
186
    {   // special case where the two lines are approximately parallel. Pick any point on the first line.
187
    {   // special case where the two lines are approximately parallel. Pick any point on the first line.
187
        if(internal::abs(coeffs().coeff(1))>internal::abs(coeffs().coeff(0)))
188
        if(abs(coeffs().coeff(1))>abs(coeffs().coeff(0)))
188
            return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0));
189
            return VectorType(coeffs().coeff(1), -coeffs().coeff(2)/coeffs().coeff(1)-coeffs().coeff(0));
189
        else
190
        else
190
            return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0));
191
            return VectorType(-coeffs().coeff(2)/coeffs().coeff(0)-coeffs().coeff(1), coeffs().coeff(0));
191
    }
192
    }
192
    else
193
    else
193
    {   // general case
194
    {   // general case
194
        Scalar invdet = Scalar(1) / det;
195
        Scalar invdet = Scalar(1) / det;
195
        return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)),
196
        return VectorType(invdet*(coeffs().coeff(1)*other.coeffs().coeff(2)-other.coeffs().coeff(1)*coeffs().coeff(2)),
(-)a/Eigen/src/Geometry/ParametrizedLine.h (-1 / +1 lines)
Lines 82-98 public: Link Here
82
  RealScalar squaredDistance(const VectorType& p) const
82
  RealScalar squaredDistance(const VectorType& p) const
83
  {
83
  {
84
    VectorType diff = p - origin();
84
    VectorType diff = p - origin();
85
    return (diff - direction().dot(diff) * direction()).squaredNorm();
85
    return (diff - direction().dot(diff) * direction()).squaredNorm();
86
  }
86
  }
87
  /** \returns the distance of a point \a p to its projection onto the line \c *this.
87
  /** \returns the distance of a point \a p to its projection onto the line \c *this.
88
    * \sa squaredDistance()
88
    * \sa squaredDistance()
89
    */
89
    */
90
  RealScalar distance(const VectorType& p) const { return internal::sqrt(squaredDistance(p)); }
90
  RealScalar distance(const VectorType& p) const { using std::sqrt; return sqrt(squaredDistance(p)); }
91
91
92
  /** \returns the projection of a point \a p onto the line \c *this. */
92
  /** \returns the projection of a point \a p onto the line \c *this. */
93
  VectorType projection(const VectorType& p) const
93
  VectorType projection(const VectorType& p) const
94
  { return origin() + direction().dot(p-origin()) * direction(); }
94
  { return origin() + direction().dot(p-origin()) * direction(); }
95
95
96
  VectorType pointAt(const Scalar& t) const;
96
  VectorType pointAt(const Scalar& t) const;
97
  
97
  
98
  template <int OtherOptions>
98
  template <int OtherOptions>
(-)a/Eigen/src/Geometry/Quaternion.h (-10 / +17 lines)
Lines 500-518 EIGEN_STRONG_INLINE Derived& QuaternionB Link Here
500
  return derived();
500
  return derived();
501
}
501
}
502
502
503
/** Set \c *this from an angle-axis \a aa and returns a reference to \c *this
503
/** Set \c *this from an angle-axis \a aa and returns a reference to \c *this
504
  */
504
  */
505
template<class Derived>
505
template<class Derived>
506
EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
506
EIGEN_STRONG_INLINE Derived& QuaternionBase<Derived>::operator=(const AngleAxisType& aa)
507
{
507
{
508
  using std::cos;
509
  using std::sin;
508
  Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
510
  Scalar ha = Scalar(0.5)*aa.angle(); // Scalar(0.5) to suppress precision loss warnings
509
  this->w() = internal::cos(ha);
511
  this->w() = cos(ha);
510
  this->vec() = internal::sin(ha) * aa.axis();
512
  this->vec() = sin(ha) * aa.axis();
511
  return derived();
513
  return derived();
512
}
514
}
513
515
514
/** Set \c *this from the expression \a xpr:
516
/** Set \c *this from the expression \a xpr:
515
  *   - if \a xpr is a 4x1 vector, then \a xpr is assumed to be a quaternion
517
  *   - if \a xpr is a 4x1 vector, then \a xpr is assumed to be a quaternion
516
  *   - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix
518
  *   - if \a xpr is a 3x3 matrix, then \a xpr is assumed to be rotation matrix
517
  *     and \a xpr is converted to a quaternion
519
  *     and \a xpr is converted to a quaternion
518
  */
520
  */
Lines 576-591 QuaternionBase<Derived>::toRotationMatri Link Here
576
  * Note that the two input vectors do \b not have to be normalized, and
578
  * Note that the two input vectors do \b not have to be normalized, and
577
  * do not need to have the same norm.
579
  * do not need to have the same norm.
578
  */
580
  */
579
template<class Derived>
581
template<class Derived>
580
template<typename Derived1, typename Derived2>
582
template<typename Derived1, typename Derived2>
581
inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
583
inline Derived& QuaternionBase<Derived>::setFromTwoVectors(const MatrixBase<Derived1>& a, const MatrixBase<Derived2>& b)
582
{
584
{
583
  using std::max;
585
  using std::max;
586
  using std::sqrt;
584
  Vector3 v0 = a.normalized();
587
  Vector3 v0 = a.normalized();
585
  Vector3 v1 = b.normalized();
588
  Vector3 v1 = b.normalized();
586
  Scalar c = v1.dot(v0);
589
  Scalar c = v1.dot(v0);
587
590
588
  // if dot == -1, vectors are nearly opposites
591
  // if dot == -1, vectors are nearly opposites
589
  // => accuraletly compute the rotation axis by computing the
592
  // => accuraletly compute the rotation axis by computing the
590
  //    intersection of the two planes. This is done by solving:
593
  //    intersection of the two planes. This is done by solving:
591
  //       x^T v0 = 0
594
  //       x^T v0 = 0
Lines 596-617 inline Derived& QuaternionBase<Derived>: Link Here
596
  if (c < Scalar(-1)+NumTraits<Scalar>::dummy_precision())
599
  if (c < Scalar(-1)+NumTraits<Scalar>::dummy_precision())
597
  {
600
  {
598
    c = max<Scalar>(c,-1);
601
    c = max<Scalar>(c,-1);
599
    Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
602
    Matrix<Scalar,2,3> m; m << v0.transpose(), v1.transpose();
600
    JacobiSVD<Matrix<Scalar,2,3> > svd(m, ComputeFullV);
603
    JacobiSVD<Matrix<Scalar,2,3> > svd(m, ComputeFullV);
601
    Vector3 axis = svd.matrixV().col(2);
604
    Vector3 axis = svd.matrixV().col(2);
602
605
603
    Scalar w2 = (Scalar(1)+c)*Scalar(0.5);
606
    Scalar w2 = (Scalar(1)+c)*Scalar(0.5);
604
    this->w() = internal::sqrt(w2);
607
    this->w() = sqrt(w2);
605
    this->vec() = axis * internal::sqrt(Scalar(1) - w2);
608
    this->vec() = axis * sqrt(Scalar(1) - w2);
606
    return derived();
609
    return derived();
607
  }
610
  }
608
  Vector3 axis = v0.cross(v1);
611
  Vector3 axis = v0.cross(v1);
609
  Scalar s = internal::sqrt((Scalar(1)+c)*Scalar(2));
612
  Scalar s = sqrt((Scalar(1)+c)*Scalar(2));
610
  Scalar invs = Scalar(1)/s;
613
  Scalar invs = Scalar(1)/s;
611
  this->vec() = axis * invs;
614
  this->vec() = axis * invs;
612
  this->w() = s * Scalar(0.5);
615
  this->w() = s * Scalar(0.5);
613
616
614
  return derived();
617
  return derived();
615
}
618
}
616
619
617
620
Lines 672-738 QuaternionBase<Derived>::conjugate() con Link Here
672
  * \sa dot()
675
  * \sa dot()
673
  */
676
  */
674
template <class Derived>
677
template <class Derived>
675
template <class OtherDerived>
678
template <class OtherDerived>
676
inline typename internal::traits<Derived>::Scalar
679
inline typename internal::traits<Derived>::Scalar
677
QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
680
QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const
678
{
681
{
679
  using std::acos;
682
  using std::acos;
680
  double d = internal::abs(this->dot(other));
683
  using std::abs;
684
  double d = abs(this->dot(other));
681
  if (d>=1.0)
685
  if (d>=1.0)
682
    return Scalar(0);
686
    return Scalar(0);
683
  return static_cast<Scalar>(2 * acos(d));
687
  return static_cast<Scalar>(2 * acos(d));
684
}
688
}
685
689
686
/** \returns the spherical linear interpolation between the two quaternions
690
/** \returns the spherical linear interpolation between the two quaternions
687
  * \c *this and \a other at the parameter \a t
691
  * \c *this and \a other at the parameter \a t
688
  */
692
  */
689
template <class Derived>
693
template <class Derived>
690
template <class OtherDerived>
694
template <class OtherDerived>
691
Quaternion<typename internal::traits<Derived>::Scalar>
695
Quaternion<typename internal::traits<Derived>::Scalar>
692
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
696
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
693
{
697
{
694
  using std::acos;
698
  using std::acos;
699
  using std::sin;
700
  using std::abs;
695
  static const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
701
  static const Scalar one = Scalar(1) - NumTraits<Scalar>::epsilon();
696
  Scalar d = this->dot(other);
702
  Scalar d = this->dot(other);
697
  Scalar absD = internal::abs(d);
703
  Scalar absD = abs(d);
698
704
699
  Scalar scale0;
705
  Scalar scale0;
700
  Scalar scale1;
706
  Scalar scale1;
701
707
702
  if(absD>=one)
708
  if(absD>=one)
703
  {
709
  {
704
    scale0 = Scalar(1) - t;
710
    scale0 = Scalar(1) - t;
705
    scale1 = t;
711
    scale1 = t;
706
  }
712
  }
707
  else
713
  else
708
  {
714
  {
709
    // theta is the angle between the 2 quaternions
715
    // theta is the angle between the 2 quaternions
710
    Scalar theta = acos(absD);
716
    Scalar theta = acos(absD);
711
    Scalar sinTheta = internal::sin(theta);
717
    Scalar sinTheta = sin(theta);
712
718
713
    scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;
719
    scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta;
714
    scale1 = internal::sin( ( t * theta) ) / sinTheta;
720
    scale1 = sin( ( t * theta) ) / sinTheta;
715
  }
721
  }
716
  if(d<0) scale1 = -scale1;
722
  if(d<0) scale1 = -scale1;
717
723
718
  return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
724
  return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
719
}
725
}
720
726
721
namespace internal {
727
namespace internal {
722
728
723
// set from a rotation matrix
729
// set from a rotation matrix
724
template<typename Other>
730
template<typename Other>
725
struct quaternionbase_assign_impl<Other,3,3>
731
struct quaternionbase_assign_impl<Other,3,3>
726
{
732
{
727
  typedef typename Other::Scalar Scalar;
733
  typedef typename Other::Scalar Scalar;
728
  typedef DenseIndex Index;
734
  typedef DenseIndex Index;
729
  template<class Derived> static inline void run(QuaternionBase<Derived>& q, const Other& mat)
735
  template<class Derived> static inline void run(QuaternionBase<Derived>& q, const Other& mat)
730
  {
736
  {
737
    using std::sqrt;
731
    // This algorithm comes from  "Quaternion Calculus and Fast Animation",
738
    // This algorithm comes from  "Quaternion Calculus and Fast Animation",
732
    // Ken Shoemake, 1987 SIGGRAPH course notes
739
    // Ken Shoemake, 1987 SIGGRAPH course notes
733
    Scalar t = mat.trace();
740
    Scalar t = mat.trace();
734
    if (t > Scalar(0))
741
    if (t > Scalar(0))
735
    {
742
    {
736
      t = sqrt(t + Scalar(1.0));
743
      t = sqrt(t + Scalar(1.0));
737
      q.w() = Scalar(0.5)*t;
744
      q.w() = Scalar(0.5)*t;
738
      t = Scalar(0.5)/t;
745
      t = Scalar(0.5)/t;
(-)a/Eigen/src/Geometry/Rotation2D.h (-3 / +6 lines)
Lines 128-154 typedef Rotation2D<double> Rotation2Dd; Link Here
128
/** Set \c *this from a 2x2 rotation matrix \a mat.
128
/** Set \c *this from a 2x2 rotation matrix \a mat.
129
  * In other words, this function extract the rotation angle
129
  * In other words, this function extract the rotation angle
130
  * from the rotation matrix.
130
  * from the rotation matrix.
131
  */
131
  */
132
template<typename Scalar>
132
template<typename Scalar>
133
template<typename Derived>
133
template<typename Derived>
134
Rotation2D<Scalar>& Rotation2D<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
134
Rotation2D<Scalar>& Rotation2D<Scalar>::fromRotationMatrix(const MatrixBase<Derived>& mat)
135
{
135
{
136
  using std::atan2;
136
  EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
137
  EIGEN_STATIC_ASSERT(Derived::RowsAtCompileTime==2 && Derived::ColsAtCompileTime==2,YOU_MADE_A_PROGRAMMING_MISTAKE)
137
  m_angle = internal::atan2(mat.coeff(1,0), mat.coeff(0,0));
138
  m_angle = atan2(mat.coeff(1,0), mat.coeff(0,0));
138
  return *this;
139
  return *this;
139
}
140
}
140
141
141
/** Constructs and \returns an equivalent 2x2 rotation matrix.
142
/** Constructs and \returns an equivalent 2x2 rotation matrix.
142
  */
143
  */
143
template<typename Scalar>
144
template<typename Scalar>
144
typename Rotation2D<Scalar>::Matrix2
145
typename Rotation2D<Scalar>::Matrix2
145
Rotation2D<Scalar>::toRotationMatrix(void) const
146
Rotation2D<Scalar>::toRotationMatrix(void) const
146
{
147
{
147
  Scalar sinA = internal::sin(m_angle);
148
  using std::sin;
148
  Scalar cosA = internal::cos(m_angle);
149
  using std::cos;
150
  Scalar sinA = sin(m_angle);
151
  Scalar cosA = cos(m_angle);
149
  return (Matrix2() << cosA, -sinA, sinA, cosA).finished();
152
  return (Matrix2() << cosA, -sinA, sinA, cosA).finished();
150
}
153
}
151
154
152
} // end namespace Eigen
155
} // end namespace Eigen
153
156
154
#endif // EIGEN_ROTATION2D_H
157
#endif // EIGEN_ROTATION2D_H
(-)a/Eigen/src/Householder/Householder.h (-1 / +2 lines)
Lines 62-92 void MatrixBase<Derived>::makeHouseholde Link Here
62
  */
62
  */
63
template<typename Derived>
63
template<typename Derived>
64
template<typename EssentialPart>
64
template<typename EssentialPart>
65
void MatrixBase<Derived>::makeHouseholder(
65
void MatrixBase<Derived>::makeHouseholder(
66
  EssentialPart& essential,
66
  EssentialPart& essential,
67
  Scalar& tau,
67
  Scalar& tau,
68
  RealScalar& beta) const
68
  RealScalar& beta) const
69
{
69
{
70
  using std::sqrt;
70
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
71
  EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
71
  VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
72
  VectorBlock<const Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
72
  
73
  
73
  RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
74
  RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
74
  Scalar c0 = coeff(0);
75
  Scalar c0 = coeff(0);
75
76
76
  if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
77
  if(tailSqNorm == RealScalar(0) && internal::imag(c0)==RealScalar(0))
77
  {
78
  {
78
    tau = RealScalar(0);
79
    tau = RealScalar(0);
79
    beta = internal::real(c0);
80
    beta = internal::real(c0);
80
    essential.setZero();
81
    essential.setZero();
81
  }
82
  }
82
  else
83
  else
83
  {
84
  {
84
    beta = internal::sqrt(internal::abs2(c0) + tailSqNorm);
85
    beta = sqrt(internal::abs2(c0) + tailSqNorm);
85
    if (internal::real(c0)>=RealScalar(0))
86
    if (internal::real(c0)>=RealScalar(0))
86
      beta = -beta;
87
      beta = -beta;
87
    essential = tail / (c0 - beta);
88
    essential = tail / (c0 - beta);
88
    tau = internal::conj((beta - c0) / beta);
89
    tau = internal::conj((beta - c0) / beta);
89
  }
90
  }
90
}
91
}
91
92
92
/** Apply the elementary reflector H given by
93
/** Apply the elementary reflector H given by
(-)a/Eigen/src/Jacobi/Jacobi.h (-14 / +20 lines)
Lines 76-114 template<typename Scalar> class JacobiRo Link Here
76
/** Makes \c *this as a Jacobi rotation \a J such that applying \a J on both the right and left sides of the selfadjoint 2x2 matrix
76
/** Makes \c *this as a Jacobi rotation \a J such that applying \a J on both the right and left sides of the selfadjoint 2x2 matrix
77
  * \f$ B = \left ( \begin{array}{cc} x & y \\ \overline y & z \end{array} \right )\f$ yields a diagonal matrix \f$ A = J^* B J \f$
77
  * \f$ B = \left ( \begin{array}{cc} x & y \\ \overline y & z \end{array} \right )\f$ yields a diagonal matrix \f$ A = J^* B J \f$
78
  *
78
  *
79
  * \sa MatrixBase::makeJacobi(const MatrixBase<Derived>&, Index, Index), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
79
  * \sa MatrixBase::makeJacobi(const MatrixBase<Derived>&, Index, Index), MatrixBase::applyOnTheLeft(), MatrixBase::applyOnTheRight()
80
  */
80
  */
81
template<typename Scalar>
81
template<typename Scalar>
82
bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
82
bool JacobiRotation<Scalar>::makeJacobi(RealScalar x, Scalar y, RealScalar z)
83
{
83
{
84
  using std::sqrt;
85
  using std::abs;
84
  typedef typename NumTraits<Scalar>::Real RealScalar;
86
  typedef typename NumTraits<Scalar>::Real RealScalar;
85
  if(y == Scalar(0))
87
  if(y == Scalar(0))
86
  {
88
  {
87
    m_c = Scalar(1);
89
    m_c = Scalar(1);
88
    m_s = Scalar(0);
90
    m_s = Scalar(0);
89
    return false;
91
    return false;
90
  }
92
  }
91
  else
93
  else
92
  {
94
  {
93
    RealScalar tau = (x-z)/(RealScalar(2)*internal::abs(y));
95
    RealScalar tau = (x-z)/(RealScalar(2)*abs(y));
94
    RealScalar w = internal::sqrt(internal::abs2(tau) + RealScalar(1));
96
    RealScalar w = sqrt(internal::abs2(tau) + RealScalar(1));
95
    RealScalar t;
97
    RealScalar t;
96
    if(tau>RealScalar(0))
98
    if(tau>RealScalar(0))
97
    {
99
    {
98
      t = RealScalar(1) / (tau + w);
100
      t = RealScalar(1) / (tau + w);
99
    }
101
    }
100
    else
102
    else
101
    {
103
    {
102
      t = RealScalar(1) / (tau - w);
104
      t = RealScalar(1) / (tau - w);
103
    }
105
    }
104
    RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
106
    RealScalar sign_t = t > RealScalar(0) ? RealScalar(1) : RealScalar(-1);
105
    RealScalar n = RealScalar(1) / internal::sqrt(internal::abs2(t)+RealScalar(1));
107
    RealScalar n = RealScalar(1) / sqrt(internal::abs2(t)+RealScalar(1));
106
    m_s = - sign_t * (internal::conj(y) / internal::abs(y)) * internal::abs(t) * n;
108
    m_s = - sign_t * (internal::conj(y) / abs(y)) * abs(t) * n;
107
    m_c = n;
109
    m_c = n;
108
    return true;
110
    return true;
109
  }
111
  }
110
}
112
}
111
113
112
/** Makes \c *this as a Jacobi rotation \c J such that applying \a J on both the right and left sides of the 2x2 selfadjoint matrix
114
/** Makes \c *this as a Jacobi rotation \c J such that applying \a J on both the right and left sides of the 2x2 selfadjoint matrix
113
  * \f$ B = \left ( \begin{array}{cc} \text{this}_{pp} & \text{this}_{pq} \\ (\text{this}_{pq})^* & \text{this}_{qq} \end{array} \right )\f$ yields
115
  * \f$ B = \left ( \begin{array}{cc} \text{this}_{pp} & \text{this}_{pq} \\ (\text{this}_{pq})^* & \text{this}_{qq} \end{array} \right )\f$ yields
114
  * a diagonal matrix \f$ A = J^* B J \f$
116
  * a diagonal matrix \f$ A = J^* B J \f$
Lines 147-243 void JacobiRotation<Scalar>::makeGivens( Link Here
147
  makeGivens(p, q, z, typename internal::conditional<NumTraits<Scalar>::IsComplex, internal::true_type, internal::false_type>::type());
149
  makeGivens(p, q, z, typename internal::conditional<NumTraits<Scalar>::IsComplex, internal::true_type, internal::false_type>::type());
148
}
150
}
149
151
150
152
151
// specialization for complexes
153
// specialization for complexes
152
template<typename Scalar>
154
template<typename Scalar>
153
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type)
155
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::true_type)
154
{
156
{
157
  using std::sqrt;
158
  using std::abs;
155
  if(q==Scalar(0))
159
  if(q==Scalar(0))
156
  {
160
  {
157
    m_c = internal::real(p)<0 ? Scalar(-1) : Scalar(1);
161
    m_c = internal::real(p)<0 ? Scalar(-1) : Scalar(1);
158
    m_s = 0;
162
    m_s = 0;
159
    if(r) *r = m_c * p;
163
    if(r) *r = m_c * p;
160
  }
164
  }
161
  else if(p==Scalar(0))
165
  else if(p==Scalar(0))
162
  {
166
  {
163
    m_c = 0;
167
    m_c = 0;
164
    m_s = -q/internal::abs(q);
168
    m_s = -q/abs(q);
165
    if(r) *r = internal::abs(q);
169
    if(r) *r = abs(q);
166
  }
170
  }
167
  else
171
  else
168
  {
172
  {
169
    RealScalar p1 = internal::norm1(p);
173
    RealScalar p1 = internal::norm1(p);
170
    RealScalar q1 = internal::norm1(q);
174
    RealScalar q1 = internal::norm1(q);
171
    if(p1>=q1)
175
    if(p1>=q1)
172
    {
176
    {
173
      Scalar ps = p / p1;
177
      Scalar ps = p / p1;
174
      RealScalar p2 = internal::abs2(ps);
178
      RealScalar p2 = internal::abs2(ps);
175
      Scalar qs = q / p1;
179
      Scalar qs = q / p1;
176
      RealScalar q2 = internal::abs2(qs);
180
      RealScalar q2 = internal::abs2(qs);
177
181
178
      RealScalar u = internal::sqrt(RealScalar(1) + q2/p2);
182
      RealScalar u = sqrt(RealScalar(1) + q2/p2);
179
      if(internal::real(p)<RealScalar(0))
183
      if(internal::real(p)<RealScalar(0))
180
        u = -u;
184
        u = -u;
181
185
182
      m_c = Scalar(1)/u;
186
      m_c = Scalar(1)/u;
183
      m_s = -qs*internal::conj(ps)*(m_c/p2);
187
      m_s = -qs*internal::conj(ps)*(m_c/p2);
184
      if(r) *r = p * u;
188
      if(r) *r = p * u;
185
    }
189
    }
186
    else
190
    else
187
    {
191
    {
188
      Scalar ps = p / q1;
192
      Scalar ps = p / q1;
189
      RealScalar p2 = internal::abs2(ps);
193
      RealScalar p2 = internal::abs2(ps);
190
      Scalar qs = q / q1;
194
      Scalar qs = q / q1;
191
      RealScalar q2 = internal::abs2(qs);
195
      RealScalar q2 = internal::abs2(qs);
192
196
193
      RealScalar u = q1 * internal::sqrt(p2 + q2);
197
      RealScalar u = q1 * sqrt(p2 + q2);
194
      if(internal::real(p)<RealScalar(0))
198
      if(internal::real(p)<RealScalar(0))
195
        u = -u;
199
        u = -u;
196
200
197
      p1 = internal::abs(p);
201
      p1 = abs(p);
198
      ps = p/p1;
202
      ps = p/p1;
199
      m_c = p1/u;
203
      m_c = p1/u;
200
      m_s = -internal::conj(ps) * (q/u);
204
      m_s = -internal::conj(ps) * (q/u);
201
      if(r) *r = ps * u;
205
      if(r) *r = ps * u;
202
    }
206
    }
203
  }
207
  }
204
}
208
}
205
209
206
// specialization for reals
210
// specialization for reals
207
template<typename Scalar>
211
template<typename Scalar>
208
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type)
212
void JacobiRotation<Scalar>::makeGivens(const Scalar& p, const Scalar& q, Scalar* r, internal::false_type)
209
{
213
{
214
  using std::sqrt;
215
  using std::abs;
210
  if(q==Scalar(0))
216
  if(q==Scalar(0))
211
  {
217
  {
212
    m_c = p<Scalar(0) ? Scalar(-1) : Scalar(1);
218
    m_c = p<Scalar(0) ? Scalar(-1) : Scalar(1);
213
    m_s = Scalar(0);
219
    m_s = Scalar(0);
214
    if(r) *r = internal::abs(p);
220
    if(r) *r = abs(p);
215
  }
221
  }
216
  else if(p==Scalar(0))
222
  else if(p==Scalar(0))
217
  {
223
  {
218
    m_c = Scalar(0);
224
    m_c = Scalar(0);
219
    m_s = q<Scalar(0) ? Scalar(1) : Scalar(-1);
225
    m_s = q<Scalar(0) ? Scalar(1) : Scalar(-1);
220
    if(r) *r = internal::abs(q);
226
    if(r) *r = abs(q);
221
  }
227
  }
222
  else if(internal::abs(p) > internal::abs(q))
228
  else if(abs(p) > abs(q))
223
  {
229
  {
224
    Scalar t = q/p;
230
    Scalar t = q/p;
225
    Scalar u = internal::sqrt(Scalar(1) + internal::abs2(t));
231
    Scalar u = sqrt(Scalar(1) + internal::abs2(t));
226
    if(p<Scalar(0))
232
    if(p<Scalar(0))
227
      u = -u;
233
      u = -u;
228
    m_c = Scalar(1)/u;
234
    m_c = Scalar(1)/u;
229
    m_s = -t * m_c;
235
    m_s = -t * m_c;
230
    if(r) *r = p * u;
236
    if(r) *r = p * u;
231
  }
237
  }
232
  else
238
  else
233
  {
239
  {
234
    Scalar t = p/q;
240
    Scalar t = p/q;
235
    Scalar u = internal::sqrt(Scalar(1) + internal::abs2(t));
241
    Scalar u = sqrt(Scalar(1) + internal::abs2(t));
236
    if(q<Scalar(0))
242
    if(q<Scalar(0))
237
      u = -u;
243
      u = -u;
238
    m_s = -Scalar(1)/u;
244
    m_s = -Scalar(1)/u;
239
    m_c = -t * m_s;
245
    m_c = -t * m_s;
240
    if(r) *r = q * u;
246
    if(r) *r = q * u;
241
  }
247
  }
242
248
243
}
249
}
(-)a/Eigen/src/LU/FullPivLU.h (-2 / +5 lines)
Lines 288-308 template<typename _MatrixType> class Ful Link Here
288
    /** \returns the rank of the matrix of which *this is the LU decomposition.
288
    /** \returns the rank of the matrix of which *this is the LU decomposition.
289
      *
289
      *
290
      * \note This method has to determine which pivots should be considered nonzero.
290
      * \note This method has to determine which pivots should be considered nonzero.
291
      *       For that, it uses the threshold value that you can control by calling
291
      *       For that, it uses the threshold value that you can control by calling
292
      *       setThreshold(const RealScalar&).
292
      *       setThreshold(const RealScalar&).
293
      */
293
      */
294
    inline Index rank() const
294
    inline Index rank() const
295
    {
295
    {
296
      using std::abs;
296
      eigen_assert(m_isInitialized && "LU is not initialized.");
297
      eigen_assert(m_isInitialized && "LU is not initialized.");
297
      RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold();
298
      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
298
      Index result = 0;
299
      Index result = 0;
299
      for(Index i = 0; i < m_nonzero_pivots; ++i)
300
      for(Index i = 0; i < m_nonzero_pivots; ++i)
300
        result += (internal::abs(m_lu.coeff(i,i)) > premultiplied_threshold);
301
        result += (abs(m_lu.coeff(i,i)) > premultiplied_threshold);
301
      return result;
302
      return result;
302
    }
303
    }
303
304
304
    /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition.
305
    /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition.
305
      *
306
      *
306
      * \note This method has to determine which pivots should be considered nonzero.
307
      * \note This method has to determine which pivots should be considered nonzero.
307
      *       For that, it uses the threshold value that you can control by calling
308
      *       For that, it uses the threshold value that you can control by calling
308
      *       setThreshold(const RealScalar&).
309
      *       setThreshold(const RealScalar&).
Lines 542-557 struct kernel_retval<FullPivLU<_MatrixTy Link Here
542
543
543
  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
544
  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
544
            MatrixType::MaxColsAtCompileTime,
545
            MatrixType::MaxColsAtCompileTime,
545
            MatrixType::MaxRowsAtCompileTime)
546
            MatrixType::MaxRowsAtCompileTime)
546
  };
547
  };
547
548
548
  template<typename Dest> void evalTo(Dest& dst) const
549
  template<typename Dest> void evalTo(Dest& dst) const
549
  {
550
  {
551
    using std::abs;
550
    const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
552
    const Index cols = dec().matrixLU().cols(), dimker = cols - rank();
551
    if(dimker == 0)
553
    if(dimker == 0)
552
    {
554
    {
553
      // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's
555
      // The Kernel is just {0}, so it doesn't have a basis properly speaking, but let's
554
      // avoid crashing/asserting as that depends on floating point calculations. Let's
556
      // avoid crashing/asserting as that depends on floating point calculations. Let's
555
      // just return a single column vector filled with zeros.
557
      // just return a single column vector filled with zeros.
556
      dst.setZero();
558
      dst.setZero();
557
      return;
559
      return;
Lines 627-642 struct image_retval<FullPivLU<_MatrixTyp Link Here
627
629
628
  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
630
  enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(
629
            MatrixType::MaxColsAtCompileTime,
631
            MatrixType::MaxColsAtCompileTime,
630
            MatrixType::MaxRowsAtCompileTime)
632
            MatrixType::MaxRowsAtCompileTime)
631
  };
633
  };
632
634
633
  template<typename Dest> void evalTo(Dest& dst) const
635
  template<typename Dest> void evalTo(Dest& dst) const
634
  {
636
  {
637
    using std::abs;
635
    if(rank() == 0)
638
    if(rank() == 0)
636
    {
639
    {
637
      // The Image is just {0}, so it doesn't have a basis properly speaking, but let's
640
      // The Image is just {0}, so it doesn't have a basis properly speaking, but let's
638
      // avoid crashing/asserting as that depends on floating point calculations. Let's
641
      // avoid crashing/asserting as that depends on floating point calculations. Let's
639
      // just return a single column vector filled with zeros.
642
      // just return a single column vector filled with zeros.
640
      dst.setZero();
643
      dst.setZero();
641
      return;
644
      return;
642
    }
645
    }
(-)a/Eigen/src/LU/Inverse.h (+4 lines)
Lines 50-65 struct compute_inverse_and_det_with_chec Link Here
50
  static inline void run(
50
  static inline void run(
51
    const MatrixType& matrix,
51
    const MatrixType& matrix,
52
    const typename MatrixType::RealScalar& absDeterminantThreshold,
52
    const typename MatrixType::RealScalar& absDeterminantThreshold,
53
    ResultType& result,
53
    ResultType& result,
54
    typename ResultType::Scalar& determinant,
54
    typename ResultType::Scalar& determinant,
55
    bool& invertible
55
    bool& invertible
56
  )
56
  )
57
  {
57
  {
58
    using std::abs;
58
    determinant = matrix.coeff(0,0);
59
    determinant = matrix.coeff(0,0);
59
    invertible = abs(determinant) > absDeterminantThreshold;
60
    invertible = abs(determinant) > absDeterminantThreshold;
60
    if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant;
61
    if(invertible) result.coeffRef(0,0) = typename ResultType::Scalar(1) / determinant;
61
  }
62
  }
62
};
63
};
63
64
64
/****************************
65
/****************************
65
*** Size 2 implementation ***
66
*** Size 2 implementation ***
Lines 93-108 struct compute_inverse_and_det_with_chec Link Here
93
  static inline void run(
94
  static inline void run(
94
    const MatrixType& matrix,
95
    const MatrixType& matrix,
95
    const typename MatrixType::RealScalar& absDeterminantThreshold,
96
    const typename MatrixType::RealScalar& absDeterminantThreshold,
96
    ResultType& inverse,
97
    ResultType& inverse,
97
    typename ResultType::Scalar& determinant,
98
    typename ResultType::Scalar& determinant,
98
    bool& invertible
99
    bool& invertible
99
  )
100
  )
100
  {
101
  {
102
    using std::abs;
101
    typedef typename ResultType::Scalar Scalar;
103
    typedef typename ResultType::Scalar Scalar;
102
    determinant = matrix.determinant();
104
    determinant = matrix.determinant();
103
    invertible = abs(determinant) > absDeterminantThreshold;
105
    invertible = abs(determinant) > absDeterminantThreshold;
104
    if(!invertible) return;
106
    if(!invertible) return;
105
    const Scalar invdet = Scalar(1) / determinant;
107
    const Scalar invdet = Scalar(1) / determinant;
106
    compute_inverse_size2_helper(matrix, invdet, inverse);
108
    compute_inverse_size2_helper(matrix, invdet, inverse);
107
  }
109
  }
108
};
110
};
Lines 162-177 struct compute_inverse_and_det_with_chec Link Here
162
  static inline void run(
164
  static inline void run(
163
    const MatrixType& matrix,
165
    const MatrixType& matrix,
164
    const typename MatrixType::RealScalar& absDeterminantThreshold,
166
    const typename MatrixType::RealScalar& absDeterminantThreshold,
165
    ResultType& inverse,
167
    ResultType& inverse,
166
    typename ResultType::Scalar& determinant,
168
    typename ResultType::Scalar& determinant,
167
    bool& invertible
169
    bool& invertible
168
  )
170
  )
169
  {
171
  {
172
    using std::abs;
170
    typedef typename ResultType::Scalar Scalar;
173
    typedef typename ResultType::Scalar Scalar;
171
    Matrix<Scalar,3,1> cofactors_col0;
174
    Matrix<Scalar,3,1> cofactors_col0;
172
    cofactors_col0.coeffRef(0) =  cofactor_3x3<MatrixType,0,0>(matrix);
175
    cofactors_col0.coeffRef(0) =  cofactor_3x3<MatrixType,0,0>(matrix);
173
    cofactors_col0.coeffRef(1) =  cofactor_3x3<MatrixType,1,0>(matrix);
176
    cofactors_col0.coeffRef(1) =  cofactor_3x3<MatrixType,1,0>(matrix);
174
    cofactors_col0.coeffRef(2) =  cofactor_3x3<MatrixType,2,0>(matrix);
177
    cofactors_col0.coeffRef(2) =  cofactor_3x3<MatrixType,2,0>(matrix);
175
    determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum();
178
    determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum();
176
    invertible = abs(determinant) > absDeterminantThreshold;
179
    invertible = abs(determinant) > absDeterminantThreshold;
177
    if(!invertible) return;
180
    if(!invertible) return;
Lines 246-261 struct compute_inverse_and_det_with_chec Link Here
246
  static inline void run(
249
  static inline void run(
247
    const MatrixType& matrix,
250
    const MatrixType& matrix,
248
    const typename MatrixType::RealScalar& absDeterminantThreshold,
251
    const typename MatrixType::RealScalar& absDeterminantThreshold,
249
    ResultType& inverse,
252
    ResultType& inverse,
250
    typename ResultType::Scalar& determinant,
253
    typename ResultType::Scalar& determinant,
251
    bool& invertible
254
    bool& invertible
252
  )
255
  )
253
  {
256
  {
257
    using std::abs;
254
    determinant = matrix.determinant();
258
    determinant = matrix.determinant();
255
    invertible = abs(determinant) > absDeterminantThreshold;
259
    invertible = abs(determinant) > absDeterminantThreshold;
256
    if(invertible) compute_inverse<MatrixType, ResultType>::run(matrix, inverse);
260
    if(invertible) compute_inverse<MatrixType, ResultType>::run(matrix, inverse);
257
  }
261
  }
258
};
262
};
259
263
260
/*************************
264
/*************************
261
*** MatrixBase methods ***
265
*** MatrixBase methods ***
(-)a/Eigen/src/QR/ColPivHouseholderQR.h (-4 / +7 lines)
Lines 176-196 template<typename _MatrixType> class Col Link Here
176
    /** \returns the rank of the matrix of which *this is the QR decomposition.
176
    /** \returns the rank of the matrix of which *this is the QR decomposition.
177
      *
177
      *
178
      * \note This method has to determine which pivots should be considered nonzero.
178
      * \note This method has to determine which pivots should be considered nonzero.
179
      *       For that, it uses the threshold value that you can control by calling
179
      *       For that, it uses the threshold value that you can control by calling
180
      *       setThreshold(const RealScalar&).
180
      *       setThreshold(const RealScalar&).
181
      */
181
      */
182
    inline Index rank() const
182
    inline Index rank() const
183
    {
183
    {
184
      using std::abs;
184
      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
185
      eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
185
      RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold();
186
      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
186
      Index result = 0;
187
      Index result = 0;
187
      for(Index i = 0; i < m_nonzero_pivots; ++i)
188
      for(Index i = 0; i < m_nonzero_pivots; ++i)
188
        result += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);
189
        result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);
189
      return result;
190
      return result;
190
    }
191
    }
191
192
192
    /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
193
    /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
193
      *
194
      *
194
      * \note This method has to determine which pivots should be considered nonzero.
195
      * \note This method has to determine which pivots should be considered nonzero.
195
      *       For that, it uses the threshold value that you can control by calling
196
      *       For that, it uses the threshold value that you can control by calling
196
      *       setThreshold(const RealScalar&).
197
      *       setThreshold(const RealScalar&).
Lines 337-368 template<typename _MatrixType> class Col Link Here
337
    RealScalar m_prescribedThreshold, m_maxpivot;
338
    RealScalar m_prescribedThreshold, m_maxpivot;
338
    Index m_nonzero_pivots;
339
    Index m_nonzero_pivots;
339
    Index m_det_pq;
340
    Index m_det_pq;
340
};
341
};
341
342
342
template<typename MatrixType>
343
template<typename MatrixType>
343
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
344
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::absDeterminant() const
344
{
345
{
346
  using std::abs;
345
  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
347
  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
346
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
348
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
347
  return internal::abs(m_qr.diagonal().prod());
349
  return abs(m_qr.diagonal().prod());
348
}
350
}
349
351
350
template<typename MatrixType>
352
template<typename MatrixType>
351
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDeterminant() const
353
typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDeterminant() const
352
{
354
{
353
  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
355
  eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");
354
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
356
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
355
  return m_qr.diagonal().cwiseAbs().array().log().sum();
357
  return m_qr.diagonal().cwiseAbs().array().log().sum();
356
}
358
}
357
359
358
template<typename MatrixType>
360
template<typename MatrixType>
359
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
361
ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
360
{
362
{
363
  using std::abs;
361
  Index rows = matrix.rows();
364
  Index rows = matrix.rows();
362
  Index cols = matrix.cols();
365
  Index cols = matrix.cols();
363
  Index size = matrix.diagonalSize();
366
  Index size = matrix.diagonalSize();
364
367
365
  m_qr = matrix;
368
  m_qr = matrix;
366
  m_hCoeffs.resize(size);
369
  m_hCoeffs.resize(size);
367
370
368
  m_temp.resize(cols);
371
  m_temp.resize(cols);
Lines 421-437 ColPivHouseholderQR<MatrixType>& ColPivH Link Here
421
    // generate the householder vector, store it below the diagonal
424
    // generate the householder vector, store it below the diagonal
422
    RealScalar beta;
425
    RealScalar beta;
423
    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
426
    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
424
427
425
    // apply the householder transformation to the diagonal coefficient
428
    // apply the householder transformation to the diagonal coefficient
426
    m_qr.coeffRef(k,k) = beta;
429
    m_qr.coeffRef(k,k) = beta;
427
430
428
    // remember the maximum absolute value of diagonal coefficients
431
    // remember the maximum absolute value of diagonal coefficients
429
    if(internal::abs(beta) > m_maxpivot) m_maxpivot = internal::abs(beta);
432
    if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);
430
433
431
    // apply the householder transformation
434
    // apply the householder transformation
432
    m_qr.bottomRightCorner(rows-k, cols-k-1)
435
    m_qr.bottomRightCorner(rows-k, cols-k-1)
433
        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
436
        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
434
437
435
    // update our table of squared norms of the columns
438
    // update our table of squared norms of the columns
436
    m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2();
439
    m_colSqNorms.tail(cols-k-1) -= m_qr.row(k).tail(cols-k-1).cwiseAbs2();
437
  }
440
  }
(-)a/Eigen/src/QR/ColPivHouseholderQR_MKL.h (-2 / +3 lines)
Lines 42-57 namespace Eigen { Link Here
42
42
43
#define EIGEN_MKL_QR_COLPIV(EIGTYPE, MKLTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \
43
#define EIGEN_MKL_QR_COLPIV(EIGTYPE, MKLTYPE, MKLPREFIX, EIGCOLROW, MKLCOLROW) \
44
template<> inline \
44
template<> inline \
45
ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >& \
45
ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >& \
46
ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >::compute( \
46
ColPivHouseholderQR<Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> >::compute( \
47
              const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix) \
47
              const Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic>& matrix) \
48
\
48
\
49
{ \
49
{ \
50
  using std::abs; \
50
  typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \
51
  typedef Matrix<EIGTYPE, Dynamic, Dynamic, EIGCOLROW, Dynamic, Dynamic> MatrixType; \
51
  typedef MatrixType::Scalar Scalar; \
52
  typedef MatrixType::Scalar Scalar; \
52
  typedef MatrixType::RealScalar RealScalar; \
53
  typedef MatrixType::RealScalar RealScalar; \
53
  Index rows = matrix.rows();\
54
  Index rows = matrix.rows();\
54
  Index cols = matrix.cols();\
55
  Index cols = matrix.cols();\
55
  Index size = matrix.diagonalSize();\
56
  Index size = matrix.diagonalSize();\
56
\
57
\
57
  m_qr = matrix;\
58
  m_qr = matrix;\
Lines 66-85 ColPivHouseholderQR<Matrix<EIGTYPE, Dyna Link Here
66
  m_colsPermutation.indices().setZero(); \
67
  m_colsPermutation.indices().setZero(); \
67
\
68
\
68
  lapack_int lda = m_qr.outerStride(), i; \
69
  lapack_int lda = m_qr.outerStride(), i; \
69
  lapack_int matrix_order = MKLCOLROW; \
70
  lapack_int matrix_order = MKLCOLROW; \
70
  LAPACKE_##MKLPREFIX##geqp3( matrix_order, rows, cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \
71
  LAPACKE_##MKLPREFIX##geqp3( matrix_order, rows, cols, (MKLTYPE*)m_qr.data(), lda, (lapack_int*)m_colsPermutation.indices().data(), (MKLTYPE*)m_hCoeffs.data()); \
71
  m_isInitialized = true; \
72
  m_isInitialized = true; \
72
  m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \
73
  m_maxpivot=m_qr.diagonal().cwiseAbs().maxCoeff(); \
73
  m_hCoeffs.adjointInPlace(); \
74
  m_hCoeffs.adjointInPlace(); \
74
  RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold(); \
75
  RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold(); \
75
  lapack_int *perm = m_colsPermutation.indices().data(); \
76
  lapack_int *perm = m_colsPermutation.indices().data(); \
76
  for(i=0;i<size;i++) { \
77
  for(i=0;i<size;i++) { \
77
    m_nonzero_pivots += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);\
78
    m_nonzero_pivots += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);\
78
  } \
79
  } \
79
  for(i=0;i<cols;i++) perm[i]--;\
80
  for(i=0;i<cols;i++) perm[i]--;\
80
\
81
\
81
  /*m_det_pq = (number_of_transpositions%2) ? -1 : 1;  // TODO: It's not needed now; fix upon availability in Eigen */ \
82
  /*m_det_pq = (number_of_transpositions%2) ? -1 : 1;  // TODO: It's not needed now; fix upon availability in Eigen */ \
82
\
83
\
83
  return *this; \
84
  return *this; \
84
}
85
}
85
86
(-)a/Eigen/src/QR/FullPivHouseholderQR.h (-4 / +7 lines)
Lines 196-216 template<typename _MatrixType> class Ful Link Here
196
    /** \returns the rank of the matrix of which *this is the QR decomposition.
196
    /** \returns the rank of the matrix of which *this is the QR decomposition.
197
      *
197
      *
198
      * \note This method has to determine which pivots should be considered nonzero.
198
      * \note This method has to determine which pivots should be considered nonzero.
199
      *       For that, it uses the threshold value that you can control by calling
199
      *       For that, it uses the threshold value that you can control by calling
200
      *       setThreshold(const RealScalar&).
200
      *       setThreshold(const RealScalar&).
201
      */
201
      */
202
    inline Index rank() const
202
    inline Index rank() const
203
    {
203
    {
204
      using std::abs;
204
      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
205
      eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
205
      RealScalar premultiplied_threshold = internal::abs(m_maxpivot) * threshold();
206
      RealScalar premultiplied_threshold = abs(m_maxpivot) * threshold();
206
      Index result = 0;
207
      Index result = 0;
207
      for(Index i = 0; i < m_nonzero_pivots; ++i)
208
      for(Index i = 0; i < m_nonzero_pivots; ++i)
208
        result += (internal::abs(m_qr.coeff(i,i)) > premultiplied_threshold);
209
        result += (abs(m_qr.coeff(i,i)) > premultiplied_threshold);
209
      return result;
210
      return result;
210
    }
211
    }
211
212
212
    /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
213
    /** \returns the dimension of the kernel of the matrix of which *this is the QR decomposition.
213
      *
214
      *
214
      * \note This method has to determine which pivots should be considered nonzero.
215
      * \note This method has to determine which pivots should be considered nonzero.
215
      *       For that, it uses the threshold value that you can control by calling
216
      *       For that, it uses the threshold value that you can control by calling
216
      *       setThreshold(const RealScalar&).
217
      *       setThreshold(const RealScalar&).
Lines 357-388 template<typename _MatrixType> class Ful Link Here
357
    Index m_nonzero_pivots;
358
    Index m_nonzero_pivots;
358
    RealScalar m_precision;
359
    RealScalar m_precision;
359
    Index m_det_pq;
360
    Index m_det_pq;
360
};
361
};
361
362
362
template<typename MatrixType>
363
template<typename MatrixType>
363
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
364
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::absDeterminant() const
364
{
365
{
366
  using std::abs;
365
  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
367
  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
366
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
368
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
367
  return internal::abs(m_qr.diagonal().prod());
369
  return abs(m_qr.diagonal().prod());
368
}
370
}
369
371
370
template<typename MatrixType>
372
template<typename MatrixType>
371
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDeterminant() const
373
typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDeterminant() const
372
{
374
{
373
  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
375
  eigen_assert(m_isInitialized && "FullPivHouseholderQR is not initialized.");
374
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
376
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
375
  return m_qr.diagonal().cwiseAbs().array().log().sum();
377
  return m_qr.diagonal().cwiseAbs().array().log().sum();
376
}
378
}
377
379
378
template<typename MatrixType>
380
template<typename MatrixType>
379
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
381
FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix)
380
{
382
{
383
  using std::abs;
381
  Index rows = matrix.rows();
384
  Index rows = matrix.rows();
382
  Index cols = matrix.cols();
385
  Index cols = matrix.cols();
383
  Index size = (std::min)(rows,cols);
386
  Index size = (std::min)(rows,cols);
384
387
385
  m_qr = matrix;
388
  m_qr = matrix;
386
  m_hCoeffs.resize(size);
389
  m_hCoeffs.resize(size);
387
390
388
  m_temp.resize(cols);
391
  m_temp.resize(cols);
Lines 434-450 FullPivHouseholderQR<MatrixType>& FullPi Link Here
434
      ++number_of_transpositions;
437
      ++number_of_transpositions;
435
    }
438
    }
436
439
437
    RealScalar beta;
440
    RealScalar beta;
438
    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
441
    m_qr.col(k).tail(rows-k).makeHouseholderInPlace(m_hCoeffs.coeffRef(k), beta);
439
    m_qr.coeffRef(k,k) = beta;
442
    m_qr.coeffRef(k,k) = beta;
440
443
441
    // remember the maximum absolute value of diagonal coefficients
444
    // remember the maximum absolute value of diagonal coefficients
442
    if(internal::abs(beta) > m_maxpivot) m_maxpivot = internal::abs(beta);
445
    if(abs(beta) > m_maxpivot) m_maxpivot = abs(beta);
443
446
444
    m_qr.bottomRightCorner(rows-k, cols-k-1)
447
    m_qr.bottomRightCorner(rows-k, cols-k-1)
445
        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
448
        .applyHouseholderOnTheLeft(m_qr.col(k).tail(rows-k-1), m_hCoeffs.coeffRef(k), &m_temp.coeffRef(k+1));
446
  }
449
  }
447
450
448
  m_cols_permutation.setIdentity(cols);
451
  m_cols_permutation.setIdentity(cols);
449
  for(Index k = 0; k < size; ++k)
452
  for(Index k = 0; k < size; ++k)
450
    m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k));
453
    m_cols_permutation.applyTranspositionOnTheRight(k, m_cols_transpositions.coeff(k));
(-)a/Eigen/src/QR/HouseholderQR.h (-1 / +2 lines)
Lines 176-194 template<typename _MatrixType> class Hou Link Here
176
    HCoeffsType m_hCoeffs;
176
    HCoeffsType m_hCoeffs;
177
    RowVectorType m_temp;
177
    RowVectorType m_temp;
178
    bool m_isInitialized;
178
    bool m_isInitialized;
179
};
179
};
180
180
181
template<typename MatrixType>
181
template<typename MatrixType>
182
typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
182
typename MatrixType::RealScalar HouseholderQR<MatrixType>::absDeterminant() const
183
{
183
{
184
  using std::abs;
184
  eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
185
  eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
185
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
186
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
186
  return internal::abs(m_qr.diagonal().prod());
187
  return abs(m_qr.diagonal().prod());
187
}
188
}
188
189
189
template<typename MatrixType>
190
template<typename MatrixType>
190
typename MatrixType::RealScalar HouseholderQR<MatrixType>::logAbsDeterminant() const
191
typename MatrixType::RealScalar HouseholderQR<MatrixType>::logAbsDeterminant() const
191
{
192
{
192
  eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
193
  eigen_assert(m_isInitialized && "HouseholderQR is not initialized.");
193
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
194
  eigen_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!");
194
  return m_qr.diagonal().cwiseAbs().array().log().sum();
195
  return m_qr.diagonal().cwiseAbs().array().log().sum();
(-)a/Eigen/src/SVD/JacobiSVD.h (-4 / +7 lines)
Lines 354-369 template<typename MatrixType, int QRPrec Link Here
354
struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
354
struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>
355
{
355
{
356
  typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
356
  typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;
357
  typedef typename MatrixType::Scalar Scalar;
357
  typedef typename MatrixType::Scalar Scalar;
358
  typedef typename MatrixType::RealScalar RealScalar;
358
  typedef typename MatrixType::RealScalar RealScalar;
359
  typedef typename SVD::Index Index;
359
  typedef typename SVD::Index Index;
360
  static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
360
  static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)
361
  {
361
  {
362
    using std::sqrt;
362
    Scalar z;
363
    Scalar z;
363
    JacobiRotation<Scalar> rot;
364
    JacobiRotation<Scalar> rot;
364
    RealScalar n = sqrt(abs2(work_matrix.coeff(p,p)) + abs2(work_matrix.coeff(q,p)));
365
    RealScalar n = sqrt(abs2(work_matrix.coeff(p,p)) + abs2(work_matrix.coeff(q,p)));
365
    if(n==0)
366
    if(n==0)
366
    {
367
    {
367
      z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
368
      z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);
368
      work_matrix.row(p) *= z;
369
      work_matrix.row(p) *= z;
369
      if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
370
      if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);
Lines 393-408 struct svd_precondition_2x2_block_to_be_ Link Here
393
  }
394
  }
394
};
395
};
395
396
396
template<typename MatrixType, typename RealScalar, typename Index>
397
template<typename MatrixType, typename RealScalar, typename Index>
397
void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
398
void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,
398
                            JacobiRotation<RealScalar> *j_left,
399
                            JacobiRotation<RealScalar> *j_left,
399
                            JacobiRotation<RealScalar> *j_right)
400
                            JacobiRotation<RealScalar> *j_right)
400
{
401
{
402
  using std::sqrt;
401
  Matrix<RealScalar,2,2> m;
403
  Matrix<RealScalar,2,2> m;
402
  m << real(matrix.coeff(p,p)), real(matrix.coeff(p,q)),
404
  m << real(matrix.coeff(p,p)), real(matrix.coeff(p,q)),
403
       real(matrix.coeff(q,p)), real(matrix.coeff(q,q));
405
       real(matrix.coeff(q,p)), real(matrix.coeff(q,q));
404
  JacobiRotation<RealScalar> rot1;
406
  JacobiRotation<RealScalar> rot1;
405
  RealScalar t = m.coeff(0,0) + m.coeff(1,1);
407
  RealScalar t = m.coeff(0,0) + m.coeff(1,1);
406
  RealScalar d = m.coeff(1,0) - m.coeff(0,1);
408
  RealScalar d = m.coeff(1,0) - m.coeff(0,1);
407
  if(t == RealScalar(0))
409
  if(t == RealScalar(0))
408
  {
410
  {
Lines 722-737 void JacobiSVD<MatrixType, QRPreconditio Link Here
722
  if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
724
  if(m_cols>m_rows) m_qr_precond_morecols.allocate(*this);
723
  if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
725
  if(m_rows>m_cols) m_qr_precond_morerows.allocate(*this);
724
}
726
}
725
727
726
template<typename MatrixType, int QRPreconditioner>
728
template<typename MatrixType, int QRPreconditioner>
727
JacobiSVD<MatrixType, QRPreconditioner>&
729
JacobiSVD<MatrixType, QRPreconditioner>&
728
JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
730
JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)
729
{
731
{
732
  using std::abs;
730
  allocate(matrix.rows(), matrix.cols(), computationOptions);
733
  allocate(matrix.rows(), matrix.cols(), computationOptions);
731
734
732
  // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
735
  // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,
733
  // only worsening the precision of U and V as we accumulate more rotations
736
  // only worsening the precision of U and V as we accumulate more rotations
734
  const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();
737
  const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();
735
738
736
  // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
739
  // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)
737
  const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits<RealScalar>::denorm_min();
740
  const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits<RealScalar>::denorm_min();
Lines 759-777 JacobiSVD<MatrixType, QRPreconditioner>: Link Here
759
    for(Index p = 1; p < m_diagSize; ++p)
762
    for(Index p = 1; p < m_diagSize; ++p)
760
    {
763
    {
761
      for(Index q = 0; q < p; ++q)
764
      for(Index q = 0; q < p; ++q)
762
      {
765
      {
763
        // if this 2x2 sub-matrix is not diagonal already...
766
        // if this 2x2 sub-matrix is not diagonal already...
764
        // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
767
        // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't
765
        // keep us iterating forever. Similarly, small denormal numbers are considered zero.
768
        // keep us iterating forever. Similarly, small denormal numbers are considered zero.
766
        using std::max;
769
        using std::max;
767
        RealScalar threshold = (max)(considerAsZero, precision * (max)(internal::abs(m_workMatrix.coeff(p,p)),
770
        RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),
768
                                                                       internal::abs(m_workMatrix.coeff(q,q))));
771
                                                                       abs(m_workMatrix.coeff(q,q))));
769
        if((max)(internal::abs(m_workMatrix.coeff(p,q)),internal::abs(m_workMatrix.coeff(q,p))) > threshold)
772
        if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold)
770
        {
773
        {
771
          finished = false;
774
          finished = false;
772
775
773
          // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
776
          // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal
774
          internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
777
          internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);
775
          JacobiRotation<RealScalar> j_left, j_right;
778
          JacobiRotation<RealScalar> j_left, j_right;
776
          internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
779
          internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);
777
780
Lines 785-801 JacobiSVD<MatrixType, QRPreconditioner>: Link Here
785
      }
788
      }
786
    }
789
    }
787
  }
790
  }
788
791
789
  /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/
792
  /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/
790
793
791
  for(Index i = 0; i < m_diagSize; ++i)
794
  for(Index i = 0; i < m_diagSize; ++i)
792
  {
795
  {
793
    RealScalar a = internal::abs(m_workMatrix.coeff(i,i));
796
    RealScalar a = abs(m_workMatrix.coeff(i,i));
794
    m_singularValues.coeffRef(i) = a;
797
    m_singularValues.coeffRef(i) = a;
795
    if(computeU() && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
798
    if(computeU() && (a!=RealScalar(0))) m_matrixU.col(i) *= m_workMatrix.coeff(i,i)/a;
796
  }
799
  }
797
800
798
  /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/
801
  /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/
799
802
800
  m_nonzeroSingularValues = m_diagSize;
803
  m_nonzeroSingularValues = m_diagSize;
801
  for(Index i = 0; i < m_diagSize; i++)
804
  for(Index i = 0; i < m_diagSize; i++)
(-)a/Eigen/src/SparseCholesky/SimplicialCholesky.h (-1 / +3 lines)
Lines 741-756 void SimplicialCholeskyBase<Derived>::an Link Here
741
  m_factorizationIsOk = false;
741
  m_factorizationIsOk = false;
742
}
742
}
743
743
744
744
745
template<typename Derived>
745
template<typename Derived>
746
template<bool DoLDLT>
746
template<bool DoLDLT>
747
void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap)
747
void SimplicialCholeskyBase<Derived>::factorize_preordered(const CholMatrixType& ap)
748
{
748
{
749
  using std::sqrt;
750
  
749
  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
751
  eigen_assert(m_analysisIsOk && "You must first call analyzePattern()");
750
  eigen_assert(ap.rows()==ap.cols());
752
  eigen_assert(ap.rows()==ap.cols());
751
  const Index size = ap.rows();
753
  const Index size = ap.rows();
752
  eigen_assert(m_parent.size()==size);
754
  eigen_assert(m_parent.size()==size);
753
  eigen_assert(m_nonZerosPerCol.size()==size);
755
  eigen_assert(m_nonZerosPerCol.size()==size);
754
756
755
  const Index* Lp = m_matrix.outerIndexPtr();
757
  const Index* Lp = m_matrix.outerIndexPtr();
756
  Index* Li = m_matrix.innerIndexPtr();
758
  Index* Li = m_matrix.innerIndexPtr();
Lines 825-841 void SimplicialCholeskyBase<Derived>::fa Link Here
825
    else
827
    else
826
    {
828
    {
827
      Index p = Lp[k] + m_nonZerosPerCol[k]++;
829
      Index p = Lp[k] + m_nonZerosPerCol[k]++;
828
      Li[p] = k ;                /* store L(k,k) = sqrt (d) in column k */
830
      Li[p] = k ;                /* store L(k,k) = sqrt (d) in column k */
829
      if(d <= RealScalar(0)) {
831
      if(d <= RealScalar(0)) {
830
        ok = false;              /* failure, matrix is not positive definite */
832
        ok = false;              /* failure, matrix is not positive definite */
831
        break;
833
        break;
832
      }
834
      }
833
      Lx[p] = internal::sqrt(d) ;
835
      Lx[p] = sqrt(d) ;
834
    }
836
    }
835
  }
837
  }
836
838
837
  m_info = ok ? Success : NumericalIssue;
839
  m_info = ok ? Success : NumericalIssue;
838
  m_factorizationIsOk = true;
840
  m_factorizationIsOk = true;
839
}
841
}
840
842
841
namespace internal {
843
namespace internal {
(-)a/Eigen/src/SparseCore/AmbiVector.h (-3 / +5 lines)
Lines 286-315 class AmbiVector<_Scalar,_Index>::Iterat Link Here
286
      * \param vec the vector on which we iterate
286
      * \param vec the vector on which we iterate
287
      * \param epsilon the minimal value used to prune zero coefficients.
287
      * \param epsilon the minimal value used to prune zero coefficients.
288
      * In practice, all coefficients having a magnitude smaller than \a epsilon
288
      * In practice, all coefficients having a magnitude smaller than \a epsilon
289
      * are skipped.
289
      * are skipped.
290
      */
290
      */
291
    Iterator(const AmbiVector& vec, RealScalar epsilon = 0)
291
    Iterator(const AmbiVector& vec, RealScalar epsilon = 0)
292
      : m_vector(vec)
292
      : m_vector(vec)
293
    {
293
    {
294
      using std::abs;
294
      m_epsilon = epsilon;
295
      m_epsilon = epsilon;
295
      m_isDense = m_vector.m_mode==IsDense;
296
      m_isDense = m_vector.m_mode==IsDense;
296
      if (m_isDense)
297
      if (m_isDense)
297
      {
298
      {
298
        m_currentEl = 0;   // this is to avoid a compilation warning
299
        m_currentEl = 0;   // this is to avoid a compilation warning
299
        m_cachedValue = 0; // this is to avoid a compilation warning
300
        m_cachedValue = 0; // this is to avoid a compilation warning
300
        m_cachedIndex = m_vector.m_start-1;
301
        m_cachedIndex = m_vector.m_start-1;
301
        ++(*this);
302
        ++(*this);
302
      }
303
      }
303
      else
304
      else
304
      {
305
      {
305
        ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
306
        ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
306
        m_currentEl = m_vector.m_llStart;
307
        m_currentEl = m_vector.m_llStart;
307
        while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<=m_epsilon)
308
        while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<=m_epsilon)
308
          m_currentEl = llElements[m_currentEl].next;
309
          m_currentEl = llElements[m_currentEl].next;
309
        if (m_currentEl<0)
310
        if (m_currentEl<0)
310
        {
311
        {
311
          m_cachedValue = 0; // this is to avoid a compilation warning
312
          m_cachedValue = 0; // this is to avoid a compilation warning
312
          m_cachedIndex = -1;
313
          m_cachedIndex = -1;
313
        }
314
        }
314
        else
315
        else
315
        {
316
        {
Lines 321-352 class AmbiVector<_Scalar,_Index>::Iterat Link Here
321
322
322
    Index index() const { return m_cachedIndex; }
323
    Index index() const { return m_cachedIndex; }
323
    Scalar value() const { return m_cachedValue; }
324
    Scalar value() const { return m_cachedValue; }
324
325
325
    operator bool() const { return m_cachedIndex>=0; }
326
    operator bool() const { return m_cachedIndex>=0; }
326
327
327
    Iterator& operator++()
328
    Iterator& operator++()
328
    {
329
    {
330
      using std::abs;
329
      if (m_isDense)
331
      if (m_isDense)
330
      {
332
      {
331
        do {
333
        do {
332
          ++m_cachedIndex;
334
          ++m_cachedIndex;
333
        } while (m_cachedIndex<m_vector.m_end && internal::abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
335
        } while (m_cachedIndex<m_vector.m_end && abs(m_vector.m_buffer[m_cachedIndex])<m_epsilon);
334
        if (m_cachedIndex<m_vector.m_end)
336
        if (m_cachedIndex<m_vector.m_end)
335
          m_cachedValue = m_vector.m_buffer[m_cachedIndex];
337
          m_cachedValue = m_vector.m_buffer[m_cachedIndex];
336
        else
338
        else
337
          m_cachedIndex=-1;
339
          m_cachedIndex=-1;
338
      }
340
      }
339
      else
341
      else
340
      {
342
      {
341
        ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
343
        ListEl* EIGEN_RESTRICT llElements = reinterpret_cast<ListEl*>(m_vector.m_buffer);
342
        do {
344
        do {
343
          m_currentEl = llElements[m_currentEl].next;
345
          m_currentEl = llElements[m_currentEl].next;
344
        } while (m_currentEl>=0 && internal::abs(llElements[m_currentEl].value)<m_epsilon);
346
        } while (m_currentEl>=0 && abs(llElements[m_currentEl].value)<m_epsilon);
345
        if (m_currentEl<0)
347
        if (m_currentEl<0)
346
        {
348
        {
347
          m_cachedIndex = -1;
349
          m_cachedIndex = -1;
348
        }
350
        }
349
        else
351
        else
350
        {
352
        {
351
          m_cachedIndex = llElements[m_currentEl].index;
353
          m_cachedIndex = llElements[m_currentEl].index;
352
          m_cachedValue = llElements[m_currentEl].value;
354
          m_cachedValue = llElements[m_currentEl].value;
(-)a/Eigen/src/SparseCore/SparseDot.h (-1 / +2 lines)
Lines 81-94 SparseMatrixBase<Derived>::squaredNorm() Link Here
81
{
81
{
82
  return internal::real((*this).cwiseAbs2().sum());
82
  return internal::real((*this).cwiseAbs2().sum());
83
}
83
}
84
84
85
template<typename Derived>
85
template<typename Derived>
86
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
86
inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
87
SparseMatrixBase<Derived>::norm() const
87
SparseMatrixBase<Derived>::norm() const
88
{
88
{
89
  return internal::sqrt(squaredNorm());
89
  using std::sqrt;
90
  return sqrt(squaredNorm());
90
}
91
}
91
92
92
} // end namespace Eigen
93
} // end namespace Eigen
93
94
94
#endif // EIGEN_SPARSE_DOT_H
95
#endif // EIGEN_SPARSE_DOT_H
(-)a/Eigen/src/SparseCore/SparseProduct.h (-1 / +2 lines)
Lines 102-118 class SparseSparseProduct : internal::no Link Here
102
    EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance)
102
    EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance)
103
      : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false)
103
      : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false)
104
    {
104
    {
105
      init();
105
      init();
106
    }
106
    }
107
107
108
    SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) const
108
    SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) const
109
    {
109
    {
110
      return SparseSparseProduct(m_lhs,m_rhs,internal::abs(reference)*epsilon);
110
      using std::abs;
111
      return SparseSparseProduct(m_lhs,m_rhs,abs(reference)*epsilon);
111
    }
112
    }
112
113
113
    template<typename Dest>
114
    template<typename Dest>
114
    void evalTo(Dest& result) const
115
    void evalTo(Dest& result) const
115
    {
116
    {
116
      if(m_conservative)
117
      if(m_conservative)
117
        internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result);
118
        internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result);
118
      else
119
      else
(-)a/blas/level1_impl.h (-8 / +11 lines)
Lines 70-130 int EIGEN_CAT(EIGEN_CAT(i,SCALAR_SUFFIX) Link Here
70
  DenseIndex ret;
70
  DenseIndex ret;
71
  if(*incx==1)  vector(x,*n).cwiseAbs().minCoeff(&ret);
71
  if(*incx==1)  vector(x,*n).cwiseAbs().minCoeff(&ret);
72
  else          vector(x,*n,std::abs(*incx)).cwiseAbs().minCoeff(&ret);
72
  else          vector(x,*n,std::abs(*incx)).cwiseAbs().minCoeff(&ret);
73
  return ret+1;
73
  return ret+1;
74
}
74
}
75
75
76
int EIGEN_BLAS_FUNC(rotg)(RealScalar *pa, RealScalar *pb, RealScalar *pc, RealScalar *ps)
76
int EIGEN_BLAS_FUNC(rotg)(RealScalar *pa, RealScalar *pb, RealScalar *pc, RealScalar *ps)
77
{
77
{
78
  using std::sqrt;
79
  using std::abs;
80
  
78
  Scalar& a = *reinterpret_cast<Scalar*>(pa);
81
  Scalar& a = *reinterpret_cast<Scalar*>(pa);
79
  Scalar& b = *reinterpret_cast<Scalar*>(pb);
82
  Scalar& b = *reinterpret_cast<Scalar*>(pb);
80
  RealScalar* c = pc;
83
  RealScalar* c = pc;
81
  Scalar* s = reinterpret_cast<Scalar*>(ps);
84
  Scalar* s = reinterpret_cast<Scalar*>(ps);
82
85
83
  #if !ISCOMPLEX
86
  #if !ISCOMPLEX
84
  Scalar r,z;
87
  Scalar r,z;
85
  Scalar aa = internal::abs(a);
88
  Scalar aa = abs(a);
86
  Scalar ab = internal::abs(b);
89
  Scalar ab = abs(b);
87
  if((aa+ab)==Scalar(0))
90
  if((aa+ab)==Scalar(0))
88
  {
91
  {
89
    *c = 1;
92
    *c = 1;
90
    *s = 0;
93
    *s = 0;
91
    r = 0;
94
    r = 0;
92
    z = 0;
95
    z = 0;
93
  }
96
  }
94
  else
97
  else
95
  {
98
  {
96
    r = internal::sqrt(a*a + b*b);
99
    r = sqrt(a*a + b*b);
97
    Scalar amax = aa>ab ? a : b;
100
    Scalar amax = aa>ab ? a : b;
98
    r = amax>0 ? r : -r;
101
    r = amax>0 ? r : -r;
99
    *c = a/r;
102
    *c = a/r;
100
    *s = b/r;
103
    *s = b/r;
101
    z = 1;
104
    z = 1;
102
    if (aa > ab) z = *s;
105
    if (aa > ab) z = *s;
103
    if (ab > aa && *c!=RealScalar(0))
106
    if (ab > aa && *c!=RealScalar(0))
104
      z = Scalar(1)/ *c;
107
      z = Scalar(1)/ *c;
105
  }
108
  }
106
  *pa = r;
109
  *pa = r;
107
  *pb = z;
110
  *pb = z;
108
  #else
111
  #else
109
  Scalar alpha;
112
  Scalar alpha;
110
  RealScalar norm,scale;
113
  RealScalar norm,scale;
111
  if(internal::abs(a)==RealScalar(0))
114
  if(abs(a)==RealScalar(0))
112
  {
115
  {
113
    *c = RealScalar(0);
116
    *c = RealScalar(0);
114
    *s = Scalar(1);
117
    *s = Scalar(1);
115
    a = b;
118
    a = b;
116
  }
119
  }
117
  else
120
  else
118
  {
121
  {
119
    scale = internal::abs(a) + internal::abs(b);
122
    scale = abs(a) + abs(b);
120
    norm = scale*internal::sqrt((internal::abs2(a/scale))+ (internal::abs2(b/scale)));
123
    norm = scale*sqrt((internal::abs2(a/scale))+ (internal::abs2(b/scale)));
121
    alpha = a/internal::abs(a);
124
    alpha = a/abs(a);
122
    *c = internal::abs(a)/norm;
125
    *c = abs(a)/norm;
123
    *s = alpha*internal::conj(b)/norm;
126
    *s = alpha*internal::conj(b)/norm;
124
    a = alpha*norm;
127
    a = alpha*norm;
125
  }
128
  }
126
  #endif
129
  #endif
127
130
128
//   JacobiRotation<Scalar> r;
131
//   JacobiRotation<Scalar> r;
129
//   r.makeGivens(a,b);
132
//   r.makeGivens(a,b);
130
//   *c = r.c();
133
//   *c = r.c();
(-)a/cmake/FindUmfpack.cmake (+3 lines)
Lines 11-26 find_path(UMFPACK_INCLUDES Link Here
11
  PATHS
11
  PATHS
12
  $ENV{UMFPACKDIR}
12
  $ENV{UMFPACKDIR}
13
  ${INCLUDE_INSTALL_DIR}
13
  ${INCLUDE_INSTALL_DIR}
14
  PATH_SUFFIXES
14
  PATH_SUFFIXES
15
  suitesparse
15
  suitesparse
16
  ufsparse
16
  ufsparse
17
)
17
)
18
18
19
if(NOT UMFPACK_LIBRARIES)
20
19
find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
21
find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
20
22
21
if(UMFPACK_LIBRARIES)
23
if(UMFPACK_LIBRARIES)
22
  if (NOT UMFPACK_LIBDIR)
24
  if (NOT UMFPACK_LIBDIR)
23
    get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH)
25
    get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH)
24
  endif(NOT UMFPACK_LIBDIR)
26
  endif(NOT UMFPACK_LIBDIR)
25
27
26
  find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
28
  find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})
Lines 38-51 if(UMFPACK_LIBRARIES) Link Here
38
  if (COLAMD_LIBRARY)
40
  if (COLAMD_LIBRARY)
39
    set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY})
41
    set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY})
40
  #else (COLAMD_LIBRARY)
42
  #else (COLAMD_LIBRARY)
41
  #  set(UMFPACK_LIBRARIES FALSE)
43
  #  set(UMFPACK_LIBRARIES FALSE)
42
  endif (COLAMD_LIBRARY)
44
  endif (COLAMD_LIBRARY)
43
45
44
endif(UMFPACK_LIBRARIES)
46
endif(UMFPACK_LIBRARIES)
45
47
48
endif()
46
49
47
include(FindPackageHandleStandardArgs)
50
include(FindPackageHandleStandardArgs)
48
find_package_handle_standard_args(UMFPACK DEFAULT_MSG
51
find_package_handle_standard_args(UMFPACK DEFAULT_MSG
49
                                  UMFPACK_INCLUDES UMFPACK_LIBRARIES)
52
                                  UMFPACK_INCLUDES UMFPACK_LIBRARIES)
50
53
51
mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY)
54
mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY)
(-)a/test/adjoint.cpp (-1 / +1 lines)
Lines 58-74 template<typename MatrixType> void adjoi Link Here
58
    // check normalized() and normalize()
58
    // check normalized() and normalize()
59
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
59
    VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());
60
    v3 = v1;
60
    v3 = v1;
61
    v3.normalize();
61
    v3.normalize();
62
    VERIFY_IS_APPROX(v1, v1.norm() * v3);
62
    VERIFY_IS_APPROX(v1, v1.norm() * v3);
63
    VERIFY_IS_APPROX(v3, v1.normalized());
63
    VERIFY_IS_APPROX(v3, v1.normalized());
64
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
64
    VERIFY_IS_APPROX(v3.norm(), RealScalar(1));
65
  }
65
  }
66
  VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(vzero.dot(v1)),  static_cast<RealScalar>(1));
66
  VERIFY_IS_MUCH_SMALLER_THAN(abs(vzero.dot(v1)),  static_cast<RealScalar>(1));
67
  
67
  
68
  // check compatibility of dot and adjoint
68
  // check compatibility of dot and adjoint
69
  
69
  
70
  ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));
70
  ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));
71
  VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));
71
  VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), ref));
72
72
73
  // like in testBasicStuff, test operator() to check const-qualification
73
  // like in testBasicStuff, test operator() to check const-qualification
74
  Index r = internal::random<Index>(0, rows-1),
74
  Index r = internal::random<Index>(0, rows-1),
(-)a/test/array.cpp (-30 / +30 lines)
Lines 115-131 template<typename ArrayType> void compar Link Here
115
  VERIFY( (m1 == m1(r,c) ).any() );
115
  VERIFY( (m1 == m1(r,c) ).any() );
116
116
117
  // test Select
117
  // test Select
118
  VERIFY_IS_APPROX( (m1<m2).select(m1,m2), m1.cwiseMin(m2) );
118
  VERIFY_IS_APPROX( (m1<m2).select(m1,m2), m1.cwiseMin(m2) );
119
  VERIFY_IS_APPROX( (m1>m2).select(m1,m2), m1.cwiseMax(m2) );
119
  VERIFY_IS_APPROX( (m1>m2).select(m1,m2), m1.cwiseMax(m2) );
120
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
120
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
121
  for (int j=0; j<cols; ++j)
121
  for (int j=0; j<cols; ++j)
122
  for (int i=0; i<rows; ++i)
122
  for (int i=0; i<rows; ++i)
123
    m3(i,j) = internal::abs(m1(i,j))<mid ? 0 : m1(i,j);
123
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
124
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
124
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
125
                        .select(ArrayType::Zero(rows,cols),m1), m3);
125
                        .select(ArrayType::Zero(rows,cols),m1), m3);
126
  // shorter versions:
126
  // shorter versions:
127
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
127
  VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))
128
                        .select(0,m1), m3);
128
                        .select(0,m1), m3);
129
  VERIFY_IS_APPROX( (m1.abs()>=ArrayType::Constant(rows,cols,mid))
129
  VERIFY_IS_APPROX( (m1.abs()>=ArrayType::Constant(rows,cols,mid))
130
                        .select(m1,0), m3);
130
                        .select(m1,0), m3);
131
  // even shorter version:
131
  // even shorter version:
Lines 158-216 template<typename ArrayType> void array_ Link Here
158
158
159
  ArrayType m1 = ArrayType::Random(rows, cols),
159
  ArrayType m1 = ArrayType::Random(rows, cols),
160
             m2 = ArrayType::Random(rows, cols),
160
             m2 = ArrayType::Random(rows, cols),
161
             m3(rows, cols);
161
             m3(rows, cols);
162
162
163
  Scalar  s1 = internal::random<Scalar>();
163
  Scalar  s1 = internal::random<Scalar>();
164
164
165
  // these tests are mostly to check possible compilation issues.
165
  // these tests are mostly to check possible compilation issues.
166
  VERIFY_IS_APPROX(m1.sin(), std::sin(m1));
166
//   VERIFY_IS_APPROX(m1.sin(), std::sin(m1));
167
  VERIFY_IS_APPROX(m1.sin(), internal::sin(m1));
167
  VERIFY_IS_APPROX(m1.sin(), sin(m1));
168
  VERIFY_IS_APPROX(m1.cos(), std::cos(m1));
168
//   VERIFY_IS_APPROX(m1.cos(), std::cos(m1));
169
  VERIFY_IS_APPROX(m1.cos(), internal::cos(m1));
169
  VERIFY_IS_APPROX(m1.cos(), cos(m1));
170
  VERIFY_IS_APPROX(m1.asin(), std::asin(m1));
170
//   VERIFY_IS_APPROX(m1.asin(), std::asin(m1));
171
  VERIFY_IS_APPROX(m1.asin(), internal::asin(m1));
171
  VERIFY_IS_APPROX(m1.asin(), asin(m1));
172
  VERIFY_IS_APPROX(m1.acos(), std::acos(m1));
172
//   VERIFY_IS_APPROX(m1.acos(), std::acos(m1));
173
  VERIFY_IS_APPROX(m1.acos(), internal::acos(m1));
173
  VERIFY_IS_APPROX(m1.acos(), acos(m1));
174
  VERIFY_IS_APPROX(m1.tan(), std::tan(m1));
174
//   VERIFY_IS_APPROX(m1.tan(), std::tan(m1));
175
  VERIFY_IS_APPROX(m1.tan(), internal::tan(m1));
175
  VERIFY_IS_APPROX(m1.tan(), tan(m1));
176
  
176
  
177
  VERIFY_IS_APPROX(internal::cos(m1+RealScalar(3)*m2), internal::cos((m1+RealScalar(3)*m2).eval()));
177
  VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));
178
  VERIFY_IS_APPROX(std::cos(m1+RealScalar(3)*m2), std::cos((m1+RealScalar(3)*m2).eval()));
178
//   VERIFY_IS_APPROX(std::cos(m1+RealScalar(3)*m2), std::cos((m1+RealScalar(3)*m2).eval()));
179
179
180
  VERIFY_IS_APPROX(m1.abs().sqrt(), std::sqrt(std::abs(m1)));
180
//   VERIFY_IS_APPROX(m1.abs().sqrt(), std::sqrt(std::abs(m1)));
181
  VERIFY_IS_APPROX(m1.abs().sqrt(), internal::sqrt(internal::abs(m1)));
181
  VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1)));
182
  VERIFY_IS_APPROX(m1.abs(), internal::sqrt(internal::abs2(m1)));
182
  VERIFY_IS_APPROX(m1.abs(), sqrt(internal::abs2(m1)));
183
183
184
  VERIFY_IS_APPROX(internal::abs2(internal::real(m1)) + internal::abs2(internal::imag(m1)), internal::abs2(m1));
184
  VERIFY_IS_APPROX(internal::abs2(internal::real(m1)) + internal::abs2(internal::imag(m1)), internal::abs2(m1));
185
  VERIFY_IS_APPROX(internal::abs2(std::real(m1)) + internal::abs2(std::imag(m1)), internal::abs2(m1));
185
  VERIFY_IS_APPROX(internal::abs2(real(m1)) + internal::abs2(imag(m1)), internal::abs2(m1));
186
  if(!NumTraits<Scalar>::IsComplex)
186
  if(!NumTraits<Scalar>::IsComplex)
187
    VERIFY_IS_APPROX(internal::real(m1), m1);
187
    VERIFY_IS_APPROX(internal::real(m1), m1);
188
188
189
  VERIFY_IS_APPROX(m1.abs().log(), std::log(std::abs(m1)));
189
  //VERIFY_IS_APPROX(m1.abs().log(), std::log(std::abs(m1)));
190
  VERIFY_IS_APPROX(m1.abs().log(), internal::log(internal::abs(m1)));
190
  VERIFY_IS_APPROX(m1.abs().log(), log(abs(m1)));
191
191
192
  VERIFY_IS_APPROX(m1.exp(), std::exp(m1));
192
//   VERIFY_IS_APPROX(m1.exp(), std::exp(m1));
193
  VERIFY_IS_APPROX(m1.exp() * m2.exp(), std::exp(m1+m2));
193
  VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));
194
  VERIFY_IS_APPROX(m1.exp(), internal::exp(m1));
194
  VERIFY_IS_APPROX(m1.exp(), exp(m1));
195
  VERIFY_IS_APPROX(m1.exp() / m2.exp(), std::exp(m1-m2));
195
  VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());
196
196
197
  VERIFY_IS_APPROX(m1.pow(2), m1.square());
197
  VERIFY_IS_APPROX(m1.pow(2), m1.square());
198
  VERIFY_IS_APPROX(std::pow(m1,2), m1.square());
198
  VERIFY_IS_APPROX(pow(m1,2), m1.square());
199
199
200
  ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2));
200
  ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2));
201
  VERIFY_IS_APPROX(std::pow(m1,exponents), m1.square());
201
  VERIFY_IS_APPROX(Eigen::pow(m1,exponents), m1.square());
202
202
203
  m3 = m1.abs();
203
  m3 = m1.abs();
204
  VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
204
  VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());
205
  VERIFY_IS_APPROX(std::pow(m3,RealScalar(0.5)), m3.sqrt());
205
  VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt());
206
206
207
  // scalar by array division
207
  // scalar by array division
208
  const RealScalar tiny = std::sqrt(std::numeric_limits<RealScalar>::epsilon());
208
  const RealScalar tiny = sqrt(std::numeric_limits<RealScalar>::epsilon());
209
  s1 += Scalar(tiny);
209
  s1 += Scalar(tiny);
210
  m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
210
  m1 += ArrayType::Constant(rows,cols,Scalar(tiny));
211
  VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());
211
  VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());
212
}
212
}
213
213
214
template<typename ArrayType> void array_complex(const ArrayType& m)
214
template<typename ArrayType> void array_complex(const ArrayType& m)
215
{
215
{
216
  typedef typename ArrayType::Index Index;
216
  typedef typename ArrayType::Index Index;
Lines 218-238 template<typename ArrayType> void array_ Link Here
218
  Index rows = m.rows();
218
  Index rows = m.rows();
219
  Index cols = m.cols();
219
  Index cols = m.cols();
220
220
221
  ArrayType m1 = ArrayType::Random(rows, cols),
221
  ArrayType m1 = ArrayType::Random(rows, cols),
222
            m2(rows, cols);
222
            m2(rows, cols);
223
223
224
  for (Index i = 0; i < m.rows(); ++i)
224
  for (Index i = 0; i < m.rows(); ++i)
225
    for (Index j = 0; j < m.cols(); ++j)
225
    for (Index j = 0; j < m.cols(); ++j)
226
      m2(i,j) = std::sqrt(m1(i,j));
226
      m2(i,j) = sqrt(m1(i,j));
227
227
228
  VERIFY_IS_APPROX(m1.sqrt(), m2);
228
  VERIFY_IS_APPROX(m1.sqrt(), m2);
229
  VERIFY_IS_APPROX(m1.sqrt(), std::sqrt(m1));
229
//   VERIFY_IS_APPROX(m1.sqrt(), std::sqrt(m1));
230
  VERIFY_IS_APPROX(m1.sqrt(), internal::sqrt(m1));
230
  VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1));
231
}
231
}
232
232
233
template<typename ArrayType> void min_max(const ArrayType& m)
233
template<typename ArrayType> void min_max(const ArrayType& m)
234
{
234
{
235
  typedef typename ArrayType::Index Index;
235
  typedef typename ArrayType::Index Index;
236
  typedef typename ArrayType::Scalar Scalar;
236
  typedef typename ArrayType::Scalar Scalar;
237
237
238
  Index rows = m.rows();
238
  Index rows = m.rows();
(-)a/test/array_for_matrix.cpp (-2 / +3 lines)
Lines 105-121 template<typename MatrixType> void compa Link Here
105
  VERIFY( (m1.array() == m1(r,c) ).any() );
105
  VERIFY( (m1.array() == m1(r,c) ).any() );
106
106
107
  // test Select
107
  // test Select
108
  VERIFY_IS_APPROX( (m1.array()<m2.array()).select(m1,m2), m1.cwiseMin(m2) );
108
  VERIFY_IS_APPROX( (m1.array()<m2.array()).select(m1,m2), m1.cwiseMin(m2) );
109
  VERIFY_IS_APPROX( (m1.array()>m2.array()).select(m1,m2), m1.cwiseMax(m2) );
109
  VERIFY_IS_APPROX( (m1.array()>m2.array()).select(m1,m2), m1.cwiseMax(m2) );
110
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
110
  Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);
111
  for (int j=0; j<cols; ++j)
111
  for (int j=0; j<cols; ++j)
112
  for (int i=0; i<rows; ++i)
112
  for (int i=0; i<rows; ++i)
113
    m3(i,j) = internal::abs(m1(i,j))<mid ? 0 : m1(i,j);
113
    m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);
114
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
114
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
115
                        .select(MatrixType::Zero(rows,cols),m1), m3);
115
                        .select(MatrixType::Zero(rows,cols),m1), m3);
116
  // shorter versions:
116
  // shorter versions:
117
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
117
  VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())
118
                        .select(0,m1), m3);
118
                        .select(0,m1), m3);
119
  VERIFY_IS_APPROX( (m1.array().abs()>=MatrixType::Constant(rows,cols,mid).array())
119
  VERIFY_IS_APPROX( (m1.array().abs()>=MatrixType::Constant(rows,cols,mid).array())
120
                        .select(m1,0), m3);
120
                        .select(m1,0), m3);
121
  // even shorter version:
121
  // even shorter version:
Lines 128-148 template<typename MatrixType> void compa Link Here
128
128
129
  // TODO allows colwise/rowwise for array
129
  // TODO allows colwise/rowwise for array
130
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().colwise().count(), VectorOfIndices::Constant(cols,rows).transpose());
130
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().colwise().count(), VectorOfIndices::Constant(cols,rows).transpose());
131
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().rowwise().count(), VectorOfIndices::Constant(rows, cols));
131
  VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().rowwise().count(), VectorOfIndices::Constant(rows, cols));
132
}
132
}
133
133
134
template<typename VectorType> void lpNorm(const VectorType& v)
134
template<typename VectorType> void lpNorm(const VectorType& v)
135
{
135
{
136
  using std::sqrt;
136
  VectorType u = VectorType::Random(v.size());
137
  VectorType u = VectorType::Random(v.size());
137
138
138
  VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
139
  VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());
139
  VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
140
  VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());
140
  VERIFY_IS_APPROX(u.template lpNorm<2>(), internal::sqrt(u.array().abs().square().sum()));
141
  VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));
141
  VERIFY_IS_APPROX(internal::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
142
  VERIFY_IS_APPROX(internal::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());
142
}
143
}
143
144
144
template<typename MatrixType> void cwise_min_max(const MatrixType& m)
145
template<typename MatrixType> void cwise_min_max(const MatrixType& m)
145
{
146
{
146
  typedef typename MatrixType::Index Index;
147
  typedef typename MatrixType::Index Index;
147
  typedef typename MatrixType::Scalar Scalar;
148
  typedef typename MatrixType::Scalar Scalar;
148
149
(-)a/test/geo_alignedbox.cpp (-1 / +1 lines)
Lines 104-120 void specificTest1() Link Here
104
    Vector2f sides = M-m;
104
    Vector2f sides = M-m;
105
    VERIFY_IS_APPROX(sides, box.sizes() );
105
    VERIFY_IS_APPROX(sides, box.sizes() );
106
    VERIFY_IS_APPROX(sides[1], box.sizes()[1] );
106
    VERIFY_IS_APPROX(sides[1], box.sizes()[1] );
107
    VERIFY_IS_APPROX(sides[1], box.sizes().maxCoeff() );
107
    VERIFY_IS_APPROX(sides[1], box.sizes().maxCoeff() );
108
    VERIFY_IS_APPROX(sides[0], box.sizes().minCoeff() );
108
    VERIFY_IS_APPROX(sides[0], box.sizes().minCoeff() );
109
109
110
    VERIFY_IS_APPROX( 14.0f, box.volume() );
110
    VERIFY_IS_APPROX( 14.0f, box.volume() );
111
    VERIFY_IS_APPROX( 53.0f, box.diagonal().squaredNorm() );
111
    VERIFY_IS_APPROX( 53.0f, box.diagonal().squaredNorm() );
112
    VERIFY_IS_APPROX( internal::sqrt( 53.0f ), box.diagonal().norm() );
112
    VERIFY_IS_APPROX( std::sqrt( 53.0f ), box.diagonal().norm() );
113
113
114
    VERIFY_IS_APPROX( m, box.corner( BoxType::BottomLeft ) );
114
    VERIFY_IS_APPROX( m, box.corner( BoxType::BottomLeft ) );
115
    VERIFY_IS_APPROX( M, box.corner( BoxType::TopRight ) );
115
    VERIFY_IS_APPROX( M, box.corner( BoxType::TopRight ) );
116
    Vector2f bottomRight; bottomRight << M[0], m[1];
116
    Vector2f bottomRight; bottomRight << M[0], m[1];
117
    Vector2f topLeft; topLeft << m[0], M[1];
117
    Vector2f topLeft; topLeft << m[0], M[1];
118
    VERIFY_IS_APPROX( bottomRight, box.corner( BoxType::BottomRight ) );
118
    VERIFY_IS_APPROX( bottomRight, box.corner( BoxType::BottomRight ) );
119
    VERIFY_IS_APPROX( topLeft, box.corner( BoxType::TopLeft ) );
119
    VERIFY_IS_APPROX( topLeft, box.corner( BoxType::TopLeft ) );
120
}
120
}
(-)a/test/geo_hyperplane.cpp (-1 / +1 lines)
Lines 85-101 template<typename Scalar> void lines() Link Here
85
  typedef Matrix<Scalar,3,1> CoeffsType;
85
  typedef Matrix<Scalar,3,1> CoeffsType;
86
86
87
  for(int i = 0; i < 10; i++)
87
  for(int i = 0; i < 10; i++)
88
  {
88
  {
89
    Vector center = Vector::Random();
89
    Vector center = Vector::Random();
90
    Vector u = Vector::Random();
90
    Vector u = Vector::Random();
91
    Vector v = Vector::Random();
91
    Vector v = Vector::Random();
92
    Scalar a = internal::random<Scalar>();
92
    Scalar a = internal::random<Scalar>();
93
    while (internal::abs(a-1) < 1e-4) a = internal::random<Scalar>();
93
    while (abs(a-1) < 1e-4) a = internal::random<Scalar>();
94
    while (u.norm() < 1e-4) u = Vector::Random();
94
    while (u.norm() < 1e-4) u = Vector::Random();
95
    while (v.norm() < 1e-4) v = Vector::Random();
95
    while (v.norm() < 1e-4) v = Vector::Random();
96
96
97
    HLine line_u = HLine::Through(center + u, center + a*u);
97
    HLine line_u = HLine::Through(center + u, center + a*u);
98
    HLine line_v = HLine::Through(center + v, center + a*v);
98
    HLine line_v = HLine::Through(center + v, center + a*v);
99
99
100
    // the line equations should be normalized so that a^2+b^2=1
100
    // the line equations should be normalized so that a^2+b^2=1
101
    VERIFY_IS_APPROX(line_u.normal().norm(), Scalar(1));
101
    VERIFY_IS_APPROX(line_u.normal().norm(), Scalar(1));
(-)a/test/geo_parametrizedline.cpp (-1 / +1 lines)
Lines 30-46 template<typename LineType> void paramet Link Here
30
  VectorType p0 = VectorType::Random(dim);
30
  VectorType p0 = VectorType::Random(dim);
31
  VectorType p1 = VectorType::Random(dim);
31
  VectorType p1 = VectorType::Random(dim);
32
32
33
  VectorType d0 = VectorType::Random(dim).normalized();
33
  VectorType d0 = VectorType::Random(dim).normalized();
34
34
35
  LineType l0(p0, d0);
35
  LineType l0(p0, d0);
36
36
37
  Scalar s0 = internal::random<Scalar>();
37
  Scalar s0 = internal::random<Scalar>();
38
  Scalar s1 = internal::abs(internal::random<Scalar>());
38
  Scalar s1 = abs(internal::random<Scalar>());
39
39
40
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0), RealScalar(1) );
40
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0), RealScalar(1) );
41
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0+s0*d0), RealScalar(1) );
41
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0+s0*d0), RealScalar(1) );
42
  VERIFY_IS_APPROX( (l0.projection(p1)-p1).norm(), l0.distance(p1) );
42
  VERIFY_IS_APPROX( (l0.projection(p1)-p1).norm(), l0.distance(p1) );
43
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(l0.projection(p1)), RealScalar(1) );
43
  VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(l0.projection(p1)), RealScalar(1) );
44
  VERIFY_IS_APPROX( Scalar(l0.distance((p0+s0*d0) + d0.unitOrthogonal() * s1)), s1 );
44
  VERIFY_IS_APPROX( Scalar(l0.distance((p0+s0*d0) + d0.unitOrthogonal() * s1)), s1 );
45
45
46
  // casting
46
  // casting
(-)a/test/geo_quaternion.cpp (-5 / +5 lines)
Lines 31-49 template<typename QuatType> void check_s Link Here
31
31
32
  Scalar theta_tot = AA(q1*q0.inverse()).angle();
32
  Scalar theta_tot = AA(q1*q0.inverse()).angle();
33
  if(theta_tot>M_PI)
33
  if(theta_tot>M_PI)
34
    theta_tot = 2.*M_PI-theta_tot;
34
    theta_tot = 2.*M_PI-theta_tot;
35
  for(Scalar t=0; t<=1.001; t+=0.1)
35
  for(Scalar t=0; t<=1.001; t+=0.1)
36
  {
36
  {
37
    QuatType q = q0.slerp(t,q1);
37
    QuatType q = q0.slerp(t,q1);
38
    Scalar theta = AA(q*q0.inverse()).angle();
38
    Scalar theta = AA(q*q0.inverse()).angle();
39
    VERIFY(internal::abs(q.norm() - 1) < largeEps);
39
    VERIFY(abs(q.norm() - 1) < largeEps);
40
    if(theta_tot==0)  VERIFY(theta_tot==0);
40
    if(theta_tot==0)  VERIFY(theta_tot==0);
41
    else              VERIFY(internal::abs(theta/theta_tot - t) < largeEps);
41
    else              VERIFY(abs(theta/theta_tot - t) < largeEps);
42
  }
42
  }
43
}
43
}
44
44
45
template<typename Scalar, int Options> void quaternion(void)
45
template<typename Scalar, int Options> void quaternion(void)
46
{
46
{
47
  /* this test covers the following files:
47
  /* this test covers the following files:
48
     Quaternion.h
48
     Quaternion.h
49
  */
49
  */
Lines 77-99 template<typename Scalar, int Options> v Link Here
77
77
78
  // concatenation
78
  // concatenation
79
  q1 *= q2;
79
  q1 *= q2;
80
80
81
  q1 = AngleAxisx(a, v0.normalized());
81
  q1 = AngleAxisx(a, v0.normalized());
82
  q2 = AngleAxisx(a, v1.normalized());
82
  q2 = AngleAxisx(a, v1.normalized());
83
83
84
  // angular distance
84
  // angular distance
85
  Scalar refangle = internal::abs(AngleAxisx(q1.inverse()*q2).angle());
85
  Scalar refangle = abs(AngleAxisx(q1.inverse()*q2).angle());
86
  if (refangle>Scalar(M_PI))
86
  if (refangle>Scalar(M_PI))
87
    refangle = Scalar(2)*Scalar(M_PI) - refangle;
87
    refangle = Scalar(2)*Scalar(M_PI) - refangle;
88
88
89
  if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)
89
  if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)
90
  {
90
  {
91
    VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(q1.angularDistance(q2) - refangle), Scalar(1));
91
    VERIFY_IS_MUCH_SMALLER_THAN(abs(q1.angularDistance(q2) - refangle), Scalar(1));
92
  }
92
  }
93
93
94
  // rotation matrix conversion
94
  // rotation matrix conversion
95
  VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);
95
  VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);
96
  VERIFY_IS_APPROX(q1 * q2 * v2,
96
  VERIFY_IS_APPROX(q1 * q2 * v2,
97
    q1.toRotationMatrix() * q2.toRotationMatrix() * v2);
97
    q1.toRotationMatrix() * q2.toRotationMatrix() * v2);
98
98
99
  VERIFY(  (q2*q1).isApprox(q1*q2, largeEps)
99
  VERIFY(  (q2*q1).isApprox(q1*q2, largeEps)
Lines 104-120 template<typename Scalar, int Options> v Link Here
104
104
105
105
106
  // angle-axis conversion
106
  // angle-axis conversion
107
  AngleAxisx aa = AngleAxisx(q1);
107
  AngleAxisx aa = AngleAxisx(q1);
108
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
108
  VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
109
109
110
  // Do not execute the test if the rotation angle is almost zero, or
110
  // Do not execute the test if the rotation angle is almost zero, or
111
  // the rotation axis and v1 are almost parallel.
111
  // the rotation axis and v1 are almost parallel.
112
  if (internal::abs(aa.angle()) > 5*test_precision<Scalar>()
112
  if (abs(aa.angle()) > 5*test_precision<Scalar>()
113
      && (aa.axis() - v1.normalized()).norm() < 1.99
113
      && (aa.axis() - v1.normalized()).norm() < 1.99
114
      && (aa.axis() + v1.normalized()).norm() < 1.99) 
114
      && (aa.axis() + v1.normalized()).norm() < 1.99) 
115
  {
115
  {
116
    VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
116
    VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);
117
  }
117
  }
118
118
119
  // from two vector creation
119
  // from two vector creation
120
  VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());
120
  VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());
(-)a/test/geo_transformations.cpp (-3 / +4 lines)
Lines 83-98 template<typename Scalar, int Mode, int Link Here
83
  VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1);
83
  VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1);
84
}
84
}
85
85
86
template<typename Scalar, int Mode, int Options> void transformations()
86
template<typename Scalar, int Mode, int Options> void transformations()
87
{
87
{
88
  /* this test covers the following files:
88
  /* this test covers the following files:
89
     Cross.h Quaternion.h, Transform.cpp
89
     Cross.h Quaternion.h, Transform.cpp
90
  */
90
  */
91
  using std::cos;
91
  typedef Matrix<Scalar,2,2> Matrix2;
92
  typedef Matrix<Scalar,2,2> Matrix2;
92
  typedef Matrix<Scalar,3,3> Matrix3;
93
  typedef Matrix<Scalar,3,3> Matrix3;
93
  typedef Matrix<Scalar,4,4> Matrix4;
94
  typedef Matrix<Scalar,4,4> Matrix4;
94
  typedef Matrix<Scalar,2,1> Vector2;
95
  typedef Matrix<Scalar,2,1> Vector2;
95
  typedef Matrix<Scalar,3,1> Vector3;
96
  typedef Matrix<Scalar,3,1> Vector3;
96
  typedef Matrix<Scalar,4,1> Vector4;
97
  typedef Matrix<Scalar,4,1> Vector4;
97
  typedef Quaternion<Scalar> Quaternionx;
98
  typedef Quaternion<Scalar> Quaternionx;
98
  typedef AngleAxis<Scalar> AngleAxisx;
99
  typedef AngleAxis<Scalar> AngleAxisx;
Lines 110-126 template<typename Scalar, int Mode, int Link Here
110
          v1 = Vector3::Random();
111
          v1 = Vector3::Random();
111
  Matrix3 matrot1, m;
112
  Matrix3 matrot1, m;
112
113
113
  Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
114
  Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
114
  Scalar s0 = internal::random<Scalar>();
115
  Scalar s0 = internal::random<Scalar>();
115
116
116
  VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);
117
  VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);
117
  VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);
118
  VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);
118
  VERIFY_IS_APPROX(internal::cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));
119
  VERIFY_IS_APPROX(cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));
119
  m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();
120
  m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();
120
  VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));
121
  VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));
121
  VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m);
122
  VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m);
122
123
123
  Quaternionx q1, q2;
124
  Quaternionx q1, q2;
124
  q1 = AngleAxisx(a, v0.normalized());
125
  q1 = AngleAxisx(a, v0.normalized());
125
  q2 = AngleAxisx(a, v1.normalized());
126
  q2 = AngleAxisx(a, v1.normalized());
126
127
Lines 150-166 template<typename Scalar, int Mode, int Link Here
150
  m = q1.toRotationMatrix();
151
  m = q1.toRotationMatrix();
151
  aa1 = m;
152
  aa1 = m;
152
  VERIFY_IS_APPROX(AngleAxisx(m).toRotationMatrix(),
153
  VERIFY_IS_APPROX(AngleAxisx(m).toRotationMatrix(),
153
    Quaternionx(m).toRotationMatrix());
154
    Quaternionx(m).toRotationMatrix());
154
155
155
  // Transform
156
  // Transform
156
  // TODO complete the tests !
157
  // TODO complete the tests !
157
  a = 0;
158
  a = 0;
158
  while (internal::abs(a)<Scalar(0.1))
159
  while (abs(a)<Scalar(0.1))
159
    a = internal::random<Scalar>(-Scalar(0.4)*Scalar(M_PI), Scalar(0.4)*Scalar(M_PI));
160
    a = internal::random<Scalar>(-Scalar(0.4)*Scalar(M_PI), Scalar(0.4)*Scalar(M_PI));
160
  q1 = AngleAxisx(a, v0.normalized());
161
  q1 = AngleAxisx(a, v0.normalized());
161
  Transform3 t0, t1, t2;
162
  Transform3 t0, t1, t2;
162
163
163
  // first test setIdentity() and Identity()
164
  // first test setIdentity() and Identity()
164
  t0.setIdentity();
165
  t0.setIdentity();
165
  VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
166
  VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());
166
  t0.matrix().setZero();
167
  t0.matrix().setZero();
Lines 244-260 template<typename Scalar, int Mode, int Link Here
244
  t5 = t5*t5;
245
  t5 = t5*t5;
245
  VERIFY_IS_APPROX(t5, t4*t4);
246
  VERIFY_IS_APPROX(t5, t4*t4);
246
247
247
  // 2D transformation
248
  // 2D transformation
248
  Transform2 t20, t21;
249
  Transform2 t20, t21;
249
  Vector2 v20 = Vector2::Random();
250
  Vector2 v20 = Vector2::Random();
250
  Vector2 v21 = Vector2::Random();
251
  Vector2 v21 = Vector2::Random();
251
  for (int k=0; k<2; ++k)
252
  for (int k=0; k<2; ++k)
252
    if (internal::abs(v21[k])<Scalar(1e-3)) v21[k] = Scalar(1e-3);
253
    if (abs(v21[k])<Scalar(1e-3)) v21[k] = Scalar(1e-3);
253
  t21.setIdentity();
254
  t21.setIdentity();
254
  t21.linear() = Rotation2D<Scalar>(a).toRotationMatrix();
255
  t21.linear() = Rotation2D<Scalar>(a).toRotationMatrix();
255
  VERIFY_IS_APPROX(t20.fromPositionOrientationScale(v20,a,v21).matrix(),
256
  VERIFY_IS_APPROX(t20.fromPositionOrientationScale(v20,a,v21).matrix(),
256
    t21.pretranslate(v20).scale(v21).matrix());
257
    t21.pretranslate(v20).scale(v21).matrix());
257
258
258
  t21.setIdentity();
259
  t21.setIdentity();
259
  t21.linear() = Rotation2D<Scalar>(-a).toRotationMatrix();
260
  t21.linear() = Rotation2D<Scalar>(-a).toRotationMatrix();
260
  VERIFY( (t20.fromPositionOrientationScale(v20,a,v21)
261
  VERIFY( (t20.fromPositionOrientationScale(v20,a,v21)
(-)a/test/inverse.cpp (-1 / +1 lines)
Lines 58-74 template<typename MatrixType> void inver Link Here
58
  VERIFY(invertible);
58
  VERIFY(invertible);
59
  VERIFY_IS_APPROX(identity, m1*m2);
59
  VERIFY_IS_APPROX(identity, m1*m2);
60
60
61
  //Second: a rank one matrix (not invertible, except for 1x1 matrices)
61
  //Second: a rank one matrix (not invertible, except for 1x1 matrices)
62
  VectorType v3 = VectorType::Random(rows);
62
  VectorType v3 = VectorType::Random(rows);
63
  MatrixType m3 = v3*v3.transpose(), m4(rows,cols);
63
  MatrixType m3 = v3*v3.transpose(), m4(rows,cols);
64
  m3.computeInverseAndDetWithCheck(m4, det, invertible);
64
  m3.computeInverseAndDetWithCheck(m4, det, invertible);
65
  VERIFY( rows==1 ? invertible : !invertible );
65
  VERIFY( rows==1 ? invertible : !invertible );
66
  VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(det-m3.determinant()), RealScalar(1));
66
  VERIFY_IS_MUCH_SMALLER_THAN(abs(det-m3.determinant()), RealScalar(1));
67
  m3.computeInverseWithCheck(m4, invertible);
67
  m3.computeInverseWithCheck(m4, invertible);
68
  VERIFY( rows==1 ? invertible : !invertible );
68
  VERIFY( rows==1 ? invertible : !invertible );
69
#endif
69
#endif
70
70
71
  // check in-place inversion
71
  // check in-place inversion
72
  if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4)
72
  if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4)
73
  {
73
  {
74
    // in-place is forbidden
74
    // in-place is forbidden
(-)a/test/linearstructure.cpp (-1 / +1 lines)
Lines 22-38 template<typename MatrixType> void linea Link Here
22
22
23
  // this test relies a lot on Random.h, and there's not much more that we can do
23
  // this test relies a lot on Random.h, and there's not much more that we can do
24
  // to test it, hence I consider that we will have tested Random.h
24
  // to test it, hence I consider that we will have tested Random.h
25
  MatrixType m1 = MatrixType::Random(rows, cols),
25
  MatrixType m1 = MatrixType::Random(rows, cols),
26
             m2 = MatrixType::Random(rows, cols),
26
             m2 = MatrixType::Random(rows, cols),
27
             m3(rows, cols);
27
             m3(rows, cols);
28
28
29
  Scalar s1 = internal::random<Scalar>();
29
  Scalar s1 = internal::random<Scalar>();
30
  while (internal::abs(s1)<1e-3) s1 = internal::random<Scalar>();
30
  while (abs(s1)<1e-3) s1 = internal::random<Scalar>();
31
31
32
  Index r = internal::random<Index>(0, rows-1),
32
  Index r = internal::random<Index>(0, rows-1),
33
        c = internal::random<Index>(0, cols-1);
33
        c = internal::random<Index>(0, cols-1);
34
34
35
  VERIFY_IS_APPROX(-(-m1),                  m1);
35
  VERIFY_IS_APPROX(-(-m1),                  m1);
36
  VERIFY_IS_APPROX(m1+m1,                   2*m1);
36
  VERIFY_IS_APPROX(m1+m1,                   2*m1);
37
  VERIFY_IS_APPROX(m1+m2-m1,                m2);
37
  VERIFY_IS_APPROX(m1+m2-m1,                m2);
38
  VERIFY_IS_APPROX(-m2+m1+m2,               m1);
38
  VERIFY_IS_APPROX(-m2+m1+m2,               m1);
(-)a/test/main.h (+2 lines)
Lines 378-393 template<> std::string type_name<int>() Link Here
378
template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }
378
template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }
379
template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }
379
template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }
380
template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }
380
template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }
381
381
382
// forward declaration of the main test function
382
// forward declaration of the main test function
383
void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
383
void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();
384
384
385
using namespace Eigen;
385
using namespace Eigen;
386
using std::abs;
387
using std::sqrt;
386
388
387
void set_repeat_from_string(const char *str)
389
void set_repeat_from_string(const char *str)
388
{
390
{
389
  errno = 0;
391
  errno = 0;
390
  g_repeat = int(strtoul(str, 0, 10));
392
  g_repeat = int(strtoul(str, 0, 10));
391
  if(errno || g_repeat <= 0)
393
  if(errno || g_repeat <= 0)
392
  {
394
  {
393
    std::cout << "Invalid repeat value " << str << std::endl;
395
    std::cout << "Invalid repeat value " << str << std::endl;
(-)a/test/meta.cpp (-1 / +1 lines)
Lines 51-67 void test_meta() Link Here
51
  
51
  
52
  VERIFY(( internal::is_same<float,internal::remove_reference<float&>::type >::value));
52
  VERIFY(( internal::is_same<float,internal::remove_reference<float&>::type >::value));
53
  VERIFY(( internal::is_same<const float,internal::remove_reference<const float&>::type >::value));
53
  VERIFY(( internal::is_same<const float,internal::remove_reference<const float&>::type >::value));
54
  VERIFY(( internal::is_same<float,internal::remove_pointer<float*>::type >::value));
54
  VERIFY(( internal::is_same<float,internal::remove_pointer<float*>::type >::value));
55
  VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));
55
  VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));
56
  VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));
56
  VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));
57
  
57
  
58
  VERIFY(internal::meta_sqrt<1>::ret == 1);
58
  VERIFY(internal::meta_sqrt<1>::ret == 1);
59
  #define VERIFY_META_SQRT(X) VERIFY(internal::meta_sqrt<X>::ret == int(internal::sqrt(double(X))))
59
  #define VERIFY_META_SQRT(X) VERIFY(internal::meta_sqrt<X>::ret == int(std::sqrt(double(X))))
60
  VERIFY_META_SQRT(2);
60
  VERIFY_META_SQRT(2);
61
  VERIFY_META_SQRT(3);
61
  VERIFY_META_SQRT(3);
62
  VERIFY_META_SQRT(4);
62
  VERIFY_META_SQRT(4);
63
  VERIFY_META_SQRT(5);
63
  VERIFY_META_SQRT(5);
64
  VERIFY_META_SQRT(6);
64
  VERIFY_META_SQRT(6);
65
  VERIFY_META_SQRT(8);
65
  VERIFY_META_SQRT(8);
66
  VERIFY_META_SQRT(9);
66
  VERIFY_META_SQRT(9);
67
  VERIFY_META_SQRT(15);
67
  VERIFY_META_SQRT(15);
(-)a/test/packetmath.cpp (-10 / +10 lines)
Lines 108-124 template<typename Scalar> void packetmat Link Here
108
  EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];
108
  EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];
109
  EIGEN_ALIGN16 Packet packets[PacketSize*2];
109
  EIGEN_ALIGN16 Packet packets[PacketSize*2];
110
  EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];
110
  EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];
111
  RealScalar refvalue = 0;
111
  RealScalar refvalue = 0;
112
  for (int i=0; i<size; ++i)
112
  for (int i=0; i<size; ++i)
113
  {
113
  {
114
    data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);
114
    data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);
115
    data2[i] = internal::random<Scalar>()/RealScalar(PacketSize);
115
    data2[i] = internal::random<Scalar>()/RealScalar(PacketSize);
116
    refvalue = (std::max)(refvalue,internal::abs(data1[i]));
116
    refvalue = (std::max)(refvalue,abs(data1[i]));
117
  }
117
  }
118
118
119
  internal::pstore(data2, internal::pload<Packet>(data1));
119
  internal::pstore(data2, internal::pload<Packet>(data1));
120
  VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");
120
  VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");
121
121
122
  for (int offset=0; offset<PacketSize; ++offset)
122
  for (int offset=0; offset<PacketSize; ++offset)
123
  {
123
  {
124
    internal::pstore(data2, internal::ploadu<Packet>(data1+offset));
124
    internal::pstore(data2, internal::ploadu<Packet>(data1+offset));
Lines 215-265 template<typename Scalar> void packetmat Link Here
215
  EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];
215
  EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];
216
  EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];
216
  EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];
217
217
218
  for (int i=0; i<size; ++i)
218
  for (int i=0; i<size; ++i)
219
  {
219
  {
220
    data1[i] = internal::random<Scalar>(-1e3,1e3);
220
    data1[i] = internal::random<Scalar>(-1e3,1e3);
221
    data2[i] = internal::random<Scalar>(-1e3,1e3);
221
    data2[i] = internal::random<Scalar>(-1e3,1e3);
222
  }
222
  }
223
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSin, internal::sin, internal::psin);
223
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSin, std::sin, internal::psin);
224
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasCos, internal::cos, internal::pcos);
224
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasCos, std::cos, internal::pcos);
225
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasTan, internal::tan, internal::ptan);
225
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasTan, std::tan, internal::ptan);
226
  
226
  
227
  for (int i=0; i<size; ++i)
227
  for (int i=0; i<size; ++i)
228
  {
228
  {
229
    data1[i] = internal::random<Scalar>(-1,1);
229
    data1[i] = internal::random<Scalar>(-1,1);
230
    data2[i] = internal::random<Scalar>(-1,1);
230
    data2[i] = internal::random<Scalar>(-1,1);
231
  }
231
  }
232
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasASin, internal::asin, internal::pasin);
232
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasASin, std::asin, internal::pasin);
233
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasACos, internal::acos, internal::pacos);
233
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasACos, std::acos, internal::pacos);
234
234
235
  for (int i=0; i<size; ++i)
235
  for (int i=0; i<size; ++i)
236
  {
236
  {
237
    data1[i] = internal::random<Scalar>(-87,88);
237
    data1[i] = internal::random<Scalar>(-87,88);
238
    data2[i] = internal::random<Scalar>(-87,88);
238
    data2[i] = internal::random<Scalar>(-87,88);
239
  }
239
  }
240
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasExp, internal::exp, internal::pexp);
240
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasExp, std::exp, internal::pexp);
241
241
242
  for (int i=0; i<size; ++i)
242
  for (int i=0; i<size; ++i)
243
  {
243
  {
244
    data1[i] = internal::random<Scalar>(0,1e6);
244
    data1[i] = internal::random<Scalar>(0,1e6);
245
    data2[i] = internal::random<Scalar>(0,1e6);
245
    data2[i] = internal::random<Scalar>(0,1e6);
246
  }
246
  }
247
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasLog, internal::log, internal::plog);
247
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasLog, std::log, internal::plog);
248
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSqrt, internal::sqrt, internal::psqrt);
248
  CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSqrt, std::sqrt, internal::psqrt);
249
249
250
  ref[0] = data1[0];
250
  ref[0] = data1[0];
251
  for (int i=0; i<PacketSize; ++i)
251
  for (int i=0; i<PacketSize; ++i)
252
    ref[0] = (std::min)(ref[0],data1[i]);
252
    ref[0] = (std::min)(ref[0],data1[i]);
253
  VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min");
253
  VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min");
254
254
255
  CHECK_CWISE2((std::min), internal::pmin);
255
  CHECK_CWISE2((std::min), internal::pmin);
256
  CHECK_CWISE2((std::max), internal::pmax);
256
  CHECK_CWISE2((std::max), internal::pmax);
257
  CHECK_CWISE1(internal::abs, internal::pabs);
257
  CHECK_CWISE1(abs, internal::pabs);
258
258
259
  ref[0] = data1[0];
259
  ref[0] = data1[0];
260
  for (int i=0; i<PacketSize; ++i)
260
  for (int i=0; i<PacketSize; ++i)
261
    ref[0] = (std::max)(ref[0],data1[i]);
261
    ref[0] = (std::max)(ref[0],data1[i]);
262
  VERIFY(internal::isApprox(ref[0], internal::predux_max(internal::pload<Packet>(data1))) && "internal::predux_max");
262
  VERIFY(internal::isApprox(ref[0], internal::predux_max(internal::pload<Packet>(data1))) && "internal::predux_max");
263
  
263
  
264
  for (int i=0; i<PacketSize; ++i)
264
  for (int i=0; i<PacketSize; ++i)
265
    ref[i] = data1[0]+Scalar(i);
265
    ref[i] = data1[0]+Scalar(i);
(-)a/test/pastix_support.cpp (-1 / +1 lines)
Lines 36-44 template<typename T> void test_pastix_T_ Link Here
36
}
36
}
37
37
38
void test_pastix_support()
38
void test_pastix_support()
39
{
39
{
40
  CALL_SUBTEST_1(test_pastix_T<float>());
40
  CALL_SUBTEST_1(test_pastix_T<float>());
41
  CALL_SUBTEST_2(test_pastix_T<double>());
41
  CALL_SUBTEST_2(test_pastix_T<double>());
42
  CALL_SUBTEST_3( (test_pastix_T_LU<std::complex<float> >()) );
42
  CALL_SUBTEST_3( (test_pastix_T_LU<std::complex<float> >()) );
43
  CALL_SUBTEST_4(test_pastix_T_LU<std::complex<double> >());
43
  CALL_SUBTEST_4(test_pastix_T_LU<std::complex<double> >());
44
} 
44
} 
(-)a/test/prec_inverse_4x4.cpp (-1 / +1 lines)
Lines 33-49 template<typename MatrixType> void inver Link Here
33
  typedef typename MatrixType::RealScalar RealScalar;
33
  typedef typename MatrixType::RealScalar RealScalar;
34
  double error_sum = 0., error_max = 0.;
34
  double error_sum = 0., error_max = 0.;
35
  for(int i = 0; i < repeat; ++i)
35
  for(int i = 0; i < repeat; ++i)
36
  {
36
  {
37
    MatrixType m;
37
    MatrixType m;
38
    RealScalar absdet;
38
    RealScalar absdet;
39
    do {
39
    do {
40
      m = MatrixType::Random();
40
      m = MatrixType::Random();
41
      absdet = internal::abs(m.determinant());
41
      absdet = abs(m.determinant());
42
    } while(absdet < NumTraits<Scalar>::epsilon());
42
    } while(absdet < NumTraits<Scalar>::epsilon());
43
    MatrixType inv = m.inverse();
43
    MatrixType inv = m.inverse();
44
    double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / NumTraits<Scalar>::epsilon() );
44
    double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / NumTraits<Scalar>::epsilon() );
45
    error_sum += error;
45
    error_sum += error;
46
    error_max = (std::max)(error_max, error);
46
    error_max = (std::max)(error_max, error);
47
  }
47
  }
48
  std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;
48
  std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;
49
  double error_avg = error_sum / repeat;
49
  double error_avg = error_sum / repeat;
(-)a/test/qr.cpp (-2 / +3 lines)
Lines 48-63 template<typename MatrixType, int Cols2> Link Here
48
  Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
48
  Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
49
  m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
49
  m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
50
  m2 = qr.solve(m3);
50
  m2 = qr.solve(m3);
51
  VERIFY_IS_APPROX(m3, m1*m2);
51
  VERIFY_IS_APPROX(m3, m1*m2);
52
}
52
}
53
53
54
template<typename MatrixType> void qr_invertible()
54
template<typename MatrixType> void qr_invertible()
55
{
55
{
56
  using std::log;
56
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
57
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
57
  typedef typename MatrixType::Scalar Scalar;
58
  typedef typename MatrixType::Scalar Scalar;
58
59
59
  int size = internal::random<int>(10,50);
60
  int size = internal::random<int>(10,50);
60
61
61
  MatrixType m1(size, size), m2(size, size), m3(size, size);
62
  MatrixType m1(size, size), m2(size, size), m3(size, size);
62
  m1 = MatrixType::Random(size,size);
63
  m1 = MatrixType::Random(size,size);
63
64
Lines 71-92 template<typename MatrixType> void qr_in Link Here
71
  HouseholderQR<MatrixType> qr(m1);
72
  HouseholderQR<MatrixType> qr(m1);
72
  m3 = MatrixType::Random(size,size);
73
  m3 = MatrixType::Random(size,size);
73
  m2 = qr.solve(m3);
74
  m2 = qr.solve(m3);
74
  VERIFY_IS_APPROX(m3, m1*m2);
75
  VERIFY_IS_APPROX(m3, m1*m2);
75
76
76
  // now construct a matrix with prescribed determinant
77
  // now construct a matrix with prescribed determinant
77
  m1.setZero();
78
  m1.setZero();
78
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
79
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
79
  RealScalar absdet = internal::abs(m1.diagonal().prod());
80
  RealScalar absdet = abs(m1.diagonal().prod());
80
  m3 = qr.householderQ(); // get a unitary
81
  m3 = qr.householderQ(); // get a unitary
81
  m1 = m3 * m1 * m3;
82
  m1 = m3 * m1 * m3;
82
  qr.compute(m1);
83
  qr.compute(m1);
83
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
84
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
84
  VERIFY_IS_APPROX(internal::log(absdet), qr.logAbsDeterminant());
85
  VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
85
}
86
}
86
87
87
template<typename MatrixType> void qr_verify_assert()
88
template<typename MatrixType> void qr_verify_assert()
88
{
89
{
89
  MatrixType tmp;
90
  MatrixType tmp;
90
91
91
  HouseholderQR<MatrixType> qr;
92
  HouseholderQR<MatrixType> qr;
92
  VERIFY_RAISES_ASSERT(qr.matrixQR())
93
  VERIFY_RAISES_ASSERT(qr.matrixQR())
(-)a/test/qr_colpivoting.cpp (-2 / +3 lines)
Lines 67-82 template<typename MatrixType, int Cols2> Link Here
67
  Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
67
  Matrix<Scalar,Rows,Cols2> m3 = m1*m2;
68
  m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
68
  m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);
69
  m2 = qr.solve(m3);
69
  m2 = qr.solve(m3);
70
  VERIFY_IS_APPROX(m3, m1*m2);
70
  VERIFY_IS_APPROX(m3, m1*m2);
71
}
71
}
72
72
73
template<typename MatrixType> void qr_invertible()
73
template<typename MatrixType> void qr_invertible()
74
{
74
{
75
  using std::log;
75
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
76
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
76
  typedef typename MatrixType::Scalar Scalar;
77
  typedef typename MatrixType::Scalar Scalar;
77
78
78
  int size = internal::random<int>(10,50);
79
  int size = internal::random<int>(10,50);
79
80
80
  MatrixType m1(size, size), m2(size, size), m3(size, size);
81
  MatrixType m1(size, size), m2(size, size), m3(size, size);
81
  m1 = MatrixType::Random(size,size);
82
  m1 = MatrixType::Random(size,size);
82
83
Lines 90-111 template<typename MatrixType> void qr_in Link Here
90
  ColPivHouseholderQR<MatrixType> qr(m1);
91
  ColPivHouseholderQR<MatrixType> qr(m1);
91
  m3 = MatrixType::Random(size,size);
92
  m3 = MatrixType::Random(size,size);
92
  m2 = qr.solve(m3);
93
  m2 = qr.solve(m3);
93
  //VERIFY_IS_APPROX(m3, m1*m2);
94
  //VERIFY_IS_APPROX(m3, m1*m2);
94
95
95
  // now construct a matrix with prescribed determinant
96
  // now construct a matrix with prescribed determinant
96
  m1.setZero();
97
  m1.setZero();
97
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
98
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
98
  RealScalar absdet = internal::abs(m1.diagonal().prod());
99
  RealScalar absdet = abs(m1.diagonal().prod());
99
  m3 = qr.householderQ(); // get a unitary
100
  m3 = qr.householderQ(); // get a unitary
100
  m1 = m3 * m1 * m3;
101
  m1 = m3 * m1 * m3;
101
  qr.compute(m1);
102
  qr.compute(m1);
102
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
103
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
103
  VERIFY_IS_APPROX(internal::log(absdet), qr.logAbsDeterminant());
104
  VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
104
}
105
}
105
106
106
template<typename MatrixType> void qr_verify_assert()
107
template<typename MatrixType> void qr_verify_assert()
107
{
108
{
108
  MatrixType tmp;
109
  MatrixType tmp;
109
110
110
  ColPivHouseholderQR<MatrixType> qr;
111
  ColPivHouseholderQR<MatrixType> qr;
111
  VERIFY_RAISES_ASSERT(qr.matrixQR())
112
  VERIFY_RAISES_ASSERT(qr.matrixQR())
(-)a/test/qr_fullpivoting.cpp (-2 / +3 lines)
Lines 46-61 template<typename MatrixType> void qr() Link Here
46
  MatrixType m3 = m1*m2;
46
  MatrixType m3 = m1*m2;
47
  m2 = MatrixType::Random(cols,cols2);
47
  m2 = MatrixType::Random(cols,cols2);
48
  m2 = qr.solve(m3);
48
  m2 = qr.solve(m3);
49
  VERIFY_IS_APPROX(m3, m1*m2);
49
  VERIFY_IS_APPROX(m3, m1*m2);
50
}
50
}
51
51
52
template<typename MatrixType> void qr_invertible()
52
template<typename MatrixType> void qr_invertible()
53
{
53
{
54
  using std::log;
54
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
55
  typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
55
  typedef typename MatrixType::Scalar Scalar;
56
  typedef typename MatrixType::Scalar Scalar;
56
57
57
  int size = internal::random<int>(10,50);
58
  int size = internal::random<int>(10,50);
58
59
59
  MatrixType m1(size, size), m2(size, size), m3(size, size);
60
  MatrixType m1(size, size), m2(size, size), m3(size, size);
60
  m1 = MatrixType::Random(size,size);
61
  m1 = MatrixType::Random(size,size);
61
62
Lines 73-94 template<typename MatrixType> void qr_in Link Here
73
74
74
  m3 = MatrixType::Random(size,size);
75
  m3 = MatrixType::Random(size,size);
75
  m2 = qr.solve(m3);
76
  m2 = qr.solve(m3);
76
  VERIFY_IS_APPROX(m3, m1*m2);
77
  VERIFY_IS_APPROX(m3, m1*m2);
77
78
78
  // now construct a matrix with prescribed determinant
79
  // now construct a matrix with prescribed determinant
79
  m1.setZero();
80
  m1.setZero();
80
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
81
  for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();
81
  RealScalar absdet = internal::abs(m1.diagonal().prod());
82
  RealScalar absdet = abs(m1.diagonal().prod());
82
  m3 = qr.matrixQ(); // get a unitary
83
  m3 = qr.matrixQ(); // get a unitary
83
  m1 = m3 * m1 * m3;
84
  m1 = m3 * m1 * m3;
84
  qr.compute(m1);
85
  qr.compute(m1);
85
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
86
  VERIFY_IS_APPROX(absdet, qr.absDeterminant());
86
  VERIFY_IS_APPROX(internal::log(absdet), qr.logAbsDeterminant());
87
  VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());
87
}
88
}
88
89
89
template<typename MatrixType> void qr_verify_assert()
90
template<typename MatrixType> void qr_verify_assert()
90
{
91
{
91
  MatrixType tmp;
92
  MatrixType tmp;
92
93
93
  FullPivHouseholderQR<MatrixType> qr;
94
  FullPivHouseholderQR<MatrixType> qr;
94
  VERIFY_RAISES_ASSERT(qr.matrixQR())
95
  VERIFY_RAISES_ASSERT(qr.matrixQR())
(-)a/test/real_qz.cpp (-3 / +3 lines)
Lines 31-51 template<typename MatrixType> void real_ Link Here
31
31
32
  RealQZ<MatrixType> qz(A,B);
32
  RealQZ<MatrixType> qz(A,B);
33
  
33
  
34
  VERIFY_IS_EQUAL(qz.info(), Success);
34
  VERIFY_IS_EQUAL(qz.info(), Success);
35
  // check for zeros
35
  // check for zeros
36
  bool all_zeros = true;
36
  bool all_zeros = true;
37
  for (Index i=0; i<A.cols(); i++)
37
  for (Index i=0; i<A.cols(); i++)
38
    for (Index j=0; j<i; j++) {
38
    for (Index j=0; j<i; j++) {
39
      if (internal::abs(qz.matrixT()(i,j))!=Scalar(0.0))
39
      if (abs(qz.matrixT()(i,j))!=Scalar(0.0))
40
        all_zeros = false;
40
        all_zeros = false;
41
      if (j<i-1 && internal::abs(qz.matrixS()(i,j))!=Scalar(0.0))
41
      if (j<i-1 && abs(qz.matrixS()(i,j))!=Scalar(0.0))
42
        all_zeros = false;
42
        all_zeros = false;
43
      if (j==i-1 && j>0 && internal::abs(qz.matrixS()(i,j))!=Scalar(0.0) && internal::abs(qz.matrixS()(i-1,j-1))!=Scalar(0.0))
43
      if (j==i-1 && j>0 && abs(qz.matrixS()(i,j))!=Scalar(0.0) && abs(qz.matrixS()(i-1,j-1))!=Scalar(0.0))
44
        all_zeros = false;
44
        all_zeros = false;
45
    }
45
    }
46
  VERIFY_IS_EQUAL(all_zeros, true);
46
  VERIFY_IS_EQUAL(all_zeros, true);
47
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixS()*qz.matrixZ(), A);
47
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixS()*qz.matrixZ(), A);
48
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixT()*qz.matrixZ(), B);
48
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixT()*qz.matrixZ(), B);
49
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixQ().adjoint(), MatrixType::Identity(dim,dim));
49
  VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixQ().adjoint(), MatrixType::Identity(dim,dim));
50
  VERIFY_IS_APPROX(qz.matrixZ()*qz.matrixZ().adjoint(), MatrixType::Identity(dim,dim));
50
  VERIFY_IS_APPROX(qz.matrixZ()*qz.matrixZ().adjoint(), MatrixType::Identity(dim,dim));
51
}
51
}
(-)a/test/redux.cpp (-3 / +3 lines)
Lines 75-125 template<typename VectorType> void vecto Link Here
75
    RealScalar minc(internal::real(v.coeff(0))), maxc(internal::real(v.coeff(0)));
75
    RealScalar minc(internal::real(v.coeff(0))), maxc(internal::real(v.coeff(0)));
76
    for(int j = 0; j < i; j++)
76
    for(int j = 0; j < i; j++)
77
    {
77
    {
78
      s += v[j];
78
      s += v[j];
79
      p *= v_for_prod[j];
79
      p *= v_for_prod[j];
80
      minc = (std::min)(minc, internal::real(v[j]));
80
      minc = (std::min)(minc, internal::real(v[j]));
81
      maxc = (std::max)(maxc, internal::real(v[j]));
81
      maxc = (std::max)(maxc, internal::real(v[j]));
82
    }
82
    }
83
    VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.head(i).sum()), Scalar(1));
83
    VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.head(i).sum()), Scalar(1));
84
    VERIFY_IS_APPROX(p, v_for_prod.head(i).prod());
84
    VERIFY_IS_APPROX(p, v_for_prod.head(i).prod());
85
    VERIFY_IS_APPROX(minc, v.real().head(i).minCoeff());
85
    VERIFY_IS_APPROX(minc, v.real().head(i).minCoeff());
86
    VERIFY_IS_APPROX(maxc, v.real().head(i).maxCoeff());
86
    VERIFY_IS_APPROX(maxc, v.real().head(i).maxCoeff());
87
  }
87
  }
88
88
89
  for(int i = 0; i < size-1; i++)
89
  for(int i = 0; i < size-1; i++)
90
  {
90
  {
91
    Scalar s(0), p(1);
91
    Scalar s(0), p(1);
92
    RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
92
    RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
93
    for(int j = i; j < size; j++)
93
    for(int j = i; j < size; j++)
94
    {
94
    {
95
      s += v[j];
95
      s += v[j];
96
      p *= v_for_prod[j];
96
      p *= v_for_prod[j];
97
      minc = (std::min)(minc, internal::real(v[j]));
97
      minc = (std::min)(minc, internal::real(v[j]));
98
      maxc = (std::max)(maxc, internal::real(v[j]));
98
      maxc = (std::max)(maxc, internal::real(v[j]));
99
    }
99
    }
100
    VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.tail(size-i).sum()), Scalar(1));
100
    VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.tail(size-i).sum()), Scalar(1));
101
    VERIFY_IS_APPROX(p, v_for_prod.tail(size-i).prod());
101
    VERIFY_IS_APPROX(p, v_for_prod.tail(size-i).prod());
102
    VERIFY_IS_APPROX(minc, v.real().tail(size-i).minCoeff());
102
    VERIFY_IS_APPROX(minc, v.real().tail(size-i).minCoeff());
103
    VERIFY_IS_APPROX(maxc, v.real().tail(size-i).maxCoeff());
103
    VERIFY_IS_APPROX(maxc, v.real().tail(size-i).maxCoeff());
104
  }
104
  }
105
105
106
  for(int i = 0; i < size/2; i++)
106
  for(int i = 0; i < size/2; i++)
107
  {
107
  {
108
    Scalar s(0), p(1);
108
    Scalar s(0), p(1);
109
    RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
109
    RealScalar minc(internal::real(v.coeff(i))), maxc(internal::real(v.coeff(i)));
110
    for(int j = i; j < size-i; j++)
110
    for(int j = i; j < size-i; j++)
111
    {
111
    {
112
      s += v[j];
112
      s += v[j];
113
      p *= v_for_prod[j];
113
      p *= v_for_prod[j];
114
      minc = (std::min)(minc, internal::real(v[j]));
114
      minc = (std::min)(minc, internal::real(v[j]));
115
      maxc = (std::max)(maxc, internal::real(v[j]));
115
      maxc = (std::max)(maxc, internal::real(v[j]));
116
    }
116
    }
117
    VERIFY_IS_MUCH_SMALLER_THAN(internal::abs(s - v.segment(i, size-2*i).sum()), Scalar(1));
117
    VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.segment(i, size-2*i).sum()), Scalar(1));
118
    VERIFY_IS_APPROX(p, v_for_prod.segment(i, size-2*i).prod());
118
    VERIFY_IS_APPROX(p, v_for_prod.segment(i, size-2*i).prod());
119
    VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff());
119
    VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff());
120
    VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff());
120
    VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff());
121
  }
121
  }
122
  
122
  
123
  // test empty objects
123
  // test empty objects
124
  VERIFY_IS_APPROX(v.head(0).sum(),   Scalar(0));
124
  VERIFY_IS_APPROX(v.head(0).sum(),   Scalar(0));
125
  VERIFY_IS_APPROX(v.tail(0).prod(),  Scalar(1));
125
  VERIFY_IS_APPROX(v.tail(0).prod(),  Scalar(1));
(-)a/test/sparselu.cpp (-1 / +1 lines)
Lines 35-43 template<typename T> void test_sparselu_ Link Here
35
}
35
}
36
36
37
void test_sparselu()
37
void test_sparselu()
38
{
38
{
39
  CALL_SUBTEST_1(test_sparselu_T<float>()); 
39
  CALL_SUBTEST_1(test_sparselu_T<float>()); 
40
  CALL_SUBTEST_2(test_sparselu_T<double>());
40
  CALL_SUBTEST_2(test_sparselu_T<double>());
41
  CALL_SUBTEST_3(test_sparselu_T<std::complex<float> >()); 
41
  CALL_SUBTEST_3(test_sparselu_T<std::complex<float> >()); 
42
  CALL_SUBTEST_4(test_sparselu_T<std::complex<double> >());
42
  CALL_SUBTEST_4(test_sparselu_T<std::complex<double> >());
43
}
43
}
(-)a/test/stable_norm.cpp (-11 / +12 lines)
Lines 27-42 template<typename T> EIGEN_DONT_INLINE T Link Here
27
  return x;
27
  return x;
28
}
28
}
29
29
30
template<typename MatrixType> void stable_norm(const MatrixType& m)
30
template<typename MatrixType> void stable_norm(const MatrixType& m)
31
{
31
{
32
  /* this test covers the following files:
32
  /* this test covers the following files:
33
     StableNorm.h
33
     StableNorm.h
34
  */
34
  */
35
  using std::sqrt;
35
  typedef typename MatrixType::Index Index;
36
  typedef typename MatrixType::Index Index;
36
  typedef typename MatrixType::Scalar Scalar;
37
  typedef typename MatrixType::Scalar Scalar;
37
  typedef typename NumTraits<Scalar>::Real RealScalar;
38
  typedef typename NumTraits<Scalar>::Real RealScalar;
38
39
39
  // Check the basic machine-dependent constants.
40
  // Check the basic machine-dependent constants.
40
  {
41
  {
41
    int ibeta, it, iemin, iemax;
42
    int ibeta, it, iemin, iemax;
42
43
Lines 68-98 template<typename MatrixType> void stabl Link Here
68
  VERIFY_IS_APPROX(vrand.stableNorm(),      vrand.norm());
69
  VERIFY_IS_APPROX(vrand.stableNorm(),      vrand.norm());
69
  VERIFY_IS_APPROX(vrand.blueNorm(),        vrand.norm());
70
  VERIFY_IS_APPROX(vrand.blueNorm(),        vrand.norm());
70
  VERIFY_IS_APPROX(vrand.hypotNorm(),       vrand.norm());
71
  VERIFY_IS_APPROX(vrand.hypotNorm(),       vrand.norm());
71
72
72
  RealScalar size = static_cast<RealScalar>(m.size());
73
  RealScalar size = static_cast<RealScalar>(m.size());
73
74
74
  // test isFinite
75
  // test isFinite
75
  VERIFY(!isFinite( std::numeric_limits<RealScalar>::infinity()));
76
  VERIFY(!isFinite( std::numeric_limits<RealScalar>::infinity()));
76
  VERIFY(!isFinite(internal::sqrt(-internal::abs(big))));
77
  VERIFY(!isFinite(sqrt(-abs(big))));
77
78
78
  // test overflow
79
  // test overflow
79
  VERIFY(isFinite(internal::sqrt(size)*internal::abs(big)));
80
  VERIFY(isFinite(sqrt(size)*abs(big)));
80
  VERIFY_IS_NOT_APPROX(internal::sqrt(copy(vbig.squaredNorm())),   internal::abs(internal::sqrt(size)*big)); // here the default norm must fail
81
  VERIFY_IS_NOT_APPROX(sqrt(copy(vbig.squaredNorm())),   abs(sqrt(size)*big)); // here the default norm must fail
81
  VERIFY_IS_APPROX(vbig.stableNorm(), internal::sqrt(size)*internal::abs(big));
82
  VERIFY_IS_APPROX(vbig.stableNorm(), sqrt(size)*abs(big));
82
  VERIFY_IS_APPROX(vbig.blueNorm(),   internal::sqrt(size)*internal::abs(big));
83
  VERIFY_IS_APPROX(vbig.blueNorm(),   sqrt(size)*abs(big));
83
  VERIFY_IS_APPROX(vbig.hypotNorm(),  internal::sqrt(size)*internal::abs(big));
84
  VERIFY_IS_APPROX(vbig.hypotNorm(),  sqrt(size)*abs(big));
84
85
85
  // test underflow
86
  // test underflow
86
  VERIFY(isFinite(internal::sqrt(size)*internal::abs(small)));
87
  VERIFY(isFinite(sqrt(size)*abs(small)));
87
  VERIFY_IS_NOT_APPROX(internal::sqrt(copy(vsmall.squaredNorm())),   internal::abs(internal::sqrt(size)*small)); // here the default norm must fail
88
  VERIFY_IS_NOT_APPROX(sqrt(copy(vsmall.squaredNorm())),   abs(sqrt(size)*small)); // here the default norm must fail
88
  VERIFY_IS_APPROX(vsmall.stableNorm(), internal::sqrt(size)*internal::abs(small));
89
  VERIFY_IS_APPROX(vsmall.stableNorm(), sqrt(size)*abs(small));
89
  VERIFY_IS_APPROX(vsmall.blueNorm(),   internal::sqrt(size)*internal::abs(small));
90
  VERIFY_IS_APPROX(vsmall.blueNorm(),   sqrt(size)*abs(small));
90
  VERIFY_IS_APPROX(vsmall.hypotNorm(),  internal::sqrt(size)*internal::abs(small));
91
  VERIFY_IS_APPROX(vsmall.hypotNorm(),  sqrt(size)*abs(small));
91
92
92
// Test compilation of cwise() version
93
// Test compilation of cwise() version
93
  VERIFY_IS_APPROX(vrand.colwise().stableNorm(),      vrand.colwise().norm());
94
  VERIFY_IS_APPROX(vrand.colwise().stableNorm(),      vrand.colwise().norm());
94
  VERIFY_IS_APPROX(vrand.colwise().blueNorm(),        vrand.colwise().norm());
95
  VERIFY_IS_APPROX(vrand.colwise().blueNorm(),        vrand.colwise().norm());
95
  VERIFY_IS_APPROX(vrand.colwise().hypotNorm(),       vrand.colwise().norm());
96
  VERIFY_IS_APPROX(vrand.colwise().hypotNorm(),       vrand.colwise().norm());
96
  VERIFY_IS_APPROX(vrand.rowwise().stableNorm(),      vrand.rowwise().norm());
97
  VERIFY_IS_APPROX(vrand.rowwise().stableNorm(),      vrand.rowwise().norm());
97
  VERIFY_IS_APPROX(vrand.rowwise().blueNorm(),        vrand.rowwise().norm());
98
  VERIFY_IS_APPROX(vrand.rowwise().blueNorm(),        vrand.rowwise().norm());
98
  VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(),       vrand.rowwise().norm());
99
  VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(),       vrand.rowwise().norm());
(-)a/test/umeyama.cpp (-2 / +2 lines)
Lines 94-110 template <typename MatrixType> Link Here
94
void run_test(int dim, int num_elements)
94
void run_test(int dim, int num_elements)
95
{
95
{
96
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
96
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
97
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
97
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
98
  typedef Matrix<Scalar, Eigen::Dynamic, 1> VectorX;
98
  typedef Matrix<Scalar, Eigen::Dynamic, 1> VectorX;
99
99
100
  // MUST be positive because in any other case det(cR_t) may become negative for
100
  // MUST be positive because in any other case det(cR_t) may become negative for
101
  // odd dimensions!
101
  // odd dimensions!
102
  const Scalar c = internal::abs(internal::random<Scalar>());
102
  const Scalar c = abs(internal::random<Scalar>());
103
103
104
  MatrixX R = randMatrixSpecialUnitary<Scalar>(dim);
104
  MatrixX R = randMatrixSpecialUnitary<Scalar>(dim);
105
  VectorX t = Scalar(50)*VectorX::Random(dim,1);
105
  VectorX t = Scalar(50)*VectorX::Random(dim,1);
106
106
107
  MatrixX cR_t = MatrixX::Identity(dim+1,dim+1);
107
  MatrixX cR_t = MatrixX::Identity(dim+1,dim+1);
108
  cR_t.block(0,0,dim,dim) = c*R;
108
  cR_t.block(0,0,dim,dim) = c*R;
109
  cR_t.block(0,dim,dim,1) = t;
109
  cR_t.block(0,dim,dim,1) = t;
110
110
Lines 126-142 void run_fixed_size_test(int num_element Link Here
126
  typedef Matrix<Scalar, Dimension+1, Dimension+1> HomMatrix;
126
  typedef Matrix<Scalar, Dimension+1, Dimension+1> HomMatrix;
127
  typedef Matrix<Scalar, Dimension, Dimension> FixedMatrix;
127
  typedef Matrix<Scalar, Dimension, Dimension> FixedMatrix;
128
  typedef Matrix<Scalar, Dimension, 1> FixedVector;
128
  typedef Matrix<Scalar, Dimension, 1> FixedVector;
129
129
130
  const int dim = Dimension;
130
  const int dim = Dimension;
131
131
132
  // MUST be positive because in any other case det(cR_t) may become negative for
132
  // MUST be positive because in any other case det(cR_t) may become negative for
133
  // odd dimensions!
133
  // odd dimensions!
134
  const Scalar c = internal::abs(internal::random<Scalar>());
134
  const Scalar c = abs(internal::random<Scalar>());
135
135
136
  FixedMatrix R = randMatrixSpecialUnitary<Scalar>(dim);
136
  FixedMatrix R = randMatrixSpecialUnitary<Scalar>(dim);
137
  FixedVector t = Scalar(50)*FixedVector::Random(dim,1);
137
  FixedVector t = Scalar(50)*FixedVector::Random(dim,1);
138
138
139
  HomMatrix cR_t = HomMatrix::Identity(dim+1,dim+1);
139
  HomMatrix cR_t = HomMatrix::Identity(dim+1,dim+1);
140
  cR_t.block(0,0,dim,dim) = c*R;
140
  cR_t.block(0,0,dim,dim) = c*R;
141
  cR_t.block(0,dim,dim,1) = t;
141
  cR_t.block(0,dim,dim,1) = t;
142
142
(-)a/unsupported/Eigen/AlignedVector3 (-1 / +2 lines)
Lines 162-178 template<typename _Scalar> class Aligned Link Here
162
    inline Scalar squaredNorm() const
162
    inline Scalar squaredNorm() const
163
    {
163
    {
164
      eigen_assert(m_coeffs.w()==Scalar(0));
164
      eigen_assert(m_coeffs.w()==Scalar(0));
165
      return m_coeffs.squaredNorm();
165
      return m_coeffs.squaredNorm();
166
    }
166
    }
167
167
168
    inline Scalar norm() const
168
    inline Scalar norm() const
169
    {
169
    {
170
      return internal::sqrt(squaredNorm());
170
      using std::sqrt;
171
      return sqrt(squaredNorm());
171
    }
172
    }
172
173
173
    inline AlignedVector3 cross(const AlignedVector3& other) const
174
    inline AlignedVector3 cross(const AlignedVector3& other) const
174
    {
175
    {
175
      return AlignedVector3(m_coeffs.cross3(other.m_coeffs));
176
      return AlignedVector3(m_coeffs.cross3(other.m_coeffs));
176
    }
177
    }
177
178
178
    template<typename Derived>
179
    template<typename Derived>
(-)a/unsupported/Eigen/src/FFT/ei_kissfft_impl.h (+2 lines)
Lines 23-38 struct kiss_cpx_fft Link Here
23
  std::vector<int> m_stageRadix;
23
  std::vector<int> m_stageRadix;
24
  std::vector<int> m_stageRemainder;
24
  std::vector<int> m_stageRemainder;
25
  std::vector<Complex> m_scratchBuf;
25
  std::vector<Complex> m_scratchBuf;
26
  bool m_inverse;
26
  bool m_inverse;
27
27
28
  inline
28
  inline
29
    void make_twiddles(int nfft,bool inverse)
29
    void make_twiddles(int nfft,bool inverse)
30
    {
30
    {
31
      using std::acos;
31
      m_inverse = inverse;
32
      m_inverse = inverse;
32
      m_twiddles.resize(nfft);
33
      m_twiddles.resize(nfft);
33
      Scalar phinc =  (inverse?2:-2)* acos( (Scalar) -1)  / nfft;
34
      Scalar phinc =  (inverse?2:-2)* acos( (Scalar) -1)  / nfft;
34
      for (int i=0;i<nfft;++i)
35
      for (int i=0;i<nfft;++i)
35
        m_twiddles[i] = exp( Complex(0,i*phinc) );
36
        m_twiddles[i] = exp( Complex(0,i*phinc) );
36
    }
37
    }
37
38
38
  void factorize(int nfft)
39
  void factorize(int nfft)
Lines 394-409 struct kissfft_impl Link Here
394
        pd.factorize(nfft);
395
        pd.factorize(nfft);
395
      }
396
      }
396
      return pd;
397
      return pd;
397
    }
398
    }
398
399
399
  inline
400
  inline
400
    Complex * real_twiddles(int ncfft2)
401
    Complex * real_twiddles(int ncfft2)
401
    {
402
    {
403
      using std::acos;
402
      std::vector<Complex> & twidref = m_realTwiddles[ncfft2];// creates new if not there
404
      std::vector<Complex> & twidref = m_realTwiddles[ncfft2];// creates new if not there
403
      if ( (int)twidref.size() != ncfft2 ) {
405
      if ( (int)twidref.size() != ncfft2 ) {
404
        twidref.resize(ncfft2);
406
        twidref.resize(ncfft2);
405
        int ncfft= ncfft2<<1;
407
        int ncfft= ncfft2<<1;
406
        Scalar pi =  acos( Scalar(-1) );
408
        Scalar pi =  acos( Scalar(-1) );
407
        for (int k=1;k<=ncfft2;++k) 
409
        for (int k=1;k<=ncfft2;++k) 
408
          twidref[k-1] = exp( Complex(0,-pi * (Scalar(k) / ncfft + Scalar(.5)) ) );
410
          twidref[k-1] = exp( Complex(0,-pi * (Scalar(k) / ncfft + Scalar(.5)) ) );
409
      }
411
      }
(-)a/unsupported/Eigen/src/IterativeSolvers/IncompleteCholesky.h (-1 / +2 lines)
Lines 111-126 class IncompleteCholesky : internal::non Link Here
111
    PermutationType m_perm; 
111
    PermutationType m_perm; 
112
    
112
    
113
}; 
113
}; 
114
114
115
template<typename Scalar, int _UpLo, typename OrderingType>
115
template<typename Scalar, int _UpLo, typename OrderingType>
116
template<typename _MatrixType>
116
template<typename _MatrixType>
117
void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType& mat)
117
void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType& mat)
118
{
118
{
119
  using std::sqrt;
119
  eigen_assert(m_analysisIsOk && "analyzePattern() should be called first"); 
120
  eigen_assert(m_analysisIsOk && "analyzePattern() should be called first"); 
120
  
121
  
121
  // FIXME Stability: We should probably compute the scaling factors and the shifts that are needed to ensure a succesful LLT factorization and an efficient preconditioner. 
122
  // FIXME Stability: We should probably compute the scaling factors and the shifts that are needed to ensure a succesful LLT factorization and an efficient preconditioner. 
122
  
123
  
123
  // Dropping strategies : Keep only the p largest elements per column, where p is the number of elements in the column of the original matrix. Other strategies will be added
124
  // Dropping strategies : Keep only the p largest elements per column, where p is the number of elements in the column of the original matrix. Other strategies will be added
124
  
125
  
125
  // Apply the fill-reducing permutation computed in analyzePattern()
126
  // Apply the fill-reducing permutation computed in analyzePattern()
126
  if (m_perm.rows() == mat.rows() )
127
  if (m_perm.rows() == mat.rows() )
Lines 177-193 void IncompleteCholesky<Scalar,_UpLo, Or Link Here
177
     //  p is the original number of elements in the column (without the diagonal)
178
     //  p is the original number of elements in the column (without the diagonal)
178
     int p = colPtr[j+1] - colPtr[j] - 2 ; 
179
     int p = colPtr[j+1] - colPtr[j] - 2 ; 
179
     internal::QuickSplit(curCol, irow, p); 
180
     internal::QuickSplit(curCol, irow, p); 
180
     if(RealScalar(diag) <= 0) 
181
     if(RealScalar(diag) <= 0) 
181
     { //FIXME We can use heuristics (Kershaw, 1978 or above reference ) to get a dynamic shift
182
     { //FIXME We can use heuristics (Kershaw, 1978 or above reference ) to get a dynamic shift
182
       m_info = NumericalIssue; 
183
       m_info = NumericalIssue; 
183
       return; 
184
       return; 
184
     }
185
     }
185
     RealScalar rdiag = internal::sqrt(RealScalar(diag));
186
     RealScalar rdiag = sqrt(RealScalar(diag));
186
     Scalar scal = Scalar(1)/rdiag; 
187
     Scalar scal = Scalar(1)/rdiag; 
187
     vals[colPtr[j]] = rdiag;
188
     vals[colPtr[j]] = rdiag;
188
     // Insert the largest p elements in the matrix and scale them meanwhile  
189
     // Insert the largest p elements in the matrix and scale them meanwhile  
189
     int cpt = 0; 
190
     int cpt = 0; 
190
     for (int i = colPtr[j]+1; i < colPtr[j+1]; i++)
191
     for (int i = colPtr[j]+1; i < colPtr[j+1]; i++)
191
     {
192
     {
192
       vals[i] = curCol(cpt) * scal; 
193
       vals[i] = curCol(cpt) * scal; 
193
       rowIdx[i] = irow(cpt); 
194
       rowIdx[i] = irow(cpt); 
(-)a/unsupported/Eigen/src/IterativeSolvers/IterationController.h (-1 / +2 lines)
Lines 124-140 class IterationController Link Here
124
    void setMaxIterations(size_t i) { m_maxiter = i; }
124
    void setMaxIterations(size_t i) { m_maxiter = i; }
125
125
126
    double rhsNorm() const { return m_rhsn; }
126
    double rhsNorm() const { return m_rhsn; }
127
    void setRhsNorm(double r) { m_rhsn = r; }
127
    void setRhsNorm(double r) { m_rhsn = r; }
128
128
129
    bool converged() const { return m_res <= m_rhsn * m_resmax; }
129
    bool converged() const { return m_res <= m_rhsn * m_resmax; }
130
    bool converged(double nr)
130
    bool converged(double nr)
131
    {
131
    {
132
      m_res = internal::abs(nr); 
132
      using std::abs;
133
      m_res = abs(nr); 
133
      m_resminreach = (std::min)(m_resminreach, m_res);
134
      m_resminreach = (std::min)(m_resminreach, m_res);
134
      return converged();
135
      return converged();
135
    }
136
    }
136
    template<typename VectorType> bool converged(const VectorType &v)
137
    template<typename VectorType> bool converged(const VectorType &v)
137
    { return converged(v.squaredNorm()); }
138
    { return converged(v.squaredNorm()); }
138
139
139
    bool finished(double nr)
140
    bool finished(double nr)
140
    {
141
    {
(-)a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h (-8 / +9 lines)
Lines 230-269 void MatrixFunction<MatrixType,AtomicTyp Link Here
230
  * # The distance between two eigenvalues in different clusters is
230
  * # The distance between two eigenvalues in different clusters is
231
  *   more than separation().
231
  *   more than separation().
232
  * The implementation follows Algorithm 4.1 in the paper of Davies
232
  * The implementation follows Algorithm 4.1 in the paper of Davies
233
  * and Higham. 
233
  * and Higham. 
234
  */
234
  */
235
template <typename MatrixType, typename AtomicType>
235
template <typename MatrixType, typename AtomicType>
236
void MatrixFunction<MatrixType,AtomicType,1>::partitionEigenvalues()
236
void MatrixFunction<MatrixType,AtomicType,1>::partitionEigenvalues()
237
{
237
{
238
  using std::abs;
238
  const Index rows = m_T.rows();
239
  const Index rows = m_T.rows();
239
  VectorType diag = m_T.diagonal(); // contains eigenvalues of A
240
  VectorType diag = m_T.diagonal(); // contains eigenvalues of A
240
241
241
  for (Index i=0; i<rows; ++i) {
242
  for (Index i=0; i<rows; ++i) {
242
    // Find set containing diag(i), adding a new set if necessary
243
    // Find set containing diag(i), adding a new set if necessary
243
    typename ListOfClusters::iterator qi = findCluster(diag(i));
244
    typename ListOfClusters::iterator qi = findCluster(diag(i));
244
    if (qi == m_clusters.end()) {
245
    if (qi == m_clusters.end()) {
245
      Cluster l;
246
      Cluster l;
246
      l.push_back(diag(i));
247
      l.push_back(diag(i));
247
      m_clusters.push_back(l);
248
      m_clusters.push_back(l);
248
      qi = m_clusters.end();
249
      qi = m_clusters.end();
249
      --qi;
250
      --qi;
250
    }
251
    }
251
252
252
    // Look for other element to add to the set
253
    // Look for other element to add to the set
253
    for (Index j=i+1; j<rows; ++j) {
254
    for (Index j=i+1; j<rows; ++j) {
254
      if (internal::abs(diag(j) - diag(i)) <= separation() && std::find(qi->begin(), qi->end(), diag(j)) == qi->end()) {
255
      if (abs(diag(j) - diag(i)) <= separation() && std::find(qi->begin(), qi->end(), diag(j)) == qi->end()) {
255
	typename ListOfClusters::iterator qj = findCluster(diag(j));
256
        typename ListOfClusters::iterator qj = findCluster(diag(j));
256
	if (qj == m_clusters.end()) {
257
        if (qj == m_clusters.end()) {
257
	  qi->push_back(diag(j));
258
          qi->push_back(diag(j));
258
	} else {
259
        } else {
259
	  qi->insert(qi->end(), qj->begin(), qj->end());
260
          qi->insert(qi->end(), qj->begin(), qj->end());
260
	  m_clusters.erase(qj);
261
          m_clusters.erase(qj);
261
	}
262
        }
262
      }
263
      }
263
    }
264
    }
264
  }
265
  }
265
}
266
}
266
267
267
/** \brief Find cluster in #m_clusters containing some value 
268
/** \brief Find cluster in #m_clusters containing some value 
268
  * \param[in] key Value to find
269
  * \param[in] key Value to find
269
  * \returns Iterator to cluster containing \c key, or
270
  * \returns Iterator to cluster containing \c key, or
(-)a/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h (-1 / +2 lines)
Lines 120-152 void MatrixLogarithmAtomic<MatrixType>:: Link Here
120
  }
120
  }
121
}
121
}
122
122
123
/** \brief Compute logarithm of triangular matrices with size > 2. 
123
/** \brief Compute logarithm of triangular matrices with size > 2. 
124
  * \details This uses a inverse scale-and-square algorithm. */
124
  * \details This uses a inverse scale-and-square algorithm. */
125
template <typename MatrixType>
125
template <typename MatrixType>
126
void MatrixLogarithmAtomic<MatrixType>::computeBig(const MatrixType& A, MatrixType& result)
126
void MatrixLogarithmAtomic<MatrixType>::computeBig(const MatrixType& A, MatrixType& result)
127
{
127
{
128
  using std::pow;
128
  int numberOfSquareRoots = 0;
129
  int numberOfSquareRoots = 0;
129
  int numberOfExtraSquareRoots = 0;
130
  int numberOfExtraSquareRoots = 0;
130
  int degree;
131
  int degree;
131
  MatrixType T = A;
132
  MatrixType T = A;
132
  const RealScalar maxNormForPade = maxPadeDegree<= 5? 5.3149729967117310e-1:                     // single precision
133
  const RealScalar maxNormForPade = maxPadeDegree<= 5? 5.3149729967117310e-1:                     // single precision
133
                                    maxPadeDegree<= 7? 2.6429608311114350e-1:                     // double precision
134
                                    maxPadeDegree<= 7? 2.6429608311114350e-1:                     // double precision
134
                                    maxPadeDegree<= 8? 2.32777776523703892094e-1L:                // extended precision
135
                                    maxPadeDegree<= 8? 2.32777776523703892094e-1L:                // extended precision
135
                                    maxPadeDegree<=10? 1.05026503471351080481093652651105e-1L:    // double-double
136
                                    maxPadeDegree<=10? 1.05026503471351080481093652651105e-1L:    // double-double
136
                                                       1.1880960220216759245467951592883642e-1L;  // quadruple precision
137
                                                       1.1880960220216759245467951592883642e-1L;  // quadruple precision
137
138
138
  while (true) {
139
  while (true) {
139
    RealScalar normTminusI = (T - MatrixType::Identity(T.rows(), T.rows())).cwiseAbs().colwise().sum().maxCoeff();
140
    RealScalar normTminusI = (T - MatrixType::Identity(T.rows(), T.rows())).cwiseAbs().colwise().sum().maxCoeff();
140
    if (normTminusI < maxNormForPade) {
141
    if (normTminusI < maxNormForPade) {
141
      degree = getPadeDegree(normTminusI);
142
      degree = getPadeDegree(normTminusI);
142
      int degree2 = getPadeDegree(normTminusI / RealScalar(2));
143
      int degree2 = getPadeDegree(normTminusI / RealScalar(2));
143
      if ((degree - degree2 <= 1) || (numberOfExtraSquareRoots == 1)) 
144
      if ((degree - degree2 <= 1) || (numberOfExtraSquareRoots == 1)) 
144
	break;
145
        break;
145
      ++numberOfExtraSquareRoots;
146
      ++numberOfExtraSquareRoots;
146
    }
147
    }
147
    MatrixType sqrtT;
148
    MatrixType sqrtT;
148
    MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);
149
    MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);
149
    T = sqrtT;
150
    T = sqrtT;
150
    ++numberOfSquareRoots;
151
    ++numberOfSquareRoots;
151
  }
152
  }
152
153
(-)a/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h (-2 / +4 lines)
Lines 94-114 void MatrixSquareRootQuasiTriangular<Mat Link Here
94
}
94
}
95
95
96
// pre:  T is quasi-upper-triangular and sqrtT is a zero matrix of the same size
96
// pre:  T is quasi-upper-triangular and sqrtT is a zero matrix of the same size
97
// post: the diagonal blocks of sqrtT are the square roots of the diagonal blocks of T
97
// post: the diagonal blocks of sqrtT are the square roots of the diagonal blocks of T
98
template <typename MatrixType>
98
template <typename MatrixType>
99
void MatrixSquareRootQuasiTriangular<MatrixType>::computeDiagonalPartOfSqrt(MatrixType& sqrtT, 
99
void MatrixSquareRootQuasiTriangular<MatrixType>::computeDiagonalPartOfSqrt(MatrixType& sqrtT, 
100
									  const MatrixType& T)
100
									  const MatrixType& T)
101
{
101
{
102
  using std::sqrt;
102
  const Index size = m_A.rows();
103
  const Index size = m_A.rows();
103
  for (Index i = 0; i < size; i++) {
104
  for (Index i = 0; i < size; i++) {
104
    if (i == size - 1 || T.coeff(i+1, i) == 0) {
105
    if (i == size - 1 || T.coeff(i+1, i) == 0) {
105
      eigen_assert(T(i,i) > 0);
106
      eigen_assert(T(i,i) > 0);
106
      sqrtT.coeffRef(i,i) = internal::sqrt(T.coeff(i,i));
107
      sqrtT.coeffRef(i,i) = sqrt(T.coeff(i,i));
107
    }
108
    }
108
    else {
109
    else {
109
      compute2x2diagonalBlock(sqrtT, T, i);
110
      compute2x2diagonalBlock(sqrtT, T, i);
110
      ++i;
111
      ++i;
111
    }
112
    }
112
  }
113
  }
113
}
114
}
114
115
Lines 284-310 class MatrixSquareRootTriangular Link Here
284
 private:
285
 private:
285
    const MatrixType& m_A;
286
    const MatrixType& m_A;
286
};
287
};
287
288
288
template <typename MatrixType>
289
template <typename MatrixType>
289
template <typename ResultType> 
290
template <typename ResultType> 
290
void MatrixSquareRootTriangular<MatrixType>::compute(ResultType &result)
291
void MatrixSquareRootTriangular<MatrixType>::compute(ResultType &result)
291
{
292
{
293
  using std::sqrt;
292
  // Compute Schur decomposition of m_A
294
  // Compute Schur decomposition of m_A
293
  const ComplexSchur<MatrixType> schurOfA(m_A);  
295
  const ComplexSchur<MatrixType> schurOfA(m_A);  
294
  const MatrixType& T = schurOfA.matrixT();
296
  const MatrixType& T = schurOfA.matrixT();
295
  const MatrixType& U = schurOfA.matrixU();
297
  const MatrixType& U = schurOfA.matrixU();
296
298
297
  // Compute square root of T and store it in upper triangular part of result
299
  // Compute square root of T and store it in upper triangular part of result
298
  // This uses that the square root of triangular matrices can be computed directly.
300
  // This uses that the square root of triangular matrices can be computed directly.
299
  result.resize(m_A.rows(), m_A.cols());
301
  result.resize(m_A.rows(), m_A.cols());
300
  typedef typename MatrixType::Index Index;
302
  typedef typename MatrixType::Index Index;
301
  for (Index i = 0; i < m_A.rows(); i++) {
303
  for (Index i = 0; i < m_A.rows(); i++) {
302
    result.coeffRef(i,i) = internal::sqrt(T.coeff(i,i));
304
    result.coeffRef(i,i) = sqrt(T.coeff(i,i));
303
  }
305
  }
304
  for (Index j = 1; j < m_A.cols(); j++) {
306
  for (Index j = 1; j < m_A.cols(); j++) {
305
    for (Index i = j-1; i >= 0; i--) {
307
    for (Index i = j-1; i >= 0; i--) {
306
      typedef typename MatrixType::Scalar Scalar;
308
      typedef typename MatrixType::Scalar Scalar;
307
      // if i = j-1, then segment has length 0 so tmp = 0
309
      // if i = j-1, then segment has length 0 so tmp = 0
308
      Scalar tmp = (result.row(i).segment(i+1,j-i-1) * result.col(j).segment(i+1,j-i-1)).value();
310
      Scalar tmp = (result.row(i).segment(i+1,j-i-1) * result.col(j).segment(i+1,j-i-1)).value();
309
      // denominator may be zero if original matrix is singular
311
      // denominator may be zero if original matrix is singular
310
      result.coeffRef(i,j) = (T.coeff(i,j) - tmp) / (result.coeff(i,i) + result.coeff(j,j));
312
      result.coeffRef(i,j) = (T.coeff(i,j) - tmp) / (result.coeff(i,i) + result.coeff(j,j));
(-)a/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h (-8 / +9 lines)
Lines 201-216 LevenbergMarquardt<FunctorType,Scalar>:: Link Here
201
201
202
    return LevenbergMarquardtSpace::NotStarted;
202
    return LevenbergMarquardtSpace::NotStarted;
203
}
203
}
204
204
205
template<typename FunctorType, typename Scalar>
205
template<typename FunctorType, typename Scalar>
206
LevenbergMarquardtSpace::Status
206
LevenbergMarquardtSpace::Status
207
LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(FVectorType  &x)
207
LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(FVectorType  &x)
208
{
208
{
209
    using std::abs;
209
    assert(x.size()==n); // check the caller is not cheating us
210
    assert(x.size()==n); // check the caller is not cheating us
210
211
211
    /* calculate the jacobian matrix. */
212
    /* calculate the jacobian matrix. */
212
    Index df_ret = functor.df(x, fjac);
213
    Index df_ret = functor.df(x, fjac);
213
    if (df_ret<0)
214
    if (df_ret<0)
214
        return LevenbergMarquardtSpace::UserAsked;
215
        return LevenbergMarquardtSpace::UserAsked;
215
    if (df_ret>0)
216
    if (df_ret>0)
216
        // numerical diff, we evaluated the function df_ret times
217
        // numerical diff, we evaluated the function df_ret times
Lines 244-260 LevenbergMarquardt<FunctorType,Scalar>:: Link Here
244
    wa4.applyOnTheLeft(qrfac.householderQ().adjoint());
245
    wa4.applyOnTheLeft(qrfac.householderQ().adjoint());
245
    qtf = wa4.head(n);
246
    qtf = wa4.head(n);
246
247
247
    /* compute the norm of the scaled gradient. */
248
    /* compute the norm of the scaled gradient. */
248
    gnorm = 0.;
249
    gnorm = 0.;
249
    if (fnorm != 0.)
250
    if (fnorm != 0.)
250
        for (Index j = 0; j < n; ++j)
251
        for (Index j = 0; j < n; ++j)
251
            if (wa2[permutation.indices()[j]] != 0.)
252
            if (wa2[permutation.indices()[j]] != 0.)
252
                gnorm = (std::max)(gnorm, internal::abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[j]]));
253
                gnorm = (std::max)(gnorm, abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[j]]));
253
254
254
    /* test for convergence of the gradient norm. */
255
    /* test for convergence of the gradient norm. */
255
    if (gnorm <= parameters.gtol)
256
    if (gnorm <= parameters.gtol)
256
        return LevenbergMarquardtSpace::CosinusTooSmall;
257
        return LevenbergMarquardtSpace::CosinusTooSmall;
257
258
258
    /* rescale if necessary. */
259
    /* rescale if necessary. */
259
    if (!useExternalScaling)
260
    if (!useExternalScaling)
260
        diag = diag.cwiseMax(wa2);
261
        diag = diag.cwiseMax(wa2);
Lines 321-347 LevenbergMarquardt<FunctorType,Scalar>:: Link Here
321
            wa2 = diag.cwiseProduct(x);
322
            wa2 = diag.cwiseProduct(x);
322
            fvec = wa4;
323
            fvec = wa4;
323
            xnorm = wa2.stableNorm();
324
            xnorm = wa2.stableNorm();
324
            fnorm = fnorm1;
325
            fnorm = fnorm1;
325
            ++iter;
326
            ++iter;
326
        }
327
        }
327
328
328
        /* tests for convergence. */
329
        /* tests for convergence. */
329
        if (internal::abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1. && delta <= parameters.xtol * xnorm)
330
        if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1. && delta <= parameters.xtol * xnorm)
330
            return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;
331
            return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;
331
        if (internal::abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1.)
332
        if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1.)
332
            return LevenbergMarquardtSpace::RelativeReductionTooSmall;
333
            return LevenbergMarquardtSpace::RelativeReductionTooSmall;
333
        if (delta <= parameters.xtol * xnorm)
334
        if (delta <= parameters.xtol * xnorm)
334
            return LevenbergMarquardtSpace::RelativeErrorTooSmall;
335
            return LevenbergMarquardtSpace::RelativeErrorTooSmall;
335
336
336
        /* tests for termination and stringent tolerances. */
337
        /* tests for termination and stringent tolerances. */
337
        if (nfev >= parameters.maxfev)
338
        if (nfev >= parameters.maxfev)
338
            return LevenbergMarquardtSpace::TooManyFunctionEvaluation;
339
            return LevenbergMarquardtSpace::TooManyFunctionEvaluation;
339
        if (internal::abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)
340
        if (abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)
340
            return LevenbergMarquardtSpace::FtolTooSmall;
341
            return LevenbergMarquardtSpace::FtolTooSmall;
341
        if (delta <= NumTraits<Scalar>::epsilon() * xnorm)
342
        if (delta <= NumTraits<Scalar>::epsilon() * xnorm)
342
            return LevenbergMarquardtSpace::XtolTooSmall;
343
            return LevenbergMarquardtSpace::XtolTooSmall;
343
        if (gnorm <= NumTraits<Scalar>::epsilon())
344
        if (gnorm <= NumTraits<Scalar>::epsilon())
344
            return LevenbergMarquardtSpace::GtolTooSmall;
345
            return LevenbergMarquardtSpace::GtolTooSmall;
345
346
346
    } while (ratio < Scalar(1e-4));
347
    } while (ratio < Scalar(1e-4));
347
348
Lines 491-507 LevenbergMarquardt<FunctorType,Scalar>:: Link Here
491
            delta = parameters.factor;
492
            delta = parameters.factor;
492
    }
493
    }
493
494
494
    /* compute the norm of the scaled gradient. */
495
    /* compute the norm of the scaled gradient. */
495
    gnorm = 0.;
496
    gnorm = 0.;
496
    if (fnorm != 0.)
497
    if (fnorm != 0.)
497
        for (j = 0; j < n; ++j)
498
        for (j = 0; j < n; ++j)
498
            if (wa2[permutation.indices()[j]] != 0.)
499
            if (wa2[permutation.indices()[j]] != 0.)
499
                gnorm = (std::max)(gnorm, internal::abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[j]]));
500
                gnorm = (std::max)(gnorm, abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[j]]));
500
501
501
    /* test for convergence of the gradient norm. */
502
    /* test for convergence of the gradient norm. */
502
    if (gnorm <= parameters.gtol)
503
    if (gnorm <= parameters.gtol)
503
        return LevenbergMarquardtSpace::CosinusTooSmall;
504
        return LevenbergMarquardtSpace::CosinusTooSmall;
504
505
505
    /* rescale if necessary. */
506
    /* rescale if necessary. */
506
    if (!useExternalScaling)
507
    if (!useExternalScaling)
507
        diag = diag.cwiseMax(wa2);
508
        diag = diag.cwiseMax(wa2);
Lines 568-594 LevenbergMarquardt<FunctorType,Scalar>:: Link Here
568
            wa2 = diag.cwiseProduct(x);
569
            wa2 = diag.cwiseProduct(x);
569
            fvec = wa4;
570
            fvec = wa4;
570
            xnorm = wa2.stableNorm();
571
            xnorm = wa2.stableNorm();
571
            fnorm = fnorm1;
572
            fnorm = fnorm1;
572
            ++iter;
573
            ++iter;
573
        }
574
        }
574
575
575
        /* tests for convergence. */
576
        /* tests for convergence. */
576
        if (internal::abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1. && delta <= parameters.xtol * xnorm)
577
        if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1. && delta <= parameters.xtol * xnorm)
577
            return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;
578
            return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;
578
        if (internal::abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1.)
579
        if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1.)
579
            return LevenbergMarquardtSpace::RelativeReductionTooSmall;
580
            return LevenbergMarquardtSpace::RelativeReductionTooSmall;
580
        if (delta <= parameters.xtol * xnorm)
581
        if (delta <= parameters.xtol * xnorm)
581
            return LevenbergMarquardtSpace::RelativeErrorTooSmall;
582
            return LevenbergMarquardtSpace::RelativeErrorTooSmall;
582
583
583
        /* tests for termination and stringent tolerances. */
584
        /* tests for termination and stringent tolerances. */
584
        if (nfev >= parameters.maxfev)
585
        if (nfev >= parameters.maxfev)
585
            return LevenbergMarquardtSpace::TooManyFunctionEvaluation;
586
            return LevenbergMarquardtSpace::TooManyFunctionEvaluation;
586
        if (internal::abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)
587
        if (abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)
587
            return LevenbergMarquardtSpace::FtolTooSmall;
588
            return LevenbergMarquardtSpace::FtolTooSmall;
588
        if (delta <= NumTraits<Scalar>::epsilon() * xnorm)
589
        if (delta <= NumTraits<Scalar>::epsilon() * xnorm)
589
            return LevenbergMarquardtSpace::XtolTooSmall;
590
            return LevenbergMarquardtSpace::XtolTooSmall;
590
        if (gnorm <= NumTraits<Scalar>::epsilon())
591
        if (gnorm <= NumTraits<Scalar>::epsilon())
591
            return LevenbergMarquardtSpace::GtolTooSmall;
592
            return LevenbergMarquardtSpace::GtolTooSmall;
592
593
593
    } while (ratio < Scalar(1e-4));
594
    } while (ratio < Scalar(1e-4));
594
595
(-)a/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h (-2 / +4 lines)
Lines 58-78 public: Link Here
58
        ValuesAtCompileTime = Functor::ValuesAtCompileTime
58
        ValuesAtCompileTime = Functor::ValuesAtCompileTime
59
    };
59
    };
60
60
61
    /**
61
    /**
62
      * return the number of evaluation of functor
62
      * return the number of evaluation of functor
63
     */
63
     */
64
    int df(const InputType& _x, JacobianType &jac) const
64
    int df(const InputType& _x, JacobianType &jac) const
65
    {
65
    {
66
        using std::sqrt;
67
        using std::abs;
66
        /* Local variables */
68
        /* Local variables */
67
        Scalar h;
69
        Scalar h;
68
        int nfev=0;
70
        int nfev=0;
69
        const typename InputType::Index n = _x.size();
71
        const typename InputType::Index n = _x.size();
70
        const Scalar eps = internal::sqrt(((std::max)(epsfcn,NumTraits<Scalar>::epsilon() )));
72
        const Scalar eps = sqrt(((std::max)(epsfcn,NumTraits<Scalar>::epsilon() )));
71
        ValueType val1, val2;
73
        ValueType val1, val2;
72
        InputType x = _x;
74
        InputType x = _x;
73
        // TODO : we should do this only if the size is not already known
75
        // TODO : we should do this only if the size is not already known
74
        val1.resize(Functor::values());
76
        val1.resize(Functor::values());
75
        val2.resize(Functor::values());
77
        val2.resize(Functor::values());
76
78
77
        // initialization
79
        // initialization
78
        switch(mode) {
80
        switch(mode) {
Lines 84-100 public: Link Here
84
                // do nothing
86
                // do nothing
85
                break;
87
                break;
86
            default:
88
            default:
87
                assert(false);
89
                assert(false);
88
        };
90
        };
89
91
90
        // Function Body
92
        // Function Body
91
        for (int j = 0; j < n; ++j) {
93
        for (int j = 0; j < n; ++j) {
92
            h = eps * internal::abs(x[j]);
94
            h = eps * abs(x[j]);
93
            if (h == 0.) {
95
            if (h == 0.) {
94
                h = eps;
96
                h = eps;
95
            }
97
            }
96
            switch(mode) {
98
            switch(mode) {
97
                case Forward:
99
                case Forward:
98
                    x[j] += h;
100
                    x[j] += h;
99
                    Functor::operator()(x, val2);
101
                    Functor::operator()(x, val2);
100
                    nfev++;
102
                    nfev++;
(-)a/unsupported/Eigen/src/Polynomials/Companion.h (+1 lines)
Lines 205-220 bool companion<_Scalar,_Deg>::balancedR( Link Here
205
      return true; }
205
      return true; }
206
  }
206
  }
207
}
207
}
208
208
209
209
210
template< typename _Scalar, int _Deg >
210
template< typename _Scalar, int _Deg >
211
void companion<_Scalar,_Deg>::balance()
211
void companion<_Scalar,_Deg>::balance()
212
{
212
{
213
  using std::abs;
213
  EIGEN_STATIC_ASSERT( Deg == Dynamic || 1 < Deg, YOU_MADE_A_PROGRAMMING_MISTAKE );
214
  EIGEN_STATIC_ASSERT( Deg == Dynamic || 1 < Deg, YOU_MADE_A_PROGRAMMING_MISTAKE );
214
  const Index deg   = m_monic.size();
215
  const Index deg   = m_monic.size();
215
  const Index deg_1 = deg-1;
216
  const Index deg_1 = deg-1;
216
217
217
  bool hasConverged=false;
218
  bool hasConverged=false;
218
  while( !hasConverged )
219
  while( !hasConverged )
219
  {
220
  {
220
    hasConverged = true;
221
    hasConverged = true;
(-)a/unsupported/Eigen/src/Polynomials/PolynomialSolver.h (-5 / +8 lines)
Lines 64-83 class PolynomialSolverBase Link Here
64
     * \param[out] bi_seq : the back insertion sequence (stl concept)
64
     * \param[out] bi_seq : the back insertion sequence (stl concept)
65
     * \param[in]  absImaginaryThreshold : the maximum bound of the imaginary part of a complex
65
     * \param[in]  absImaginaryThreshold : the maximum bound of the imaginary part of a complex
66
     *  number that is considered as real.
66
     *  number that is considered as real.
67
     * */
67
     * */
68
    template<typename Stl_back_insertion_sequence>
68
    template<typename Stl_back_insertion_sequence>
69
    inline void realRoots( Stl_back_insertion_sequence& bi_seq,
69
    inline void realRoots( Stl_back_insertion_sequence& bi_seq,
70
        const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
70
        const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
71
    {
71
    {
72
      using std::abs;
72
      bi_seq.clear();
73
      bi_seq.clear();
73
      for(Index i=0; i<m_roots.size(); ++i )
74
      for(Index i=0; i<m_roots.size(); ++i )
74
      {
75
      {
75
        if( internal::abs( m_roots[i].imag() ) < absImaginaryThreshold ){
76
        if( abs( m_roots[i].imag() ) < absImaginaryThreshold ){
76
          bi_seq.push_back( m_roots[i].real() ); }
77
          bi_seq.push_back( m_roots[i].real() ); }
77
      }
78
      }
78
    }
79
    }
79
80
80
  protected:
81
  protected:
81
    template<typename squaredNormBinaryPredicate>
82
    template<typename squaredNormBinaryPredicate>
82
    inline const RootType& selectComplexRoot_withRespectToNorm( squaredNormBinaryPredicate& pred ) const
83
    inline const RootType& selectComplexRoot_withRespectToNorm( squaredNormBinaryPredicate& pred ) const
83
    {
84
    {
Lines 113-135 class PolynomialSolverBase Link Here
113
114
114
  protected:
115
  protected:
115
    template<typename squaredRealPartBinaryPredicate>
116
    template<typename squaredRealPartBinaryPredicate>
116
    inline const RealScalar& selectRealRoot_withRespectToAbsRealPart(
117
    inline const RealScalar& selectRealRoot_withRespectToAbsRealPart(
117
        squaredRealPartBinaryPredicate& pred,
118
        squaredRealPartBinaryPredicate& pred,
118
        bool& hasArealRoot,
119
        bool& hasArealRoot,
119
        const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
120
        const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
120
    {
121
    {
122
      using std::abs;
121
      hasArealRoot = false;
123
      hasArealRoot = false;
122
      Index res=0;
124
      Index res=0;
123
      RealScalar abs2(0);
125
      RealScalar abs2(0);
124
126
125
      for( Index i=0; i<m_roots.size(); ++i )
127
      for( Index i=0; i<m_roots.size(); ++i )
126
      {
128
      {
127
        if( internal::abs( m_roots[i].imag() ) < absImaginaryThreshold )
129
        if( abs( m_roots[i].imag() ) < absImaginaryThreshold )
128
        {
130
        {
129
          if( !hasArealRoot )
131
          if( !hasArealRoot )
130
          {
132
          {
131
            hasArealRoot = true;
133
            hasArealRoot = true;
132
            res = i;
134
            res = i;
133
            abs2 = m_roots[i].real() * m_roots[i].real();
135
            abs2 = m_roots[i].real() * m_roots[i].real();
134
          }
136
          }
135
          else
137
          else
Lines 139-175 class PolynomialSolverBase Link Here
139
            {
141
            {
140
              abs2 = currAbs2;
142
              abs2 = currAbs2;
141
              res = i;
143
              res = i;
142
            }
144
            }
143
          }
145
          }
144
        }
146
        }
145
        else
147
        else
146
        {
148
        {
147
          if( internal::abs( m_roots[i].imag() ) < internal::abs( m_roots[res].imag() ) ){
149
          if( abs( m_roots[i].imag() ) < abs( m_roots[res].imag() ) ){
148
            res = i; }
150
            res = i; }
149
        }
151
        }
150
      }
152
      }
151
      return internal::real_ref(m_roots[res]);
153
      return internal::real_ref(m_roots[res]);
152
    }
154
    }
153
155
154
156
155
    template<typename RealPartBinaryPredicate>
157
    template<typename RealPartBinaryPredicate>
156
    inline const RealScalar& selectRealRoot_withRespectToRealPart(
158
    inline const RealScalar& selectRealRoot_withRespectToRealPart(
157
        RealPartBinaryPredicate& pred,
159
        RealPartBinaryPredicate& pred,
158
        bool& hasArealRoot,
160
        bool& hasArealRoot,
159
        const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
161
        const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const
160
    {
162
    {
163
      using std::abs;
161
      hasArealRoot = false;
164
      hasArealRoot = false;
162
      Index res=0;
165
      Index res=0;
163
      RealScalar val(0);
166
      RealScalar val(0);
164
167
165
      for( Index i=0; i<m_roots.size(); ++i )
168
      for( Index i=0; i<m_roots.size(); ++i )
166
      {
169
      {
167
        if( internal::abs( m_roots[i].imag() ) < absImaginaryThreshold )
170
        if( abs( m_roots[i].imag() ) < absImaginaryThreshold )
168
        {
171
        {
169
          if( !hasArealRoot )
172
          if( !hasArealRoot )
170
          {
173
          {
171
            hasArealRoot = true;
174
            hasArealRoot = true;
172
            res = i;
175
            res = i;
173
            val = m_roots[i].real();
176
            val = m_roots[i].real();
174
          }
177
          }
175
          else
178
          else
Lines 179-195 class PolynomialSolverBase Link Here
179
            {
182
            {
180
              val = curr;
183
              val = curr;
181
              res = i;
184
              res = i;
182
            }
185
            }
183
          }
186
          }
184
        }
187
        }
185
        else
188
        else
186
        {
189
        {
187
          if( internal::abs( m_roots[i].imag() ) < internal::abs( m_roots[res].imag() ) ){
190
          if( abs( m_roots[i].imag() ) < abs( m_roots[res].imag() ) ){
188
            res = i; }
191
            res = i; }
189
        }
192
        }
190
      }
193
      }
191
      return internal::real_ref(m_roots[res]);
194
      return internal::real_ref(m_roots[res]);
192
    }
195
    }
193
196
194
  public:
197
  public:
195
    /**
198
    /**
(-)a/unsupported/Eigen/src/Polynomials/PolynomialUtils.h (-2 / +4 lines)
Lines 69-118 T poly_eval( const Polynomials& poly, co Link Here
69
 *
69
 *
70
 *  <i><b>Precondition:</b></i>
70
 *  <i><b>Precondition:</b></i>
71
 *  <dd> the leading coefficient of the input polynomial poly must be non zero </dd>
71
 *  <dd> the leading coefficient of the input polynomial poly must be non zero </dd>
72
 */
72
 */
73
template <typename Polynomial>
73
template <typename Polynomial>
74
inline
74
inline
75
typename NumTraits<typename Polynomial::Scalar>::Real cauchy_max_bound( const Polynomial& poly )
75
typename NumTraits<typename Polynomial::Scalar>::Real cauchy_max_bound( const Polynomial& poly )
76
{
76
{
77
  using std::abs;
77
  typedef typename Polynomial::Scalar Scalar;
78
  typedef typename Polynomial::Scalar Scalar;
78
  typedef typename NumTraits<Scalar>::Real Real;
79
  typedef typename NumTraits<Scalar>::Real Real;
79
80
80
  assert( Scalar(0) != poly[poly.size()-1] );
81
  assert( Scalar(0) != poly[poly.size()-1] );
81
  const Scalar inv_leading_coeff = Scalar(1)/poly[poly.size()-1];
82
  const Scalar inv_leading_coeff = Scalar(1)/poly[poly.size()-1];
82
  Real cb(0);
83
  Real cb(0);
83
84
84
  for( DenseIndex i=0; i<poly.size()-1; ++i ){
85
  for( DenseIndex i=0; i<poly.size()-1; ++i ){
85
    cb += internal::abs(poly[i]*inv_leading_coeff); }
86
    cb += abs(poly[i]*inv_leading_coeff); }
86
  return cb + Real(1);
87
  return cb + Real(1);
87
}
88
}
88
89
89
/** \ingroup Polynomials_Module
90
/** \ingroup Polynomials_Module
90
 * \returns a minimum bound for the absolute value of any non zero root of the polynomial.
91
 * \returns a minimum bound for the absolute value of any non zero root of the polynomial.
91
 * \param[in] poly : the vector of coefficients of the polynomial ordered
92
 * \param[in] poly : the vector of coefficients of the polynomial ordered
92
 *  by degrees i.e. poly[i] is the coefficient of degree i of the polynomial
93
 *  by degrees i.e. poly[i] is the coefficient of degree i of the polynomial
93
 *  e.g. \f$ 1 + 3x^2 \f$ is stored as a vector \f$ [ 1, 0, 3 ] \f$.
94
 *  e.g. \f$ 1 + 3x^2 \f$ is stored as a vector \f$ [ 1, 0, 3 ] \f$.
94
 */
95
 */
95
template <typename Polynomial>
96
template <typename Polynomial>
96
inline
97
inline
97
typename NumTraits<typename Polynomial::Scalar>::Real cauchy_min_bound( const Polynomial& poly )
98
typename NumTraits<typename Polynomial::Scalar>::Real cauchy_min_bound( const Polynomial& poly )
98
{
99
{
100
  using std::abs;
99
  typedef typename Polynomial::Scalar Scalar;
101
  typedef typename Polynomial::Scalar Scalar;
100
  typedef typename NumTraits<Scalar>::Real Real;
102
  typedef typename NumTraits<Scalar>::Real Real;
101
103
102
  DenseIndex i=0;
104
  DenseIndex i=0;
103
  while( i<poly.size()-1 && Scalar(0) == poly(i) ){ ++i; }
105
  while( i<poly.size()-1 && Scalar(0) == poly(i) ){ ++i; }
104
  if( poly.size()-1 == i ){
106
  if( poly.size()-1 == i ){
105
    return Real(1); }
107
    return Real(1); }
106
108
107
  const Scalar inv_min_coeff = Scalar(1)/poly[i];
109
  const Scalar inv_min_coeff = Scalar(1)/poly[i];
108
  Real cb(1);
110
  Real cb(1);
109
  for( DenseIndex j=i+1; j<poly.size(); ++j ){
111
  for( DenseIndex j=i+1; j<poly.size(); ++j ){
110
    cb += internal::abs(poly[j]*inv_min_coeff); }
112
    cb += abs(poly[j]*inv_min_coeff); }
111
  return Real(1)/cb;
113
  return Real(1)/cb;
112
}
114
}
113
115
114
/** \ingroup Polynomials_Module
116
/** \ingroup Polynomials_Module
115
 * Given the roots of a polynomial compute the coefficients in the
117
 * Given the roots of a polynomial compute the coefficients in the
116
 * monomial basis of the monic polynomial with same roots and minimal degree.
118
 * monomial basis of the monic polynomial with same roots and minimal degree.
117
 * If RootVector is a vector of complexes, Polynomial should also be a vector
119
 * If RootVector is a vector of complexes, Polynomial should also be a vector
118
 * of complexes.
120
 * of complexes.
(-)a/unsupported/test/mpreal_support.cpp (-1 lines)
Lines 1-16 Link Here
1
#include "main.h"
1
#include "main.h"
2
#include <Eigen/MPRealSupport>
2
#include <Eigen/MPRealSupport>
3
#include <Eigen/LU>
3
#include <Eigen/LU>
4
#include <Eigen/Eigenvalues>
4
#include <Eigen/Eigenvalues>
5
#include <sstream>
5
#include <sstream>
6
6
7
using namespace mpfr;
7
using namespace mpfr;
8
using namespace std;
9
using namespace Eigen;
8
using namespace Eigen;
10
9
11
void test_mpreal_support()
10
void test_mpreal_support()
12
{
11
{
13
  // set precision to 256 bits (double has only 53 bits)
12
  // set precision to 256 bits (double has only 53 bits)
14
  mpreal::set_default_prec(256);
13
  mpreal::set_default_prec(256);
15
  typedef Matrix<mpreal,Eigen::Dynamic,Eigen::Dynamic> MatrixXmp;
14
  typedef Matrix<mpreal,Eigen::Dynamic,Eigen::Dynamic> MatrixXmp;
16
15
(-)a/unsupported/test/polynomialsolver.cpp (-5 / +6 lines)
Lines 87-102 void evalSolver( const POLYNOMIAL& pols Link Here
87
}
87
}
88
88
89
89
90
90
91
91
92
template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
92
template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >
93
void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
93
void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )
94
{
94
{
95
  using std::sqrt;
95
  typedef typename POLYNOMIAL::Scalar Scalar;
96
  typedef typename POLYNOMIAL::Scalar Scalar;
96
97
97
  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;
98
  typedef PolynomialSolver<Scalar, Deg >              PolynomialSolverType;
98
99
99
  PolynomialSolverType psolve;
100
  PolynomialSolverType psolve;
100
  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
101
  if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )
101
  {
102
  {
102
    //It is supposed that
103
    //It is supposed that
Lines 110-158 void evalSolverSugarFunction( const POLY Link Here
110
    typedef typename PolynomialSolverType::RootsType    RootsType;
111
    typedef typename PolynomialSolverType::RootsType    RootsType;
111
    typedef Matrix<Scalar,Deg,1>                        EvalRootsType;
112
    typedef Matrix<Scalar,Deg,1>                        EvalRootsType;
112
113
113
    //Test realRoots
114
    //Test realRoots
114
    std::vector< Real > calc_realRoots;
115
    std::vector< Real > calc_realRoots;
115
    psolve.realRoots( calc_realRoots );
116
    psolve.realRoots( calc_realRoots );
116
    VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );
117
    VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );
117
118
118
    const Scalar psPrec = internal::sqrt( test_precision<Scalar>() );
119
    const Scalar psPrec = sqrt( test_precision<Scalar>() );
119
120
120
    for( size_t i=0; i<calc_realRoots.size(); ++i )
121
    for( size_t i=0; i<calc_realRoots.size(); ++i )
121
    {
122
    {
122
      bool found = false;
123
      bool found = false;
123
      for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
124
      for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )
124
      {
125
      {
125
        if( internal::isApprox( calc_realRoots[i], real_roots[j] ), psPrec ){
126
        if( internal::isApprox( calc_realRoots[i], real_roots[j] ), psPrec ){
126
          found = true; }
127
          found = true; }
127
      }
128
      }
128
      VERIFY( found );
129
      VERIFY( found );
129
    }
130
    }
130
131
131
    //Test greatestRoot
132
    //Test greatestRoot
132
    VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
133
    VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),
133
          internal::abs( psolve.greatestRoot() ), psPrec ) );
134
          abs( psolve.greatestRoot() ), psPrec ) );
134
135
135
    //Test smallestRoot
136
    //Test smallestRoot
136
    VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
137
    VERIFY( internal::isApprox( roots.array().abs().minCoeff(),
137
          internal::abs( psolve.smallestRoot() ), psPrec ) );
138
          abs( psolve.smallestRoot() ), psPrec ) );
138
139
139
    bool hasRealRoot;
140
    bool hasRealRoot;
140
    //Test absGreatestRealRoot
141
    //Test absGreatestRealRoot
141
    Real r = psolve.absGreatestRealRoot( hasRealRoot );
142
    Real r = psolve.absGreatestRealRoot( hasRealRoot );
142
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
143
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
143
    if( hasRealRoot ){
144
    if( hasRealRoot ){
144
      VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), internal::abs(r), psPrec ) );  }
145
      VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), abs(r), psPrec ) );  }
145
146
146
    //Test absSmallestRealRoot
147
    //Test absSmallestRealRoot
147
    r = psolve.absSmallestRealRoot( hasRealRoot );
148
    r = psolve.absSmallestRealRoot( hasRealRoot );
148
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
149
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
149
    if( hasRealRoot ){
150
    if( hasRealRoot ){
150
      VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), internal::abs( r ), psPrec ) ); }
151
      VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), abs( r ), psPrec ) ); }
151
152
152
    //Test greatestRealRoot
153
    //Test greatestRealRoot
153
    r = psolve.greatestRealRoot( hasRealRoot );
154
    r = psolve.greatestRealRoot( hasRealRoot );
154
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
155
    VERIFY( hasRealRoot == (real_roots.size() > 0 ) );
155
    if( hasRealRoot ){
156
    if( hasRealRoot ){
156
      VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }
157
      VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }
157
158
158
    //Test smallestRealRoot
159
    //Test smallestRealRoot

Return to bug 314