aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2010-07-22 16:29:35 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2010-07-22 16:29:35 +0200
commit7020f30da3ce2b646ddafa535c6564ed00fc762f (patch)
tree5d26ac3fd8b082dfe2d89903d58b760529632d72
parentb9edd6fb85a4930f0291f1b52c7f84cb6684e063 (diff)
parent96ba7cd6557769e01778441cdf7855295542aad0 (diff)
sync with default branch
-rw-r--r--Eigen/src/Core/BandMatrix.h2
-rw-r--r--Eigen/src/Core/Block.h112
-rw-r--r--Eigen/src/Core/CwiseNullaryOp.h36
-rw-r--r--Eigen/src/Core/CwiseUnaryView.h2
-rw-r--r--Eigen/src/Core/DenseBase.h19
-rw-r--r--Eigen/src/Core/DenseCoeffsBase.h28
-rw-r--r--Eigen/src/Core/DenseStorageBase.h4
-rw-r--r--Eigen/src/Core/Diagonal.h2
-rw-r--r--Eigen/src/Core/DiagonalMatrix.h5
-rw-r--r--Eigen/src/Core/Functors.h2
-rw-r--r--Eigen/src/Core/Redux.h9
-rw-r--r--Eigen/src/Core/Reverse.h7
-rw-r--r--Eigen/src/Core/products/GeneralBlockPanelKernel.h2
-rw-r--r--Eigen/src/Core/products/GeneralMatrixVector.h1
-rw-r--r--Eigen/src/Core/products/SelfadjointMatrixMatrix.h2
-rw-r--r--Eigen/src/Core/products/TriangularMatrixMatrix.h22
-rw-r--r--Eigen/src/Core/util/Constants.h12
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h5
-rw-r--r--Eigen/src/Core/util/Memory.h3
-rw-r--r--Eigen/src/Core/util/StaticAssert.h1
-rw-r--r--Eigen/src/Core/util/XprHelper.h4
-rw-r--r--Eigen/src/Eigenvalues/ComplexEigenSolver.h4
-rw-r--r--Eigen/src/Eigenvalues/HessenbergDecomposition.h6
-rw-r--r--Eigen/src/Eigenvalues/Tridiagonalization.h42
-rw-r--r--Eigen/src/Geometry/arch/Geometry_SSE.h54
-rw-r--r--Eigen/src/Householder/Householder.h2
-rw-r--r--Eigen/src/LU/Determinant.h2
-rw-r--r--Eigen/src/Sparse/DynamicSparseMatrix.h2
-rw-r--r--Eigen/src/Sparse/SparseMatrix.h2
-rw-r--r--Eigen/src/Sparse/SparseVector.h2
-rw-r--r--Eigen/src/Sparse/SparseView.h9
-rw-r--r--bench/bench_gemm.cpp4
-rw-r--r--bench/btl/libs/C_BLAS/blas.h10
-rw-r--r--bench/eig33.cpp139
-rw-r--r--bench/quatmul.cpp47
-rw-r--r--blas/common.h7
-rw-r--r--blas/level1_impl.h103
-rw-r--r--blas/level3_impl.h333
-rw-r--r--blas/xerbla.cpp2
-rw-r--r--cmake/FindGMP.cmake21
-rw-r--r--cmake/FindMPFR.cmake83
-rw-r--r--demos/mandelbrot/mandelbrot.cpp15
-rw-r--r--demos/mandelbrot/mandelbrot.h2
-rw-r--r--demos/opengl/quaternion_demo.cpp7
-rw-r--r--doc/C01_TutorialMatrixClass.dox45
-rw-r--r--doc/C02_TutorialMatrixArithmetic.dox18
-rw-r--r--doc/C03_TutorialArrayClass.dox135
-rw-r--r--doc/C04_TutorialBlockOperations.dox195
-rw-r--r--doc/C07_TutorialReductionsVisitorsBroadcasting.dox2
-rw-r--r--doc/Doxyfile.in6
-rw-r--r--doc/QuickReference.dox8
-rw-r--r--doc/examples/DenseBase_middleCols_int.cpp15
-rw-r--r--doc/examples/DenseBase_middleRows_int.cpp15
-rw-r--r--doc/examples/DenseBase_template_int_middleCols.cpp15
-rw-r--r--doc/examples/DenseBase_template_int_middleRows.cpp15
-rw-r--r--doc/examples/Tutorial_ArrayClass_accessors.cpp8
-rw-r--r--doc/examples/Tutorial_ArrayClass_addition.cpp9
-rw-r--r--doc/examples/Tutorial_ArrayClass_addition_scalar.cpp17
-rw-r--r--doc/examples/Tutorial_ArrayClass_cwise_other.cpp19
-rw-r--r--doc/examples/Tutorial_ArrayClass_interop.cpp20
-rw-r--r--doc/examples/Tutorial_ArrayClass_interop_array.cpp34
-rw-r--r--doc/examples/Tutorial_ArrayClass_interop_matrix.cpp25
-rw-r--r--doc/examples/Tutorial_ArrayClass_mult.cpp6
-rw-r--r--doc/examples/Tutorial_BlockOperations_block_assignment.cpp23
-rw-r--r--doc/examples/Tutorial_BlockOperations_colrow.cpp11
-rw-r--r--doc/examples/Tutorial_BlockOperations_corner.cpp20
-rw-r--r--doc/examples/Tutorial_BlockOperations_print_block.cpp20
-rw-r--r--doc/examples/Tutorial_BlockOperations_vector.cpp20
-rw-r--r--doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp5
-rw-r--r--doc/examples/tut_matrix_coefficient_accessors.cpp1
-rw-r--r--doc/snippets/DenseBase_LinSpaced.cpp4
-rw-r--r--doc/snippets/DenseBase_LinSpaced_seq.cpp4
-rw-r--r--doc/snippets/DenseBase_setLinSpaced.cpp2
-rw-r--r--doc/unsupported_modules.dox3
-rw-r--r--test/array_for_matrix.cpp4
-rw-r--r--test/corners.cpp23
-rw-r--r--test/determinant.cpp3
-rw-r--r--test/main.h2
-rw-r--r--test/nullary.cpp12
-rw-r--r--test/product_trmm.cpp9
-rw-r--r--test/redux.cpp11
-rw-r--r--test/sparse_basic.cpp7
-rw-r--r--unsupported/Eigen/CMakeLists.txt2
-rw-r--r--unsupported/Eigen/MPRealSupport160
-rw-r--r--unsupported/Eigen/OpenGLSupport190
-rw-r--r--unsupported/doc/examples/CMakeLists.txt2
-rw-r--r--unsupported/test/CMakeLists.txt27
-rw-r--r--unsupported/test/mpreal.cpp408
-rw-r--r--unsupported/test/mpreal.h3122
-rw-r--r--unsupported/test/mpreal_support.cpp42
-rw-r--r--unsupported/test/openglsupport.cpp61
91 files changed, 5386 insertions, 597 deletions
diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h
index e846b38e5..2f94d12dc 100644
--- a/Eigen/src/Core/BandMatrix.h
+++ b/Eigen/src/Core/BandMatrix.h
@@ -55,7 +55,7 @@ struct ei_traits<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
ColsAtCompileTime = Cols,
MaxRowsAtCompileTime = Rows,
MaxColsAtCompileTime = Cols,
- Flags = 0
+ Flags = LvalueBit
};
};
diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h
index f888d5ea0..498757ad9 100644
--- a/Eigen/src/Core/Block.h
+++ b/Eigen/src/Core/Block.h
@@ -93,7 +93,7 @@ struct ei_traits<Block<XprType, BlockRows, BlockCols, HasDirectAccess> > : ei_tr
&& (InnerStrideAtCompileTime == 1)
? PacketAccessBit : 0,
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
- Flags0 = ei_traits<XprType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit),
+ Flags0 = ei_traits<XprType>::Flags & (HereditaryBits | MaskPacketAccessBit | LvalueBit | DirectAccessBit),
Flags1 = Flags0 | FlagsLinearAccessBit,
Flags = (Flags1 & ~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0)
};
@@ -679,9 +679,62 @@ DenseBase<Derived>::bottomRows() const
+/** \returns a block consisting of a range of rows of *this.
+ *
+ * \param startRow the index of the first row in the block
+ * \param numRows the number of rows in the block
+ *
+ * Example: \include MatrixBase_middleRows_int.cpp
+ * Output: \verbinclude MatrixBase_middleRows_int.out
+ *
+ * \sa class Block, block(Index,Index,Index,Index)
+ */
+template<typename Derived>
+inline typename DenseBase<Derived>::RowsBlockXpr DenseBase<Derived>
+ ::middleRows(Index startRow, Index numRows)
+{
+ return RowsBlockXpr(derived(), startRow, 0, numRows, cols());
+}
+/** This is the const version of middleRows(Index,Index).*/
+template<typename Derived>
+inline const typename DenseBase<Derived>::RowsBlockXpr
+DenseBase<Derived>::middleRows(Index startRow, Index numRows) const
+{
+ return RowsBlockXpr(derived(), startRow, 0, numRows, cols());
+}
-/** \returns a block consisting of the top columns of *this.
+/** \returns a block consisting of a range of rows of *this.
+ *
+ * \param N the number of rows in the block
+ * \param startRow the index of the first row in the block
+ *
+ * Example: \include MatrixBase_template_int_middleRows.cpp
+ * Output: \verbinclude MatrixBase_template_int_middleRows.out
+ *
+ * \sa class Block, block(Index,Index,Index,Index)
+ */
+template<typename Derived>
+template<int N>
+inline typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type
+DenseBase<Derived>::middleRows(Index startRow)
+{
+ return typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type(derived(), startRow, 0, N, cols());
+}
+
+/** This is the const version of middleRows<int>().*/
+template<typename Derived>
+template<int N>
+inline const typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type
+DenseBase<Derived>::middleRows(Index startRow) const
+{
+ return typename DenseBase<Derived>::template NRowsBlockXpr<N>::Type(derived(), startRow, 0, N, cols());
+}
+
+
+
+
+/** \returns a block consisting of the left columns of *this.
*
* \param n the number of columns in the block
*
@@ -788,6 +841,61 @@ DenseBase<Derived>::rightCols() const
+/** \returns a block consisting of a range of columns of *this.
+ *
+ * \param startCol the index of the first column in the block
+ * \param numCols the number of columns in the block
+ *
+ * Example: \include MatrixBase_middleCols_int.cpp
+ * Output: \verbinclude MatrixBase_middleCols_int.out
+ *
+ * \sa class Block, block(Index,Index,Index,Index)
+ */
+template<typename Derived>
+inline typename DenseBase<Derived>::ColsBlockXpr DenseBase<Derived>
+ ::middleCols(Index startCol, Index numCols)
+{
+ return ColsBlockXpr(derived(), 0, startCol, rows(), numCols);
+}
+
+/** This is the const version of middleCols(Index,Index).*/
+template<typename Derived>
+inline const typename DenseBase<Derived>::ColsBlockXpr
+DenseBase<Derived>::middleCols(Index startCol, Index numCols) const
+{
+ return ColsBlockXpr(derived(), 0, startCol, rows(), numCols);
+}
+
+/** \returns a block consisting of a range of columns of *this.
+ *
+ * \param N the number of columns in the block
+ * \param startCol the index of the first column in the block
+ *
+ * Example: \include MatrixBase_template_int_middleCols.cpp
+ * Output: \verbinclude MatrixBase_template_int_middleCols.out
+ *
+ * \sa class Block, block(Index,Index,Index,Index)
+ */
+template<typename Derived>
+template<int N>
+inline typename DenseBase<Derived>::template NColsBlockXpr<N>::Type
+DenseBase<Derived>::middleCols(Index startCol)
+{
+ return typename NColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), N);
+}
+
+/** This is the const version of middleCols<int>().*/
+template<typename Derived>
+template<int N>
+inline const typename DenseBase<Derived>::template NColsBlockXpr<N>::Type
+DenseBase<Derived>::middleCols(Index startCol) const
+{
+ return typename NColsBlockXpr<N>::Type(derived(), 0, startCol, rows(), N);
+}
+
+
+
+
/** \returns a fixed-size expression of a block in *this.
*
diff --git a/Eigen/src/Core/CwiseNullaryOp.h b/Eigen/src/Core/CwiseNullaryOp.h
index 25041d1b7..97331fa26 100644
--- a/Eigen/src/Core/CwiseNullaryOp.h
+++ b/Eigen/src/Core/CwiseNullaryOp.h
@@ -240,17 +240,30 @@ DenseBase<Derived>::Constant(const Scalar& value)
* Example: \include DenseBase_LinSpaced_seq.cpp
* Output: \verbinclude DenseBase_LinSpaced_seq.out
*
- * \sa setLinSpaced(const Scalar&,const Scalar&,Index), LinSpaced(Scalar,Scalar,Index), CwiseNullaryOp
+ * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Index,Scalar,Scalar), CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
-DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high, Index size)
+DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return DenseBase<Derived>::NullaryExpr(size, ei_linspaced_op<Scalar,false>(low,high,size));
}
/**
+ * \copydoc DenseBase<Derived>::LinSpaced(Sequential_t, Index, const Scalar&, const Scalar&)
+ * Special version for fixed size types which does not require the size parameter.
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename DenseBase<Derived>::SequentialLinSpacedReturnType
+DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
+ return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, ei_linspaced_op<Scalar,false>(low,high,Derived::SizeAtCompileTime));
+}
+
+/**
* \brief Sets a linearly space vector.
*
* The function generates 'size' equally spaced values in the closed interval [low,high].
@@ -260,16 +273,29 @@ DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& hig
* Example: \include DenseBase_LinSpaced.cpp
* Output: \verbinclude DenseBase_LinSpaced.out
*
- * \sa setLinSpaced(const Scalar&,const Scalar&,Index), LinSpaced(Sequential_t,const Scalar&,const Scalar&,Index), CwiseNullaryOp
+ * \sa setLinSpaced(Index,const Scalar&,const Scalar&), LinSpaced(Sequential_t,Index,const Scalar&,const Scalar&,Index), CwiseNullaryOp
*/
template<typename Derived>
EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
-DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high, Index size)
+DenseBase<Derived>::LinSpaced(Index size, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return DenseBase<Derived>::NullaryExpr(size, ei_linspaced_op<Scalar,true>(low,high,size));
}
+/**
+ * \copydoc DenseBase<Derived>::LinSpaced(Index, const Scalar&, const Scalar&)
+ * Special version for fixed size types which does not require the size parameter.
+ */
+template<typename Derived>
+EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
+DenseBase<Derived>::LinSpaced(const Scalar& low, const Scalar& high)
+{
+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
+ EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
+ return DenseBase<Derived>::NullaryExpr(Derived::SizeAtCompileTime, ei_linspaced_op<Scalar,true>(low,high,Derived::SizeAtCompileTime));
+}
+
/** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */
template<typename Derived>
bool DenseBase<Derived>::isApproxToConstant
@@ -360,7 +386,7 @@ DenseStorageBase<Derived>::setConstant(Index rows, Index cols, const Scalar& val
* \sa CwiseNullaryOp
*/
template<typename Derived>
-EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(const Scalar& low, const Scalar& high, Index size)
+EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setLinSpaced(Index size, const Scalar& low, const Scalar& high)
{
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
return derived() = Derived::NullaryExpr(size, ei_linspaced_op<Scalar,false>(low,high,size));
diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h
index 612b28f1f..37c58223e 100644
--- a/Eigen/src/Core/CwiseUnaryView.h
+++ b/Eigen/src/Core/CwiseUnaryView.h
@@ -48,7 +48,7 @@ struct ei_traits<CwiseUnaryView<ViewOp, MatrixType> >
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
enum {
- Flags = (ei_traits<_MatrixTypeNested>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)),
+ Flags = (ei_traits<_MatrixTypeNested>::Flags & (HereditaryBits | LvalueBit | LinearAccessBit | DirectAccessBit)),
CoeffReadCost = ei_traits<_MatrixTypeNested>::CoeffReadCost + ei_functor_traits<ViewOp>::Cost,
MatrixTypeInnerStride = ei_inner_stride_at_compile_time<MatrixType>::ret,
// need to cast the sizeof's from size_t to int explicitly, otherwise:
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 8c1e24fec..c84544ec3 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -327,10 +327,14 @@ template<typename Derived> class DenseBase
const RowsBlockXpr topRows(Index n) const;
RowsBlockXpr bottomRows(Index n);
const RowsBlockXpr bottomRows(Index n) const;
+ RowsBlockXpr middleRows(Index startRow, Index numRows);
+ const RowsBlockXpr middleRows(Index startRow, Index numRows) const;
ColsBlockXpr leftCols(Index n);
const ColsBlockXpr leftCols(Index n) const;
ColsBlockXpr rightCols(Index n);
const ColsBlockXpr rightCols(Index n) const;
+ ColsBlockXpr middleCols(Index startCol, Index numCols);
+ const ColsBlockXpr middleCols(Index startCol, Index numCols) const;
template<int CRows, int CCols> Block<Derived, CRows, CCols> topLeftCorner();
template<int CRows, int CCols> const Block<Derived, CRows, CCols> topLeftCorner() const;
@@ -345,10 +349,14 @@ template<typename Derived> class DenseBase
template<int NRows> const typename NRowsBlockXpr<NRows>::Type topRows() const;
template<int NRows> typename NRowsBlockXpr<NRows>::Type bottomRows();
template<int NRows> const typename NRowsBlockXpr<NRows>::Type bottomRows() const;
+ template<int NRows> typename NRowsBlockXpr<NRows>::Type middleRows(Index startRow);
+ template<int NRows> const typename NRowsBlockXpr<NRows>::Type middleRows(Index startRow) const;
template<int NCols> typename NColsBlockXpr<NCols>::Type leftCols();
template<int NCols> const typename NColsBlockXpr<NCols>::Type leftCols() const;
template<int NCols> typename NColsBlockXpr<NCols>::Type rightCols();
template<int NCols> const typename NColsBlockXpr<NCols>::Type rightCols() const;
+ template<int NCols> typename NColsBlockXpr<NCols>::Type middleCols(Index startCol);
+ template<int NCols> const typename NColsBlockXpr<NCols>::Type middleCols(Index startCol) const;
template<int BlockRows, int BlockCols>
Block<Derived, BlockRows, BlockCols> block(Index startRow, Index startCol);
@@ -390,9 +398,13 @@ template<typename Derived> class DenseBase
Constant(const Scalar& value);
static const SequentialLinSpacedReturnType
- LinSpaced(Sequential_t, const Scalar& low, const Scalar& high, Index size);
+ LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high);
static const RandomAccessLinSpacedReturnType
- LinSpaced(const Scalar& low, const Scalar& high, Index size);
+ LinSpaced(Index size, const Scalar& low, const Scalar& high);
+ static const SequentialLinSpacedReturnType
+ LinSpaced(Sequential_t, const Scalar& low, const Scalar& high);
+ static const RandomAccessLinSpacedReturnType
+ LinSpaced(const Scalar& low, const Scalar& high);
template<typename CustomNullaryOp>
static const CwiseNullaryOp<CustomNullaryOp, Derived>
@@ -413,7 +425,8 @@ template<typename Derived> class DenseBase
void fill(const Scalar& value);
Derived& setConstant(const Scalar& value);
- Derived& setLinSpaced(const Scalar& low, const Scalar& high, Index size);
+ Derived& setLinSpaced(Index size, const Scalar& low, const Scalar& high);
+ Derived& setLinSpaced(const Scalar& low, const Scalar& high);
Derived& setZero();
Derived& setOnes();
Derived& setRandom();
diff --git a/Eigen/src/Core/DenseCoeffsBase.h b/Eigen/src/Core/DenseCoeffsBase.h
index 6802cea24..0b348c81d 100644
--- a/Eigen/src/Core/DenseCoeffsBase.h
+++ b/Eigen/src/Core/DenseCoeffsBase.h
@@ -25,15 +25,15 @@
#ifndef EIGEN_DENSECOEFFSBASE_H
#define EIGEN_DENSECOEFFSBASE_H
-template<typename Derived, bool EnableDirectAccessAPI>
-class DenseCoeffsBase : public EigenBase<Derived>
+template<typename Derived>
+class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
{
public:
typedef typename ei_traits<Derived>::StorageKind StorageKind;
typedef typename ei_traits<Derived>::Index Index;
typedef typename ei_traits<Derived>::Scalar Scalar;
typedef typename ei_packet_traits<Scalar>::type PacketScalar;
- typedef typename ei_meta_if<ei_has_direct_access<Derived>::ret,
+ typedef typename ei_meta_if<bool(ei_traits<Derived>::Flags&LvalueBit),
const Scalar&,
typename ei_meta_if<ei_is_arithmetic<Scalar>::ret, Scalar, const Scalar>::ret
>::ret CoeffReturnType;
@@ -239,11 +239,11 @@ class DenseCoeffsBase : public EigenBase<Derived>
};
template<typename Derived>
-class DenseCoeffsBase<Derived, true> : public DenseCoeffsBase<Derived, false>
+class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
{
public:
- typedef DenseCoeffsBase<Derived, false> Base;
+ typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
typedef typename ei_traits<Derived>::StorageKind StorageKind;
typedef typename ei_traits<Derived>::Index Index;
@@ -512,6 +512,23 @@ class DenseCoeffsBase<Derived, true> : public DenseCoeffsBase<Derived, false>
}
#endif
+};
+
+template<typename Derived>
+class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, WriteAccessors>
+{
+ public:
+
+ typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
+ typedef typename ei_traits<Derived>::Index Index;
+ typedef typename ei_traits<Derived>::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
+
+ using Base::rows;
+ using Base::cols;
+ using Base::size;
+ using Base::derived;
+
/** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
*
* \sa outerStride(), rowStride(), colStride()
@@ -531,6 +548,7 @@ class DenseCoeffsBase<Derived, true> : public DenseCoeffsBase<Derived, false>
return derived().outerStride();
}
+ // FIXME shall we remove it ?
inline Index stride() const
{
return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
diff --git a/Eigen/src/Core/DenseStorageBase.h b/Eigen/src/Core/DenseStorageBase.h
index 16e0a86f1..e818d40a1 100644
--- a/Eigen/src/Core/DenseStorageBase.h
+++ b/Eigen/src/Core/DenseStorageBase.h
@@ -483,8 +483,8 @@ class DenseStorageBase : public ei_dense_xpr_base<Derived>::type
template<typename T0, typename T1>
EIGEN_STRONG_INLINE void _init2(Index rows, Index cols, typename ei_enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0)
{
- ei_assert(rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
- && cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
+ ei_assert(rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
+ && cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
m_storage.resize(rows*cols,rows,cols);
EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED
}
diff --git a/Eigen/src/Core/Diagonal.h b/Eigen/src/Core/Diagonal.h
index 8c2eacd96..0b7d14179 100644
--- a/Eigen/src/Core/Diagonal.h
+++ b/Eigen/src/Core/Diagonal.h
@@ -62,7 +62,7 @@ struct ei_traits<Diagonal<MatrixType,DiagIndex> >
MatrixType::MaxColsAtCompileTime)
: (EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime) - AbsDiagIndex),
MaxColsAtCompileTime = 1,
- Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit) & ~RowMajorBit,
+ Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit | LvalueBit | DirectAccessBit) & ~RowMajorBit,
CoeffReadCost = _MatrixTypeNested::CoeffReadCost,
MatrixTypeOuterStride = ei_outer_stride_at_compile_time<MatrixType>::ret,
InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic ? Dynamic : MatrixTypeOuterStride+1,
diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h
index 8c4200a6f..0c0525028 100644
--- a/Eigen/src/Core/DiagonalMatrix.h
+++ b/Eigen/src/Core/DiagonalMatrix.h
@@ -105,6 +105,9 @@ struct ei_traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime>
typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType;
typedef Dense StorageKind;
typedef DenseIndex Index;
+ enum {
+ Flags = LvalueBit
+ };
};
template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime>
@@ -213,7 +216,7 @@ struct ei_traits<DiagonalWrapper<_DiagonalVectorType> >
ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
MaxRowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
MaxColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime,
- Flags = 0
+ Flags = ei_traits<DiagonalVectorType>::Flags & LvalueBit
};
};
diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h
index cde91ff97..41ae4af42 100644
--- a/Eigen/src/Core/Functors.h
+++ b/Eigen/src/Core/Functors.h
@@ -577,7 +577,7 @@ template <typename Scalar, bool RandomAccess> struct ei_linspaced_op
template<typename Index>
EIGEN_STRONG_INLINE const Packet packetOp(Index i, Index = 0) const { return impl.packetOp(i); }
// This proxy object handles the actual required temporaries, the different
- // implementations (random vs. sequential access) as well as the piping
+ // implementations (random vs. sequential access) as well as the
// correct piping to size 2/4 packet operations.
const ei_linspaced_op_impl<Scalar,RandomAccess> impl;
};
diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h
index b1dd7d727..504a51229 100644
--- a/Eigen/src/Core/Redux.h
+++ b/Eigen/src/Core/Redux.h
@@ -183,7 +183,7 @@ struct ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
typedef typename Derived::Index Index;
static EIGEN_STRONG_INLINE Scalar run(const Derived& mat, const Func& func)
{
- ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
+ ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
Scalar res;
res = mat.coeffByOuterInner(0, 0);
for(Index i = 1; i < mat.innerSize(); ++i)
@@ -210,6 +210,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
static Scalar run(const Derived& mat, const Func& func)
{
const Index size = mat.size();
+ ei_assert(size && "you are using an empty matrix");
const Index packetSize = ei_packet_traits<Scalar>::size;
const Index alignedStart = ei_first_aligned(mat);
enum {
@@ -253,6 +254,7 @@ struct ei_redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
static Scalar run(const Derived& mat, const Func& func)
{
+ ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
const Index innerSize = mat.innerSize();
const Index outerSize = mat.outerSize();
enum {
@@ -294,6 +296,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling
};
EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func)
{
+ ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using an empty matrix");
Scalar res = func.predux(ei_redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
if (VectorizedSize != Size)
res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
@@ -345,6 +348,8 @@ template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar
DenseBase<Derived>::sum() const
{
+ if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
+ return Scalar(0);
return this->redux(Eigen::ei_scalar_sum_op<Scalar>());
}
@@ -370,6 +375,8 @@ template<typename Derived>
EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar
DenseBase<Derived>::prod() const
{
+ if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
+ return Scalar(1);
return this->redux(Eigen::ei_scalar_product_op<Scalar>());
}
diff --git a/Eigen/src/Core/Reverse.h b/Eigen/src/Core/Reverse.h
index 5a96aeeb3..6051f7366 100644
--- a/Eigen/src/Core/Reverse.h
+++ b/Eigen/src/Core/Reverse.h
@@ -59,7 +59,7 @@ struct ei_traits<Reverse<MatrixType, Direction> >
LinearAccess = ( (Direction==BothDirections) && (int(_MatrixTypeNested::Flags)&PacketAccessBit) )
? LinearAccessBit : 0,
- Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | PacketAccessBit | LinearAccess),
+ Flags = int(_MatrixTypeNested::Flags) & (HereditaryBits | LvalueBit | PacketAccessBit | LinearAccess),
CoeffReadCost = _MatrixTypeNested::CoeffReadCost
};
@@ -109,6 +109,11 @@ template<typename MatrixType, int Direction> class Reverse
inline Index rows() const { return m_matrix.rows(); }
inline Index cols() const { return m_matrix.cols(); }
+ inline Index innerStride() const
+ {
+ return -m_matrix.innerStride();
+ }
+
inline Scalar& operator()(Index row, Index col)
{
ei_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
diff --git a/Eigen/src/Core/products/GeneralBlockPanelKernel.h b/Eigen/src/Core/products/GeneralBlockPanelKernel.h
index e3b9d25ef..7e2d496fe 100644
--- a/Eigen/src/Core/products/GeneralBlockPanelKernel.h
+++ b/Eigen/src/Core/products/GeneralBlockPanelKernel.h
@@ -126,7 +126,7 @@ void computeProductBlockingSizes(std::ptrdiff_t& k, std::ptrdiff_t& m, std::ptrd
ei_manage_caching_sizes(GetAction, &l1, &l2);
k = std::min<std::ptrdiff_t>(k, l1/kdiv);
- std::ptrdiff_t _m = l2/(4 * sizeof(LhsScalar) * k);
+ std::ptrdiff_t _m = k>0 ? l2/(4 * sizeof(LhsScalar) * k) : 0;
if(_m<m) m = _m & mr_mask;
n = n;
}
diff --git a/Eigen/src/Core/products/GeneralMatrixVector.h b/Eigen/src/Core/products/GeneralMatrixVector.h
index 8222123d9..44986dc16 100644
--- a/Eigen/src/Core/products/GeneralMatrixVector.h
+++ b/Eigen/src/Core/products/GeneralMatrixVector.h
@@ -319,6 +319,7 @@ EIGEN_DONT_INLINE static void run(
ResScalar* res, Index resIncr,
ResScalar alpha)
{
+ EIGEN_UNUSED_VARIABLE(rhsIncr);
ei_internal_assert(rhsIncr==1);
#ifdef _EIGEN_ACCUMULATE_PACKETS
#error _EIGEN_ACCUMULATE_PACKETS has already been defined
diff --git a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
index 0fbdd024c..ede8b77bf 100644
--- a/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+++ b/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
@@ -135,7 +135,7 @@ struct ei_symm_pack_rhs
for (Index w=0 ; w<h; ++w)
blockB[count+w] = rhs(k,j2+w);
- blockB[count+h] = rhs(k,k);
+ blockB[count+h] = ei_real(rhs(k,k));
// transpose
for (Index w=h+1 ; w<nr; ++w)
diff --git a/Eigen/src/Core/products/TriangularMatrixMatrix.h b/Eigen/src/Core/products/TriangularMatrixMatrix.h
index 0f90b5683..cef5eeba1 100644
--- a/Eigen/src/Core/products/TriangularMatrixMatrix.h
+++ b/Eigen/src/Core/products/TriangularMatrixMatrix.h
@@ -75,7 +75,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,LhsIsTriangular,
Scalar alpha)
{
ei_product_triangular_matrix_matrix<Scalar, Index,
- (Mode&UnitDiag) | ((Mode&Upper) ? Lower : Upper),
+ (Mode&(UnitDiag|ZeroDiag)) | ((Mode&Upper) ? Lower : Upper),
(!LhsIsTriangular),
RhsStorageOrder==RowMajor ? ColMajor : RowMajor,
ConjugateRhs,
@@ -108,7 +108,8 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,true,
typedef ei_gebp_traits<Scalar,Scalar> Traits;
enum {
SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
- IsLower = (Mode&Lower) == Lower
+ IsLower = (Mode&Lower) == Lower,
+ SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
};
Index kc = depth; // cache block size along the K direction
@@ -124,7 +125,10 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,true,
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,LhsStorageOrder> triangularBuffer;
triangularBuffer.setZero();
- triangularBuffer.diagonal().setOnes();
+ if((Mode&ZeroDiag)==ZeroDiag)
+ triangularBuffer.diagonal().setZero();
+ else
+ triangularBuffer.diagonal().setOnes();
ei_gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
ei_gemm_pack_lhs<Scalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
@@ -166,7 +170,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,true,
// To this end we do an extra triangular copy to a small temporary buffer
for (Index k=0;k<actualPanelWidth;++k)
{
- if (!(Mode&UnitDiag))
+ if (SetDiag)
triangularBuffer.coeffRef(k,k) = lhs(startBlock+k,startBlock+k);
for (Index i=IsLower ? k+1 : 0; IsLower ? i<actualPanelWidth : i<k; ++i)
triangularBuffer.coeffRef(i,k) = lhs(startBlock+i,startBlock+k);
@@ -231,7 +235,8 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,false,
typedef ei_gebp_traits<Scalar,Scalar> Traits;
enum {
SmallPanelWidth = EIGEN_PLAIN_ENUM_MAX(Traits::mr,Traits::nr),
- IsLower = (Mode&Lower) == Lower
+ IsLower = (Mode&Lower) == Lower,
+ SetDiag = (Mode&(ZeroDiag|UnitDiag)) ? 0 : 1
};
Index kc = depth; // cache block size along the K direction
@@ -247,7 +252,10 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,false,
Matrix<Scalar,SmallPanelWidth,SmallPanelWidth,RhsStorageOrder> triangularBuffer;
triangularBuffer.setZero();
- triangularBuffer.diagonal().setOnes();
+ if((Mode&ZeroDiag)==ZeroDiag)
+ triangularBuffer.diagonal().setZero();
+ else
+ triangularBuffer.diagonal().setOnes();
ei_gebp_kernel<Scalar, Scalar, Index, Traits::mr, Traits::nr, ConjugateLhs, ConjugateRhs> gebp_kernel;
ei_gemm_pack_lhs<Scalar, Index, Traits::mr, Traits::LhsProgress, LhsStorageOrder> pack_lhs;
@@ -295,7 +303,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Index,Mode,false,
// append the triangular part via a temporary buffer
for (Index j=0;j<actualPanelWidth;++j)
{
- if (!(Mode&UnitDiag))
+ if (SetDiag)
triangularBuffer.coeffRef(j,j) = rhs(actual_j2+j,actual_j2+j);
for (Index k=IsLower ? j+1 : 0; IsLower ? k<actualPanelWidth : k<j; ++k)
triangularBuffer.coeffRef(k,j) = rhs(actual_j2+k,actual_j2+j);
diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h
index eb70981e4..60fdcf2e2 100644
--- a/Eigen/src/Core/util/Constants.h
+++ b/Eigen/src/Core/util/Constants.h
@@ -139,6 +139,14 @@ const unsigned int DirectAccessBit = 0x20;
* means the first coefficient packet is guaranteed to be aligned */
const unsigned int AlignedBit = 0x40;
+/** \ingroup flags
+ *
+ * Means the expression is writable. Note that DirectAccessBit implies LvalueBit.
+ * Internaly, it is mainly used to enable the writable coeff accessors, and makes
+ * the read-only coeff accessors to return by const reference.
+ */
+const unsigned int LvalueBit = 0x80;
+
const unsigned int NestByRefBit = 0x100;
// list of flags that are inherited by default
@@ -236,6 +244,10 @@ enum {
IsSparse
};
+enum AccessorLevels {
+ ReadOnlyAccessors, WriteAccessors, DirectAccessors
+};
+
enum DecompositionOptions {
Pivoting = 0x01, // LDLT,
NoPivoting = 0x02, // LDLT,
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 2c0e9c3e2..7f626c62b 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -36,7 +36,10 @@ template<typename Derived> struct ei_has_direct_access
template<typename Derived> struct EigenBase;
template<typename Derived> class DenseBase;
-template<typename Derived, bool EnableDirectAccessAPI = ei_has_direct_access<Derived>::ret>
+template<typename Derived,
+ AccessorLevels Level = (ei_traits<Derived>::Flags & DirectAccessBit) ? DirectAccessors
+ : (ei_traits<Derived>::Flags & LvalueBit) ? WriteAccessors
+ : ReadOnlyAccessors>
class DenseCoeffsBase;
template<typename _Scalar, int _Rows, int _Cols,
diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h
index 1b89525a8..75c3e5ec4 100644
--- a/Eigen/src/Core/util/Memory.h
+++ b/Eigen/src/Core/util/Memory.h
@@ -315,7 +315,8 @@ template<typename T> inline T* ei_construct_elements_of_array(T *ptr, size_t siz
template<typename T> inline void ei_destruct_elements_of_array(T *ptr, size_t size)
{
// always destruct an array starting from the end.
- while(size) ptr[--size].~T();
+ if(ptr)
+ while(size) ptr[--size].~T();
}
/*****************************************************************************
diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h
index 9d3169967..bf686975b 100644
--- a/Eigen/src/Core/util/StaticAssert.h
+++ b/Eigen/src/Core/util/StaticAssert.h
@@ -60,6 +60,7 @@
YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES,
THIS_METHOD_IS_ONLY_FOR_VECTORS_OF_A_SPECIFIC_SIZE,
THIS_METHOD_IS_ONLY_FOR_MATRICES_OF_A_SPECIFIC_SIZE,
+ THIS_METHOD_IS_ONLY_FOR_OBJECTS_OF_A_SPECIFIC_SIZE,
YOU_MADE_A_PROGRAMMING_MISTAKE,
EIGEN_INTERNAL_COMPILATION_ERROR_OR_YOU_MADE_A_PROGRAMMING_MISTAKE,
YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR,
diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h
index c93398092..3c89a7f3f 100644
--- a/Eigen/src/Core/util/XprHelper.h
+++ b/Eigen/src/Core/util/XprHelper.h
@@ -155,7 +155,7 @@ class ei_compute_matrix_flags
};
public:
- enum { ret = LinearAccessBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit };
+ enum { ret = LinearAccessBit | LvalueBit | DirectAccessBit | NestByRefBit | packet_access_bit | row_major_bit | aligned_bit };
};
template<int _Rows, int _Cols> struct ei_size_at_compile_time
@@ -355,7 +355,7 @@ template<typename T, int n=1, typename PlainObject = typename ei_eval<T>::type>
template<unsigned int Flags> struct ei_are_flags_consistent
{
- enum { ret = true };
+ enum { ret = EIGEN_IMPLIES(bool(Flags&DirectAccessBit), bool(Flags&LvalueBit)) };
};
template<typename Derived, typename XprKind = typename ei_traits<Derived>::XprKind>
diff --git a/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/Eigen/src/Eigenvalues/ComplexEigenSolver.h
index 08276c5c0..7bf1d140e 100644
--- a/Eigen/src/Eigenvalues/ComplexEigenSolver.h
+++ b/Eigen/src/Eigenvalues/ComplexEigenSolver.h
@@ -291,8 +291,8 @@ void ComplexEigenSolver<MatrixType>::doComputeEigenvectors(RealScalar matrixnorm
ComplexScalar z = m_schur.matrixT().coeff(i,i) - m_schur.matrixT().coeff(k,k);
if(z==ComplexScalar(0))
{
- // If the i-th and k-th eigenvalue are equal, then z equals 0.
- // Use a small value instead, to prevent division by zero.
+ // If the i-th and k-th eigenvalue are equal, then z equals 0.
+ // Use a small value instead, to prevent division by zero.
ei_real_ref(z) = NumTraits<RealScalar>::epsilon() * matrixnorm;
}
m_matX.coeffRef(i,k) = m_matX.coeff(i,k) / z;
diff --git a/Eigen/src/Eigenvalues/HessenbergDecomposition.h b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
index 0f2b78e27..79554187a 100644
--- a/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+++ b/Eigen/src/Eigenvalues/HessenbergDecomposition.h
@@ -130,7 +130,7 @@ template<typename _MatrixType> class HessenbergDecomposition
{
if(matrix.rows()<2)
{
- m_isInitialized = true;
+ m_isInitialized = true;
return;
}
m_hCoeffs.resize(matrix.rows()-1,1);
@@ -160,7 +160,7 @@ template<typename _MatrixType> class HessenbergDecomposition
m_matrix = matrix;
if(matrix.rows()<2)
{
- m_isInitialized = true;
+ m_isInitialized = true;
return *this;
}
m_hCoeffs.resize(matrix.rows()-1,1);
@@ -360,7 +360,7 @@ template<typename MatrixType> struct HessenbergDecompositionMatrixHReturnType
result = m_hess.packedMatrix();
Index n = result.rows();
if (n>2)
- result.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
+ result.bottomLeftCorner(n-2, n-2).template triangularView<Lower>().setZero();
}
Index rows() const { return m_hess.packedMatrix().rows(); }
diff --git a/Eigen/src/Eigenvalues/Tridiagonalization.h b/Eigen/src/Eigenvalues/Tridiagonalization.h
index 611b89730..4211981af 100644
--- a/Eigen/src/Eigenvalues/Tridiagonalization.h
+++ b/Eigen/src/Eigenvalues/Tridiagonalization.h
@@ -384,7 +384,9 @@ void ei_tridiagonalization_inplace(MatrixType& matA, CoeffVectorType& hCoeffs)
}
// forward declaration, implementation at the end of this file
-template<typename MatrixType, int Size=MatrixType::ColsAtCompileTime>
+template<typename MatrixType,
+ int Size=MatrixType::ColsAtCompileTime,
+ bool IsComplex=NumTraits<typename MatrixType::Scalar>::IsComplex>
struct ei_tridiagonalization_inplace_selector;
/** \brief Performs a full tridiagonalization in place
@@ -439,7 +441,7 @@ void ei_tridiagonalization_inplace(MatrixType& mat, DiagonalType& diag, SubDiago
/** \internal
* General full tridiagonalization
*/
-template<typename MatrixType, int Size>
+template<typename MatrixType, int Size, bool IsComplex>
struct ei_tridiagonalization_inplace_selector
{
typedef typename Tridiagonalization<MatrixType>::CoeffVectorType CoeffVectorType;
@@ -458,11 +460,11 @@ struct ei_tridiagonalization_inplace_selector
};
/** \internal
- * Specialization for 3x3 matrices.
+ * Specialization for 3x3 real matrices.
* Especially useful for plane fitting.
*/
template<typename MatrixType>
-struct ei_tridiagonalization_inplace_selector<MatrixType,3>
+struct ei_tridiagonalization_inplace_selector<MatrixType,3,false>
{
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::RealScalar RealScalar;
@@ -470,14 +472,14 @@ struct ei_tridiagonalization_inplace_selector<MatrixType,3>
template<typename DiagonalType, typename SubDiagonalType>
static void run(MatrixType& mat, DiagonalType& diag, SubDiagonalType& subdiag, bool extractQ)
{
- diag[0] = ei_real(mat(0,0));
+ diag[0] = mat(0,0);
RealScalar v1norm2 = ei_abs2(mat(2,0));
- if (ei_isMuchSmallerThan(v1norm2, RealScalar(1)))
+ if(v1norm2 == RealScalar(0))
{
- diag[1] = ei_real(mat(1,1));
- diag[2] = ei_real(mat(2,2));
- subdiag[0] = ei_real(mat(1,0));
- subdiag[1] = ei_real(mat(2,1));
+ diag[1] = mat(1,1);
+ diag[2] = mat(2,2);
+ subdiag[0] = mat(1,0);
+ subdiag[1] = mat(2,1);
if (extractQ)
mat.setIdentity();
}
@@ -485,18 +487,18 @@ struct ei_tridiagonalization_inplace_selector<MatrixType,3>
{
RealScalar beta = ei_sqrt(ei_abs2(mat(1,0)) + v1norm2);
RealScalar invBeta = RealScalar(1)/beta;
- Scalar m01 = ei_conj(mat(1,0)) * invBeta;
- Scalar m02 = ei_conj(mat(2,0)) * invBeta;
- Scalar q = RealScalar(2)*m01*ei_conj(mat(2,1)) + m02*(mat(2,2) - mat(1,1));
- diag[1] = ei_real(mat(1,1) + m02*q);
- diag[2] = ei_real(mat(2,2) - m02*q);
+ Scalar m01 = mat(1,0) * invBeta;
+ Scalar m02 = mat(2,0) * invBeta;
+ Scalar q = RealScalar(2)*m01*mat(2,1) + m02*(mat(2,2) - mat(1,1));
+ diag[1] = mat(1,1) + m02*q;
+ diag[2] = mat(2,2) - m02*q;
subdiag[0] = beta;
- subdiag[1] = ei_real(ei_conj(mat(2,1)) - m01 * q);
+ subdiag[1] = mat(2,1) - m01 * q;
if (extractQ)
{
mat << 1, 0, 0,
- 0, m01, m02,
- 0, m02, -m01;
+ 0, m01, m02,
+ 0, m02, -m01;
}
}
}
@@ -505,8 +507,8 @@ struct ei_tridiagonalization_inplace_selector<MatrixType,3>
/** \internal
* Trivial specialization for 1x1 matrices
*/
-template<typename MatrixType>
-struct ei_tridiagonalization_inplace_selector<MatrixType,1>
+template<typename MatrixType, bool IsComplex>
+struct ei_tridiagonalization_inplace_selector<MatrixType,1,IsComplex>
{
typedef typename MatrixType::Scalar Scalar;
diff --git a/Eigen/src/Geometry/arch/Geometry_SSE.h b/Eigen/src/Geometry/arch/Geometry_SSE.h
index 080b87d4b..0078e4aab 100644
--- a/Eigen/src/Geometry/arch/Geometry_SSE.h
+++ b/Eigen/src/Geometry/arch/Geometry_SSE.h
@@ -64,4 +64,58 @@ struct ei_cross3_impl<Architecture::SSE,VectorLhs,VectorRhs,float,true>
}
};
+
+
+
+template<class Derived, class OtherDerived>
+struct ei_quat_product<Architecture::SSE, Derived, OtherDerived, double, Aligned>
+{
+ inline static Quaternion<double> run(const QuaternionBase<Derived>& _a, const QuaternionBase<OtherDerived>& _b)
+ {
+ const Packet2d mask = _mm_castsi128_pd(_mm_set_epi32(0x0,0x0,0x80000000,0x0));
+
+ Quaternion<double> res;
+
+ const double* a = _a.coeffs().data();
+ Packet2d b_xy = _b.coeffs().template packet<Aligned>(0);
+ Packet2d b_zw = _b.coeffs().template packet<Aligned>(2);
+ Packet2d a_xx = ei_pset1(a[0]);
+ Packet2d a_yy = ei_pset1(a[1]);
+ Packet2d a_zz = ei_pset1(a[2]);
+ Packet2d a_ww = ei_pset1(a[3]);
+
+ // two temporaries:
+ Packet2d t1, t2;
+
+ /*
+ * t1 = ww*xy + yy*zw
+ * t2 = zz*xy - xx*zw
+ * res.xy = t1 +/- swap(t2)
+ */
+ t1 = ei_padd(ei_pmul(a_ww, b_xy), ei_pmul(a_yy, b_zw));
+ t2 = ei_psub(ei_pmul(a_zz, b_xy), ei_pmul(a_xx, b_zw));
+#ifdef __SSE3__
+ ei_pstore(&res.x(), _mm_addsub_pd(t1, ei_preverse(t2)));
+#else
+ ei_pstore(&res.x(), ei_padd(t1, ei_pxor(mask,ei_preverse(t2))));
+#endif
+
+ /*
+ * t1 = ww*zw - yy*xy
+ * t2 = zz*zw + xx*xy
+ * res.zw = t1 -/+ swap(t2) = swap( swap(t1) +/- t2)
+ */
+ t1 = ei_psub(ei_pmul(a_ww, b_zw), ei_pmul(a_yy, b_xy));
+ t2 = ei_padd(ei_pmul(a_zz, b_zw), ei_pmul(a_xx, b_xy));
+#ifdef __SSE3__
+ ei_pstore(&res.z(), ei_preverse(_mm_addsub_pd(ei_preverse(t1), t2)));
+#else
+ ei_pstore(&res.z(), ei_psub(t1, ei_pxor(mask,ei_preverse(t2))));
+#endif
+
+ return res;
+}
+};
+
+
#endif // EIGEN_GEOMETRY_SSE_H
diff --git a/Eigen/src/Householder/Householder.h b/Eigen/src/Householder/Householder.h
index f943a0852..c45e6469d 100644
--- a/Eigen/src/Householder/Householder.h
+++ b/Eigen/src/Householder/Householder.h
@@ -65,7 +65,7 @@ void MatrixBase<Derived>::makeHouseholder(
EIGEN_STATIC_ASSERT_VECTOR_ONLY(EssentialPart)
VectorBlock<Derived, EssentialPart::SizeAtCompileTime> tail(derived(), 1, size()-1);
- RealScalar tailSqNorm = size()==1 ? 0 : tail.squaredNorm();
+ RealScalar tailSqNorm = size()==1 ? RealScalar(0) : tail.squaredNorm();
Scalar c0 = coeff(0);
if(tailSqNorm == RealScalar(0) && ei_imag(c0)==RealScalar(0))
diff --git a/Eigen/src/LU/Determinant.h b/Eigen/src/LU/Determinant.h
index d0b70a31c..ea7db9c0f 100644
--- a/Eigen/src/LU/Determinant.h
+++ b/Eigen/src/LU/Determinant.h
@@ -47,6 +47,8 @@ template<typename Derived,
{
static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
{
+ if(Derived::ColsAtCompileTime==Dynamic && m.rows()==0)
+ return typename ei_traits<Derived>::Scalar(1);
return m.partialPivLu().determinant();
}
};
diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h
index 69e1f55ba..620f09289 100644
--- a/Eigen/src/Sparse/DynamicSparseMatrix.h
+++ b/Eigen/src/Sparse/DynamicSparseMatrix.h
@@ -54,7 +54,7 @@ struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags, _Index> >
ColsAtCompileTime = Dynamic,
MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = Dynamic,
- Flags = _Flags | NestByRefBit,
+ Flags = _Flags | NestByRefBit | LvalueBit,
CoeffReadCost = NumTraits<Scalar>::ReadCost,
SupportedAccessPatterns = OuterRandomAccessPattern
};
diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h
index ecf8efbe7..820cf2884 100644
--- a/Eigen/src/Sparse/SparseMatrix.h
+++ b/Eigen/src/Sparse/SparseMatrix.h
@@ -54,7 +54,7 @@ struct ei_traits<SparseMatrix<_Scalar, _Options, _Index> >
ColsAtCompileTime = Dynamic,
MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = Dynamic,
- Flags = _Options | NestByRefBit,
+ Flags = _Options | NestByRefBit | LvalueBit,
CoeffReadCost = NumTraits<Scalar>::ReadCost,
SupportedAccessPatterns = InnerRandomAccessPattern
};
diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h
index dfe79a3b2..c5d0a6981 100644
--- a/Eigen/src/Sparse/SparseVector.h
+++ b/Eigen/src/Sparse/SparseVector.h
@@ -48,7 +48,7 @@ struct ei_traits<SparseVector<_Scalar, _Options, _Index> >
ColsAtCompileTime = IsColVector ? 1 : Dynamic,
MaxRowsAtCompileTime = RowsAtCompileTime,
MaxColsAtCompileTime = ColsAtCompileTime,
- Flags = _Options | NestByRefBit,
+ Flags = _Options | NestByRefBit | LvalueBit,
CoeffReadCost = NumTraits<Scalar>::ReadCost,
SupportedAccessPatterns = InnerRandomAccessPattern
};
diff --git a/Eigen/src/Sparse/SparseView.h b/Eigen/src/Sparse/SparseView.h
index 3b656d5c8..5a152b255 100644
--- a/Eigen/src/Sparse/SparseView.h
+++ b/Eigen/src/Sparse/SparseView.h
@@ -31,18 +31,23 @@ struct ei_traits<SparseView<MatrixType> > : ei_traits<MatrixType>
{
typedef int Index;
typedef Sparse StorageKind;
+ enum {
+ Flags = int(ei_traits<MatrixType>::Flags) & (RowMajorBit)
+ };
};
template<typename MatrixType>
class SparseView : public SparseMatrixBase<SparseView<MatrixType> >
{
typedef typename MatrixType::Nested MatrixTypeNested;
+ typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested;
public:
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView)
SparseView(const MatrixType& mat, const Scalar& m_reference = Scalar(0),
typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) :
m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {}
+
class InnerIterator;
inline Index rows() const { return m_matrix.rows(); }
@@ -58,10 +63,10 @@ protected:
};
template<typename MatrixType>
-class SparseView<MatrixType>::InnerIterator : public MatrixTypeNested::InnerIterator
+class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator
{
public:
- typedef typename MatrixTypeNested::InnerIterator IterBase;
+ typedef typename _MatrixTypeNested::InnerIterator IterBase;
InnerIterator(const SparseView& view, Index outer) :
IterBase(view.m_matrix, outer), m_view(view)
{
diff --git a/bench/bench_gemm.cpp b/bench/bench_gemm.cpp
index 922c3cd64..bc3089b9f 100644
--- a/bench/bench_gemm.cpp
+++ b/bench/bench_gemm.cpp
@@ -10,8 +10,8 @@ using namespace std;
using namespace Eigen;
#ifndef SCALAR
-#define SCALAR std::complex<float>
-// #define SCALAR float
+// #define SCALAR std::complex<float>
+#define SCALAR float
#endif
typedef SCALAR Scalar;
diff --git a/bench/btl/libs/C_BLAS/blas.h b/bench/btl/libs/C_BLAS/blas.h
index 1da288dd4..ab3d44052 100644
--- a/bench/btl/libs/C_BLAS/blas.h
+++ b/bench/btl/libs/C_BLAS/blas.h
@@ -11,7 +11,7 @@ typedef long BLASLONG;
typedef unsigned long BLASULONG;
#endif
-int BLASFUNC(xerbla)(char *, int *info, int);
+int BLASFUNC(xerbla)(const char *, int *info, int);
float BLASFUNC(sdot) (int *, float *, int *, float *, int *);
float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *);
@@ -38,10 +38,10 @@ void BLASFUNC(zdotc) (double *, int *, double *, int *, double *, int *);
void BLASFUNC(xdotu) (double *, int *, double *, int *, double *, int *);
void BLASFUNC(xdotc) (double *, int *, double *, int *, double *, int *);
#else
-float BLASFUNC(cdotu) (int *, float *, int *, float *, int *);
-float BLASFUNC(cdotc) (int *, float *, int *, float *, int *);
-double BLASFUNC(zdotu) (int *, double *, int *, double *, int *);
-double BLASFUNC(zdotc) (int *, double *, int *, double *, int *);
+std::complex<float> BLASFUNC(cdotu) (int *, float *, int *, float *, int *);
+std::complex<float> BLASFUNC(cdotc) (int *, float *, int *, float *, int *);
+std::complex<double> BLASFUNC(zdotu) (int *, double *, int *, double *, int *);
+std::complex<double> BLASFUNC(zdotc) (int *, double *, int *, double *, int *);
double BLASFUNC(xdotu) (int *, double *, int *, double *, int *);
double BLASFUNC(xdotc) (int *, double *, int *, double *, int *);
#endif
diff --git a/bench/eig33.cpp b/bench/eig33.cpp
new file mode 100644
index 000000000..2016c2c01
--- /dev/null
+++ b/bench/eig33.cpp
@@ -0,0 +1,139 @@
+#include <iostream>
+#include <Eigen/Core>
+#include <Eigen/Eigenvalues>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+
+using namespace Eigen;
+using namespace std;
+
+template<typename Matrix, typename Roots>
+inline void computeRoots (const Matrix& rkA, Roots& adRoot)
+{
+ typedef typename Matrix::Scalar Scalar;
+ const Scalar msInv3 = 1.0/3.0;
+ const Scalar msRoot3 = ei_sqrt(Scalar(3.0));
+
+ Scalar dA00 = rkA(0,0);
+ Scalar dA01 = rkA(0,1);
+ Scalar dA02 = rkA(0,2);
+ Scalar dA11 = rkA(1,1);
+ Scalar dA12 = rkA(1,2);
+ Scalar dA22 = rkA(2,2);
+
+ // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The
+ // eigenvalues are the roots to this equation, all guaranteed to be
+ // real-valued, because the matrix is symmetric.
+ Scalar dC0 = dA00*dA11*dA22 + Scalar(2)*dA01*dA02*dA12 - dA00*dA12*dA12 - dA11*dA02*dA02 - dA22*dA01*dA01;
+ Scalar dC1 = dA00*dA11 - dA01*dA01 + dA00*dA22 - dA02*dA02 + dA11*dA22 - dA12*dA12;
+ Scalar dC2 = dA00 + dA11 + dA22;
+
+ // Construct the parameters used in classifying the roots of the equation
+ // and in solving the equation for the roots in closed form.
+ Scalar dC2Div3 = dC2*msInv3;
+ Scalar dADiv3 = (dC1 - dC2*dC2Div3)*msInv3;
+ if (dADiv3 > Scalar(0))
+ dADiv3 = Scalar(0);
+
+ Scalar dMBDiv2 = Scalar(0.5)*(dC0 + dC2Div3*(Scalar(2)*dC2Div3*dC2Div3 - dC1));
+
+ Scalar dQ = dMBDiv2*dMBDiv2 + dADiv3*dADiv3*dADiv3;
+ if (dQ > Scalar(0))
+ dQ = Scalar(0);
+
+ // Compute the eigenvalues by solving for the roots of the polynomial.
+ Scalar dMagnitude = ei_sqrt(-dADiv3);
+ Scalar dAngle = std::atan2(ei_sqrt(-dQ),dMBDiv2)*msInv3;
+ Scalar dCos = ei_cos(dAngle);
+ Scalar dSin = ei_sin(dAngle);
+ adRoot(0) = dC2Div3 + 2.f*dMagnitude*dCos;
+ adRoot(1) = dC2Div3 - dMagnitude*(dCos + msRoot3*dSin);
+ adRoot(2) = dC2Div3 - dMagnitude*(dCos - msRoot3*dSin);
+
+ // Sort in increasing order.
+ if (adRoot(0) >= adRoot(1))
+ std::swap(adRoot(0),adRoot(1));
+ if (adRoot(1) >= adRoot(2))
+ {
+ std::swap(adRoot(1),adRoot(2));
+ if (adRoot(0) >= adRoot(1))
+ std::swap(adRoot(0),adRoot(1));
+ }
+}
+
+template<typename Matrix, typename Vector>
+void eigen33(const Matrix& mat, Matrix& evecs, Vector& evals)
+{
+ typedef typename Matrix::Scalar Scalar;
+ // Scale the matrix so its entries are in [-1,1]. The scaling is applied
+ // only when at least one matrix entry has magnitude larger than 1.
+
+ Scalar scale = mat.cwiseAbs()/*.template triangularView<Lower>()*/.maxCoeff();
+ scale = std::max(scale,Scalar(1));
+ Matrix scaledMat = mat / scale;
+
+ // Compute the eigenvalues
+// scaledMat.setZero();
+ computeRoots(scaledMat,evals);
+
+ // compute the eigen vectors
+ // here we assume 3 differents eigenvalues
+
+ // "optimized version" which appears to be slower with gcc!
+// Vector base;
+// Scalar alpha, beta;
+// base << scaledMat(1,0) * scaledMat(2,1),
+// scaledMat(1,0) * scaledMat(2,0),
+// -scaledMat(1,0) * scaledMat(1,0);
+// for(int k=0; k<2; ++k)
+// {
+// alpha = scaledMat(0,0) - evals(k);
+// beta = scaledMat(1,1) - evals(k);
+// evecs.col(k) = (base + Vector(-beta*scaledMat(2,0), -alpha*scaledMat(2,1), alpha*beta)).normalized();
+// }
+// evecs.col(2) = evecs.col(0).cross(evecs.col(1)).normalized();
+
+ // naive version
+ Matrix tmp;
+ tmp = scaledMat;
+ tmp.diagonal().array() -= evals(0);
+ evecs.col(0) = tmp.row(0).cross(tmp.row(1)).normalized();
+
+ tmp = scaledMat;
+ tmp.diagonal().array() -= evals(1);
+ evecs.col(1) = tmp.row(0).cross(tmp.row(1)).normalized();
+
+ tmp = scaledMat;
+ tmp.diagonal().array() -= evals(2);
+ evecs.col(2) = tmp.row(0).cross(tmp.row(1)).normalized();
+
+ // Rescale back to the original size.
+ evals *= scale;
+}
+
+int main()
+{
+ BenchTimer t;
+ int tries = 10;
+ int rep = 400000;
+ typedef Matrix3f Mat;
+ typedef Vector3f Vec;
+ Mat A = Mat::Random(3,3);
+ A = A.adjoint() * A;
+
+ SelfAdjointEigenSolver<Mat> eig(A);
+ BENCH(t, tries, rep, eig.compute(A));
+ std::cout << "Eigen: " << t.best() << "s\n";
+
+ Mat evecs;
+ Vec evals;
+ BENCH(t, tries, rep, eigen33(A,evecs,evals));
+ std::cout << "Direct: " << t.best() << "s\n\n";
+
+ std::cerr << "Eigenvalue/eigenvector diffs:\n";
+ std::cerr << (evals - eig.eigenvalues()).transpose() << "\n";
+ for(int k=0;k<3;++k)
+ if(evecs.col(k).dot(eig.eigenvectors().col(k))<0)
+ evecs.col(k) = -evecs.col(k);
+ std::cerr << evecs - eig.eigenvectors() << "\n\n";
+}
diff --git a/bench/quatmul.cpp b/bench/quatmul.cpp
new file mode 100644
index 000000000..d91a4b01b
--- /dev/null
+++ b/bench/quatmul.cpp
@@ -0,0 +1,47 @@
+#include <iostream>
+#include <Eigen/Core>
+#include <Eigen/Geometry>
+#include <bench/BenchTimer.h>
+
+using namespace Eigen;
+
+template<typename Quat>
+EIGEN_DONT_INLINE void quatmul_default(const Quat& a, const Quat& b, Quat& c)
+{
+ c = a * b;
+}
+
+template<typename Quat>
+EIGEN_DONT_INLINE void quatmul_novec(const Quat& a, const Quat& b, Quat& c)
+{
+ c = ei_quat_product<0, Quat, Quat, typename Quat::Scalar, Aligned>::run(a,b);
+}
+
+template<typename Quat> void bench(const std::string& label)
+{
+ int tries = 10;
+ int rep = 1000000;
+ BenchTimer t;
+
+ Quat a(4, 1, 2, 3);
+ Quat b(2, 3, 4, 5);
+ Quat c;
+
+ std::cout.precision(3);
+
+ BENCH(t, tries, rep, quatmul_default(a,b,c));
+ std::cout << label << " default " << 1e3*t.best(CPU_TIMER) << "ms \t" << 1e-6*double(rep)/(t.best(CPU_TIMER)) << " M mul/s\n";
+
+ BENCH(t, tries, rep, quatmul_novec(a,b,c));
+ std::cout << label << " novec " << 1e3*t.best(CPU_TIMER) << "ms \t" << 1e-6*double(rep)/(t.best(CPU_TIMER)) << " M mul/s\n";
+}
+
+int main()
+{
+ bench<Quaternionf>("float ");
+ bench<Quaterniond>("double");
+
+ return 0;
+
+}
+
diff --git a/blas/common.h b/blas/common.h
index fa211b141..5e7117dee 100644
--- a/blas/common.h
+++ b/blas/common.h
@@ -26,6 +26,7 @@
#define EIGEN_BLAS_COMMON_H
#include <iostream>
+#include <complex>
#ifndef SCALAR
#error the token SCALAR must be defined to compile this file
@@ -86,15 +87,15 @@ enum
Conj = IsComplex
};
-typedef Map<Matrix<Scalar,Dynamic,Dynamic>, 0, OuterStride<Dynamic> > MatrixType;
+typedef Map<Matrix<Scalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > MatrixType;
typedef Map<Matrix<Scalar,Dynamic,1>, 0, InnerStride<Dynamic> > StridedVectorType;
typedef Map<Matrix<Scalar,Dynamic,1> > CompactVectorType;
template<typename T>
-Map<Matrix<T,Dynamic,Dynamic>, 0, OuterStride<Dynamic> >
+Map<Matrix<T,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> >
matrix(T* data, int rows, int cols, int stride)
{
- return Map<Matrix<T,Dynamic,Dynamic>, 0, OuterStride<Dynamic> >(data, rows, cols, OuterStride<Dynamic>(stride));
+ return Map<Matrix<T,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> >(data, rows, cols, OuterStride<>(stride));
}
template<typename T>
diff --git a/blas/level1_impl.h b/blas/level1_impl.h
index 9b79da6d5..1665310c4 100644
--- a/blas/level1_impl.h
+++ b/blas/level1_impl.h
@@ -30,8 +30,6 @@ int EIGEN_BLAS_FUNC(axpy)(int *n, RealScalar *palpha, RealScalar *px, int *incx,
Scalar* y = reinterpret_cast<Scalar*>(py);
Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
-// std::cerr << "axpy " << *n << " " << alpha << " " << *incx << " " << *incy << "\n";
-
if(*incx==1 && *incy==1) vector(y,*n) += alpha * vector(x,*n);
else if(*incx>0 && *incy>0) vector(y,*n,*incy) += alpha * vector(x,*n,*incx);
else if(*incx>0 && *incy<0) vector(y,*n,-*incy).reverse() += alpha * vector(x,*n,*incx);
@@ -126,7 +124,7 @@ int EIGEN_CAT(EIGEN_CAT(i,SCALAR_SUFFIX),amax_)(int *n, RealScalar *px, int *inc
if(*n<=0)
return 0;
- int ret;
+ DenseIndex ret;
if(*incx==1) vector(x,*n).cwiseAbs().maxCoeff(&ret);
else vector(x,*n,std::abs(*incx)).cwiseAbs().maxCoeff(&ret);
@@ -155,44 +153,36 @@ Scalar EIGEN_BLAS_FUNC(sdot)(int *n, RealScalar *px, int *incx, RealScalar *py,
#if ISCOMPLEX
// computes a dot product of a conjugated vector with another vector.
-void EIGEN_BLAS_FUNC(dotc)(RealScalar* dot, int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
+Scalar EIGEN_BLAS_FUNC(dotc)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
{
-
- std::cerr << "Eigen BLAS: _dotc is not implemented yet\n";
-
- return;
-
- // TODO: find how to return a complex to fortran
-
// std::cerr << "_dotc " << *n << " " << *incx << " " << *incy << "\n";
Scalar* x = reinterpret_cast<Scalar*>(px);
Scalar* y = reinterpret_cast<Scalar*>(py);
- if(*incx==1 && *incy==1)
- *reinterpret_cast<Scalar*>(dot) = vector(x,*n).dot(vector(y,*n));
- else
- *reinterpret_cast<Scalar*>(dot) = vector(x,*n,*incx).dot(vector(y,*n,*incy));
+ Scalar res;
+ if(*incx==1 && *incy==1) res = (vector(x,*n).dot(vector(y,*n)));
+ else if(*incx>0 && *incy>0) res = (vector(x,*n,*incx).dot(vector(y,*n,*incy)));
+ else if(*incx<0 && *incy>0) res = (vector(x,*n,-*incx).reverse().dot(vector(y,*n,*incy)));
+ else if(*incx>0 && *incy<0) res = (vector(x,*n,*incx).dot(vector(y,*n,-*incy).reverse()));
+ else if(*incx<0 && *incy<0) res = (vector(x,*n,-*incx).reverse().dot(vector(y,*n,-*incy).reverse()));
+ return res;
}
// computes a vector-vector dot product without complex conjugation.
-void EIGEN_BLAS_FUNC(dotu)(RealScalar* dot, int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
+Scalar EIGEN_BLAS_FUNC(dotu)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)
{
- std::cerr << "Eigen BLAS: _dotu is not implemented yet\n";
-
- return;
-
- // TODO: find how to return a complex to fortran
-
// std::cerr << "_dotu " << *n << " " << *incx << " " << *incy << "\n";
Scalar* x = reinterpret_cast<Scalar*>(px);
Scalar* y = reinterpret_cast<Scalar*>(py);
-
- if(*incx==1 && *incy==1)
- *reinterpret_cast<Scalar*>(dot) = (vector(x,*n).cwiseProduct(vector(y,*n))).sum();
- else
- *reinterpret_cast<Scalar*>(dot) = (vector(x,*n,*incx).cwiseProduct(vector(y,*n,*incy))).sum();
+ Scalar res;
+ if(*incx==1 && *incy==1) res = (vector(x,*n).cwiseProduct(vector(y,*n))).sum();
+ else if(*incx>0 && *incy>0) res = (vector(x,*n,*incx).cwiseProduct(vector(y,*n,*incy))).sum();
+ else if(*incx<0 && *incy>0) res = (vector(x,*n,-*incx).reverse().cwiseProduct(vector(y,*n,*incy))).sum();
+ else if(*incx>0 && *incy<0) res = (vector(x,*n,*incx).cwiseProduct(vector(y,*n,-*incy).reverse())).sum();
+ else if(*incx<0 && *incy<0) res = (vector(x,*n,-*incx).reverse().cwiseProduct(vector(y,*n,-*incy).reverse())).sum();
+ return res;
}
#endif // ISCOMPLEX
@@ -253,15 +243,60 @@ int EIGEN_BLAS_FUNC(rot)(int *n, RealScalar *px, int *incx, RealScalar *py, int
int EIGEN_BLAS_FUNC(rotg)(RealScalar *pa, RealScalar *pb, RealScalar *pc, RealScalar *ps)
{
- Scalar a = *reinterpret_cast<Scalar*>(pa);
- Scalar b = *reinterpret_cast<Scalar*>(pb);
- Scalar* c = reinterpret_cast<Scalar*>(pc);
+ Scalar& a = *reinterpret_cast<Scalar*>(pa);
+ Scalar& b = *reinterpret_cast<Scalar*>(pb);
+ RealScalar* c = pc;
Scalar* s = reinterpret_cast<Scalar*>(ps);
- PlanarRotation<Scalar> r;
- r.makeGivens(a,b);
- *c = r.c();
- *s = r.s();
+ #if !ISCOMPLEX
+ Scalar r,z;
+ Scalar aa = ei_abs(a);
+ Scalar ab = ei_abs(b);
+ if((aa+ab)==Scalar(0))
+ {
+ *c = 1;
+ *s = 0;
+ r = 0;
+ z = 0;
+ }
+ else
+ {
+ r = ei_sqrt(a*a + b*b);
+ Scalar amax = aa>ab ? a : b;
+ r = amax>0 ? r : -r;
+ *c = a/r;
+ *s = b/r;
+ z = 1;
+ if (aa > ab) z = *s;
+ if (ab > aa && *c!=RealScalar(0))
+ z = Scalar(1)/ *c;
+ }
+ *pa = r;
+ *pb = z;
+ #else
+ Scalar alpha;
+ RealScalar norm,scale;
+ if(ei_abs(a)==RealScalar(0))
+ {
+ *c = RealScalar(0);
+ *s = Scalar(1);
+ a = b;
+ }
+ else
+ {
+ scale = ei_abs(a) + ei_abs(b);
+ norm = scale*ei_sqrt((ei_abs2(a/scale))+ (ei_abs2(b/scale)));
+ alpha = a/ei_abs(a);
+ *c = ei_abs(a)/norm;
+ *s = alpha*ei_conj(b)/norm;
+ a = alpha*norm;
+ }
+ #endif
+
+// PlanarRotation<Scalar> r;
+// r.makeGivens(a,b);
+// *c = r.c();
+// *s = r.s();
return 0;
}
diff --git a/blas/level3_impl.h b/blas/level3_impl.h
index 9f04ddcb0..38b2637c3 100644
--- a/blas/level3_impl.h
+++ b/blas/level3_impl.h
@@ -27,7 +27,7 @@
int EIGEN_BLAS_FUNC(gemm)(char *opa, char *opb, int *m, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
{
// std::cerr << "in gemm " << *opa << " " << *opb << " " << *m << " " << *n << " " << *k << " " << *lda << " " << *ldb << " " << *ldc << " " << *palpha << " " << *pbeta << "\n";
- typedef void (*functype)(int, int, int, const Scalar *, int, const Scalar *, int, Scalar *, int, Scalar, Eigen::GemmParallelInfo<Scalar>*);
+ typedef void (*functype)(DenseIndex, DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, Scalar, ei_level3_blocking<Scalar,Scalar>&, Eigen::GemmParallelInfo<DenseIndex>*);
static functype func[12];
static bool init = false;
@@ -35,15 +35,15 @@ int EIGEN_BLAS_FUNC(gemm)(char *opa, char *opb, int *m, int *n, int *k, RealScal
{
for(int k=0; k<12; ++k)
func[k] = 0;
- func[NOTR | (NOTR << 2)] = (ei_general_matrix_matrix_product<Scalar,ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (NOTR << 2)] = (ei_general_matrix_matrix_product<Scalar,RowMajor,false,ColMajor,false,ColMajor>::run);
- func[ADJ | (NOTR << 2)] = (ei_general_matrix_matrix_product<Scalar,RowMajor,Conj, ColMajor,false,ColMajor>::run);
- func[NOTR | (TR << 2)] = (ei_general_matrix_matrix_product<Scalar,ColMajor,false,RowMajor,false,ColMajor>::run);
- func[TR | (TR << 2)] = (ei_general_matrix_matrix_product<Scalar,RowMajor,false,RowMajor,false,ColMajor>::run);
- func[ADJ | (TR << 2)] = (ei_general_matrix_matrix_product<Scalar,RowMajor,Conj, RowMajor,false,ColMajor>::run);
- func[NOTR | (ADJ << 2)] = (ei_general_matrix_matrix_product<Scalar,ColMajor,false,RowMajor,Conj, ColMajor>::run);
- func[TR | (ADJ << 2)] = (ei_general_matrix_matrix_product<Scalar,RowMajor,false,RowMajor,Conj, ColMajor>::run);
- func[ADJ | (ADJ << 2)] = (ei_general_matrix_matrix_product<Scalar,RowMajor,Conj, RowMajor,Conj, ColMajor>::run);
+ func[NOTR | (NOTR << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (NOTR << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,RowMajor,false,ColMajor,false,ColMajor>::run);
+ func[ADJ | (NOTR << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,RowMajor,Conj, ColMajor,false,ColMajor>::run);
+ func[NOTR | (TR << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,ColMajor,false,RowMajor,false,ColMajor>::run);
+ func[TR | (TR << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,RowMajor,false,RowMajor,false,ColMajor>::run);
+ func[ADJ | (TR << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,RowMajor,Conj, RowMajor,false,ColMajor>::run);
+ func[NOTR | (ADJ << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,ColMajor,false,RowMajor,Conj, ColMajor>::run);
+ func[TR | (ADJ << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,RowMajor,false,RowMajor,Conj, ColMajor>::run);
+ func[ADJ | (ADJ << 2)] = (ei_general_matrix_matrix_product<Scalar,DenseIndex,RowMajor,Conj, RowMajor,Conj, ColMajor>::run);
init = true;
}
@@ -62,19 +62,21 @@ int EIGEN_BLAS_FUNC(gemm)(char *opa, char *opb, int *m, int *n, int *k, RealScal
}
if(beta!=Scalar(1))
- if(beta==Scalar(0))
- matrix(c, *m, *n, *ldc).setZero();
- else
- matrix(c, *m, *n, *ldc) *= beta;
+ {
+ if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();
+ else matrix(c, *m, *n, *ldc) *= beta;
+ }
- func[code](*m, *n, *k, a, *lda, b, *ldb, c, *ldc, alpha, 0);
+ ei_gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic> blocking(*m,*n,*k);
+
+ func[code](*m, *n, *k, a, *lda, b, *ldb, c, *ldc, alpha, blocking, 0);
return 0;
}
int EIGEN_BLAS_FUNC(trsm)(char *side, char *uplo, char *opa, char *diag, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb)
{
// std::cerr << "in trsm " << *side << " " << *uplo << " " << *opa << " " << *diag << " " << *m << "," << *n << " " << *palpha << " " << *lda << " " << *ldb<< "\n";
- typedef void (*functype)(int, int, const Scalar *, int, Scalar *, int);
+ typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex);
static functype func[32];
static bool init = false;
@@ -83,38 +85,38 @@ int EIGEN_BLAS_FUNC(trsm)(char *side, char *uplo, char *opa, char *diag, int *m,
for(int k=0; k<32; ++k)
func[k] = 0;
- func[NOTR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Upper|0, false,ColMajor,ColMajor>::run);
- func[TR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Lower|0, false,RowMajor,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Lower|0, Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0, false,ColMajor,ColMajor>::run);
+ func[TR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0, false,RowMajor,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0, Conj, RowMajor,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Upper|0, false,ColMajor,ColMajor>::run);
- func[TR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Lower|0, false,RowMajor,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Lower|0, Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0, false,ColMajor,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0, false,RowMajor,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0, Conj, RowMajor,ColMajor>::run);
- func[NOTR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Lower|0, false,ColMajor,ColMajor>::run);
- func[TR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Upper|0, false,RowMajor,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Upper|0, Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0, false,ColMajor,ColMajor>::run);
+ func[TR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0, false,RowMajor,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0, Conj, RowMajor,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Lower|0, false,ColMajor,ColMajor>::run);
- func[TR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Upper|0, false,RowMajor,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Upper|0, Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0, false,ColMajor,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0, false,RowMajor,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0, Conj, RowMajor,ColMajor>::run);
- func[NOTR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Upper|UnitDiag,false,ColMajor,ColMajor>::run);
- func[TR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Lower|UnitDiag,false,RowMajor,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,false,ColMajor,ColMajor>::run);
+ func[TR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,false,RowMajor,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Upper|UnitDiag,false,ColMajor,ColMajor>::run);
- func[TR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Lower|UnitDiag,false,RowMajor,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,false,ColMajor,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,false,RowMajor,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);
- func[NOTR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Lower|UnitDiag,false,ColMajor,ColMajor>::run);
- func[TR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Upper|UnitDiag,false,RowMajor,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheLeft, Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,false,ColMajor,ColMajor>::run);
+ func[TR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,false,RowMajor,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Lower|UnitDiag,false,ColMajor,ColMajor>::run);
- func[TR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Upper|UnitDiag,false,RowMajor,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,OnTheRight,Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,false,ColMajor,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,false,RowMajor,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);
init = true;
}
@@ -148,7 +150,7 @@ int EIGEN_BLAS_FUNC(trsm)(char *side, char *uplo, char *opa, char *diag, int *m,
int EIGEN_BLAS_FUNC(trmm)(char *side, char *uplo, char *opa, char *diag, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb)
{
// std::cerr << "in trmm " << *side << " " << *uplo << " " << *opa << " " << *diag << " " << *m << " " << *n << " " << *lda << " " << *ldb << " " << *palpha << "\n";
- typedef void (*functype)(int, int, const Scalar *, int, const Scalar *, int, Scalar *, int, Scalar);
+ typedef void (*functype)(DenseIndex, DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, Scalar);
static functype func[32];
static bool init = false;
if(!init)
@@ -156,37 +158,37 @@ int EIGEN_BLAS_FUNC(trmm)(char *side, char *uplo, char *opa, char *diag, int *m,
for(int k=0; k<32; ++k)
func[k] = 0;
- func[NOTR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|0, true, ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|0, true, RowMajor,false,ColMajor,false,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|0, true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, true, ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, true, RowMajor,false,ColMajor,false,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|0, false,ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|0, false,ColMajor,false,RowMajor,false,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|0, false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, false,ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, false,ColMajor,false,RowMajor,false,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
- func[NOTR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|0, true, ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|0, true, RowMajor,false,ColMajor,false,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|0, true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, true, ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, true, RowMajor,false,ColMajor,false,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|0, false,ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|0, false,ColMajor,false,RowMajor,false,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|0, false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, false,ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, false,ColMajor,false,RowMajor,false,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
- func[NOTR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
- func[NOTR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);
- func[ADJ | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
+ func[NOTR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);
+ func[ADJ | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);
- func[NOTR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Lower|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);
- func[TR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);
- func[ADJ | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,Upper|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
+ func[NOTR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);
+ func[TR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);
+ func[ADJ | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (ei_product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);
init = true;
}
@@ -203,14 +205,17 @@ int EIGEN_BLAS_FUNC(trmm)(char *side, char *uplo, char *opa, char *diag, int *m,
return 0;
}
+ if(*m==0 || *n==0)
+ return 1;
+
// FIXME find a way to avoid this copy
- Matrix<Scalar,Dynamic,Dynamic> tmp = matrix(b,*m,*n,*ldb);
+ Matrix<Scalar,Dynamic,Dynamic,ColMajor> tmp = matrix(b,*m,*n,*ldb);
matrix(b,*m,*n,*ldb).setZero();
if(SIDE(*side)==LEFT)
- func[code](*m, *n, a, *lda, tmp.data(), tmp.outerStride(), b, *ldb, alpha);
+ func[code](*m, *n, *m, a, *lda, tmp.data(), tmp.outerStride(), b, *ldb, alpha);
else
- func[code](*n, *m, tmp.data(), tmp.outerStride(), a, *lda, b, *ldb, alpha);
+ func[code](*m, *n, *n, tmp.data(), tmp.outerStride(), a, *lda, b, *ldb, alpha);
return 1;
}
@@ -233,19 +238,46 @@ int EIGEN_BLAS_FUNC(symm)(char *side, char *uplo, int *m, int *n, RealScalar *pa
}
if(beta!=Scalar(1))
+ {
if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();
else matrix(c, *m, *n, *ldc) *= beta;
+ }
+ if(*m==0 || *n==0)
+ {
+ return 1;
+ }
+
+ #if ISCOMPLEX
+ // FIXME add support for symmetric complex matrix
+ int size = (SIDE(*side)==LEFT) ? (*m) : (*n);
+ Matrix<Scalar,Dynamic,Dynamic,ColMajor> matA(size,size);
+ if(UPLO(*uplo)==UP)
+ {
+ matA.triangularView<Upper>() = matrix(a,size,size,*lda);
+ matA.triangularView<Lower>() = matrix(a,size,size,*lda).transpose();
+ }
+ else if(UPLO(*uplo)==LO)
+ {
+ matA.triangularView<Lower>() = matrix(a,size,size,*lda);
+ matA.triangularView<Upper>() = matrix(a,size,size,*lda).transpose();
+ }
+ if(SIDE(*side)==LEFT)
+ matrix(c, *m, *n, *ldc) += alpha * matA * matrix(b, *m, *n, *ldb);
+ else if(SIDE(*side)==RIGHT)
+ matrix(c, *m, *n, *ldc) += alpha * matrix(b, *m, *n, *ldb) * matA;
+ #else
if(SIDE(*side)==LEFT)
- if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar, RowMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
- else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar, ColMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
+ if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar, DenseIndex, RowMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
+ else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
else return 0;
else if(SIDE(*side)==RIGHT)
- if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar, ColMajor,false,false, RowMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
- else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar, ColMajor,false,false, ColMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
+ if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,false,false, RowMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
+ else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,false,false, ColMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
else return 0;
else
return 0;
+ #endif
return 0;
}
@@ -255,7 +287,7 @@ int EIGEN_BLAS_FUNC(symm)(char *side, char *uplo, int *m, int *n, RealScalar *pa
int EIGEN_BLAS_FUNC(syrk)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pbeta, RealScalar *pc, int *ldc)
{
// std::cerr << "in syrk " << *uplo << " " << *op << " " << *n << " " << *k << " " << *palpha << " " << *lda << " " << *pbeta << " " << *ldc << "\n";
- typedef void (*functype)(int, int, const Scalar *, int, Scalar *, int, Scalar);
+ typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, Scalar);
static functype func[8];
static bool init = false;
@@ -264,13 +296,13 @@ int EIGEN_BLAS_FUNC(syrk)(char *uplo, char *op, int *n, int *k, RealScalar *palp
for(int k=0; k<8; ++k)
func[k] = 0;
- func[NOTR | (UP << 2)] = (ei_selfadjoint_product<Scalar,ColMajor,ColMajor,true, Upper>::run);
- func[TR | (UP << 2)] = (ei_selfadjoint_product<Scalar,RowMajor,ColMajor,false,Upper>::run);
- func[ADJ | (UP << 2)] = (ei_selfadjoint_product<Scalar,RowMajor,ColMajor,false,Upper>::run);
+ func[NOTR | (UP << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,ColMajor,ColMajor,true, Upper>::run);
+ func[TR | (UP << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,RowMajor,ColMajor,false,Upper>::run);
+ func[ADJ | (UP << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,RowMajor,ColMajor,false,Upper>::run);
- func[NOTR | (LO << 2)] = (ei_selfadjoint_product<Scalar,ColMajor,ColMajor,true, Lower>::run);
- func[TR | (LO << 2)] = (ei_selfadjoint_product<Scalar,RowMajor,ColMajor,false,Lower>::run);
- func[ADJ | (LO << 2)] = (ei_selfadjoint_product<Scalar,RowMajor,ColMajor,false,Lower>::run);
+ func[NOTR | (LO << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,ColMajor,ColMajor,true, Lower>::run);
+ func[TR | (LO << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,RowMajor,ColMajor,false,Lower>::run);
+ func[ADJ | (LO << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,RowMajor,ColMajor,false,Lower>::run);
init = true;
}
@@ -289,10 +321,30 @@ int EIGEN_BLAS_FUNC(syrk)(char *uplo, char *op, int *n, int *k, RealScalar *palp
}
if(beta!=Scalar(1))
+ {
if(UPLO(*uplo)==UP) matrix(c, *n, *n, *ldc).triangularView<Upper>() *= beta;
else matrix(c, *n, *n, *ldc).triangularView<Lower>() *= beta;
+ }
+ #if ISCOMPLEX
+ // FIXME add support for symmetric complex matrix
+ if(UPLO(*uplo)==UP)
+ {
+ if(OP(*op)==NOTR)
+ matrix(c, *n, *n, *ldc).triangularView<Upper>() += alpha * matrix(a,*n,*k,*lda) * matrix(a,*n,*k,*lda).transpose();
+ else
+ matrix(c, *n, *n, *ldc).triangularView<Upper>() += alpha * matrix(a,*k,*n,*lda).transpose() * matrix(a,*k,*n,*lda);
+ }
+ else
+ {
+ if(OP(*op)==NOTR)
+ matrix(c, *n, *n, *ldc).triangularView<Lower>() += alpha * matrix(a,*n,*k,*lda) * matrix(a,*n,*k,*lda).transpose();
+ else
+ matrix(c, *n, *n, *ldc).triangularView<Lower>() += alpha * matrix(a,*k,*n,*lda).transpose() * matrix(a,*k,*n,*lda);
+ }
+ #else
func[code](*n, *k, a, *lda, c, *ldc, alpha);
+ #endif
return 0;
}
@@ -307,8 +359,44 @@ int EIGEN_BLAS_FUNC(syr2k)(char *uplo, char *op, int *n, int *k, RealScalar *pal
Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
Scalar beta = *reinterpret_cast<Scalar*>(pbeta);
- // TODO
- std::cerr << "Eigen BLAS: _syr2k is not implemented yet\n";
+ if(*n<=0 || *k<0)
+ {
+ return 0;
+ }
+
+ if(beta!=Scalar(1))
+ {
+ if(UPLO(*uplo)==UP) matrix(c, *n, *n, *ldc).triangularView<Upper>() *= beta;
+ else matrix(c, *n, *n, *ldc).triangularView<Lower>() *= beta;
+ }
+
+ if(*k==0)
+ return 1;
+
+ if(OP(*op)==NOTR)
+ {
+ if(UPLO(*uplo)==UP)
+ {
+ matrix(c, *n, *n, *ldc).triangularView<Upper>()
+ += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).transpose()
+ + alpha*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).transpose();
+ }
+ else if(UPLO(*uplo)==LO)
+ matrix(c, *n, *n, *ldc).triangularView<Lower>()
+ += alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).transpose()
+ + alpha*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).transpose();
+ }
+ else if(OP(*op)==TR || OP(*op)==ADJ)
+ {
+ if(UPLO(*uplo)==UP)
+ matrix(c, *n, *n, *ldc).triangularView<Upper>()
+ += alpha*matrix(a, *k, *n, *lda).transpose()*matrix(b, *k, *n, *ldb)
+ + alpha*matrix(b, *k, *n, *ldb).transpose()*matrix(a, *k, *n, *lda);
+ else if(UPLO(*uplo)==LO)
+ matrix(c, *n, *n, *ldc).triangularView<Lower>()
+ += alpha*matrix(a, *k, *n, *lda).transpose()*matrix(b, *k, *n, *ldb)
+ + alpha*matrix(b, *k, *n, *ldb).transpose()*matrix(a, *k, *n, *lda);
+ }
return 0;
}
@@ -333,17 +421,32 @@ int EIGEN_BLAS_FUNC(hemm)(char *side, char *uplo, int *m, int *n, RealScalar *pa
return 0;
}
- if(beta!=Scalar(1))
+ if(beta==Scalar(0))
+ matrix(c, *m, *n, *ldc).setZero();
+ else if(beta!=Scalar(1))
matrix(c, *m, *n, *ldc) *= beta;
+
+ if(*m==0 || *n==0)
+ {
+ return 1;
+ }
if(SIDE(*side)==LEFT)
- if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar, RowMajor,true,Conj, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
- else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar, ColMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
+ {
+ if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar,DenseIndex,RowMajor,true,Conj, ColMajor,false,false, ColMajor>
+ ::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
+ else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,true,false, ColMajor,false,false, ColMajor>
+ ::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);
else return 0;
+ }
else if(SIDE(*side)==RIGHT)
- if(UPLO(*uplo)==UP) ei_product_selfadjoint_matrix<Scalar, ColMajor,false,false, RowMajor,true,Conj, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
- else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar, ColMajor,false,false, ColMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
+ {
+ if(UPLO(*uplo)==UP) matrix(c,*m,*n,*ldc) += alpha * matrix(b,*m,*n,*ldb) * matrix(a,*n,*n,*lda).selfadjointView<Upper>();/*ei_product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,false,false, RowMajor,true,Conj, ColMajor>
+ ::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);*/
+ else if(UPLO(*uplo)==LO) ei_product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,false,false, ColMajor,true,false, ColMajor>
+ ::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);
else return 0;
+ }
else
{
return 0;
@@ -356,7 +459,7 @@ int EIGEN_BLAS_FUNC(hemm)(char *side, char *uplo, int *m, int *n, RealScalar *pa
// c = alpha*conj(a')*a + beta*c for op = 'C'or'c'
int EIGEN_BLAS_FUNC(herk)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pbeta, RealScalar *pc, int *ldc)
{
- typedef void (*functype)(int, int, const Scalar *, int, Scalar *, int, Scalar);
+ typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, Scalar);
static functype func[8];
static bool init = false;
@@ -365,11 +468,11 @@ int EIGEN_BLAS_FUNC(herk)(char *uplo, char *op, int *n, int *k, RealScalar *palp
for(int k=0; k<8; ++k)
func[k] = 0;
- func[NOTR | (UP << 2)] = (ei_selfadjoint_product<Scalar,ColMajor,ColMajor,true, Upper>::run);
- func[ADJ | (UP << 2)] = (ei_selfadjoint_product<Scalar,RowMajor,ColMajor,false,Upper>::run);
+ func[NOTR | (UP << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,ColMajor,ColMajor,true, Upper>::run);
+ func[ADJ | (UP << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,RowMajor,ColMajor,false,Upper>::run);
- func[NOTR | (LO << 2)] = (ei_selfadjoint_product<Scalar,ColMajor,ColMajor,true, Lower>::run);
- func[ADJ | (LO << 2)] = (ei_selfadjoint_product<Scalar,RowMajor,ColMajor,false,Lower>::run);
+ func[NOTR | (LO << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,ColMajor,ColMajor,true, Lower>::run);
+ func[ADJ | (LO << 2)] = (ei_selfadjoint_product<Scalar,DenseIndex,RowMajor,ColMajor,false,Lower>::run);
init = true;
}
@@ -408,24 +511,60 @@ int EIGEN_BLAS_FUNC(herk)(char *uplo, char *op, int *n, int *k, RealScalar *palp
}
// c = alpha*a*conj(b') + conj(alpha)*b*conj(a') + beta*c, for op = 'N'or'n'
-// c = alpha*conj(b')*a + conj(alpha)*conj(a')*b + beta*c, for op = 'C'or'c'
+// c = alpha*conj(a')*b + conj(alpha)*conj(b')*a + beta*c, for op = 'C'or'c'
int EIGEN_BLAS_FUNC(her2k)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)
{
Scalar* a = reinterpret_cast<Scalar*>(pa);
Scalar* b = reinterpret_cast<Scalar*>(pb);
Scalar* c = reinterpret_cast<Scalar*>(pc);
Scalar alpha = *reinterpret_cast<Scalar*>(palpha);
- Scalar beta = *reinterpret_cast<Scalar*>(pbeta);
+ RealScalar beta = *pbeta;
- if(*n<0 || *k<0)
+ if(*n<=0 || *k<0)
{
return 0;
}
- // TODO
- std::cerr << "Eigen BLAS: _her2k is not implemented yet\n";
+ if(beta!=RealScalar(1))
+ {
+ if(UPLO(*uplo)==UP) matrix(c, *n, *n, *ldc).triangularView<StrictlyUpper>() *= beta;
+ else matrix(c, *n, *n, *ldc).triangularView<StrictlyLower>() *= beta;
- return 0;
+ matrix(c, *n, *n, *ldc).diagonal().real() *= beta;
+ matrix(c, *n, *n, *ldc).diagonal().imag().setZero();
+ }
+ else if(*k>0 && alpha!=Scalar(0))
+ matrix(c, *n, *n, *ldc).diagonal().imag().setZero();
+
+ if(*k==0)
+ return 1;
+
+ if(OP(*op)==NOTR)
+ {
+ if(UPLO(*uplo)==UP)
+ {
+ matrix(c, *n, *n, *ldc).triangularView<Upper>()
+ += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
+ + ei_conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
+ }
+ else if(UPLO(*uplo)==LO)
+ matrix(c, *n, *n, *ldc).triangularView<Lower>()
+ += alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()
+ + ei_conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();
+ }
+ else if(OP(*op)==ADJ)
+ {
+ if(UPLO(*uplo)==UP)
+ matrix(c, *n, *n, *ldc).triangularView<Upper>()
+ += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
+ + ei_conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
+ else if(UPLO(*uplo)==LO)
+ matrix(c, *n, *n, *ldc).triangularView<Lower>()
+ += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)
+ + ei_conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);
+ }
+
+ return 1;
}
#endif // ISCOMPLEX
diff --git a/blas/xerbla.cpp b/blas/xerbla.cpp
index 2e7ad6eff..bda1d2f46 100644
--- a/blas/xerbla.cpp
+++ b/blas/xerbla.cpp
@@ -6,7 +6,7 @@ extern "C"
{
#endif
-int xerbla_(char * msg, int *info, int)
+int xerbla_(const char * msg, int *info, int)
{
std::cerr << "Eigen BLAS ERROR #" << *info << ": " << msg << "\n";
return 0;
diff --git a/cmake/FindGMP.cmake b/cmake/FindGMP.cmake
new file mode 100644
index 000000000..1f0273960
--- /dev/null
+++ b/cmake/FindGMP.cmake
@@ -0,0 +1,21 @@
+# Try to find the GNU Multiple Precision Arithmetic Library (GMP)
+# See http://gmplib.org/
+
+if (GMP_INCLUDES AND GMP_LIBRARIES)
+ set(GMP_FIND_QUIETLY TRUE)
+endif (GMP_INCLUDES AND GMP_LIBRARIES)
+
+find_path(GMP_INCLUDES
+ NAMES
+ gmp.h
+ PATHS
+ $ENV{GMPDIR}
+ ${INCLUDE_INSTALL_DIR}
+)
+
+find_library(GMP_LIBRARIES gmp PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(GMP DEFAULT_MSG
+ GMP_INCLUDES GMP_LIBRARIES)
+mark_as_advanced(GMP_INCLUDES GMP_LIBRARIES)
diff --git a/cmake/FindMPFR.cmake b/cmake/FindMPFR.cmake
new file mode 100644
index 000000000..aa4c2cd7d
--- /dev/null
+++ b/cmake/FindMPFR.cmake
@@ -0,0 +1,83 @@
+# Try to find the MPFR library
+# See http://www.mpfr.org/
+#
+# This module supports requiring a minimum version, e.g. you can do
+# find_package(MPFR 2.3.0)
+# to require version 2.3.0 to newer of MPFR.
+#
+# Once done this will define
+#
+# MPFR_FOUND - system has MPFR lib with correct version
+# MPFR_INCLUDES - the MPFR include directory
+# MPFR_LIBRARIES - the MPFR library
+# MPFR_VERSION - MPFR version
+
+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>
+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>
+# Copyright (c) 2010 Jitse Niesen, <jitse@maths.leeds.ac.uk>
+# Redistribution and use is allowed according to the terms of the BSD license.
+
+# Set MPFR_INCLUDES
+
+find_path(MPFR_INCLUDES
+ NAMES
+ mpfr.h
+ PATHS
+ $ENV{GMPDIR}
+ ${INCLUDE_INSTALL_DIR}
+)
+
+# Set MPFR_FIND_VERSION to 1.0.0 if no minimum version is specified
+
+if(NOT MPFR_FIND_VERSION)
+ if(NOT MPFR_FIND_VERSION_MAJOR)
+ set(MPFR_FIND_VERSION_MAJOR 1)
+ endif(NOT MPFR_FIND_VERSION_MAJOR)
+ if(NOT MPFR_FIND_VERSION_MINOR)
+ set(MPFR_FIND_VERSION_MINOR 0)
+ endif(NOT MPFR_FIND_VERSION_MINOR)
+ if(NOT MPFR_FIND_VERSION_PATCH)
+ set(MPFR_FIND_VERSION_PATCH 0)
+ endif(NOT MPFR_FIND_VERSION_PATCH)
+
+ set(MPFR_FIND_VERSION "${MPFR_FIND_VERSION_MAJOR}.${MPFR_FIND_VERSION_MINOR}.${MPFR_FIND_VERSION_PATCH}")
+endif(NOT MPFR_FIND_VERSION)
+
+
+if(MPFR_INCLUDES)
+
+ # Set MPFR_VERSION
+
+ file(READ "${MPFR_INCLUDES}/mpfr.h" _mpfr_version_header)
+
+ string(REGEX MATCH "define[ \t]+MPFR_VERSION_MAJOR[ \t]+([0-9]+)" _mpfr_major_version_match "${_mpfr_version_header}")
+ set(MPFR_MAJOR_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+MPFR_VERSION_MINOR[ \t]+([0-9]+)" _mpfr_minor_version_match "${_mpfr_version_header}")
+ set(MPFR_MINOR_VERSION "${CMAKE_MATCH_1}")
+ string(REGEX MATCH "define[ \t]+MPFR_VERSION_PATCHLEVEL[ \t]+([0-9]+)" _mpfr_patchlevel_version_match "${_mpfr_version_header}")
+ set(MPFR_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}")
+
+ set(MPFR_VERSION ${MPFR_MAJOR_VERSION}.${MPFR_MINOR_VERSION}.${MPFR_PATCHLEVEL_VERSION})
+
+ # Check whether found version exceeds minimum version
+
+ if(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})
+ set(MPFR_VERSION_OK FALSE)
+ message(STATUS "MPFR version ${MPFR_VERSION} found in ${MPFR_INCLUDES}, "
+ "but at least version ${MPFR_FIND_VERSION} is required")
+ else(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})
+ set(MPFR_VERSION_OK TRUE)
+ endif(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})
+
+endif(MPFR_INCLUDES)
+
+# Set MPFR_LIBRARIES
+
+find_library(MPFR_LIBRARIES mpfr PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})
+
+# Epilogue
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MPFR DEFAULT_MSG
+ MPFR_INCLUDES MPFR_LIBRARIES MPFR_VERSION_OK)
+mark_as_advanced(MPFR_INCLUDES MPFR_LIBRARIES)
diff --git a/demos/mandelbrot/mandelbrot.cpp b/demos/mandelbrot/mandelbrot.cpp
index 14341b7e4..f89526cf6 100644
--- a/demos/mandelbrot/mandelbrot.cpp
+++ b/demos/mandelbrot/mandelbrot.cpp
@@ -23,6 +23,7 @@
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "mandelbrot.h"
+#include <iostream>
#include<QtGui/QPainter>
#include<QtGui/QImage>
#include<QtGui/QMouseEvent>
@@ -45,7 +46,7 @@ template<> struct iters_before_test<double> { enum { ret = 16 }; };
template<typename Real> void MandelbrotThread::render(int img_width, int img_height)
{
enum { packetSize = Eigen::ei_packet_traits<Real>::size }; // number of reals in a Packet
- typedef Eigen::Matrix<Real, packetSize, 1> Packet; // wrap a Packet as a vector
+ typedef Eigen::Array<Real, packetSize, 1> Packet; // wrap a Packet as a vector
enum { iters_before_test = iters_before_test<Real>::ret };
max_iter = (max_iter / iters_before_test) * iters_before_test;
@@ -54,7 +55,7 @@ template<typename Real> void MandelbrotThread::render(int img_width, int img_hei
const double xradius = widget->xradius;
const double yradius = xradius * img_height / img_width;
const int threadcount = widget->threadcount;
- typedef Eigen::Matrix<Real, 2, 1> Vector2;
+ typedef Eigen::Array<Real, 2, 1> Vector2;
Vector2 start(widget->center.x() - widget->xradius, widget->center.y() - yradius);
Vector2 step(2*widget->xradius/img_width, 2*yradius/img_height);
total_iter = 0;
@@ -87,16 +88,16 @@ template<typename Real> void MandelbrotThread::render(int img_width, int img_hei
{
# define ITERATE \
pzr_buf = pzr; \
- pzr = pzr.cwise().square(); \
- pzr -= pzi.cwise().square(); \
+ pzr = pzr.square(); \
+ pzr -= pzi.square(); \
pzr += pcr; \
- pzi = (2*pzr_buf).cwise()*pzi; \
+ pzi = (2*pzr_buf)*pzi; \
pzi += pci;
ITERATE ITERATE ITERATE ITERATE
}
- pix_dont_diverge = ((pzr.cwise().square() + pzi.cwise().square())
+ pix_dont_diverge = ((pzr.square() + pzi.square())
.eval() // temporary fix as what follows is not yet vectorized by Eigen
- .cwise() <= Packet::Constant(4))
+ <= Packet::Constant(4))
// the 4 here is not a magic value, it's a math fact that if
// the square modulus is >4 then divergence is inevitable.
.template cast<int>();
diff --git a/demos/mandelbrot/mandelbrot.h b/demos/mandelbrot/mandelbrot.h
index d0e3b6c96..950be82e2 100644
--- a/demos/mandelbrot/mandelbrot.h
+++ b/demos/mandelbrot/mandelbrot.h
@@ -25,7 +25,7 @@
#ifndef MANDELBROT_H
#define MANDELBROT_H
-#include <Eigen/Array>
+#include <Eigen/Core>
#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtCore/QThread>
diff --git a/demos/opengl/quaternion_demo.cpp b/demos/opengl/quaternion_demo.cpp
index 1de645c05..c03a89cd5 100644
--- a/demos/opengl/quaternion_demo.cpp
+++ b/demos/opengl/quaternion_demo.cpp
@@ -25,10 +25,11 @@
#include "quaternion_demo.h"
#include "icosphere.h"
-#include <Eigen/Array>
+#include <Eigen/Geometry>
#include <Eigen/QR>
#include <Eigen/LU>
+#include <iostream>
#include <QEvent>
#include <QMouseEvent>
#include <QInputDialog>
@@ -187,8 +188,8 @@ public:
Matrix3 toRotationMatrix(void) const
{
- Vector3 c = m_angles.cwise().cos();
- Vector3 s = m_angles.cwise().sin();
+ Vector3 c = m_angles.array().cos();
+ Vector3 s = m_angles.array().sin();
Matrix3 res;
res << c.y()*c.z(), -c.y()*s.z(), s.y(),
c.z()*s.x()*s.y()+c.x()*s.z(), c.x()*c.z()-s.x()*s.y()*s.z(), -c.y()*s.x(),
diff --git a/doc/C01_TutorialMatrixClass.dox b/doc/C01_TutorialMatrixClass.dox
index 27788b2b2..b5d7ec0c7 100644
--- a/doc/C01_TutorialMatrixClass.dox
+++ b/doc/C01_TutorialMatrixClass.dox
@@ -132,13 +132,15 @@ Vector4d c(5.0, 6.0, 7.0, 8.0);
The primary coefficient accessors and mutators in Eigen are the overloaded parenthesis operators.
For matrices, the row index is always passed first. For vectors, just pass one index.
The numbering starts at 0. This example is self-explanatory:
-\include tut_matrix_coefficient_accessors.cpp
+
+<table class="tutorial_code"><tr><td>
+Example: \include tut_matrix_coefficient_accessors.cpp
+</td>
+<td>
Output: \verbinclude tut_matrix_coefficient_accessors.out
+</td></tr></table>
-Note that the syntax
-\code
-m(index)
-\endcode
+Note that the syntax <tt> m(index) </tt>
is not restricted to vectors, it is also available for general matrices, meaning index-based access
in the array of coefficients. This however depends on the matrix's storage order. All Eigen matrices default to
column-major storage order, but this can be changed to row-major, see \ref TopicStorageOrders "Storage orders".
@@ -149,17 +151,29 @@ would make matrix[i,j] compile to the same thing as matrix[j] !
\section TutorialMatrixCommaInitializer Comma-initialization
-Matrix and vector coefficients can be conveniently set using the so-called \em comma-initializer syntax.
+%Matrix and vector coefficients can be conveniently set using the so-called \em comma-initializer syntax.
For now, it is enough to know this example:
-\include Tutorial_commainit_01.cpp
+
+<table class="tutorial_code"><tr><td>
+Example: \include Tutorial_commainit_01.cpp
+</td>
+<td>
Output: \verbinclude Tutorial_commainit_01.out
+</td></tr></table>
+
+
The right-hand side can also contain matrix expressions as discussed in \ref TutorialAdvancedInitialization "this page".
\section TutorialMatrixSizesResizing Resizing
The current size of a matrix can be retrieved by \link EigenBase::rows() rows()\endlink, \link EigenBase::cols() cols() \endlink and \link EigenBase::size() size()\endlink. These methods return the number of rows, the number of columns and the number of coefficients, respectively. Resizing a dynamic-size matrix is done by the \link DenseStorageBase::resize(Index,Index) resize() \endlink method.
-For example: \include tut_matrix_resize.cpp
+
+<table class="tutorial_code"><tr><td>
+Example: \include tut_matrix_resize.cpp
+</td>
+<td>
Output: \verbinclude tut_matrix_resize.out
+</td></tr></table>
The resize() method is a no-operation if the actual matrix size doesn't change; otherwise it is destructive: the values of the coefficients may change.
If you want a conservative variant of resize() which does not change the coefficients, use \link DenseStorageBase::conservativeResize() conservativeResize()\endlink, see \ref TopicResizing "this page" for more details.
@@ -167,14 +181,25 @@ If you want a conservative variant of resize() which does not change the coeffic
All these methods are still available on fixed-size matrices, for the sake of API uniformity. Of course, you can't actually
resize a fixed-size matrix. Trying to change a fixed size to an actually different value will trigger an assertion failure;
but the following code is legal:
-\include tut_matrix_resize_fixed_size.cpp
+
+<table class="tutorial_code"><tr><td>
+Example: \include tut_matrix_resize_fixed_size.cpp
+</td>
+<td>
Output: \verbinclude tut_matrix_resize_fixed_size.out
+</td></tr></table>
+
\section TutorialMatrixAssignment Assignment and resizing
Assignment is the action of copying a matrix into another, using \c operator=. Eigen resizes the matrix on the left-hand side automatically so that it matches the size of the matrix on the right-hand size. For example:
-\include tut_matrix_assignment_resizing.cpp
+
+<table class="tutorial_code"><tr><td>
+Example: \include tut_matrix_assignment_resizing.cpp
+</td>
+<td>
Output: \verbinclude tut_matrix_assignment_resizing.out
+</td></tr></table>
Of course, if the left-hand side is of fixed size, resizing it is not allowed.
diff --git a/doc/C02_TutorialMatrixArithmetic.dox b/doc/C02_TutorialMatrixArithmetic.dox
index df2360d40..d076c8048 100644
--- a/doc/C02_TutorialMatrixArithmetic.dox
+++ b/doc/C02_TutorialMatrixArithmetic.dox
@@ -43,7 +43,7 @@ also have the same \c Scalar type, as Eigen doesn't do automatic type promotion.
Example: \include tut_arithmetic_add_sub.cpp
</td>
<td>
-Output: \include tut_arithmetic_add_sub.out
+Output: \verbinclude tut_arithmetic_add_sub.out
</td></tr></table>
\section TutorialArithmeticScalarMulDiv Scalar multiplication and division
@@ -59,7 +59,7 @@ Multiplication and division by a scalar is very simple too. The operators at han
Example: \include tut_arithmetic_scalar_mul_div.cpp
</td>
<td>
-Output: \include tut_arithmetic_scalar_mul_div.out
+Output: \verbinclude tut_arithmetic_scalar_mul_div.out
</td></tr></table>
@@ -93,7 +93,7 @@ The transpose \f$ a^T \f$, conjugate \f$ \bar{a} \f$, and adjoint (i.e., conjuga
Example: \include tut_arithmetic_transpose_conjugate.cpp
</td>
<td>
-Output: \include tut_arithmetic_transpose_conjugate.out
+Output: \verbinclude tut_arithmetic_transpose_conjugate.out
</td></tr></table>
For real matrices, \c conjugate() is a no-operation, and so \c adjoint() is 100% equivalent to \c transpose().
@@ -103,7 +103,7 @@ As for basic arithmetic operators, \c transpose() and \c adjoint() simply return
Example: \include tut_arithmetic_transpose_aliasing.cpp
</td>
<td>
-Output: \include tut_arithmetic_transpose_aliasing.out
+Output: \verbinclude tut_arithmetic_transpose_aliasing.out
</td></tr></table>
This is the so-called \ref TopicAliasing "aliasing issue". In "debug mode", i.e., when \ref TopicAssertions "assertions" have not been disabled, such common pitfalls are automatically detected.
@@ -112,7 +112,7 @@ For \em in-place transposition, as for instance in <tt>a = a.transpose()</tt>, s
Example: \include tut_arithmetic_transpose_inplace.cpp
</td>
<td>
-Output: \include tut_arithmetic_transpose_inplace.out
+Output: \verbinclude tut_arithmetic_transpose_inplace.out
</td></tr></table>
There is also the \link MatrixBase::adjointInPlace() adjointInPlace()\endlink function for complex matrices.
@@ -129,7 +129,7 @@ two operators:
Example: \include tut_arithmetic_matrix_mul.cpp
</td>
<td>
-Output: \include tut_arithmetic_matrix_mul.out
+Output: \verbinclude tut_arithmetic_matrix_mul.out
</td></tr></table>
Note: if you read the above paragraph on expression templates and are worried that doing \c m=m*m might cause
@@ -154,7 +154,7 @@ The above-discussed \c operator* cannot be used to compute dot and cross product
Example: \include tut_arithmetic_dot_cross.cpp
</td>
<td>
-Output: \include tut_arithmetic_dot_cross.out
+Output: \verbinclude tut_arithmetic_dot_cross.out
</td></tr></table>
Remember that cross product is only for vectors of size 3. Dot product is for vectors of any sizes.
@@ -168,7 +168,7 @@ Eigen also provides some reduction operations to reduce a given matrix or vector
Example: \include tut_arithmetic_redux_basic.cpp
</td>
<td>
-Output: \include tut_arithmetic_redux_basic.out
+Output: \verbinclude tut_arithmetic_redux_basic.out
</td></tr></table>
The \em trace of a matrix, as returned by the function \link MatrixBase::trace() trace()\endlink, is the sum of the diagonal coefficients and can also be computed as efficiently using <tt>a.diagonal().sum()</tt>, as we will see later on.
@@ -179,7 +179,7 @@ There also exist variants of the \c minCoeff and \c maxCoeff functions returning
Example: \include tut_arithmetic_redux_minmax.cpp
</td>
<td>
-Output: \include tut_arithmetic_redux_minmax.out
+Output: \verbinclude tut_arithmetic_redux_minmax.out
</td></tr></table>
diff --git a/doc/C03_TutorialArrayClass.dox b/doc/C03_TutorialArrayClass.dox
index 0828bf39b..92bcebe9d 100644
--- a/doc/C03_TutorialArrayClass.dox
+++ b/doc/C03_TutorialArrayClass.dox
@@ -7,7 +7,7 @@ namespace Eigen {
\li \b Next: \ref TutorialBlockOperations
This tutorial aims to provide an overview and explanations on how to use
-Eigen's \link ArrayBase Array \endlink class
+Eigen's Array class.
\b Table \b of \b contents
- \ref TutorialArrayClassIntro
@@ -15,6 +15,7 @@ Eigen's \link ArrayBase Array \endlink class
- \ref TutorialArrayClassAccess
- \ref TutorialArrayClassAddSub
- \ref TutorialArrayClassMult
+ - \ref TutorialArrayClassCwiseOther
- \ref TutorialArrayClassConvert
\section TutorialArrayClassIntro What is the Array class?
@@ -27,17 +28,17 @@ such as adding a constant to every coefficient in the array or multiplying two a
\section TutorialArrayClassTypes Array types
Array is a class template taking the same template parameters as Matrix.
-As with Matrix, the first 3 template parameters are mandatory:
+As with Matrix, the first three template parameters are mandatory:
\code
Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
\endcode
-And the last 3 template parameters are optional. Since this is exactly the same as for Matrix,
-we won't reexplain it and just refer to \ref TutorialMatrixClass "this page".
+The last three template parameters are optional. Since this is exactly the same as for Matrix,
+we won't explain it again here and just refer to \ref TutorialMatrixClass.
Eigen also provides typedefs for some common cases, in a way that is similar to the Matrix typedefs
but with some slight differences, as the word "array" is used for both 1-dimensional and 2-dimensional arrays.
We adopt that convention that typedefs of the form ArrayNt stand for 1-dimensional arrays, where N and t are
-as in the Matrix typedefs explained on \ref TutorialMatrixClass "this page". For 2-dimensional arrays, we
+the size and the scalar type, as in the Matrix typedefs explained on \ref TutorialMatrixClass "this page". For 2-dimensional arrays, we
use typedefs of the form ArrayNNt. Some examples are shown in the following table:
<table class="tutorial_code" align="center">
@@ -71,69 +72,103 @@ use typedefs of the form ArrayNNt. Some examples are shown in the following tabl
\section TutorialArrayClassAccess Accessing values inside an Array
-Write and read access to coefficients of an array expression is done in the same way as with matrix expressions.
-For example:
-\include Tutorial_ArrayClass_accessors.cpp
-Output:
-\verbinclude Tutorial_ArrayClass_accessors.out
-
-For more information about the comma initializer, refer to \ref TutorialAdvancedInitialization "this page".
+The parenthesis operator is overloaded to provide write and read access to the coefficients of an array, just as with matrices.
+Furthermore, the \c << operator can be used to initialize arrays (via the comma initializer) or to print them.
+<table class="tutorial_code"><tr><td>
+Example: \include Tutorial_ArrayClass_accessors.cpp
+</td>
+<td>
+Output: \verbinclude Tutorial_ArrayClass_accessors.out
+</td></tr></table>
-\section TutorialArrayClassAddSub Addition and substraction
+For more information about the comma initializer, see \ref TutorialAdvancedInitialization.
-Adding and substracting two arrays has the same result as for Matrices.
-This is valid as long as both arrays have the same sizes:
+\section TutorialArrayClassAddSub Addition and subtraction
-\include Tutorial_ArrayClass_addition.cpp
-Output:
-\verbinclude Tutorial_ArrayClass_addition.out
+Adding and subtracting two arrays is the same as for matrices.
+The operation is valid if both arrays have the same size, and the addition or subtraction is done coefficient-wise.
-It is also allowed to add a scalar to each coefficient in an Array,
-providing a functionality that was not available for Matrix objects:
+Arrays also support expressions of the form <tt>array + scalar</tt> which add a scalar to each coefficient in the array.
+This provides a functionality that is not directly available for Matrix objects.
-\include Tutorial_ArrayClass_addition_scalar.cpp
-Output:
-\verbinclude Tutorial_ArrayClass_addition_scalar.out
+<table class="tutorial_code"><tr><td>
+Example: \include Tutorial_ArrayClass_addition.cpp
+</td>
+<td>
+Output: \verbinclude Tutorial_ArrayClass_addition.out
+</td></tr></table>
-\subsection TutorialArrayClassMult Array multiplication
+\section TutorialArrayClassMult Array multiplication
First of all, of course you can multiply an array by a scalar, this works in the same way as matrices. Where arrays
-are fundamentally different from matrices, is when you multiply two arrays together. While Matrices interprete
-multiplication as matrix product, arrays interprete multiplication as coefficient-wise product. For example:
+are fundamentally different from matrices, is when you multiply two together. Matrices interpret
+multiplication as the matrix product and arrays interpret multiplication as the coefficient-wise product. Thus, two
+arrays can be multiplied if they have the same size.
-\include Tutorial_ArrayClass_mult.cpp
-Output:
-\verbinclude Tutorial_ArrayClass_mult.out
+<table class="tutorial_code"><tr><td>
+Example: \include Tutorial_ArrayClass_mult.cpp
+</td>
+<td>
+Output: \verbinclude Tutorial_ArrayClass_mult.out
+</td></tr></table>
+\section TutorialArrayClassCwiseOther Other coefficient-wise operations
+
+The Array class defined other coefficient-wise operations besides the addition, subtraction and multiplication
+operators described about. For example, the \link ArrayBase::abs() .abs() \endlink method takes the absolute
+value of each coefficient, while \link ArrayBase::sqrt() .sqrt() \endlink computes the square root of the
+coefficients. If you have two arrays of the same size, you can call \link ArrayBase::min() .min() \endlink to
+construct the array whose coefficients are the minimum of the corresponding coefficients of the two given
+arrays. These operations are illustrated in the following example.
+
+<table class="tutorial_code"><tr><td>
+Example: \include Tutorial_ArrayClass_cwise_other.cpp
+</td>
+<td>
+Output: \verbinclude Tutorial_ArrayClass_cwise_other.out
+</td></tr></table>
+
+More coefficient-wise operations can be found in the \ref QuickRefPage.
+
\section TutorialArrayClassConvert Converting between array and matrix expressions
-It is possible to wrap a matrix expression as an array expression and conversely. This gives access to all operations
-regardless of the choice of declaring objects as arrays or as matrices.
+When should you use objects of the Matrix class and when should you use objects of the Array class? You cannot
+apply Matrix operations on arrays, or Array operations on matrices. Thus, if you need to do linear algebraic
+operations such as matrix multiplication, then you should use matrices; if you need to do coefficient-wise
+operations, then you should use arrays. However, sometimes it is not that simple, but you need to use both
+Matrix and Array operations. In that case, you need to convert a matrix to an array or reversely. This gives
+access to all operations regardless of the choice of declaring objects as arrays or as matrices.
-\link MatrixBase Matrix expressions \endlink have a \link MatrixBase::array() .array() \endlink method that
-'converts' them into \link ArrayBase array expressions \endlink, so that coefficient-wise operations
+\link MatrixBase Matrix expressions \endlink have an \link MatrixBase::array() .array() \endlink method that
+'converts' them into \link ArrayBase array expressions\endlink, so that coefficient-wise operations
can be applied easily. Conversely, \link ArrayBase array expressions \endlink
have a \link ArrayBase::matrix() .matrix() \endlink method. As with all Eigen expression abstractions,
this doesn't have any runtime cost (provided that you let your compiler optimize).
-
Both \link MatrixBase::array() .array() \endlink and \link ArrayBase::matrix() .matrix() \endlink
can be used as rvalues and as lvalues.
-Mixing matrices and arrays in an expression is forbidden with Eigen. However,
+Mixing matrices and arrays in an expression is forbidden with Eigen. For instance, you cannot add a amtrix and
+array directly; the operands of a \c + operator should either both be matrices or both be arrays. However,
it is easy to convert from one to the other with \link MatrixBase::array() .array() \endlink and
-\link ArrayBase::matrix() .matrix() \endlink.
+\link ArrayBase::matrix() .matrix()\endlink. The exception to this rule is the assignment operator: it is
+allowed to assign a matrix expression to an array variable, or to assign an array expression to a matrix
+variable.
-On the other hand, assigning a matrix (resp. array) expression to an array (resp. matrix) expression is allowed.
+The following example shows how to use array operations on a Matrix object by employing the
+\link MatrixBase::array() .array() \endlink method. For example, the statement
+<tt>result = m.array() * n.array()</tt> takes two matrices \c m and \c n, converts them both to an array, uses
+* to multiply them coefficient-wise and assigns the result to the matrix variable \c result (this is legal
+because Eigen allows assigning array expressions to matrix variables).
-\subsection TutorialArrayClassInteropMatrix Matrix to array example
-The following example shows how to use array operations on a Matrix object by employing
-the \link MatrixBase::array() .array() \endlink method:
+As a matter of fact, this usage case is so common that Eigen provides a \link MatrixBase::cwiseProduct()
+.cwiseProduct() \endlink method for matrices to compute the coefficient-wise product. This is also shown in
+the example program.
<table class="tutorial_code"><tr><td>
\include Tutorial_ArrayClass_interop_matrix.cpp
@@ -143,21 +178,13 @@ Output:
\verbinclude Tutorial_ArrayClass_interop_matrix.out
</td></tr></table>
+Similarly, if \c array1 and \c array2 are arrays, then the expression <tt>array1.matrix() * array2.matrix()</tt>
+computes their matrix product.
-\subsection TutorialArrayClassInteropArray Array to matrix example
-The following example shows how to use matrix operations with an Array
-object by employing the \link ArrayBase::matrix() .matrix() \endlink method:
-
-<table class="tutorial_code"><tr><td>
-\include Tutorial_ArrayClass_interop_array.cpp
-</td>
-<td>
-Output:
-\verbinclude Tutorial_ArrayClass_interop_array.out
-</td></tr></table>
-
-\subsection TutorialArrayClassInteropCombination Example with combinations of .array() and .matrix()
-Here is a more advanced example:
+Here is a more advanced example. The expression <tt>(m.array() + 4).matrix() * m</tt> adds 4 to every
+coefficient in the matrix \c m and then computes the matrix product of the result with \c m. Similarly, the
+expression <tt>(m.array() * n.array()).matrix() * m</tt> computes the coefficient-wise product of the matrices
+\c m and \c n and then the matrix product of the result with \c m.
<table class="tutorial_code"><tr><td>
\include Tutorial_ArrayClass_interop.cpp
diff --git a/doc/C04_TutorialBlockOperations.dox b/doc/C04_TutorialBlockOperations.dox
index 70773a463..b45cbfbc8 100644
--- a/doc/C04_TutorialBlockOperations.dox
+++ b/doc/C04_TutorialBlockOperations.dox
@@ -13,21 +13,22 @@ provided that you let your compiler optimize.
\b Table \b of \b contents
- \ref TutorialBlockOperationsUsing
- - \ref TutorialBlockOperationsSyntax
- - \ref TutorialBlockOperationsSyntaxColumnRows
- - \ref TutorialBlockOperationsSyntaxCorners
+ - \ref TutorialBlockOperationsSyntaxColumnRows
+ - \ref TutorialBlockOperationsSyntaxCorners
+ - \ref TutorialBlockOperationsSyntaxVectors
+
\section TutorialBlockOperationsUsing Using block operations
The most general block operation in Eigen is called \link DenseBase::block() .block() \endlink.
-This function returns a block of size <tt>(p,q)</tt> whose origin is at <tt>(i,j)</tt> by using
-the following syntax:
+This function returns a block of size <tt>(p,q)</tt> whose origin is at <tt>(i,j)</tt>.
+There are two versions, whose syntax is as follows:
<table class="tutorial_code" align="center">
-<tr><td align="center">\b Block \b operation</td>
-<td align="center">Default \b version</td>
+<tr><td align="center">\b %Block \b operation</td>
+<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
-<tr><td>Block of size <tt>(p,q)</tt>, starting at <tt>(i,j)</tt></td>
+<tr><td>%Block of size <tt>(p,q)</tt>, starting at <tt>(i,j)</tt></td>
<td>\code
matrix.block(i,j,p,q);\endcode </td>
<td>\code
@@ -35,7 +36,15 @@ matrix.block<p,q>(i,j);\endcode </td>
</tr>
</table>
-Therefore, if we want to print the values of a block inside a matrix we can simply write:
+The default version is a method which takes four arguments. It can always be used. The optimized version
+takes two template arguments (the size of the block) and two normal arguments (the position of the block).
+It can only be used if the size of the block is known at compile time, but it may be faster than the
+non-optimized version, especially if the size of the block is small. Both versions can be used on fixed-size
+and dynamic-size matrices and arrays.
+
+The following program uses the default and optimized versions to print the values of several blocks inside a
+matrix.
+
<table class="tutorial_code"><tr><td>
\include Tutorial_BlockOperations_print_block.cpp
</td>
@@ -44,10 +53,15 @@ Output:
\verbinclude Tutorial_BlockOperations_print_block.out
</td></tr></table>
+In the above example the \link DenseBase::block() .block() \endlink function was employed
+to read the values inside matrix \p m . However, blocks can also be used as lvalues, meaning that you can
+assign to a block.
-In the previous example the \link DenseBase::block() .block() \endlink function was employed
-to read the values inside matrix \p m . Blocks can also be used to perform operations and
-assignments within matrices or arrays of different size:
+This is illustrated in the following example, which uses arrays instead of matrices. The coefficients of the
+5-by-5 array \c n are first all set to 0.6, but then the 3-by-3 block in the middle is set to the values in
+\c m . The penultimate line shows that blocks can be combined with matrices and arrays to create more complex
+expressions. Blocks of an array are an array expression, and thus the multiplication here is coefficient-wise
+multiplication.
<table class="tutorial_code"><tr><td>
\include Tutorial_BlockOperations_block_assignment.cpp
@@ -57,55 +71,38 @@ Output:
\verbinclude Tutorial_BlockOperations_block_assignment.out
</td></tr></table>
+The \link DenseBase::block() .block() \endlink method is used for general block operations, but there are
+other methods for special cases. These are described in the rest of this page.
-Blocks can also be combined with matrices and arrays to create more complex expressions:
-\code
- MatrixXf m(3,3), n(2,2);
- MatrixXf p(3,3);
-
- m.block(0,0,2,2) = m.block(0,0,2,2) * n + p.block(1,1,2,2);
-\endcode
+\section TutorialBlockOperationsSyntaxColumnRows Columns and rows
-It is important to point out that \link DenseBase::block() .block() \endlink is the
-general case for a block operation but there are many other useful block operations,
-as described in the next section.
-
-\section TutorialBlockOperationsSyntax Block operation syntax
-The following tables show a summary of Eigen's block operations and how they are applied to
-fixed- and dynamic-sized Eigen objects.
-
-\subsection TutorialBlockOperationsSyntaxColumnRows Columns and rows
-Other extremely useful block operations are \link DenseBase::col() .col() \endlink and
-\link DenseBase::row() .row() \endlink which provide access to a
-specific row or column. This is a special case in the sense that the syntax for fixed- and
-dynamic-sized objects is exactly the same:
+Individual columns and rows are special cases of blocks. Eigen provides methods to easily access them:
+\link DenseBase::col() .col() \endlink and \link DenseBase::row() .row()\endlink. There is no syntax variant
+for an optimized version.
<table class="tutorial_code" align="center">
-<tr><td align="center">\b Block \b operation</td>
+<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
<tr><td>i<sup>th</sup> row
\link DenseBase::row() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.row(i);\endcode </td>
+matrix.row(i);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.row(i);\endcode </td>
+matrix.row(i);\endcode </td>
</tr>
<tr><td>j<sup>th</sup> column
\link DenseBase::col() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.col(j);\endcode </td>
+matrix.col(j);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.col(j);\endcode </td>
+matrix.col(j);\endcode </td>
</tr>
</table>
-A simple example demonstrating these feature follows:
+The argument for \p col() and \p row() is the index of the column or row to be accessed, starting at
+0. Therefore, \p col(0) will access the first column and \p col(1) the second one.
<table class="tutorial_code"><tr><td>
C++ code:
@@ -113,94 +110,83 @@ C++ code:
</td>
<td>
Output:
-\include Tutorial_BlockOperations_colrow.out
+\verbinclude Tutorial_BlockOperations_colrow.out
</td></tr></table>
-\b NOTE: the argument for \p col() and \p row() is the index of the column or row to be accessed,
-starting at 0. Therefore, \p col(0) will access the first column and \p col(1) the second one.
+\section TutorialBlockOperationsSyntaxCorners Corner-related operations
+
+Eigen also provides special methods for blocks that are flushed against one of the corners or sides of a
+matrix or array. For instance, \link DenseBase::topLeftCorner() .topLeftCorner() \endlink can be used to refer
+to a block in the top-left corner of a matrix. Use <tt>matrix.topLeftCorner(p,q)</tt> to access the block
+consisting of the coefficients <tt>matrix(i,j)</tt> with \c i &lt; \c p and \c j &lt; \c q. As an other
+example, blocks consisting of whole rows flushed against the top side of the matrix can be accessed by
+\link DenseBase::topRows() .topRows() \endlink.
+The different possibilities are summarized in the following table:
-\subsection TutorialBlockOperationsSyntaxCorners Corner-related operations
<table class="tutorial_code" align="center">
-<tr><td align="center">\b Block \b operation</td>
+<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
<tr><td>Top-left p by q block \link DenseBase::topLeftCorner() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.topLeftCorner(p,q);\endcode </td>
+matrix.topLeftCorner(p,q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.topLeftCorner<p,q>();\endcode </td>
+matrix.topLeftCorner<p,q>();\endcode </td>
</tr>
<tr><td>Bottom-left p by q block
\link DenseBase::bottomLeftCorner() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.bottomLeftCorner(p,q);\endcode </td>
+matrix.bottomLeftCorner(p,q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.bottomLeftCorner<p,q>();\endcode </td>
+matrix.bottomLeftCorner<p,q>();\endcode </td>
</tr>
<tr><td>Top-right p by q block
\link DenseBase::topRightCorner() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.topRightCorner(p,q);\endcode </td>
+matrix.topRightCorner(p,q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.topRightCorner<p,q>();\endcode </td>
+matrix.topRightCorner<p,q>();\endcode </td>
</tr>
<tr><td>Bottom-right p by q block
\link DenseBase::bottomRightCorner() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.bottomRightCorner(p,q);\endcode </td>
+matrix.bottomRightCorner(p,q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.bottomRightCorner<p,q>();\endcode </td>
+matrix.bottomRightCorner<p,q>();\endcode </td>
</tr>
-<tr><td>Block containing the first q rows
+<tr><td>%Block containing the first q rows
\link DenseBase::topRows() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.topRows(q);\endcode </td>
+matrix.topRows(q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.topRows<q>();\endcode </td>
+matrix.topRows<q>();\endcode </td>
</tr>
-<tr><td>Block containing the last q rows
+<tr><td>%Block containing the last q rows
\link DenseBase::bottomRows() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.bottomRows(q);\endcode </td>
+matrix.bottomRows(q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.bottomRows<q>();\endcode </td>
+matrix.bottomRows<q>();\endcode </td>
</tr>
-<tr><td>Block containing the first p columns
+<tr><td>%Block containing the first p columns
\link DenseBase::leftCols() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.leftCols(p);\endcode </td>
+matrix.leftCols(p);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.leftCols<p>();\endcode </td>
+matrix.leftCols<p>();\endcode </td>
</tr>
-<tr><td>Block containing the last q columns
+<tr><td>%Block containing the last q columns
\link DenseBase::rightCols() * \endlink</td>
<td>\code
-MatrixXf m;
-std::cout << m.rightCols(q);\endcode </td>
+matrix.rightCols(q);\endcode </td>
<td>\code
-Matrix3f m;
-std::cout << m.rightCols<q>();\endcode </td>
+matrix.rightCols<q>();\endcode </td>
</tr>
</table>
-
-Here is a simple example showing the power of the operations presented above:
+Here is a simple example illustrating the use of the operations presented above:
<table class="tutorial_code"><tr><td>
C++ code:
@@ -208,49 +194,38 @@ C++ code:
</td>
<td>
Output:
-\include Tutorial_BlockOperations_corner.out
+\verbinclude Tutorial_BlockOperations_corner.out
</td></tr></table>
+\section TutorialBlockOperationsSyntaxVectors Block operations for vectors
-
-
-
-
-
-\subsection TutorialBlockOperationsSyntaxVectors Block operations for vectors
-Eigen also provides a set of block operations designed specifically for vectors:
+Eigen also provides a set of block operations designed specifically for vectors and one-dimensional arrays:
<table class="tutorial_code" align="center">
-<tr><td align="center">\b Block \b operation</td>
+<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
-<tr><td>Block containing the first \p n elements
+<tr><td>%Block containing the first \p n elements
\link DenseBase::head() * \endlink</td>
<td>\code
-VectorXf v;
-std::cout << v.head(n);\endcode </td>
+vector.head(n);\endcode </td>
<td>\code
-Vector3f v;
-std::cout << v.head<n>();\endcode </td>
+vector.head<n>();\endcode </td>
</tr>
-<tr><td>Block containing the last \p n elements
+<tr><td>%Block containing the last \p n elements
\link DenseBase::tail() * \endlink</td>
<td>\code
-VectorXf v;
-std::cout << v.tail(n);\endcode </td>
+vector.tail(n);\endcode </td>
<td>\code
-Vector3f m;
-std::cout << v.tail<n>();\endcode </td>
+vector.tail<n>();\endcode </td>
</tr>
-<tr><td>Block containing \p n elements, starting at position \p i
+<tr><td>%Block containing \p n elements, starting at position \p i
\link DenseBase::segment() * \endlink</td>
<td>\code
-VectorXf v;
-std::cout << v.segment(i,n);\endcode </td>
+vector.segment(i,n);\endcode </td>
<td>\code
-Vector3f m;
-std::cout << v.segment<n>(i);\endcode </td>
+vector.segment<n>(i);\endcode </td>
</tr>
</table>
@@ -262,7 +237,7 @@ C++ code:
</td>
<td>
Output:
-\include Tutorial_BlockOperations_vector.out
+\verbinclude Tutorial_BlockOperations_vector.out
</td></tr></table>
\li \b Next: \ref TutorialAdvancedInitialization
diff --git a/doc/C07_TutorialReductionsVisitorsBroadcasting.dox b/doc/C07_TutorialReductionsVisitorsBroadcasting.dox
index 1930d7a94..93d18f47b 100644
--- a/doc/C07_TutorialReductionsVisitorsBroadcasting.dox
+++ b/doc/C07_TutorialReductionsVisitorsBroadcasting.dox
@@ -30,7 +30,7 @@ which returns the addition of all the coefficients inside a given matrix or arra
Example: \include tut_arithmetic_redux_basic.cpp
</td>
<td>
-Output: \include tut_arithmetic_redux_basic.out
+Output: \verbinclude tut_arithmetic_redux_basic.out
</td></tr></table>
The \em trace of a matrix, as returned by the function \c trace(), is the sum of the diagonal coefficients and can also be computed as efficiently using <tt>a.diagonal().sum()</tt>, as we will see later on.
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index da5d291f9..091ce5639 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -1217,12 +1217,14 @@ PREDEFINED = EIGEN_EMPTY_STRUCT \
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
-EXPAND_AS_DEFINED = EIGEN_MAKE_SCALAR_OPS \
- EIGEN_MAKE_TYPEDEFS \
+EXPAND_AS_DEFINED = EIGEN_MAKE_TYPEDEFS \
EIGEN_MAKE_FIXED_TYPEDEFS \
EIGEN_MAKE_TYPEDEFS_ALL_SIZES \
+ EIGEN_MAKE_CWISE_BINARY_OP \
EIGEN_CWISE_UNOP_RETURN_TYPE \
EIGEN_CWISE_BINOP_RETURN_TYPE \
+ EIGEN_CWISE_PRODUCT_RETURN_TYPE \
+ EIGEN_CURRENT_STORAGE_BASE_CLASS \
_EIGEN_GENERIC_PUBLIC_INTERFACE
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
diff --git a/doc/QuickReference.dox b/doc/QuickReference.dox
index edd00988d..0f6886f75 100644
--- a/doc/QuickReference.dox
+++ b/doc/QuickReference.dox
@@ -218,11 +218,13 @@ x = FixedXD::Zero();
x = FixedXD::Ones();
x = FixedXD::Constant(value);
x = FixedXD::Random();
+x = FixedXD::LinSpaced(low, high, size);
x.setZero();
x.setOnes();
x.setConstant(value);
x.setRandom();
+x.setLinSpaced(low, high, size);
\endcode
</td>
<td>
@@ -234,11 +236,13 @@ x = Dynamic2D::Zero(rows, cols);
x = Dynamic2D::Ones(rows, cols);
x = Dynamic2D::Constant(rows, cols, value);
x = Dynamic2D::Random(rows, cols);
+N/A
x.setZero(rows, cols);
x.setOnes(rows, cols);
x.setConstant(rows, cols, value);
x.setRandom(rows, cols);
+N/A
\endcode
</td>
<td>
@@ -250,11 +254,13 @@ x = Dynamic1D::Zero(size);
x = Dynamic1D::Ones(size);
x = Dynamic1D::Constant(size, value);
x = Dynamic1D::Random(size);
+x = Dynamic1D::LinSpaced(low, high, size);
x.setZero(size);
x.setOnes(size);
x.setConstant(size, value);
x.setRandom(size);
+x.setLinSpaced(low, high, size);
\endcode
</td>
</tr>
@@ -595,7 +601,7 @@ m3 -= s1 * m2.conjugate() * m1.adjoint().triangularView<Eigen::Lower>() \endcode
Solving linear equations:\n
\f$ M_2 := L_1^{-1} M_2 \f$ \n
\f$ M_3 := {L_1^*}^{-1} M_3 \f$ \n
-\f$ M_4 := M_3 U_1^{-1} \f$
+\f$ M_4 := M_4 U_1^{-1} \f$
</td><td>\n \code
L1.triangularView<Eigen::UnitLower>().solveInPlace(M2)
L1.triangularView<Eigen::Lower>().adjoint().solveInPlace(M3)
diff --git a/doc/examples/DenseBase_middleCols_int.cpp b/doc/examples/DenseBase_middleCols_int.cpp
new file mode 100644
index 000000000..0ebd955ec
--- /dev/null
+++ b/doc/examples/DenseBase_middleCols_int.cpp
@@ -0,0 +1,15 @@
+#include <Eigen/Core>
+#include <iostream>
+
+using namespace Eigen;
+using namespace std;
+
+int main(void)
+{
+ int const N = 5;
+ MatrixXi A(N,N);
+ A.setRandom();
+ cout << "A =\n" << A << '\n' << endl;
+ cout << "A(1..3,:) =\n" << A.middleCols(1,3) << endl;
+ return 0;
+}
diff --git a/doc/examples/DenseBase_middleRows_int.cpp b/doc/examples/DenseBase_middleRows_int.cpp
new file mode 100644
index 000000000..a6fe9e844
--- /dev/null
+++ b/doc/examples/DenseBase_middleRows_int.cpp
@@ -0,0 +1,15 @@
+#include <Eigen/Core>
+#include <iostream>
+
+using namespace Eigen;
+using namespace std;
+
+int main(void)
+{
+ int const N = 5;
+ MatrixXi A(N,N);
+ A.setRandom();
+ cout << "A =\n" << A << '\n' << endl;
+ cout << "A(2..3,:) =\n" << A.middleRows(2,2) << endl;
+ return 0;
+}
diff --git a/doc/examples/DenseBase_template_int_middleCols.cpp b/doc/examples/DenseBase_template_int_middleCols.cpp
new file mode 100644
index 000000000..6191d79c8
--- /dev/null
+++ b/doc/examples/DenseBase_template_int_middleCols.cpp
@@ -0,0 +1,15 @@
+#include <Eigen/Core>
+#include <iostream>
+
+using namespace Eigen;
+using namespace std;
+
+int main(void)
+{
+ int const N = 5;
+ MatrixXi A(N,N);
+ A.setRandom();
+ cout << "A =\n" << A << '\n' << endl;
+ cout << "A(:,1..3) =\n" << A.middleCols<3>(1) << endl;
+ return 0;
+}
diff --git a/doc/examples/DenseBase_template_int_middleRows.cpp b/doc/examples/DenseBase_template_int_middleRows.cpp
new file mode 100644
index 000000000..7e8b6573f
--- /dev/null
+++ b/doc/examples/DenseBase_template_int_middleRows.cpp
@@ -0,0 +1,15 @@
+#include <Eigen/Core>
+#include <iostream>
+
+using namespace Eigen;
+using namespace std;
+
+int main(void)
+{
+ int const N = 5;
+ MatrixXi A(N,N);
+ A.setRandom();
+ cout << "A =\n" << A << '\n' << endl;
+ cout << "A(1..3,:) =\n" << A.middleRows<3>(1) << endl;
+ return 0;
+}
diff --git a/doc/examples/Tutorial_ArrayClass_accessors.cpp b/doc/examples/Tutorial_ArrayClass_accessors.cpp
index 812ba61a4..dc720ff58 100644
--- a/doc/examples/Tutorial_ArrayClass_accessors.cpp
+++ b/doc/examples/Tutorial_ArrayClass_accessors.cpp
@@ -8,17 +8,17 @@ int main()
{
ArrayXXf m(2,2);
- //assign some values coefficient by coefficient
+ // assign some values coefficient by coefficient
m(0,0) = 1.0; m(0,1) = 2.0;
- m(1,0) = 3.0; m(1,1) = 4.0;
+ m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0);
- //print values to standard output
+ // print values to standard output
cout << m << endl << endl;
// using the comma-initializer is also allowed
m << 1.0,2.0,
3.0,4.0;
- //print values to standard output
+ // print values to standard output
cout << m << endl;
}
diff --git a/doc/examples/Tutorial_ArrayClass_addition.cpp b/doc/examples/Tutorial_ArrayClass_addition.cpp
index eae1957bd..480ffb00f 100644
--- a/doc/examples/Tutorial_ArrayClass_addition.cpp
+++ b/doc/examples/Tutorial_ArrayClass_addition.cpp
@@ -8,15 +8,16 @@ int main()
{
ArrayXXf a(3,3);
ArrayXXf b(3,3);
-
a << 1,2,3,
4,5,6,
7,8,9;
-
b << 1,2,3,
1,2,3,
1,2,3;
- cout << "a + b = " << endl
- << a + b << endl;
+ // Adding two arrays
+ cout << "a + b = " << endl << a + b << endl << endl;
+
+ // Subtracting a scalar from an array
+ cout << "a - 2 = " << endl << a - 2 << endl;
}
diff --git a/doc/examples/Tutorial_ArrayClass_addition_scalar.cpp b/doc/examples/Tutorial_ArrayClass_addition_scalar.cpp
deleted file mode 100644
index 1c2665287..000000000
--- a/doc/examples/Tutorial_ArrayClass_addition_scalar.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <Eigen/Dense>
-#include <iostream>
-
-using namespace Eigen;
-using namespace std;
-
-int main()
-{
- ArrayXXf a(3,3);
-
- a << 1,2,3,
- 4,5,6,
- 7,8,9;
-
- cout << "a + 2 = " << endl
- << a + 2 << endl;
-}
diff --git a/doc/examples/Tutorial_ArrayClass_cwise_other.cpp b/doc/examples/Tutorial_ArrayClass_cwise_other.cpp
new file mode 100644
index 000000000..d9046c63d
--- /dev/null
+++ b/doc/examples/Tutorial_ArrayClass_cwise_other.cpp
@@ -0,0 +1,19 @@
+#include <Eigen/Dense>
+#include <iostream>
+
+using namespace Eigen;
+using namespace std;
+
+int main()
+{
+ ArrayXf a = ArrayXf::Random(5);
+ a *= 2;
+ cout << "a =" << endl
+ << a << endl;
+ cout << "a.abs() =" << endl
+ << a.abs() << endl;
+ cout << "a.abs().sqrt() =" << endl
+ << a.abs().sqrt() << endl;
+ cout << "a.min(a.abs().sqrt()) =" << endl
+ << a.min(a.abs().sqrt()) << endl;
+}
diff --git a/doc/examples/Tutorial_ArrayClass_interop.cpp b/doc/examples/Tutorial_ArrayClass_interop.cpp
index 72ac5d307..371f07068 100644
--- a/doc/examples/Tutorial_ArrayClass_interop.cpp
+++ b/doc/examples/Tutorial_ArrayClass_interop.cpp
@@ -8,31 +8,15 @@ int main()
{
MatrixXf m(2,2);
MatrixXf n(2,2);
-
MatrixXf result(2,2);
- //initialize matrices
m << 1,2,
3,4;
-
n << 5,6,
7,8;
- // mix of array and matrix operations
- // first coefficient-wise addition
- // then the result is used with matrix multiplication
result = (m.array() + 4).matrix() * m;
-
- cout << "-- Combination 1: --" << endl
- << result << endl << endl;
-
-
- // mix of array and matrix operations
- // first coefficient-wise multiplication
- // then the result is used with matrix multiplication
+ cout << "-- Combination 1: --" << endl << result << endl << endl;
result = (m.array() * n.array()).matrix() * m;
-
- cout << "-- Combination 2: --" << endl
- << result << endl << endl;
-
+ cout << "-- Combination 2: --" << endl << result << endl << endl;
}
diff --git a/doc/examples/Tutorial_ArrayClass_interop_array.cpp b/doc/examples/Tutorial_ArrayClass_interop_array.cpp
deleted file mode 100644
index c2cb6bf3f..000000000
--- a/doc/examples/Tutorial_ArrayClass_interop_array.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <Eigen/Dense>
-#include <iostream>
-
-using namespace Eigen;
-using namespace std;
-
-int main()
-{
- ArrayXXf m(2,2);
- ArrayXXf n(2,2);
-
- ArrayXXf result(2,2);
-
- //initialize arrays
- m << 1,2,
- 3,4;
-
- n << 5,6,
- 7,8;
-
-
- // --> array multiplication
- result = m * n;
-
- cout << "-- Array m*n: --" << endl
- << result << endl << endl;
-
-
- // --> Matrix multiplication
- result = m.matrix() * n.matrix();
-
- cout << "-- Matrix m*n: --" << endl
- << result << endl << endl;
-}
diff --git a/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp b/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp
index b3d48b6ae..101427511 100644
--- a/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp
+++ b/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp
@@ -8,34 +8,19 @@ int main()
{
MatrixXf m(2,2);
MatrixXf n(2,2);
-
MatrixXf result(2,2);
- //initialize matrices
m << 1,2,
3,4;
-
n << 5,6,
7,8;
-
- // --> matrix multiplication
result = m * n;
-
- cout << "-- Matrix m*n: --" << endl
- << result << endl << endl;
-
-
- // --> coeff-wise multiplication
+ cout << "-- Matrix m*n: --" << endl << result << endl << endl;
result = m.array() * n.array();
-
- cout << "-- Array m*n: --" << endl
- << result << endl << endl;
-
-
- // ->> coeff-wise addition of a scalar
+ cout << "-- Array m*n: --" << endl << result << endl << endl;
+ result = m.cwiseProduct(n);
+ cout << "-- With cwiseProduct: --" << endl << result << endl << endl;
result = m.array() + 4;
-
- cout << "-- Array m + 4: --" << endl
- << result << endl << endl;
+ cout << "-- Array m + 4: --" << endl << result << endl << endl;
}
diff --git a/doc/examples/Tutorial_ArrayClass_mult.cpp b/doc/examples/Tutorial_ArrayClass_mult.cpp
index 27c83e040..6cb439ff7 100644
--- a/doc/examples/Tutorial_ArrayClass_mult.cpp
+++ b/doc/examples/Tutorial_ArrayClass_mult.cpp
@@ -8,13 +8,9 @@ int main()
{
ArrayXXf a(2,2);
ArrayXXf b(2,2);
-
a << 1,2,
3,4;
-
b << 5,6,
7,8;
-
- cout << "a * b = " << endl
- << a * b << endl;
+ cout << "a * b = " << endl << a * b << endl;
}
diff --git a/doc/examples/Tutorial_BlockOperations_block_assignment.cpp b/doc/examples/Tutorial_BlockOperations_block_assignment.cpp
index 0419a500f..56ca69a6e 100644
--- a/doc/examples/Tutorial_BlockOperations_block_assignment.cpp
+++ b/doc/examples/Tutorial_BlockOperations_block_assignment.cpp
@@ -6,26 +6,13 @@ using namespace Eigen;
int main()
{
- MatrixXf m(3,3), n(2,2);
-
+ Array33f m;
m << 1,2,3,
4,5,6,
7,8,9;
-
- // assignment through a block operation,
- // block as rvalue
- n = m.block(0,0,2,2);
-
- //print n
+ Array<float,5,5> n = Array<float,5,5>::Constant(0.6);
+ n.block(1,1,3,3) = m;
cout << "n = " << endl << n << endl << endl;
-
-
- n << 1,1,
- 1,1;
-
- // block as lvalue
- m.block(0,0,2,2) = n;
-
- //print m
- cout << "m = " << endl << m << endl;
+ Array33f res = n.block(0,0,3,3) * m;
+ cout << "res =" << endl << res << endl;
}
diff --git a/doc/examples/Tutorial_BlockOperations_colrow.cpp b/doc/examples/Tutorial_BlockOperations_colrow.cpp
index e639324b2..e98263057 100644
--- a/doc/examples/Tutorial_BlockOperations_colrow.cpp
+++ b/doc/examples/Tutorial_BlockOperations_colrow.cpp
@@ -1,15 +1,14 @@
#include <Eigen/Dense>
#include <iostream>
-using namespace Eigen;
int main()
{
- MatrixXf m(3,3);
-
+ Eigen::MatrixXf m(3,3);
m << 1,2,3,
4,5,6,
7,8,9;
-
- std::cout << "2nd Row: "
- << m.row(1) << std::endl;
+ std::cout << "2nd Row: " << m.row(1) << std::endl;
+ m.col(0) += m.col(2);
+ std::cout << "m after adding third column to first:\n";
+ std::cout << m << std::endl;
}
diff --git a/doc/examples/Tutorial_BlockOperations_corner.cpp b/doc/examples/Tutorial_BlockOperations_corner.cpp
index 96c6df62b..3a31507aa 100644
--- a/doc/examples/Tutorial_BlockOperations_corner.cpp
+++ b/doc/examples/Tutorial_BlockOperations_corner.cpp
@@ -2,26 +2,16 @@
#include <iostream>
using namespace std;
-using namespace Eigen;
int main()
{
- MatrixXf m(4,4);
-
+ Eigen::Matrix4f m;
m << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10,11,12,
13,14,15,16;
-
- //print first two columns
- cout << "-- leftCols(2) --" << endl
- << m.leftCols(2) << endl << endl;
-
- //print last two rows
- cout << "-- bottomRows(2) --" << endl
- << m.bottomRows(2) << endl << endl;
-
- //print top-left 2x3 corner
- cout << "-- topLeftCorner(2,3) --" << endl
- << m.topLeftCorner(2,3) << endl;
+ cout << "m.leftCols(2) =" << endl << m.leftCols(2) << endl << endl;
+ cout << "m.bottomRows<2>() =" << endl << m.bottomRows<2>() << endl << endl;
+ m.topLeftCorner(1,3) = m.bottomRightCorner(3,1).transpose();
+ cout << "After assignment, m = " << endl << m << endl;
}
diff --git a/doc/examples/Tutorial_BlockOperations_print_block.cpp b/doc/examples/Tutorial_BlockOperations_print_block.cpp
index a2d0db864..0fdefecdf 100644
--- a/doc/examples/Tutorial_BlockOperations_print_block.cpp
+++ b/doc/examples/Tutorial_BlockOperations_print_block.cpp
@@ -1,14 +1,18 @@
#include <Eigen/Dense>
#include <iostream>
-using namespace Eigen;
int main()
{
- MatrixXf m(3,3);
-
- m << 1,2,3,
- 4,5,6,
- 7,8,9;
-
- std::cout << m.block(0,0,2,2) << std::endl;
+ Eigen::MatrixXf m(4,4);
+ m << 1, 2, 3, 4,
+ 5, 6, 7, 8,
+ 9,10,11,12,
+ 13,14,15,16;
+ std::cout << "Block in the middle" << std::endl;
+ std::cout << m.block<2,2>(1,1) << std::endl << std::endl;
+ for (int i = 1; i < 4; ++i)
+ {
+ std::cout << "Block of size " << i << std::endl;
+ std::cout << m.block(0,0,i,i) << std::endl << std::endl;
+ }
}
diff --git a/doc/examples/Tutorial_BlockOperations_vector.cpp b/doc/examples/Tutorial_BlockOperations_vector.cpp
index 211b55472..4a0b02342 100644
--- a/doc/examples/Tutorial_BlockOperations_vector.cpp
+++ b/doc/examples/Tutorial_BlockOperations_vector.cpp
@@ -2,23 +2,13 @@
#include <iostream>
using namespace std;
-using namespace Eigen;
int main()
{
- VectorXf v(6);
-
+ Eigen::ArrayXf v(6);
v << 1, 2, 3, 4, 5, 6;
-
- //print first three elements
- cout << "-- head(3) --" << endl
- << v.head(3) << endl << endl;
-
- //print last three elements
- cout << "-- tail(3) --" << endl
- << v.tail(3) << endl << endl;
-
- //print between 2nd and 5th elem. inclusive
- cout << "-- segment(1,4) --" << endl
- << v.segment(1,4) << endl;
+ cout << "v.head(3) =" << endl << v.head(3) << endl << endl;
+ cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl;
+ v.segment(1,4) *= 2;
+ cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
}
diff --git a/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp b/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp
index cb46887b6..049c747b0 100644
--- a/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp
+++ b/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp
@@ -2,13 +2,14 @@
#include <Eigen/Dense>
using namespace std;
+using namespace Eigen;
int main()
{
- Eigen::MatrixXf mat(2,4);
+ MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
3, 1, 7, 2;
- int maxIndex;
+ MatrixXf::Index maxIndex;
float maxNorm = mat.colwise().sum().maxCoeff(&maxIndex);
std::cout << "Maximum sum at position " << maxIndex << std::endl;
diff --git a/doc/examples/tut_matrix_coefficient_accessors.cpp b/doc/examples/tut_matrix_coefficient_accessors.cpp
index 6d982b6e1..c2da17158 100644
--- a/doc/examples/tut_matrix_coefficient_accessors.cpp
+++ b/doc/examples/tut_matrix_coefficient_accessors.cpp
@@ -15,5 +15,4 @@ int main()
v(0) = 4;
v(1) = v(0) - 1;
std::cout << "Here is the vector v:\n" << v << std::endl;
-
}
diff --git a/doc/snippets/DenseBase_LinSpaced.cpp b/doc/snippets/DenseBase_LinSpaced.cpp
index c8c3e972c..8e54b17fc 100644
--- a/doc/snippets/DenseBase_LinSpaced.cpp
+++ b/doc/snippets/DenseBase_LinSpaced.cpp
@@ -1,2 +1,2 @@
-cout << VectorXi::LinSpaced(7,10,4).transpose() << endl;
-cout << VectorXd::LinSpaced(0.0,1.0,5).transpose() << endl;
+cout << VectorXi::LinSpaced(4,7,10).transpose() << endl;
+cout << VectorXd::LinSpaced(5,0.0,1.0).transpose() << endl;
diff --git a/doc/snippets/DenseBase_LinSpaced_seq.cpp b/doc/snippets/DenseBase_LinSpaced_seq.cpp
index 73873c4e9..f55c5085d 100644
--- a/doc/snippets/DenseBase_LinSpaced_seq.cpp
+++ b/doc/snippets/DenseBase_LinSpaced_seq.cpp
@@ -1,2 +1,2 @@
-cout << VectorXi::LinSpaced(Sequential,7,10,4).transpose() << endl;
-cout << VectorXd::LinSpaced(Sequential,0.0,1.0,5).transpose() << endl;
+cout << VectorXi::LinSpaced(Sequential,4,7,10).transpose() << endl;
+cout << VectorXd::LinSpaced(Sequential,5,0.0,1.0).transpose() << endl;
diff --git a/doc/snippets/DenseBase_setLinSpaced.cpp b/doc/snippets/DenseBase_setLinSpaced.cpp
index a8ea73407..50871dfcc 100644
--- a/doc/snippets/DenseBase_setLinSpaced.cpp
+++ b/doc/snippets/DenseBase_setLinSpaced.cpp
@@ -1,3 +1,3 @@
VectorXf v;
-v.setLinSpaced(0.5f,1.5f,5).transpose();
+v.setLinSpaced(5,0.5f,1.5f).transpose();
cout << v << endl;
diff --git a/doc/unsupported_modules.dox b/doc/unsupported_modules.dox
index dff74ca1b..9f0517c4c 100644
--- a/doc/unsupported_modules.dox
+++ b/doc/unsupported_modules.dox
@@ -61,4 +61,7 @@ namespace Eigen {
/** \ingroup Unsupported_modules
* \defgroup SparseExtra_Module */
+/** \ingroup Unsupported_modules
+ * \defgroup MpfrcxxSupport_Module */
+
} // namespace Eigen
diff --git a/test/array_for_matrix.cpp b/test/array_for_matrix.cpp
index 01e31d05b..3699b861a 100644
--- a/test/array_for_matrix.cpp
+++ b/test/array_for_matrix.cpp
@@ -72,6 +72,10 @@ template<typename MatrixType> void array_for_matrix(const MatrixType& m)
VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);
m3 = m1;
VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);
+
+ // empty objects
+ VERIFY_IS_APPROX(m1.block(0,0,0,cols).colwise().sum(), RowVectorType::Zero(cols));
+ VERIFY_IS_APPROX(m1.block(0,0,rows,0).rowwise().prod(), ColVectorType::Ones(rows));
}
template<typename MatrixType> void comparisons(const MatrixType& m)
diff --git a/test/corners.cpp b/test/corners.cpp
index 70d12fded..fe2b205d7 100644
--- a/test/corners.cpp
+++ b/test/corners.cpp
@@ -45,13 +45,20 @@ template<typename MatrixType> void corners(const MatrixType& m)
COMPARE_CORNER(bottomLeftCorner(r,c), block(rows-r,0,r,c));
COMPARE_CORNER(bottomRightCorner(r,c), block(rows-r,cols-c,r,c));
+ Index sr = ei_random<Index>(1,rows) - 1;
+ Index nr = ei_random<Index>(1,rows-sr);
+ Index sc = ei_random<Index>(1,cols) - 1;
+ Index nc = ei_random<Index>(1,cols-sc);
+
COMPARE_CORNER(topRows(r), block(0,0,r,cols));
+ COMPARE_CORNER(middleRows(sr,nr), block(sr,0,nr,cols));
COMPARE_CORNER(bottomRows(r), block(rows-r,0,r,cols));
COMPARE_CORNER(leftCols(c), block(0,0,rows,c));
+ COMPARE_CORNER(middleCols(sc,nc), block(0,sc,rows,nc));
COMPARE_CORNER(rightCols(c), block(0,cols-c,rows,c));
}
-template<typename MatrixType, int CRows, int CCols> void corners_fixedsize()
+template<typename MatrixType, int CRows, int CCols, int SRows, int SCols> void corners_fixedsize()
{
MatrixType matrix = MatrixType::Random();
const MatrixType const_matrix = MatrixType::Random();
@@ -60,7 +67,9 @@ template<typename MatrixType, int CRows, int CCols> void corners_fixedsize()
rows = MatrixType::RowsAtCompileTime,
cols = MatrixType::ColsAtCompileTime,
r = CRows,
- c = CCols
+ c = CCols,
+ sr = SRows,
+ sc = SCols
};
VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template block<r,c>(0,0)));
@@ -69,8 +78,10 @@ template<typename MatrixType, int CRows, int CCols> void corners_fixedsize()
VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template block<r,c>(rows-r,cols-c)));
VERIFY_IS_EQUAL((matrix.template topRows<r>()), (matrix.template block<r,cols>(0,0)));
+ VERIFY_IS_EQUAL((matrix.template middleRows<r>(sr)), (matrix.template block<r,cols>(sr,0)));
VERIFY_IS_EQUAL((matrix.template bottomRows<r>()), (matrix.template block<r,cols>(rows-r,0)));
VERIFY_IS_EQUAL((matrix.template leftCols<c>()), (matrix.template block<rows,c>(0,0)));
+ VERIFY_IS_EQUAL((matrix.template middleCols<c>(sc)), (matrix.template block<rows,c>(0,sc)));
VERIFY_IS_EQUAL((matrix.template rightCols<c>()), (matrix.template block<rows,c>(0,cols-c)));
VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template block<r,c>(0,0)));
@@ -79,8 +90,10 @@ template<typename MatrixType, int CRows, int CCols> void corners_fixedsize()
VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,cols-c)));
VERIFY_IS_EQUAL((const_matrix.template topRows<r>()), (const_matrix.template block<r,cols>(0,0)));
+ VERIFY_IS_EQUAL((const_matrix.template middleRows<r>(sr)), (const_matrix.template block<r,cols>(sr,0)));
VERIFY_IS_EQUAL((const_matrix.template bottomRows<r>()), (const_matrix.template block<r,cols>(rows-r,0)));
VERIFY_IS_EQUAL((const_matrix.template leftCols<c>()), (const_matrix.template block<rows,c>(0,0)));
+ VERIFY_IS_EQUAL((const_matrix.template middleCols<c>(sc)), (const_matrix.template block<rows,c>(0,sc)));
VERIFY_IS_EQUAL((const_matrix.template rightCols<c>()), (const_matrix.template block<rows,c>(0,cols-c)));
}
@@ -93,8 +106,8 @@ void test_corners()
CALL_SUBTEST_4( corners(MatrixXcf(5, 7)) );
CALL_SUBTEST_5( corners(MatrixXf(21, 20)) );
- CALL_SUBTEST_1(( corners_fixedsize<Matrix<float, 1, 1>, 1, 1>() ));
- CALL_SUBTEST_2(( corners_fixedsize<Matrix4d,2,2>() ));
- CALL_SUBTEST_3(( corners_fixedsize<Matrix<int,10,12>,4,7>() ));
+ CALL_SUBTEST_1(( corners_fixedsize<Matrix<float, 1, 1>, 1, 1, 0, 0>() ));
+ CALL_SUBTEST_2(( corners_fixedsize<Matrix4d,2,2,1,1>() ));
+ CALL_SUBTEST_3(( corners_fixedsize<Matrix<int,10,12>,4,7,5,2>() ));
}
}
diff --git a/test/determinant.cpp b/test/determinant.cpp
index 494fa5eab..8112131b7 100644
--- a/test/determinant.cpp
+++ b/test/determinant.cpp
@@ -61,6 +61,9 @@ template<typename MatrixType> void determinant(const MatrixType& m)
m2 = m1;
m2.row(i) *= x;
VERIFY_IS_APPROX(m2.determinant(), m1.determinant() * x);
+
+ // check empty matrix
+ VERIFY_IS_APPROX(m2.block(0,0,0,0).determinant(), Scalar(1));
}
void test_determinant()
diff --git a/test/main.h b/test/main.h
index 6e1b28cb4..3d277ba61 100644
--- a/test/main.h
+++ b/test/main.h
@@ -283,7 +283,7 @@ namespace Eigen
namespace Eigen {
-template<typename T> inline typename NumTraits<T>::Real test_precision() { return T(0); }
+template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }
template<> inline float test_precision<float>() { return 1e-3f; }
template<> inline double test_precision<double>() { return 1e-6; }
template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }
diff --git a/test/nullary.cpp b/test/nullary.cpp
index c54999580..78d2e9117 100644
--- a/test/nullary.cpp
+++ b/test/nullary.cpp
@@ -59,7 +59,7 @@ void testVectorType(const VectorType& base)
// check whether the result yields what we expect it to do
VectorType m(base);
- m.setLinSpaced(low,high,size);
+ m.setLinSpaced(size,low,high);
VectorType n(size);
for (int i=0; i<size; ++i)
@@ -68,7 +68,7 @@ void testVectorType(const VectorType& base)
VERIFY( (m-n).norm() < std::numeric_limits<Scalar>::epsilon()*10e3 );
// random access version
- m = VectorType::LinSpaced(low,high,size);
+ m = VectorType::LinSpaced(size,low,high);
VERIFY( (m-n).norm() < std::numeric_limits<Scalar>::epsilon()*10e3 );
// These guys sometimes fail! This is not good. Any ideas how to fix them!?
@@ -76,7 +76,7 @@ void testVectorType(const VectorType& base)
//VERIFY( m(0) == low );
// sequential access version
- m = VectorType::LinSpaced(Sequential,low,high,size);
+ m = VectorType::LinSpaced(Sequential,size,low,high);
VERIFY( (m-n).norm() < std::numeric_limits<Scalar>::epsilon()*10e3 );
// These guys sometimes fail! This is not good. Any ideas how to fix them!?
@@ -86,12 +86,12 @@ void testVectorType(const VectorType& base)
// check whether everything works with row and col major vectors
Matrix<Scalar,Dynamic,1> row_vector(size);
Matrix<Scalar,1,Dynamic> col_vector(size);
- row_vector.setLinSpaced(low,high,size);
- col_vector.setLinSpaced(low,high,size);
+ row_vector.setLinSpaced(size,low,high);
+ col_vector.setLinSpaced(size,low,high);
VERIFY( row_vector.isApprox(col_vector.transpose(), NumTraits<Scalar>::epsilon()));
Matrix<Scalar,Dynamic,1> size_changer(size+50);
- size_changer.setLinSpaced(low,high,size);
+ size_changer.setLinSpaced(size,low,high);
VERIFY( size_changer.size() == size );
}
diff --git a/test/product_trmm.cpp b/test/product_trmm.cpp
index e20b408c4..e4790fb66 100644
--- a/test/product_trmm.cpp
+++ b/test/product_trmm.cpp
@@ -35,7 +35,7 @@ template<typename Scalar> void trmm(int size,int /*othersize*/)
DenseIndex cols = ei_random<DenseIndex>(1,size);
MatrixColMaj triV(rows,cols), triH(cols,rows), upTri(cols,rows), loTri(rows,cols),
- unitUpTri(cols,rows), unitLoTri(rows,cols);
+ unitUpTri(cols,rows), unitLoTri(rows,cols), strictlyUpTri(cols,rows), strictlyLoTri(rows,cols);
MatrixColMaj ge1(rows,cols), ge2(cols,rows), ge3;
MatrixRowMaj rge3;
@@ -48,6 +48,8 @@ template<typename Scalar> void trmm(int size,int /*othersize*/)
upTri = triH.template triangularView<Upper>();
unitLoTri = triV.template triangularView<UnitLower>();
unitUpTri = triH.template triangularView<UnitUpper>();
+ strictlyLoTri = triV.template triangularView<StrictlyLower>();
+ strictlyUpTri = triH.template triangularView<StrictlyUpper>();
ge1.setRandom();
ge2.setRandom();
@@ -72,6 +74,11 @@ template<typename Scalar> void trmm(int size,int /*othersize*/)
VERIFY_IS_APPROX( rge3.noalias() = ge2 * triV.template triangularView<UnitLower>(), ge2 * unitLoTri);
VERIFY_IS_APPROX( ge3 = ge2 * triV.template triangularView<UnitLower>(), ge2 * unitLoTri);
VERIFY_IS_APPROX( ge3 = (s1*triV).adjoint().template triangularView<UnitUpper>() * ge2.adjoint(), ei_conj(s1) * unitLoTri.adjoint() * ge2.adjoint());
+
+ VERIFY_IS_APPROX( ge3 = triV.template triangularView<StrictlyLower>() * ge2, strictlyLoTri * ge2);
+ VERIFY_IS_APPROX( rge3.noalias() = ge2 * triV.template triangularView<StrictlyLower>(), ge2 * strictlyLoTri);
+ VERIFY_IS_APPROX( ge3 = ge2 * triV.template triangularView<StrictlyLower>(), ge2 * strictlyLoTri);
+ VERIFY_IS_APPROX( ge3 = (s1*triV).adjoint().template triangularView<StrictlyUpper>() * ge2.adjoint(), ei_conj(s1) * strictlyLoTri.adjoint() * ge2.adjoint());
}
void test_product_trmm()
diff --git a/test/redux.cpp b/test/redux.cpp
index b28252903..9a1df71a8 100644
--- a/test/redux.cpp
+++ b/test/redux.cpp
@@ -64,6 +64,10 @@ template<typename MatrixType> void matrixRedux(const MatrixType& m)
VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).prod(), m1.block(r0,c0,r1,c1).eval().prod());
VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().minCoeff(), m1.block(r0,c0,r1,c1).real().eval().minCoeff());
VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().maxCoeff(), m1.block(r0,c0,r1,c1).real().eval().maxCoeff());
+
+ // test empty objects
+ VERIFY_IS_APPROX(m1.block(r0,c0,0,0).sum(), Scalar(0));
+ VERIFY_IS_APPROX(m1.block(r0,c0,0,0).prod(), Scalar(1));
}
template<typename VectorType> void vectorRedux(const VectorType& w)
@@ -124,6 +128,13 @@ template<typename VectorType> void vectorRedux(const VectorType& w)
VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff());
VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff());
}
+
+ // test empty objects
+ VERIFY_IS_APPROX(v.head(0).sum(), Scalar(0));
+ VERIFY_IS_APPROX(v.tail(0).prod(), Scalar(1));
+ VERIFY_RAISES_ASSERT(v.head(0).mean());
+ VERIFY_RAISES_ASSERT(v.head(0).minCoeff());
+ VERIFY_RAISES_ASSERT(v.head(0).maxCoeff());
}
void test_redux()
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 3ebd59294..8c93909c6 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -250,6 +250,13 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
VERIFY(countTrueNonZero==m2.nonZeros());
VERIFY_IS_APPROX(m2, refM2);
}
+
+ // test sparseView
+ {
+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
+ SparseMatrixType m2(rows, rows);
+ VERIFY_IS_APPROX(m2.eval(), refMat2.sparseView().eval());
+ }
}
void test_sparse_basic()
diff --git a/unsupported/Eigen/CMakeLists.txt b/unsupported/Eigen/CMakeLists.txt
index d01f95d71..a858e5113 100644
--- a/unsupported/Eigen/CMakeLists.txt
+++ b/unsupported/Eigen/CMakeLists.txt
@@ -1,6 +1,6 @@
set(Eigen_HEADERS AdolcForward BVH IterativeSolvers MatrixFunctions MoreVectorization AutoDiff AlignedVector3 Polynomials
CholmodSupport FFT NonLinearOptimization SparseExtra SuperLUSupport UmfPackSupport IterativeSolvers
- NumericalDiff Skyline TaucsSupport
+ NumericalDiff Skyline TaucsSupport MPRealSupport
)
install(FILES
diff --git a/unsupported/Eigen/MPRealSupport b/unsupported/Eigen/MPRealSupport
new file mode 100644
index 000000000..abc719ba7
--- /dev/null
+++ b/unsupported/Eigen/MPRealSupport
@@ -0,0 +1,160 @@
+// This file is part of a joint effort between Eigen, a lightweight C++ template library
+// for linear algebra, and MPFR C++, a C++ interface to MPFR library (http://www.holoborodko.com/pavel/)
+//
+// Copyright (C) 2010 Pavel Holoborodko <pavel@holoborodko.com>
+// Copyright (C) 2010 Konstantin Holoborodko <konstantin@holoborodko.com>
+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// this library. If not, see <http://www.gnu.org/licenses/>.
+//
+// Contributors:
+// Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen, Pere Constans
+
+#ifndef EIGEN_MPREALSUPPORT_MODULE_H
+#define EIGEN_MPREALSUPPORT_MODULE_H
+
+#include <mpreal.h>
+#include <Eigen/Core>
+
+namespace Eigen {
+
+ /** \defgroup MPRealSupport_Module MPFRC++ Support module
+ *
+ * \code
+ * #include <Eigen/MPRealSupport>
+ * \endcode
+ *
+ * This module provides support for multi precision floating point numbers
+ * via the <a href="http://www.holoborodko.com/pavel/?page_id=12">MPFR C++</a>
+ * library which itself is built upon <a href="http://www.mpfr.org/">MPFR</a>/<a href="http://gmplib.org/">GMP</a>.
+ *
+ * Here is an example:
+ *
+\code
+#include <iostream>
+#include <Eigen/Mpfrc++Support>
+#include <Eigen/LU>
+using namespace mpfr;
+using namespace Eigen;
+int main()
+{
+ // set precision to 256 bits (double has only 53 bits)
+ mpreal::set_default_prec(256);
+ // Declare matrix and vector types with multi-precision scalar type
+ typedef Matrix<mpreal,Dynamic,Dynamic> MatrixXmp;
+ typedef Matrix<mpreal,Dynamic,1> VectorXmp;
+
+ MatrixXmp A = MatrixXmp::Random(100,100);
+ VectorXmp b = VectorXmp::Random(100);
+
+ // Solve Ax=b using LU
+ VectorXmp x = A.lu().solve(b);
+ std::cout << "relative error: " << (A*x - b).norm() / b.norm() << std::endl;
+ return 0;
+}
+\endcode
+ *
+ */
+
+ template<> struct NumTraits<mpfr::mpreal>
+ : GenericNumTraits<mpfr::mpreal>
+ {
+ enum {
+ IsInteger = 0,
+ IsSigned = 1,
+ IsComplex = 0,
+ ReadCost = 10,
+ AddCost = 10,
+ MulCost = 40
+ };
+
+ typedef mpfr::mpreal Real;
+ typedef mpfr::mpreal NonInteger;
+
+ inline static mpfr::mpreal highest() { return mpfr::mpreal_max(mpfr::mpreal::get_default_prec()); }
+ inline static mpfr::mpreal lowest() { return -mpfr::mpreal_max(mpfr::mpreal::get_default_prec()); }
+
+ inline static Real epsilon()
+ {
+ return mpfr::machine_epsilon(mpfr::mpreal::get_default_prec());
+ }
+ inline static Real dummy_precision()
+ {
+ unsigned int weak_prec = ((mpfr::mpreal::get_default_prec()-1)*90)/100;
+ return mpfr::machine_epsilon(weak_prec);
+ }
+ };
+
+ template<> mpfr::mpreal ei_random<mpfr::mpreal>()
+ {
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
+ static gmp_randstate_t state;
+ static bool isFirstTime = true;
+
+ if(isFirstTime)
+ {
+ gmp_randinit_default(state);
+ gmp_randseed_ui(state,(unsigned)time(NULL));
+ isFirstTime = false;
+ }
+
+ return mpfr::urandom(state)*2-1;
+#else
+ return mpfr::mpreal(ei_random<double>());
+#endif
+ }
+
+ template<> mpfr::mpreal ei_random<mpfr::mpreal>(const mpfr::mpreal& a, const mpfr::mpreal& b)
+ {
+ return a + (b-a) * ei_random<mpfr::mpreal>();
+ }
+}
+
+namespace mpfr {
+
+ inline const mpreal& ei_conj(const mpreal& x) { return x; }
+ inline const mpreal& ei_real(const mpreal& x) { return x; }
+ inline mpreal ei_imag(const mpreal&) { return 0.0; }
+ inline mpreal ei_abs(const mpreal& x) { return fabs(x); }
+ inline mpreal ei_abs2(const mpreal& x) { return x*x; }
+ inline mpreal ei_sqrt(const mpreal& x) { return sqrt(x); }
+ inline mpreal ei_exp(const mpreal& x) { return exp(x); }
+ inline mpreal ei_log(const mpreal& x) { return log(x); }
+ inline mpreal ei_sin(const mpreal& x) { return sin(x); }
+ inline mpreal ei_cos(const mpreal& x) { return cos(x); }
+ inline mpreal ei_pow(const mpreal& x, mpreal& y) { return pow(x, y); }
+
+ bool ei_isMuchSmallerThan(const mpreal& a, const mpreal& b, const mpreal& prec)
+ {
+ return ei_abs(a) <= abs(b) * prec;
+ }
+
+ inline bool ei_isApprox(const mpreal& a, const mpreal& b, const mpreal& prec)
+ {
+ return ei_abs(a - b) <= min(abs(a), abs(b)) * prec;
+ }
+
+ inline bool ei_isApproxOrLessThan(const mpreal& a, const mpreal& b, const mpreal& prec)
+ {
+ return a <= b || ei_isApprox(a, b, prec);
+ }
+}
+
+#endif // EIGEN_MPREALSUPPORT_MODULE_H
diff --git a/unsupported/Eigen/OpenGLSupport b/unsupported/Eigen/OpenGLSupport
new file mode 100644
index 000000000..2a9de99b0
--- /dev/null
+++ b/unsupported/Eigen/OpenGLSupport
@@ -0,0 +1,190 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_OPENGL_MODULE
+#define EIGEN_OPENGL_MODULE
+
+#include <Eigen/Geometry>
+#include <GL/gl.h>
+
+namespace Eigen {
+
+/** \ingroup Unsupported_modules
+ * \defgroup OpenGLSUpport_Module OpenGL Support module
+ *
+ * This module provides wrapper functions for a couple of OpenGL functions
+ * which simplify the way to pass Eigen's object to openGL.
+ * Here is an exmaple:
+ *
+ * \code
+ * // You need to add path_to_eigen/unsupported to your include path.
+ * #include <Eigen/OpenGLSupport>
+ * // ...
+ * Vector3f x, y;
+ * Matrix3f rot;
+ *
+ * glVertex(y + x * rot);
+ *
+ * Quaternion q;
+ * glRotate(q);
+ *
+ * // ...
+ * \endcode
+ *
+ */
+//@{
+
+#define EIGEN_GL_FUNC_DECLARATION(FUNC) \
+template< typename XprType, \
+ typename Scalar = typename XprType::Scalar, \
+ int Rows = XprType::RowsAtCompileTime, \
+ int Cols = XprType::ColsAtCompileTime, \
+ bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit) \
+ && bool(XprType::Flags&DirectAccessBit) \
+ && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)> \
+struct EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl); \
+ \
+template<typename XprType, typename Scalar, int Rows, int Cols> \
+struct EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> { \
+ inline static void run(const XprType& p) { \
+ EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl)<typename ei_plain_matrix_type_column_major<XprType>::type>::run(p); } \
+}; \
+ \
+template<typename Derived> inline void FUNC(const Eigen::DenseBase<Derived>& p) { \
+ EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl)<Derived>::run(p.derived()); \
+}
+
+
+#define EIGEN_GL_FUNC_SPECIALIZATION_MAT(FUNC,SCALAR,ROWS,COLS,SUFFIX) \
+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> { \
+ inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \
+ };
+
+
+#define EIGEN_GL_FUNC_SPECIALIZATION_VEC(FUNC,SCALAR,SIZE,SUFFIX) \
+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> { \
+ inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \
+ }; \
+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(ei_gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> { \
+ inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \
+ };
+
+EIGEN_GL_FUNC_DECLARATION (glVertex)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 2,2iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 2,2sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 2,2fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 2,2dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 3,3iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 3,3sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 3,3fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 3,3dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 4,4iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 4,4sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 4,4fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 4,4dv)
+
+EIGEN_GL_FUNC_DECLARATION (glTexCoord)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 2,2iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 2,2sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 2,2fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 2,2dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 3,3iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 3,3sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 3,3fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 3,3dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 4,4iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 4,4sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 4,4fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 4,4dv)
+
+EIGEN_GL_FUNC_DECLARATION (glColor)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 2,2iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 2,2sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 2,2fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 2,2dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 3,3iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 3,3sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 3,3fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 3,3dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 4,4iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 4,4sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 4,4fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 4,4dv)
+
+EIGEN_GL_FUNC_DECLARATION (glNormal)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,int, 3,3iv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,short, 3,3sv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,float, 3,3fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,double, 3,3dv)
+
+inline void glScale2fv(const float* v) { glScalef(v[0], v[1], 1.f); }
+inline void glScale2dv(const double* v) { glScaled(v[0], v[1], 1.0); }
+inline void glScale3fv(const float* v) { glScalef(v[0], v[1], v[2]); }
+inline void glScale3dv(const double* v) { glScaled(v[0], v[1], v[2]); }
+
+EIGEN_GL_FUNC_DECLARATION (glScale)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 2,2fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 2,2dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 3,3fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 3,3dv)
+
+inline void glTranslate2fv(const float* v) { glScalef(v[0], v[1], 1.f); }
+inline void glTranslate2dv(const double* v) { glScaled(v[0], v[1], 1.0); }
+inline void glTranslate3fv(const float* v) { glScalef(v[0], v[1], v[2]); }
+inline void glTranslate3dv(const double* v) { glScaled(v[0], v[1], v[2]); }
+
+EIGEN_GL_FUNC_DECLARATION (glTranslate)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 2,2fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 2,2dv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 3,3fv)
+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 3,3dv)
+
+EIGEN_GL_FUNC_DECLARATION (glMultMatrix)
+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,float, 4,4,f)
+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,double, 4,4,d)
+
+EIGEN_GL_FUNC_DECLARATION (glLoadMatrix)
+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,float, 4,4,f)
+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,double, 4,4,d)
+
+void glRotate(const Rotation2D<float>& rot)
+{
+ glRotatef(rot.angle()*180.f/float(M_PI), 0.f, 0.f, 1.f);
+}
+void glRotate(const Rotation2D<double>& rot)
+{
+ glRotated(rot.angle()*180.0/M_PI, 0.0, 0.0, 1.0);
+}
+
+template<typename Derived> void glRotate(const RotationBase<Derived,3>& rot)
+{
+ Transform<typename Derived::Scalar,3,Projective> tr(rot);
+ glMultMatrix(tr.matrix());
+}
+
+//@}
+
+}
+
+#endif // EIGEN_OPENGL_MODULE
diff --git a/unsupported/doc/examples/CMakeLists.txt b/unsupported/doc/examples/CMakeLists.txt
index 61af3e5a5..978f9afd8 100644
--- a/unsupported/doc/examples/CMakeLists.txt
+++ b/unsupported/doc/examples/CMakeLists.txt
@@ -2,6 +2,8 @@ FILE(GLOB examples_SRCS "*.cpp")
ADD_CUSTOM_TARGET(unsupported_examples)
+INCLUDE_DIRECTORIES(../../../unsupported ../../../unsupported/test)
+
FOREACH(example_src ${examples_SRCS})
GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
ADD_EXECUTABLE(example_${example} ${example_src})
diff --git a/unsupported/test/CMakeLists.txt b/unsupported/test/CMakeLists.txt
index c7cfc8881..ad2b9296e 100644
--- a/unsupported/test/CMakeLists.txt
+++ b/unsupported/test/CMakeLists.txt
@@ -55,10 +55,10 @@ include_directories(../../test ../../unsupported ../../Eigen)
if(ADOLC_FOUND)
include_directories(${ADOLC_INCLUDES})
- ei_add_property(EIGEN_TESTED_BACKENDS "Adolc")
+ ei_add_property(EIGEN_TESTED_BACKENDS "Adolc, ")
ei_add_test(forward_adolc " " ${ADOLC_LIBRARIES})
else(ADOLC_FOUND)
- ei_add_property(EIGEN_MISSING_BACKENDS "Adolc")
+ ei_add_property(EIGEN_MISSING_BACKENDS "Adolc, ")
endif(ADOLC_FOUND)
ei_add_test(NonLinearOptimization)
@@ -70,6 +70,15 @@ ei_add_test(matrix_function)
ei_add_test(alignedvector3)
ei_add_test(FFT)
+find_package(MPFR 2.3.0)
+if(MPFR_FOUND)
+ include_directories(${MPFR_INCLUDES})
+ ei_add_property(EIGEN_TESTED_BACKENDS "MPFR C++, ")
+ ei_add_test(mpreal_support " " ${MPFR_LIBRARIES} )
+else()
+ ei_add_property(EIGEN_MISSING_BACKENDS "MPFR C++, ")
+endif()
+
ei_add_test(sparse_llt " " "${SPARSE_LIBS}")
ei_add_test(sparse_ldlt " " "${SPARSE_LIBS}")
ei_add_test(sparse_lu " " "${SPARSE_LIBS}")
@@ -77,8 +86,20 @@ ei_add_test(sparse_extra " " " ")
find_package(FFTW)
if(FFTW_FOUND)
+ ei_add_property(EIGEN_TESTED_BACKENDS "fftw, ")
ei_add_test(FFTW "-DEIGEN_FFTW_DEFAULT " "-lfftw3 -lfftw3f -lfftw3l" )
-endif(FFTW_FOUND)
+else()
+ ei_add_property(EIGEN_MISSING_BACKENDS "fftw, ")
+endif()
+
+find_package(OpenGL)
+find_package(GLUT)
+if(OPENGL_FOUND AND GLUT_FOUND)
+ ei_add_property(EIGEN_TESTED_BACKENDS "opengl, ")
+ ei_add_test(openglsupport "" "${GLUT_LIBRARY}" )
+else()
+ ei_add_property(EIGEN_MISSING_BACKENDS "opengl, ")
+endif()
find_package(GSL)
if(GSL_FOUND AND GSL_VERSION_MINOR LESS 9)
diff --git a/unsupported/test/mpreal.cpp b/unsupported/test/mpreal.cpp
new file mode 100644
index 000000000..bb34c246d
--- /dev/null
+++ b/unsupported/test/mpreal.cpp
@@ -0,0 +1,408 @@
+/*
+ Multi-precision real number class. C++ wrapper fo MPFR library.
+ Project homepage: http://www.holoborodko.com/pavel/
+ Contact e-mail: pavel@holoborodko.com
+
+ Copyright (c) 2008-2010 Pavel Holoborodko
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Contributors:
+ Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze,
+ Heinz van Saanen, Pere Constans, Dmitriy Gubanov
+*/
+
+#include <cstring>
+#include "mpreal.h"
+
+using std::ws;
+using std::cerr;
+using std::endl;
+using std::string;
+using std::ostream;
+using std::istream;
+
+namespace mpfr{
+
+mp_rnd_t mpreal::default_rnd = mpfr_get_default_rounding_mode();
+mp_prec_t mpreal::default_prec = mpfr_get_default_prec();
+int mpreal::default_base = 10;
+int mpreal::double_bits = -1;
+
+// Default constructor: creates mp number and initializes it to 0.
+mpreal::mpreal()
+{
+ mpfr_init2(mp,default_prec);
+ mpfr_set_ui(mp,0,default_rnd);
+}
+
+mpreal::mpreal(const mpreal& u)
+{
+ mpfr_init2(mp,mpfr_get_prec(u.mp));
+ mpfr_set(mp,u.mp,default_rnd);
+}
+
+mpreal::mpreal(const mpfr_t u)
+{
+ mpfr_init2(mp,mpfr_get_prec(u));
+ mpfr_set(mp,u,default_rnd);
+}
+
+mpreal::mpreal(const mpf_t u)
+{
+ mpfr_init2(mp,mpf_get_prec(u));
+ mpfr_set_f(mp,u,default_rnd);
+}
+
+mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_z(mp,u,mode);
+}
+
+mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_q(mp,u,mode);
+}
+
+mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode)
+{
+ if(double_bits == -1 || fits_in_bits(u, double_bits))
+ {
+ mpfr_init2(mp,prec);
+ mpfr_set_d(mp,u,mode);
+ }
+ else
+ throw conversion_overflow();
+}
+
+mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_ld(mp,u,mode);
+}
+
+mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_ui(mp,u,mode);
+}
+
+mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_ui(mp,u,mode);
+}
+
+mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_si(mp,u,mode);
+}
+
+mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_si(mp,u,mode);
+}
+
+mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode)
+{
+ mpfr_init2(mp,prec);
+ mpfr_set_str(mp, s, base, mode);
+}
+
+mpreal::~mpreal()
+{
+ mpfr_clear(mp);
+}
+
+// Operators - Assignment
+mpreal& mpreal::operator=(const char* s)
+{
+ mpfr_t t;
+ if(0==mpfr_init_set_str(t,s,default_base,default_rnd))
+ {
+ mpfr_set(mp,t,mpreal::default_rnd);
+ mpfr_clear(t);
+ }else{
+ mpfr_clear(t);
+ // cerr<<"fail to convert string"<<endl;
+ }
+
+ return *this;
+}
+
+const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t p1, p2, p3;
+
+ p1 = v1.get_prec();
+ p2 = v2.get_prec();
+ p3 = v3.get_prec();
+
+ a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
+
+ mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
+ return a;
+}
+
+const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t p1, p2, p3;
+
+ p1 = v1.get_prec();
+ p2 = v2.get_prec();
+ p3 = v3.get_prec();
+
+ a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1));
+
+ mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode);
+ return a;
+}
+
+const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t p1, p2;
+
+ p1 = v1.get_prec();
+ p2 = v2.get_prec();
+
+ a.set_prec(p1>p2?p1:p2);
+
+ mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode);
+
+ return a;
+}
+
+const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t yp, xp;
+
+ yp = y.get_prec();
+ xp = x.get_prec();
+
+ a.set_prec(yp>xp?yp:xp);
+
+ mpfr_hypot(a.mp, x.mp, y.mp, rnd_mode);
+
+ return a;
+}
+
+const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ mpfr_ptr* t;
+ unsigned long int i;
+
+ t = new mpfr_ptr[n];
+ for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp;
+ mpfr_sum(x.mp,t,n,rnd_mode);
+ delete[] t;
+ return x;
+}
+
+const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t yp, xp;
+
+ yp = y.get_prec();
+ xp = x.get_prec();
+
+ a.set_prec(yp>xp?yp:xp);
+
+ mpfr_remainder(a.mp, x.mp, y.mp, rnd_mode);
+
+ return a;
+}
+
+const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t yp, xp;
+
+ yp = y.get_prec();
+ xp = x.get_prec();
+
+ a.set_prec(yp>xp?yp:xp);
+
+ mpfr_remquo(a.mp,q, x.mp, y.mp, rnd_mode);
+
+ return a;
+}
+
+template <class T>
+std::string to_string(T t, std::ios_base & (*f)(std::ios_base&))
+{
+ std::ostringstream oss;
+ oss << f << t;
+ return oss.str();
+}
+
+mpreal::operator std::string() const
+{
+ return to_string();
+}
+
+string mpreal::to_string(size_t n, int b, mp_rnd_t mode) const
+{
+ char *s, *ns = NULL;
+ size_t slen, nslen;
+ mp_exp_t exp;
+ string out;
+
+ if(mpfr_inf_p(mp))
+ {
+ if(mpfr_sgn(mp)>0) return "+@Inf@";
+ else return "-@Inf@";
+ }
+
+ if(mpfr_zero_p(mp)) return "0";
+ if(mpfr_nan_p(mp)) return "@NaN@";
+
+
+ s = mpfr_get_str(NULL,&exp,b,0,mp,mode);
+ ns = mpfr_get_str(NULL,&exp,b,n,mp,mode);
+
+ if(s!=NULL && ns!=NULL)
+ {
+ slen = strlen(s);
+ nslen = strlen(ns);
+ if(nslen<=slen)
+ {
+ mpfr_free_str(s);
+ s = ns;
+ slen = nslen;
+ }
+ else {
+ mpfr_free_str(ns);
+ }
+
+ // Make human eye-friendly formatting if possible
+ if (exp>0 && static_cast<size_t>(exp)<slen)
+ {
+ if(s[0]=='-')
+ {
+ // Remove zeros starting from right end
+ char* ptr = s+slen-1;
+ while (*ptr=='0' && ptr>s+exp) ptr--;
+
+ if(ptr==s+exp) out = string(s,exp+1);
+ else out = string(s,exp+1)+'.'+string(s+exp+1,ptr-(s+exp+1)+1);
+
+ //out = string(s,exp+1)+'.'+string(s+exp+1);
+ }
+ else
+ {
+ // Remove zeros starting from right end
+ char* ptr = s+slen-1;
+ while (*ptr=='0' && ptr>s+exp-1) ptr--;
+
+ if(ptr==s+exp-1) out = string(s,exp);
+ else out = string(s,exp)+'.'+string(s+exp,ptr-(s+exp)+1);
+
+ //out = string(s,exp)+'.'+string(s+exp);
+ }
+
+ }else{ // exp<0 || exp>slen
+ if(s[0]=='-')
+ {
+ // Remove zeros starting from right end
+ char* ptr = s+slen-1;
+ while (*ptr=='0' && ptr>s+1) ptr--;
+
+ if(ptr==s+1) out = string(s,2);
+ else out = string(s,2)+'.'+string(s+2,ptr-(s+2)+1);
+
+ //out = string(s,2)+'.'+string(s+2);
+ }
+ else
+ {
+ // Remove zeros starting from right end
+ char* ptr = s+slen-1;
+ while (*ptr=='0' && ptr>s) ptr--;
+
+ if(ptr==s) out = string(s,1);
+ else out = string(s,1)+'.'+string(s+1,ptr-(s+1)+1);
+
+ //out = string(s,1)+'.'+string(s+1);
+ }
+
+ // Make final string
+ if(--exp)
+ {
+ if(exp>0) out += "e+"+mpfr::to_string<mp_exp_t>(exp,std::dec);
+ else out += "e"+mpfr::to_string<mp_exp_t>(exp,std::dec);
+ }
+ }
+
+ mpfr_free_str(s);
+ return out;
+ }else{
+ return "conversion error!";
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
+// I/O
+ostream& operator<<(ostream& os, const mpreal& v)
+{
+ return os<<v.to_string(os.precision());
+}
+
+istream& operator>>(istream &is, mpreal& v)
+{
+ char c;
+ string s = "";
+ mpfr_t t;
+
+ if(is.good())
+ {
+ is>>ws;
+ while ((c = is.get())!=EOF)
+ {
+ if(c ==' ' || c == '\t' || c == '\n' || c == '\r')
+ {
+ is.putback(c);
+ break;
+ }
+ s += c;
+ }
+
+ if(s.size() != 0)
+ {
+ // Protect current value from alternation in case of input error
+ // so some error handling(roll back) procedure can be used
+ if(0==mpfr_init_set_str(t,s.c_str(),mpreal::default_base,mpreal::default_rnd))
+ {
+ mpfr_set(v.mp,t,mpreal::default_rnd);
+ mpfr_clear(t);
+
+ }else{
+ mpfr_clear(t);
+ cerr<<"error reading from istream"<<endl;
+ // throw an exception
+ }
+ }
+ }
+ return is;
+}
+}
diff --git a/unsupported/test/mpreal.h b/unsupported/test/mpreal.h
new file mode 100644
index 000000000..29a0cf7ff
--- /dev/null
+++ b/unsupported/test/mpreal.h
@@ -0,0 +1,3122 @@
+/*
+ Multi-precision real number class. C++ wrapper fo MPFR library.
+ Project homepage: http://www.holoborodko.com/pavel/
+ Contact e-mail: pavel@holoborodko.com
+
+ Copyright (c) 2008-2010 Pavel Holoborodko
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Contributors:
+ Brian Gladman, Helmut Jarausch, Fokko Beekhof, Ulrich Mutze,
+ Heinz van Saanen, Pere Constans, Dmitriy Gubanov
+*/
+
+#ifndef __MP_REAL_H__
+#define __MP_REAL_H__
+
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <cfloat>
+#include <cmath>
+
+#include <mpfr.h>
+
+// Detect compiler using signatures from http://predef.sourceforge.net/
+#if defined(__GNUC__) && defined(__INTEL_COMPILER)
+ #define IsInf(x) isinf(x) // GNU C/C++ + Intel ICC compiler
+
+#elif defined(__GNUC__)
+ #define IsInf(x) std::isinf(x) // GNU C/C++
+
+#elif defined(_MSC_VER)
+ #define IsInf(x) (!_finite(x)) // Microsoft Visual C++
+
+#else
+ #define IsInf(x) std::isinf(x) // C99 conformance
+#endif
+
+namespace mpfr {
+
+class mpreal {
+private:
+ mpfr_t mp;
+
+public:
+ static mp_rnd_t default_rnd;
+ static mp_prec_t default_prec;
+ static int default_base;
+ static int double_bits;
+
+public:
+ // Constructors && type conversion
+ mpreal();
+ mpreal(const mpreal& u);
+
+ mpreal(const mpfr_t u);
+ mpreal(const mpf_t u);
+
+ mpreal(const mpz_t u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const mpq_t u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const double u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const long double u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const unsigned long int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const unsigned int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const long int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const int u, mp_prec_t prec = default_prec, mp_rnd_t mode = default_rnd);
+ mpreal(const char* s, mp_prec_t prec = default_prec, int base = default_base, mp_rnd_t mode = default_rnd);
+
+ ~mpreal();
+
+ // Operations
+ // =
+ // +, -, *, /, ++, --, <<, >>
+ // *=, +=, -=, /=,
+ // <, >, ==, <=, >=
+
+ // =
+ mpreal& operator=(const mpreal& v);
+ mpreal& operator=(const mpf_t v);
+ mpreal& operator=(const mpz_t v);
+ mpreal& operator=(const mpq_t v);
+ mpreal& operator=(const long double v);
+ mpreal& operator=(const double v);
+ mpreal& operator=(const unsigned long int v);
+ mpreal& operator=(const unsigned int v);
+ mpreal& operator=(const long int v);
+ mpreal& operator=(const int v);
+ mpreal& operator=(const char* s);
+
+ // +
+ mpreal& operator+=(const mpreal& v);
+ mpreal& operator+=(const mpf_t v);
+ mpreal& operator+=(const mpz_t v);
+ mpreal& operator+=(const mpq_t v);
+ mpreal& operator+=(const long double u);
+ mpreal& operator+=(const double u);
+ mpreal& operator+=(const unsigned long int u);
+ mpreal& operator+=(const unsigned int u);
+ mpreal& operator+=(const long int u);
+ mpreal& operator+=(const int u);
+ const mpreal operator+() const;
+ mpreal& operator++ ();
+ const mpreal operator++ (int);
+
+ // -
+ mpreal& operator-=(const mpreal& v);
+ mpreal& operator-=(const mpz_t v);
+ mpreal& operator-=(const mpq_t v);
+ mpreal& operator-=(const long double u);
+ mpreal& operator-=(const double u);
+ mpreal& operator-=(const unsigned long int u);
+ mpreal& operator-=(const unsigned int u);
+ mpreal& operator-=(const long int u);
+ mpreal& operator-=(const int u);
+ const mpreal operator-() const;
+ friend const mpreal operator-(const unsigned long int b, const mpreal& a);
+ friend const mpreal operator-(const unsigned int b, const mpreal& a);
+ friend const mpreal operator-(const long int b, const mpreal& a);
+ friend const mpreal operator-(const int b, const mpreal& a);
+ friend const mpreal operator-(const double b, const mpreal& a);
+ mpreal& operator-- ();
+ const mpreal operator-- (int);
+
+ // *
+ mpreal& operator*=(const mpreal& v);
+ mpreal& operator*=(const mpz_t v);
+ mpreal& operator*=(const mpq_t v);
+ mpreal& operator*=(const long double v);
+ mpreal& operator*=(const double v);
+ mpreal& operator*=(const unsigned long int v);
+ mpreal& operator*=(const unsigned int v);
+ mpreal& operator*=(const long int v);
+ mpreal& operator*=(const int v);
+
+ // /
+ mpreal& operator/=(const mpreal& v);
+ mpreal& operator/=(const mpz_t v);
+ mpreal& operator/=(const mpq_t v);
+ mpreal& operator/=(const long double v);
+ mpreal& operator/=(const double v);
+ mpreal& operator/=(const unsigned long int v);
+ mpreal& operator/=(const unsigned int v);
+ mpreal& operator/=(const long int v);
+ mpreal& operator/=(const int v);
+ friend const mpreal operator/(const unsigned long int b, const mpreal& a);
+ friend const mpreal operator/(const unsigned int b, const mpreal& a);
+ friend const mpreal operator/(const long int b, const mpreal& a);
+ friend const mpreal operator/(const int b, const mpreal& a);
+ friend const mpreal operator/(const double b, const mpreal& a);
+
+ //<<= Fast Multiplication by 2^u
+ mpreal& operator<<=(const unsigned long int u);
+ mpreal& operator<<=(const unsigned int u);
+ mpreal& operator<<=(const long int u);
+ mpreal& operator<<=(const int u);
+
+ //>>= Fast Division by 2^u
+ mpreal& operator>>=(const unsigned long int u);
+ mpreal& operator>>=(const unsigned int u);
+ mpreal& operator>>=(const long int u);
+ mpreal& operator>>=(const int u);
+
+ // Boolean Operators
+ friend bool operator > (const mpreal& a, const mpreal& b);
+ friend bool operator >= (const mpreal& a, const mpreal& b);
+ friend bool operator < (const mpreal& a, const mpreal& b);
+ friend bool operator <= (const mpreal& a, const mpreal& b);
+ friend bool operator == (const mpreal& a, const mpreal& b);
+ friend bool operator != (const mpreal& a, const mpreal& b);
+
+ // Type Conversion operators
+ inline operator long double() const;
+ inline operator double() const;
+ inline operator float() const;
+ inline operator unsigned long() const;
+ inline operator unsigned int() const;
+ inline operator long() const;
+ operator std::string() const;
+ inline operator mpfr_ptr();
+
+ // Math Functions
+ friend const mpreal sqr(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend int cmpabs(const mpreal& a,const mpreal& b);
+
+ friend const mpreal log (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal exp (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+ friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+ friend const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+ friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal fac_ui (unsigned long int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal log1p (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal expm1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+ friend const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal _j0 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal _j1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal _jn (long n, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal _y0 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal _y1 (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal _yn (long n, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend int sgn(const mpreal& v); // -1 or +1
+
+// MPFR 2.4.0 Specifics
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ friend int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal li2(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+#endif
+
+// MPFR 3.0.0 Specifics
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
+ friend const mpreal digamma(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal urandom (gmp_randstate_t& state,mp_rnd_t rnd_mode = mpreal::default_rnd); // use gmp_randinit_default() to init state, gmp_randclear() to clear
+ friend bool _isregular(const mpreal& v);
+#endif
+
+ // Exponent and mantissa manipulation
+ friend const mpreal frexp(const mpreal& v, mp_exp_t* exp);
+ friend const mpreal ldexp(const mpreal& v, mp_exp_t exp);
+
+ // Splits mpreal value into fractional and integer parts.
+ // Returns fractional part and stores integer part in n.
+ friend const mpreal modf(const mpreal& v, mpreal& n);
+
+ // Constants
+ // don't forget to call mpfr_free_cache() for every thread where you are using const-functions
+ friend const mpreal const_log2 (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal const_pi (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal const_euler (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal const_catalan (mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ // returns +inf iff sign>=0 otherwise -inf
+ friend const mpreal const_infinity(int sign = 1, mp_prec_t prec = mpreal::default_prec, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+ // Output/ Input
+ friend std::ostream& operator<<(std::ostream& os, const mpreal& v);
+ friend std::istream& operator>>(std::istream& is, mpreal& v);
+
+ // Integer Related Functions
+ friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal ceil (const mpreal& v);
+ friend const mpreal floor(const mpreal& v);
+ friend const mpreal round(const mpreal& v);
+ friend const mpreal trunc(const mpreal& v);
+ friend const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal rint_floor(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal rint_round(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal rint_trunc(const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
+ friend const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+ // Miscellaneous Functions
+ friend const mpreal nexttoward (const mpreal& x, const mpreal& y);
+ friend const mpreal nextabove (const mpreal& x);
+ friend const mpreal nextbelow (const mpreal& x);
+
+ // use gmp_randinit_default() to init state, gmp_randclear() to clear
+ friend const mpreal urandomb (gmp_randstate_t& state);
+
+// MPFR < 2.4.2 Specifics
+#if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
+ friend const mpreal random2 (mp_size_t size, mp_exp_t exp);
+#endif
+
+ // Instance Checkers
+ friend bool _isnan(const mpreal& v);
+ friend bool _isinf(const mpreal& v);
+ friend bool _isnum(const mpreal& v);
+ friend bool _iszero(const mpreal& v);
+ friend bool _isint(const mpreal& v);
+
+ // Set/Get instance properties
+ inline mp_prec_t get_prec() const;
+ inline void set_prec(mp_prec_t prec, mp_rnd_t rnd_mode = default_rnd); // Change precision with rounding mode
+
+ // Set mpreal to +-inf, NaN
+ void set_inf(int sign = +1);
+ void set_nan();
+
+ // sign = -1 or +1
+ void set_sign(int sign, mp_rnd_t rnd_mode = default_rnd);
+
+ //Exponent
+ mp_exp_t get_exp();
+ int set_exp(mp_exp_t e);
+ int check_range (int t, mp_rnd_t rnd_mode = default_rnd);
+ int subnormalize (int t,mp_rnd_t rnd_mode = default_rnd);
+
+ // Inexact conversion from float
+ inline bool fits_in_bits(double x, int n);
+
+ // Set/Get global properties
+ static void set_default_prec(mp_prec_t prec);
+ static mp_prec_t get_default_prec();
+ static void set_default_base(int base);
+ static int get_default_base();
+ static void set_double_bits(int dbits);
+ static int get_double_bits();
+ static void set_default_rnd(mp_rnd_t rnd_mode);
+ static mp_rnd_t get_default_rnd();
+ static mp_exp_t get_emin (void);
+ static mp_exp_t get_emax (void);
+ static mp_exp_t get_emin_min (void);
+ static mp_exp_t get_emin_max (void);
+ static mp_exp_t get_emax_min (void);
+ static mp_exp_t get_emax_max (void);
+ static int set_emin (mp_exp_t exp);
+ static int set_emax (mp_exp_t exp);
+
+ // Get/Set conversions
+ // Convert mpreal to string with n significant digits in base b
+ // n = 0 -> convert with the maximum available digits
+ std::string to_string(size_t n = 0, int b = default_base, mp_rnd_t mode = default_rnd) const;
+
+ // Efficient swapping of two mpreal values
+ friend void swap(mpreal& x, mpreal& y);
+
+ //Min Max - macros is evil. Needed for systems which defines max and min globally as macros (e.g. Windows)
+ //Hope that globally defined macros use > < operations only
+ #ifndef max
+ friend const mpreal max(const mpreal& x, const mpreal& y);
+ #endif
+
+ #ifndef min
+ friend const mpreal min(const mpreal& x, const mpreal& y);
+ #endif
+};
+
+//////////////////////////////////////////////////////////////////////////
+// Exceptions
+class conversion_overflow : public std::exception {
+public:
+ std::string why() { return "inexact conversion from floating point"; }
+};
+
+//////////////////////////////////////////////////////////////////////////
+// + Addition
+const mpreal operator+(const mpreal& a, const mpreal& b);
+
+// + Fast specialized addition - implemented through fast += operations
+const mpreal operator+(const mpreal& a, const mpz_t b);
+const mpreal operator+(const mpreal& a, const mpq_t b);
+const mpreal operator+(const mpreal& a, const long double b);
+const mpreal operator+(const mpreal& a, const double b);
+const mpreal operator+(const mpreal& a, const unsigned long int b);
+const mpreal operator+(const mpreal& a, const unsigned int b);
+const mpreal operator+(const mpreal& a, const long int b);
+const mpreal operator+(const mpreal& a, const int b);
+const mpreal operator+(const mpreal& a, const char* b);
+const mpreal operator+(const char* a, const mpreal& b);
+const std::string operator+(const mpreal& a, const std::string b);
+const std::string operator+(const std::string a, const mpreal& b);
+
+const mpreal operator+(const mpz_t b, const mpreal& a);
+const mpreal operator+(const mpq_t b, const mpreal& a);
+const mpreal operator+(const long double b, const mpreal& a);
+const mpreal operator+(const double b, const mpreal& a);
+const mpreal operator+(const unsigned long int b, const mpreal& a);
+const mpreal operator+(const unsigned int b, const mpreal& a);
+const mpreal operator+(const long int b, const mpreal& a);
+const mpreal operator+(const int b, const mpreal& a);
+
+//////////////////////////////////////////////////////////////////////////
+// - Subtraction
+const mpreal operator-(const mpreal& a, const mpreal& b);
+
+// - Fast specialized subtraction - implemented through fast -= operations
+const mpreal operator-(const mpreal& a, const mpz_t b);
+const mpreal operator-(const mpreal& a, const mpq_t b);
+const mpreal operator-(const mpreal& a, const long double b);
+const mpreal operator-(const mpreal& a, const double b);
+const mpreal operator-(const mpreal& a, const unsigned long int b);
+const mpreal operator-(const mpreal& a, const unsigned int b);
+const mpreal operator-(const mpreal& a, const long int b);
+const mpreal operator-(const mpreal& a, const int b);
+const mpreal operator-(const mpreal& a, const char* b);
+const mpreal operator-(const char* a, const mpreal& b);
+
+const mpreal operator-(const mpz_t b, const mpreal& a);
+const mpreal operator-(const mpq_t b, const mpreal& a);
+const mpreal operator-(const long double b, const mpreal& a);
+//const mpreal operator-(const double b, const mpreal& a);
+
+//////////////////////////////////////////////////////////////////////////
+// * Multiplication
+const mpreal operator*(const mpreal& a, const mpreal& b);
+
+// * Fast specialized multiplication - implemented through fast *= operations
+const mpreal operator*(const mpreal& a, const mpz_t b);
+const mpreal operator*(const mpreal& a, const mpq_t b);
+const mpreal operator*(const mpreal& a, const long double b);
+const mpreal operator*(const mpreal& a, const double b);
+const mpreal operator*(const mpreal& a, const unsigned long int b);
+const mpreal operator*(const mpreal& a, const unsigned int b);
+const mpreal operator*(const mpreal& a, const long int b);
+const mpreal operator*(const mpreal& a, const int b);
+
+const mpreal operator*(const mpz_t b, const mpreal& a);
+const mpreal operator*(const mpq_t b, const mpreal& a);
+const mpreal operator*(const long double b, const mpreal& a);
+const mpreal operator*(const double b, const mpreal& a);
+const mpreal operator*(const unsigned long int b, const mpreal& a);
+const mpreal operator*(const unsigned int b, const mpreal& a);
+const mpreal operator*(const long int b, const mpreal& a);
+const mpreal operator*(const int b, const mpreal& a);
+
+//////////////////////////////////////////////////////////////////////////
+// / Division
+const mpreal operator/(const mpreal& a, const mpreal& b);
+
+// / Fast specialized division - implemented through fast /= operations
+const mpreal operator/(const mpreal& a, const mpz_t b);
+const mpreal operator/(const mpreal& a, const mpq_t b);
+const mpreal operator/(const mpreal& a, const long double b);
+const mpreal operator/(const mpreal& a, const double b);
+const mpreal operator/(const mpreal& a, const unsigned long int b);
+const mpreal operator/(const mpreal& a, const unsigned int b);
+const mpreal operator/(const mpreal& a, const long int b);
+const mpreal operator/(const mpreal& a, const int b);
+
+const mpreal operator/(const long double b, const mpreal& a);
+
+//////////////////////////////////////////////////////////////////////////
+// Shifts operators - Multiplication/Division by a power of 2
+const mpreal operator<<(const mpreal& v, const unsigned long int k);
+const mpreal operator<<(const mpreal& v, const unsigned int k);
+const mpreal operator<<(const mpreal& v, const long int k);
+const mpreal operator<<(const mpreal& v, const int k);
+
+const mpreal operator>>(const mpreal& v, const unsigned long int k);
+const mpreal operator>>(const mpreal& v, const unsigned int k);
+const mpreal operator>>(const mpreal& v, const long int k);
+const mpreal operator>>(const mpreal& v, const int k);
+
+//////////////////////////////////////////////////////////////////////////
+// Boolean operators
+bool operator < (const mpreal& a, const unsigned long int b);
+bool operator < (const mpreal& a, const unsigned int b);
+bool operator < (const mpreal& a, const long int b);
+bool operator < (const mpreal& a, const int b);
+bool operator < (const mpreal& a, const long double b);
+bool operator < (const mpreal& a, const double b);
+
+bool operator < (const unsigned long int a,const mpreal& b);
+bool operator < (const unsigned int a, const mpreal& b);
+bool operator < (const long int a, const mpreal& b);
+bool operator < (const int a, const mpreal& b);
+bool operator < (const long double a, const mpreal& b);
+bool operator < (const double a, const mpreal& b);
+
+bool operator > (const mpreal& a, const unsigned long int b);
+bool operator > (const mpreal& a, const unsigned int b);
+bool operator > (const mpreal& a, const long int b);
+bool operator > (const mpreal& a, const int b);
+bool operator > (const mpreal& a, const long double b);
+bool operator > (const mpreal& a, const double b);
+
+bool operator > (const unsigned long int a,const mpreal& b);
+bool operator > (const unsigned int a, const mpreal& b);
+bool operator > (const long int a, const mpreal& b);
+bool operator > (const int a, const mpreal& b);
+bool operator > (const long double a, const mpreal& b);
+bool operator > (const double a, const mpreal& b);
+
+bool operator >= (const mpreal& a, const unsigned long int b);
+bool operator >= (const mpreal& a, const unsigned int b);
+bool operator >= (const mpreal& a, const long int b);
+bool operator >= (const mpreal& a, const int b);
+bool operator >= (const mpreal& a, const long double b);
+bool operator >= (const mpreal& a, const double b);
+
+bool operator >= (const unsigned long int a,const mpreal& b);
+bool operator >= (const unsigned int a, const mpreal& b);
+bool operator >= (const long int a, const mpreal& b);
+bool operator >= (const int a, const mpreal& b);
+bool operator >= (const long double a, const mpreal& b);
+bool operator >= (const double a, const mpreal& b);
+
+bool operator <= (const mpreal& a, const unsigned long int b);
+bool operator <= (const mpreal& a, const unsigned int b);
+bool operator <= (const mpreal& a, const long int b);
+bool operator <= (const mpreal& a, const int b);
+bool operator <= (const mpreal& a, const long double b);
+bool operator <= (const mpreal& a, const double b);
+
+bool operator <= (const unsigned long int a,const mpreal& b);
+bool operator <= (const unsigned int a, const mpreal& b);
+bool operator <= (const long int a, const mpreal& b);
+bool operator <= (const int a, const mpreal& b);
+bool operator <= (const long double a, const mpreal& b);
+bool operator <= (const double a, const mpreal& b);
+
+bool operator == (const mpreal& a, const unsigned long int b);
+bool operator == (const mpreal& a, const unsigned int b);
+bool operator == (const mpreal& a, const long int b);
+bool operator == (const mpreal& a, const int b);
+bool operator == (const mpreal& a, const long double b);
+bool operator == (const mpreal& a, const double b);
+
+bool operator == (const unsigned long int a,const mpreal& b);
+bool operator == (const unsigned int a, const mpreal& b);
+bool operator == (const long int a, const mpreal& b);
+bool operator == (const int a, const mpreal& b);
+bool operator == (const long double a, const mpreal& b);
+bool operator == (const double a, const mpreal& b);
+
+bool operator != (const mpreal& a, const unsigned long int b);
+bool operator != (const mpreal& a, const unsigned int b);
+bool operator != (const mpreal& a, const long int b);
+bool operator != (const mpreal& a, const int b);
+bool operator != (const mpreal& a, const long double b);
+bool operator != (const mpreal& a, const double b);
+
+bool operator != (const unsigned long int a,const mpreal& b);
+bool operator != (const unsigned int a, const mpreal& b);
+bool operator != (const long int a, const mpreal& b);
+bool operator != (const int a, const mpreal& b);
+bool operator != (const long double a, const mpreal& b);
+bool operator != (const double a, const mpreal& b);
+
+//////////////////////////////////////////////////////////////////////////
+// sqrt
+const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+//////////////////////////////////////////////////////////////////////////
+// pow
+const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::default_rnd);
+
+//////////////////////////////////////////////////////////////////////////
+// Estimate machine epsilon for the given precision
+inline const mpreal machine_epsilon(mp_prec_t prec);
+inline const mpreal mpreal_min(mp_prec_t prec);
+inline const mpreal mpreal_max(mp_prec_t prec);
+
+//////////////////////////////////////////////////////////////////////////
+// Implementation of inline functions
+//////////////////////////////////////////////////////////////////////////
+
+//////////////////////////////////////////////////////////////////////////
+// Operators - Assignment
+inline mpreal& mpreal::operator=(const mpreal& v)
+{
+ if (this!= &v) mpfr_set(mp,v.mp,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const mpf_t v)
+{
+ mpfr_set_f(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const mpz_t v)
+{
+ mpfr_set_z(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const mpq_t v)
+{
+ mpfr_set_q(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const long double v)
+{
+ mpfr_set_ld(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const double v)
+{
+ if(double_bits == -1 || fits_in_bits(v, double_bits))
+ {
+ mpfr_set_d(mp,v,default_rnd);
+ }
+ else
+ throw conversion_overflow();
+
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const unsigned long int v)
+{
+ mpfr_set_ui(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const unsigned int v)
+{
+ mpfr_set_ui(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const long int v)
+{
+ mpfr_set_si(mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator=(const int v)
+{
+ mpfr_set_si(mp,v,default_rnd);
+ return *this;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// + Addition
+inline mpreal& mpreal::operator+=(const mpreal& v)
+{
+ mpfr_add(mp,mp,v.mp,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+=(const mpf_t u)
+{
+ *this += mpreal(u);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+=(const mpz_t u)
+{
+ mpfr_add_z(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+=(const mpq_t u)
+{
+ mpfr_add_q(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+= (const long double u)
+{
+ return *this += mpreal(u);
+}
+
+inline mpreal& mpreal::operator+= (const double u)
+{
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ mpfr_add_d(mp,mp,u,default_rnd);
+ return *this;
+#else
+ return *this += mpreal(u);
+#endif
+}
+
+inline mpreal& mpreal::operator+=(const unsigned long int u)
+{
+ mpfr_add_ui(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+=(const unsigned int u)
+{
+ mpfr_add_ui(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+=(const long int u)
+{
+ mpfr_add_si(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator+=(const int u)
+{
+ mpfr_add_si(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline const mpreal mpreal::operator+()const
+{
+ return mpreal(*this);
+}
+
+inline const mpreal operator+(const mpreal& a, const mpreal& b)
+{
+ // prec(a+b) = max(prec(a),prec(b))
+ if(a.get_prec()>b.get_prec()) return mpreal(a) += b;
+ else return mpreal(b) += a;
+}
+
+inline const std::string operator+(const mpreal& a, const std::string b)
+{
+ return (std::string)a+b;
+}
+
+inline const std::string operator+(const std::string a, const mpreal& b)
+{
+ return a+(std::string)b;
+}
+
+inline const mpreal operator+(const mpreal& a, const mpz_t b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const char* b)
+{
+ return a+mpreal(b);
+}
+
+inline const mpreal operator+(const char* a, const mpreal& b)
+{
+ return mpreal(a)+b;
+
+}
+
+inline const mpreal operator+(const mpreal& a, const mpq_t b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const long double b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const double b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const unsigned long int b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const unsigned int b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const long int b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpreal& a, const int b)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpz_t b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const mpq_t b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const long double b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const double b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const unsigned long int b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const unsigned int b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const long int b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline const mpreal operator+(const int b, const mpreal& a)
+{
+ return mpreal(a) += b;
+}
+
+inline mpreal& mpreal::operator++()
+{
+ *this += 1;
+ return *this;
+}
+
+inline const mpreal mpreal::operator++ (int)
+{
+ mpreal x(*this);
+ *this += 1;
+ return x;
+}
+
+inline mpreal& mpreal::operator--()
+{
+ *this -= 1;
+ return *this;
+}
+
+inline const mpreal mpreal::operator-- (int)
+{
+ mpreal x(*this);
+ *this -= 1;
+ return x;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// - Subtraction
+inline mpreal& mpreal::operator-= (const mpreal& v)
+{
+ mpfr_sub(mp,mp,v.mp,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator-=(const mpz_t v)
+{
+ mpfr_sub_z(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator-=(const mpq_t v)
+{
+ mpfr_sub_q(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator-=(const long double v)
+{
+ return *this -= mpreal(v);
+}
+
+inline mpreal& mpreal::operator-=(const double v)
+{
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ mpfr_sub_d(mp,mp,v,default_rnd);
+ return *this;
+#else
+ return *this -= mpreal(v);
+#endif
+}
+
+inline mpreal& mpreal::operator-=(const unsigned long int v)
+{
+ mpfr_sub_ui(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator-=(const unsigned int v)
+{
+ mpfr_sub_ui(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator-=(const long int v)
+{
+ mpfr_sub_si(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator-=(const int v)
+{
+ mpfr_sub_si(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline const mpreal mpreal::operator-()const
+{
+ mpreal u(*this);
+ mpfr_neg(u.mp,u.mp,default_rnd);
+ return u;
+}
+
+inline const mpreal operator-(const mpreal& a, const mpreal& b)
+{
+ // prec(a-b) = max(prec(a),prec(b))
+ if(a.get_prec()>b.get_prec()) return mpreal(a) -= b;
+ else return -(mpreal(b) -= a);
+}
+
+inline const mpreal operator-(const mpreal& a, const mpz_t b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const mpq_t b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const long double b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const double b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const unsigned long int b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const unsigned int b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const long int b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpreal& a, const int b)
+{
+ return mpreal(a) -= b;
+}
+
+inline const mpreal operator-(const mpz_t b, const mpreal& a)
+{
+ return -(mpreal(a) -= b);
+}
+
+inline const mpreal operator-(const mpq_t b, const mpreal& a)
+{
+ return -(mpreal(a) -= b);
+}
+
+inline const mpreal operator-(const long double b, const mpreal& a)
+{
+ return -(mpreal(a) -= b);
+}
+
+inline const mpreal operator-(const double b, const mpreal& a)
+{
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ mpreal x(a);
+ mpfr_d_sub(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+#else
+ return -(mpreal(a) -= b);
+#endif
+}
+
+inline const mpreal operator-(const unsigned long int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_ui_sub(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator-(const unsigned int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_ui_sub(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator-(const long int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_si_sub(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator-(const int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_si_sub(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator-(const mpreal& a, const char* b)
+{
+ return a-mpreal(b);
+}
+
+inline const mpreal operator-(const char* a, const mpreal& b)
+{
+ return mpreal(a)-b;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// * Multiplication
+inline mpreal& mpreal::operator*= (const mpreal& v)
+{
+ mpfr_mul(mp,mp,v.mp,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator*=(const mpz_t v)
+{
+ mpfr_mul_z(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator*=(const mpq_t v)
+{
+ mpfr_mul_q(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator*=(const long double v)
+{
+ return *this *= mpreal(v);
+}
+
+inline mpreal& mpreal::operator*=(const double v)
+{
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ mpfr_mul_d(mp,mp,v,default_rnd);
+ return *this;
+#else
+ return *this *= mpreal(v);
+#endif
+}
+
+inline mpreal& mpreal::operator*=(const unsigned long int v)
+{
+ mpfr_mul_ui(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator*=(const unsigned int v)
+{
+ mpfr_mul_ui(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator*=(const long int v)
+{
+ mpfr_mul_si(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator*=(const int v)
+{
+ mpfr_mul_si(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline const mpreal operator*(const mpreal& a, const mpreal& b)
+{
+ // prec(a*b) = max(prec(a),prec(b))
+ if(a.get_prec()>b.get_prec()) return mpreal(a) *= b;
+ else return mpreal(b) *= a;
+}
+
+inline const mpreal operator*(const mpreal& a, const mpz_t b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const mpq_t b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const long double b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const double b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const unsigned long int b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const unsigned int b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const long int b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpreal& a, const int b)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpz_t b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const mpq_t b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const long double b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const double b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const unsigned long int b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const unsigned int b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const long int b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+inline const mpreal operator*(const int b, const mpreal& a)
+{
+ return mpreal(a) *= b;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// / Division
+inline mpreal& mpreal::operator/=(const mpreal& v)
+{
+ mpfr_div(mp,mp,v.mp,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator/=(const mpz_t v)
+{
+ mpfr_div_z(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator/=(const mpq_t v)
+{
+ mpfr_div_q(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator/=(const long double v)
+{
+ return *this /= mpreal(v);
+}
+
+inline mpreal& mpreal::operator/=(const double v)
+{
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ mpfr_div_d(mp,mp,v,default_rnd);
+ return *this;
+#else
+ return *this /= mpreal(v);
+#endif
+}
+
+inline mpreal& mpreal::operator/=(const unsigned long int v)
+{
+ mpfr_div_ui(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator/=(const unsigned int v)
+{
+ mpfr_div_ui(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator/=(const long int v)
+{
+ mpfr_div_si(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator/=(const int v)
+{
+ mpfr_div_si(mp,mp,v,default_rnd);
+ return *this;
+}
+
+inline const mpreal operator/(const mpreal& a, const mpreal& b)
+{
+ mpreal x(a);
+ mp_prec_t pb;
+ mp_prec_t pa;
+
+ // prec(a/b) = max(prec(a),prec(b))
+ pa = a.get_prec();
+ pb = b.get_prec();
+ if(pb>pa) x.set_prec(pb);
+
+ return x /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const mpz_t b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const mpq_t b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const long double b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const double b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const unsigned long int b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const unsigned int b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const long int b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const mpreal& a, const int b)
+{
+ return mpreal(a) /= b;
+}
+
+inline const mpreal operator/(const unsigned long int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_ui_div(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator/(const unsigned int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_ui_div(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator/(const long int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_si_div(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator/(const int b, const mpreal& a)
+{
+ mpreal x(a);
+ mpfr_si_div(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal operator/(const long double b, const mpreal& a)
+{
+ mpreal x(b);
+ return x/a;
+}
+
+inline const mpreal operator/(const double b, const mpreal& a)
+{
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+ mpreal x(a);
+ mpfr_d_div(x.mp,b,a.mp,mpreal::default_rnd);
+ return x;
+#else
+ mpreal x(b);
+ return x/a;
+#endif
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Shifts operators - Multiplication/Division by power of 2
+inline mpreal& mpreal::operator<<=(const unsigned long int u)
+{
+ mpfr_mul_2ui(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator<<=(const unsigned int u)
+{
+ mpfr_mul_2ui(mp,mp,static_cast<unsigned long int>(u),default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator<<=(const long int u)
+{
+ mpfr_mul_2si(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator<<=(const int u)
+{
+ mpfr_mul_2si(mp,mp,static_cast<long int>(u),default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator>>=(const unsigned long int u)
+{
+ mpfr_div_2ui(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator>>=(const unsigned int u)
+{
+ mpfr_div_2ui(mp,mp,static_cast<unsigned long int>(u),default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator>>=(const long int u)
+{
+ mpfr_div_2si(mp,mp,u,default_rnd);
+ return *this;
+}
+
+inline mpreal& mpreal::operator>>=(const int u)
+{
+ mpfr_div_2si(mp,mp,static_cast<long int>(u),default_rnd);
+ return *this;
+}
+
+inline const mpreal operator<<(const mpreal& v, const unsigned long int k)
+{
+ return mul_2ui(v,k);
+}
+
+inline const mpreal operator<<(const mpreal& v, const unsigned int k)
+{
+ return mul_2ui(v,static_cast<unsigned long int>(k));
+}
+
+inline const mpreal operator<<(const mpreal& v, const long int k)
+{
+ return mul_2si(v,k);
+}
+
+inline const mpreal operator<<(const mpreal& v, const int k)
+{
+ return mul_2si(v,static_cast<long int>(k));
+}
+
+inline const mpreal operator>>(const mpreal& v, const unsigned long int k)
+{
+ return div_2ui(v,k);
+}
+
+inline const mpreal operator>>(const mpreal& v, const long int k)
+{
+ return div_2si(v,k);
+}
+
+inline const mpreal operator>>(const mpreal& v, const unsigned int k)
+{
+ return div_2ui(v,static_cast<unsigned long int>(k));
+}
+
+inline const mpreal operator>>(const mpreal& v, const int k)
+{
+ return div_2si(v,static_cast<long int>(k));
+}
+
+// mul_2ui
+inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_mul_2ui(x.mp,v.mp,k,rnd_mode);
+ return x;
+}
+
+// mul_2si
+inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_mul_2si(x.mp,v.mp,k,rnd_mode);
+ return x;
+}
+
+inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_div_2ui(x.mp,v.mp,k,rnd_mode);
+ return x;
+}
+
+inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_div_2si(x.mp,v.mp,k,rnd_mode);
+ return x;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//Boolean operators
+inline bool operator > (const mpreal& a, const mpreal& b)
+{
+ return (mpfr_greater_p(a.mp,b.mp)!=0);
+}
+
+inline bool operator > (const mpreal& a, const unsigned long int b)
+{
+ return a>mpreal(b);
+}
+
+inline bool operator > (const mpreal& a, const unsigned int b)
+{
+ return a>mpreal(b);
+}
+
+inline bool operator > (const mpreal& a, const long int b)
+{
+ return a>mpreal(b);
+}
+
+inline bool operator > (const mpreal& a, const int b)
+{
+ return a>mpreal(b);
+}
+
+inline bool operator > (const mpreal& a, const long double b)
+{
+ return a>mpreal(b);
+}
+
+inline bool operator > (const mpreal& a, const double b)
+{
+ return a>mpreal(b);
+}
+
+inline bool operator > (const unsigned long int a, const mpreal& b)
+{
+ return mpreal(a)>b;
+}
+
+inline bool operator > (const unsigned int a, const mpreal& b)
+{
+ return mpreal(a)>b;
+}
+
+inline bool operator > (const long int a, const mpreal& b)
+{
+ return mpreal(a)>b;
+}
+
+inline bool operator > (const int a, const mpreal& b)
+{
+ return mpreal(a)>b;
+}
+
+inline bool operator > (const long double a, const mpreal& b)
+{
+ return mpreal(a)>b;
+}
+
+inline bool operator > (const double a, const mpreal& b)
+{
+ return mpreal(a)>b;
+}
+
+inline bool operator >= (const mpreal& a, const mpreal& b)
+{
+ return (mpfr_greaterequal_p(a.mp,b.mp)!=0);
+}
+
+inline bool operator >= (const mpreal& a, const unsigned long int b)
+{
+ return a>=mpreal(b);
+}
+
+inline bool operator >= (const mpreal& a, const unsigned int b)
+{
+ return a>=mpreal(b);
+}
+
+inline bool operator >= (const mpreal& a, const long int b)
+{
+ return a>=mpreal(b);
+}
+
+inline bool operator >= (const mpreal& a, const int b)
+{
+ return a>=mpreal(b);
+}
+
+inline bool operator >= (const mpreal& a, const long double b)
+{
+ return a>=mpreal(b);
+}
+
+inline bool operator >= (const mpreal& a, const double b)
+{
+ return a>=mpreal(b);
+}
+
+inline bool operator >= (const unsigned long int a,const mpreal& b)
+{
+ return mpreal(a)>=b;
+}
+
+inline bool operator >= (const unsigned int a, const mpreal& b)
+{
+ return mpreal(a)>=b;
+}
+
+inline bool operator >= (const long int a, const mpreal& b)
+{
+ return mpreal(a)>=b;
+}
+
+inline bool operator >= (const int a, const mpreal& b)
+{
+ return mpreal(a)>=b;
+}
+
+inline bool operator >= (const long double a, const mpreal& b)
+{
+ return mpreal(a)>=b;
+}
+
+inline bool operator >= (const double a, const mpreal& b)
+{
+ return mpreal(a)>=b;
+}
+
+inline bool operator < (const mpreal& a, const mpreal& b)
+{
+ return (mpfr_less_p(a.mp,b.mp)!=0);
+}
+
+inline bool operator < (const mpreal& a, const unsigned long int b)
+{
+ return a<mpreal(b);
+}
+
+inline bool operator < (const mpreal& a, const unsigned int b)
+{
+ return a<mpreal(b);
+}
+
+inline bool operator < (const mpreal& a, const long int b)
+{
+ return a<mpreal(b);
+}
+
+inline bool operator < (const mpreal& a, const int b)
+{
+ return a<mpreal(b);
+}
+
+inline bool operator < (const mpreal& a, const long double b)
+{
+ return a<mpreal(b);
+}
+
+inline bool operator < (const mpreal& a, const double b)
+{
+ return a<mpreal(b);
+}
+
+inline bool operator < (const unsigned long int a, const mpreal& b)
+{
+ return mpreal(a)<b;
+}
+
+inline bool operator < (const unsigned int a,const mpreal& b)
+{
+ return mpreal(a)<b;
+}
+
+inline bool operator < (const long int a,const mpreal& b)
+{
+ return mpreal(a)<b;
+}
+
+inline bool operator < (const int a,const mpreal& b)
+{
+ return mpreal(a)<b;
+}
+
+inline bool operator < (const long double a,const mpreal& b)
+{
+ return mpreal(a)<b;
+}
+
+inline bool operator < (const double a,const mpreal& b)
+{
+ return mpreal(a)<b;
+}
+
+inline bool operator <= (const mpreal& a, const mpreal& b)
+{
+ return (mpfr_lessequal_p(a.mp,b.mp)!=0);
+}
+
+inline bool operator <= (const mpreal& a, const unsigned long int b)
+{
+ return a<=mpreal(b);
+}
+
+inline bool operator <= (const mpreal& a, const unsigned int b)
+{
+ return a<=mpreal(b);
+}
+
+inline bool operator <= (const mpreal& a, const long int b)
+{
+ return a<=mpreal(b);
+}
+
+inline bool operator <= (const mpreal& a, const int b)
+{
+ return a<=mpreal(b);
+}
+
+inline bool operator <= (const mpreal& a, const long double b)
+{
+ return a<=mpreal(b);
+}
+
+inline bool operator <= (const mpreal& a, const double b)
+{
+ return a<=mpreal(b);
+}
+
+inline bool operator <= (const unsigned long int a,const mpreal& b)
+{
+ return mpreal(a)<=b;
+}
+
+inline bool operator <= (const unsigned int a, const mpreal& b)
+{
+ return mpreal(a)<=b;
+}
+
+inline bool operator <= (const long int a, const mpreal& b)
+{
+ return mpreal(a)<=b;
+}
+
+inline bool operator <= (const int a, const mpreal& b)
+{
+ return mpreal(a)<=b;
+}
+
+inline bool operator <= (const long double a, const mpreal& b)
+{
+ return mpreal(a)<=b;
+}
+
+inline bool operator <= (const double a, const mpreal& b)
+{
+ return mpreal(a)<=b;
+}
+
+inline bool operator == (const mpreal& a, const mpreal& b)
+{
+ return (mpfr_equal_p(a.mp,b.mp)!=0);
+}
+
+inline bool operator == (const mpreal& a, const unsigned long int b)
+{
+ return a==mpreal(b);
+}
+
+inline bool operator == (const mpreal& a, const unsigned int b)
+{
+ return a==mpreal(b);
+}
+
+inline bool operator == (const mpreal& a, const long int b)
+{
+ return a==mpreal(b);
+}
+
+inline bool operator == (const mpreal& a, const int b)
+{
+ return a==mpreal(b);
+}
+
+inline bool operator == (const mpreal& a, const long double b)
+{
+ return a==mpreal(b);
+}
+
+inline bool operator == (const mpreal& a, const double b)
+{
+ return a==mpreal(b);
+}
+
+inline bool operator == (const unsigned long int a,const mpreal& b)
+{
+ return mpreal(a)==b;
+}
+
+inline bool operator == (const unsigned int a, const mpreal& b)
+{
+ return mpreal(a)==b;
+}
+
+inline bool operator == (const long int a, const mpreal& b)
+{
+ return mpreal(a)==b;
+}
+
+inline bool operator == (const int a, const mpreal& b)
+{
+ return mpreal(a)==b;
+}
+
+inline bool operator == (const long double a, const mpreal& b)
+{
+ return mpreal(a)==b;
+}
+
+inline bool operator == (const double a, const mpreal& b)
+{
+ return mpreal(a)==b;
+}
+
+inline bool operator != (const mpreal& a, const mpreal& b)
+{
+ return (mpfr_lessgreater_p(a.mp,b.mp)!=0);
+}
+
+inline bool operator != (const mpreal& a, const unsigned long int b)
+{
+ return a!=mpreal(b);
+}
+
+inline bool operator != (const mpreal& a, const unsigned int b)
+{
+ return a!=mpreal(b);
+}
+
+inline bool operator != (const mpreal& a, const long int b)
+{
+ return a!=mpreal(b);
+}
+
+inline bool operator != (const mpreal& a, const int b)
+{
+ return a!=mpreal(b);
+}
+
+inline bool operator != (const mpreal& a, const long double b)
+{
+ return a!=mpreal(b);
+}
+
+inline bool operator != (const mpreal& a, const double b)
+{
+ return a!=mpreal(b);
+}
+
+inline bool operator != (const unsigned long int a,const mpreal& b)
+{
+ return mpreal(a)!=b;
+}
+
+inline bool operator != (const unsigned int a, const mpreal& b)
+{
+ return mpreal(a)!=b;
+}
+
+inline bool operator != (const long int a, const mpreal& b)
+{
+ return mpreal(a)!=b;
+}
+
+inline bool operator != (const int a, const mpreal& b)
+{
+ return mpreal(a)!=b;
+}
+
+inline bool operator != (const long double a, const mpreal& b)
+{
+ return mpreal(a)!=b;
+}
+
+inline bool operator != (const double a, const mpreal& b)
+{
+ return mpreal(a)!=b;
+}
+
+inline bool _isnan(const mpreal& v)
+{
+ return (mpfr_nan_p(v.mp)!=0);
+}
+
+inline bool _isinf(const mpreal& v)
+{
+ return (mpfr_inf_p(v.mp)!=0);
+}
+
+inline bool _isnum(const mpreal& v)
+{
+ return (mpfr_number_p(v.mp)!=0);
+}
+
+inline bool _iszero(const mpreal& v)
+{
+ return (mpfr_zero_p(v.mp)!=0);
+}
+
+inline bool _isint(const mpreal& v)
+{
+ return (mpfr_integer_p(v.mp)!=0);
+}
+
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
+inline bool _isregular(const mpreal& v)
+{
+ return (mpfr_regular_p(v.mp));
+}
+#endif // MPFR 3.0.0 Specifics
+
+//////////////////////////////////////////////////////////////////////////
+// Type Converters
+inline mpreal::operator double() const
+{
+ return mpfr_get_d(mp,default_rnd);
+}
+
+inline mpreal::operator float() const
+{
+ return (float)mpfr_get_d(mp,default_rnd);
+}
+
+inline mpreal::operator long double() const
+{
+ return mpfr_get_ld(mp,default_rnd);
+}
+
+inline mpreal::operator unsigned long() const
+{
+ return mpfr_get_ui(mp,default_rnd);
+}
+
+inline mpreal::operator unsigned int() const
+{
+ return static_cast<unsigned int>(mpfr_get_ui(mp,default_rnd));
+}
+
+inline mpreal::operator long() const
+{
+ return mpfr_get_si(mp,default_rnd);
+}
+
+inline mpreal::operator mpfr_ptr()
+{
+ return mp;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Set/Get number properties
+inline int sgn(const mpreal& v)
+{
+ int r = mpfr_signbit(v.mp);
+ return (r>0?-1:1);
+}
+
+inline void mpreal::set_sign(int sign, mp_rnd_t rnd_mode)
+{
+ mpfr_setsign(mp,mp,(sign<0?1:0),rnd_mode);
+}
+
+inline mp_prec_t mpreal::get_prec() const
+{
+ return mpfr_get_prec(mp);
+}
+
+inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode)
+{
+ mpfr_prec_round(mp,prec,rnd_mode);
+}
+
+inline void mpreal::set_inf(int sign)
+{
+ mpfr_set_inf(mp,sign);
+}
+
+inline void mpreal::set_nan()
+{
+ mpfr_set_nan(mp);
+}
+
+inline mp_exp_t mpreal::get_exp ()
+{
+ return mpfr_get_exp(mp);
+}
+
+inline int mpreal::set_exp (mp_exp_t e)
+{
+ return mpfr_set_exp(mp,e);
+}
+
+inline const mpreal frexp(const mpreal& v, mp_exp_t* exp)
+{
+ mpreal x(v);
+ *exp = x.get_exp();
+ x.set_exp(0);
+ return x;
+}
+
+inline const mpreal ldexp(const mpreal& v, mp_exp_t exp)
+{
+ mpreal x(v);
+
+ // rounding is not important since we just increasing the exponent
+ mpfr_mul_2si(x.mp,x.mp,exp,mpreal::default_rnd);
+ return x;
+}
+
+inline const mpreal machine_epsilon(mp_prec_t prec)
+{
+ // smallest eps such that 1.0+eps != 1.0
+ // depends (of cause) on the precision
+ mpreal x(1,prec);
+ return nextabove(x)-x;
+}
+
+inline const mpreal mpreal_min(mp_prec_t prec)
+{
+ // min = 1/2*2^emin = 2^(emin-1)
+
+ mpreal x(1,prec);
+ return x <<= mpreal::get_emin()-1;
+}
+
+inline const mpreal mpreal_max(mp_prec_t prec)
+{
+ // max = (1-eps)*2^emax, assume eps = 0?,
+ // and use emax-1 to prevent value to be +inf
+ // max = 2^(emax-1)
+
+ mpreal x(1,prec);
+ return x <<= mpreal::get_emax()-1;
+}
+
+inline const mpreal modf(const mpreal& v, mpreal& n)
+{
+ mpreal frac(v);
+
+ // rounding is not important since we are using the same number
+ mpfr_frac(frac.mp,frac.mp,mpreal::default_rnd);
+ mpfr_trunc(n.mp,v.mp);
+ return frac;
+}
+
+inline int mpreal::check_range (int t, mp_rnd_t rnd_mode)
+{
+ return mpfr_check_range(mp,t,rnd_mode);
+}
+
+inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode)
+{
+ return mpfr_subnormalize(mp,t,rnd_mode);
+}
+
+inline mp_exp_t mpreal::get_emin (void)
+{
+ return mpfr_get_emin();
+}
+
+inline int mpreal::set_emin (mp_exp_t exp)
+{
+ return mpfr_set_emin(exp);
+}
+
+inline mp_exp_t mpreal::get_emax (void)
+{
+ return mpfr_get_emax();
+}
+
+inline int mpreal::set_emax (mp_exp_t exp)
+{
+ return mpfr_set_emax(exp);
+}
+
+inline mp_exp_t mpreal::get_emin_min (void)
+{
+ return mpfr_get_emin_min();
+}
+
+inline mp_exp_t mpreal::get_emin_max (void)
+{
+ return mpfr_get_emin_max();
+}
+
+inline mp_exp_t mpreal::get_emax_min (void)
+{
+ return mpfr_get_emax_min();
+}
+
+inline mp_exp_t mpreal::get_emax_max (void)
+{
+ return mpfr_get_emax_max();
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Mathematical Functions
+//////////////////////////////////////////////////////////////////////////
+inline const mpreal sqr(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_sqr(x.mp,x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_sqrt(x.mp,x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ mpfr_sqrt_ui(x.mp,v,rnd_mode);
+ return x;
+}
+
+inline const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode)
+{
+ return sqrt(static_cast<unsigned long int>(v),rnd_mode);
+}
+
+inline const mpreal sqrt(const long int v, mp_rnd_t rnd_mode)
+{
+ if (v>=0) return sqrt(static_cast<unsigned long int>(v),rnd_mode);
+ else return mpreal(); // NaN
+}
+
+inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode)
+{
+ if (v>=0) return sqrt(static_cast<unsigned long int>(v),rnd_mode);
+ else return mpreal(); // NaN
+}
+
+inline const mpreal sqrt(const long double v, mp_rnd_t rnd_mode)
+{
+ return sqrt(mpreal(v),rnd_mode);
+}
+
+inline const mpreal sqrt(const double v, mp_rnd_t rnd_mode)
+{
+ return sqrt(mpreal(v),rnd_mode);
+}
+
+inline const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_cbrt(x.mp,x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_root(x.mp,x.mp,k,rnd_mode);
+ return x;
+}
+
+inline const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_abs(x.mp,x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_abs(x.mp,x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_dim(x.mp,a.mp,b.mp,rnd_mode);
+ return x;
+}
+
+inline int cmpabs(const mpreal& a,const mpreal& b)
+{
+ return mpfr_cmpabs(a.mp,b.mp);
+}
+
+inline const mpreal log (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_log(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal log2(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_log2(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_log10(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal exp(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_exp(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal exp2(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_exp2(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_exp10(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_cos(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_sin(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_tan(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_sec(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_csc(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_cot(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode)
+{
+ return mpfr_sin_cos(s.mp,c.mp,v.mp,rnd_mode);
+}
+
+inline const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_acos(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_asin(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_atan(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t yp, xp;
+
+ yp = y.get_prec();
+ xp = x.get_prec();
+
+ a.set_prec(yp>xp?yp:xp);
+
+ mpfr_atan2(a.mp, y.mp, x.mp, rnd_mode);
+
+ return a;
+}
+
+inline const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_cosh(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_sinh(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_tanh(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_sech(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_csch(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_coth(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_acosh(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_asinh(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_atanh(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal fac_ui (unsigned long int v, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ mpfr_fac_ui(x.mp,v,rnd_mode);
+ return x;
+}
+
+inline const mpreal log1p (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_log1p(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal expm1 (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_expm1(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_eint(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_gamma(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_lngamma(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_lgamma(x.mp,signp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_zeta(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_erf(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_erfc(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal _j0 (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_j0(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal _j1 (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_j1(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal _jn (long n, const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_jn(x.mp,n,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal _y0 (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_y0(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal _y1 (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_y1(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal _yn (long n, const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_yn(x.mp,n,v.mp,rnd_mode);
+ return x;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// MPFR 2.4.0 Specifics
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0))
+
+inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode)
+{
+ return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode);
+}
+
+inline const mpreal li2(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_li2(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode)
+{
+ mpreal a;
+ mp_prec_t yp, xp;
+
+ yp = y.get_prec();
+ xp = x.get_prec();
+
+ a.set_prec(yp>xp?yp:xp);
+
+ mpfr_fmod(a.mp, x.mp, y.mp, rnd_mode);
+
+ return a;
+}
+
+inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_rec_sqrt(x.mp,v.mp,rnd_mode);
+ return x;
+}
+#endif // MPFR 2.4.0 Specifics
+
+//////////////////////////////////////////////////////////////////////////
+// MPFR 3.0.0 Specifics
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
+inline const mpreal digamma(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_digamma(x.mp,v.mp,rnd_mode);
+ return x;
+}
+#endif // MPFR 3.0.0 Specifics
+
+//////////////////////////////////////////////////////////////////////////
+// Constants
+inline const mpreal const_log2 (mp_prec_t prec, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ x.set_prec(prec);
+ mpfr_const_log2(x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal const_pi (mp_prec_t prec, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ x.set_prec(prec);
+ mpfr_const_pi(x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal const_euler (mp_prec_t prec, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ x.set_prec(prec);
+ mpfr_const_euler(x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal const_catalan (mp_prec_t prec, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ x.set_prec(prec);
+ mpfr_const_catalan(x.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal const_infinity (int sign, mp_prec_t prec, mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ x.set_prec(prec,rnd_mode);
+ mpfr_set_inf(x.mp, sign);
+ return x;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Integer Related Functions
+inline const mpreal rint(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_rint(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal ceil(const mpreal& v)
+{
+ mpreal x(v);
+ mpfr_ceil(x.mp,v.mp);
+ return x;
+
+}
+
+inline const mpreal floor(const mpreal& v)
+{
+ mpreal x(v);
+ mpfr_floor(x.mp,v.mp);
+ return x;
+}
+
+inline const mpreal round(const mpreal& v)
+{
+ mpreal x(v);
+ mpfr_round(x.mp,v.mp);
+ return x;
+}
+
+inline const mpreal trunc(const mpreal& v)
+{
+ mpreal x(v);
+ mpfr_trunc(x.mp,v.mp);
+ return x;
+}
+
+inline const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_rint_ceil(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal rint_floor(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_rint_floor(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal rint_round(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_rint_round(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal rint_trunc(const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_rint_trunc(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode)
+{
+ mpreal x(v);
+ mpfr_frac(x.mp,v.mp,rnd_mode);
+ return x;
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Miscellaneous Functions
+inline void swap(mpreal& a, mpreal& b)
+{
+ mpfr_swap(a.mp,b.mp);
+}
+
+#ifndef max
+inline const mpreal max(const mpreal& x, const mpreal& y)
+{
+ return (x>y?x:y);
+}
+#endif
+
+#ifndef min
+inline const mpreal min(const mpreal& x, const mpreal& y)
+{
+ return (x<y?x:y);
+}
+#endif
+
+inline const mpreal nexttoward (const mpreal& x, const mpreal& y)
+{
+ mpreal a(x);
+ mpfr_nexttoward(a.mp,y.mp);
+ return a;
+}
+
+inline const mpreal nextabove (const mpreal& x)
+{
+ mpreal a(x);
+ mpfr_nextabove(a.mp);
+ return a;
+}
+
+inline const mpreal nextbelow (const mpreal& x)
+{
+ mpreal a(x);
+ mpfr_nextbelow(a.mp);
+ return a;
+}
+
+inline const mpreal urandomb (gmp_randstate_t& state)
+{
+ mpreal x;
+ mpfr_urandomb(x.mp,state);
+ return x;
+}
+
+#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0))
+// use gmp_randinit_default() to init state, gmp_randclear() to clear
+inline const mpreal urandom (gmp_randstate_t& state,mp_rnd_t rnd_mode)
+{
+ mpreal x;
+ mpfr_urandom(x.mp,state,rnd_mode);
+ return x;
+}
+#endif
+
+#if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2))
+inline const mpreal random2 (mp_size_t size, mp_exp_t exp)
+{
+ mpreal x;
+ mpfr_random2(x.mp,size,exp);
+ return x;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+// Set/Get global properties
+inline void mpreal::set_default_prec(mp_prec_t prec)
+{
+ default_prec = prec;
+ mpfr_set_default_prec(prec);
+}
+
+inline mp_prec_t mpreal::get_default_prec()
+{
+ return mpfr_get_default_prec();
+}
+
+inline void mpreal::set_default_base(int base)
+{
+ default_base = base;
+}
+
+inline int mpreal::get_default_base()
+{
+ return default_base;
+}
+
+inline void mpreal::set_default_rnd(mp_rnd_t rnd_mode)
+{
+ default_rnd = rnd_mode;
+ mpfr_set_default_rounding_mode(rnd_mode);
+}
+
+inline mp_rnd_t mpreal::get_default_rnd()
+{
+ return mpfr_get_default_rounding_mode();
+}
+
+inline void mpreal::set_double_bits(int dbits)
+{
+ double_bits = dbits;
+}
+
+inline int mpreal::get_double_bits()
+{
+ return double_bits;
+}
+
+inline bool mpreal::fits_in_bits(double x, int n)
+{
+ int i;
+ double t;
+ return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0);
+}
+
+inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_pow(x.mp,x.mp,b.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_pow_z(x.mp,x.mp,b,rnd_mode);
+ return x;
+}
+
+inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_pow_ui(x.mp,x.mp,b,rnd_mode);
+ return x;
+}
+
+inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ return pow(a,static_cast<unsigned long int>(b),rnd_mode);
+}
+
+inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_pow_si(x.mp,x.mp,b,rnd_mode);
+ return x;
+}
+
+inline const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode)
+{
+ return pow(a,static_cast<long int>(b),rnd_mode);
+}
+
+inline const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode)
+{
+ return pow(a,mpreal(b),rnd_mode);
+}
+
+inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode)
+{
+ return pow(a,mpreal(b),rnd_mode);
+}
+
+inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_ui_pow(x.mp,a,b.mp,rnd_mode);
+ return x;
+}
+
+inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ return pow(static_cast<unsigned long int>(a),b,rnd_mode);
+}
+
+inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ if (a>=0) return pow(static_cast<unsigned long int>(a),b,rnd_mode);
+ else return pow(mpreal(a),b,rnd_mode);
+}
+
+inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ if (a>=0) return pow(static_cast<unsigned long int>(a),b,rnd_mode);
+ else return pow(mpreal(a),b,rnd_mode);
+}
+
+inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),b,rnd_mode);
+}
+
+inline const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),b,rnd_mode);
+}
+
+// pow unsigned long int
+inline const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ mpreal x(a);
+ mpfr_ui_pow_ui(x.mp,a,b,rnd_mode);
+ return x;
+}
+
+inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+}
+
+inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode)
+{
+ if(b>0) return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode)
+{
+ if(b>0) return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode)
+{
+ return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+inline const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode)
+{
+ return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+// pow unsigned int
+inline const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
+}
+
+inline const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+}
+
+inline const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode)
+{
+ if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+inline const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode)
+{
+ if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+inline const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode)
+{
+ return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+inline const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode)
+{
+ return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+}
+
+// pow long int
+inline const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
+ else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
+}
+
+inline const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
+}
+
+inline const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode)
+{
+ if (a>0)
+ {
+ if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ }else{
+ return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
+ }
+}
+
+inline const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode)
+{
+ if (a>0)
+ {
+ if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ }else{
+ return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
+ }
+}
+
+inline const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode)
+{
+ if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
+}
+
+inline const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode)
+{
+ if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
+}
+
+// pow int
+inline const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui
+ else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
+}
+
+inline const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
+}
+
+inline const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode)
+{
+ if (a>0)
+ {
+ if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ }else{
+ return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
+ }
+}
+
+inline const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode)
+{
+ if (a>0)
+ {
+ if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui
+ else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ }else{
+ return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
+ }
+}
+
+inline const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode)
+{
+ if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
+}
+
+inline const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode)
+{
+ if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow
+ else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow
+}
+
+// pow long double
+inline const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),mpreal(b),rnd_mode);
+}
+
+inline const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui
+}
+
+inline const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui
+}
+
+inline const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
+}
+
+inline const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
+}
+
+inline const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),mpreal(b),rnd_mode);
+}
+
+inline const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),b,rnd_mode); // mpfr_pow_ui
+}
+
+inline const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); // mpfr_pow_ui
+}
+
+inline const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si
+}
+
+inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode)
+{
+ return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si
+}
+}
+
+// Explicit specialization of std::swap for mpreal numbers
+// Thus standard algorithms will use efficient version of swap (due to Koenig lookup)
+// Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap
+namespace std
+{
+ template <>
+ inline void swap(mpfr::mpreal& x, mpfr::mpreal& y)
+ {
+ return mpfr::swap(x, y);
+ }
+}
+
+#endif /* __MP_REAL_H__ */
diff --git a/unsupported/test/mpreal_support.cpp b/unsupported/test/mpreal_support.cpp
new file mode 100644
index 000000000..32570f092
--- /dev/null
+++ b/unsupported/test/mpreal_support.cpp
@@ -0,0 +1,42 @@
+#include "main.h"
+#include <Eigen/MPRealSupport>
+
+using namespace mpfr;
+using namespace std;
+using namespace Eigen;
+
+void test_mpreal_support()
+{
+ // set precision to 256 bits (double has only 53 bits)
+ mpreal::set_default_prec(256);
+ typedef Matrix<mpreal,Eigen::Dynamic,Eigen::Dynamic> MatrixXmp;
+
+ std::cerr << "epsilon = " << NumTraits<mpreal>::epsilon() << "\n";
+ std::cerr << "dummy_precision = " << NumTraits<mpreal>::dummy_precision() << "\n";
+ std::cerr << "highest = " << NumTraits<mpreal>::highest() << "\n";
+ std::cerr << "lowest = " << NumTraits<mpreal>::lowest() << "\n";
+
+ for(int i = 0; i < g_repeat; i++) {
+ int s = ei_random<int>(1,100);
+ MatrixXmp A = MatrixXmp::Random(s,s);
+ MatrixXmp B = MatrixXmp::Random(s,s);
+ MatrixXmp S = A.adjoint() * A;
+ MatrixXmp X;
+
+ // Cholesky
+ X = S.selfadjointView<Lower>().llt().solve(B);
+ VERIFY_IS_APPROX((S.selfadjointView<Lower>()*X).eval(),B);
+
+ // partial LU
+ X = A.lu().solve(B);
+ VERIFY_IS_APPROX((A*X).eval(),B);
+
+ // symmetric eigenvalues
+ SelfAdjointEigenSolver<MatrixXmp> eig(S);
+ VERIFY_IS_EQUAL(eig.info(), Success);
+ VERIFY_IS_APPROX((S.selfadjointView<Lower>() * eig.eigenvectors()),
+ eig.eigenvectors() * eig.eigenvalues().asDiagonal());
+ }
+}
+
+#include "mpreal.cpp"
diff --git a/unsupported/test/openglsupport.cpp b/unsupported/test/openglsupport.cpp
new file mode 100644
index 000000000..83b476917
--- /dev/null
+++ b/unsupported/test/openglsupport.cpp
@@ -0,0 +1,61 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra.
+//
+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#include <iostream>
+#include <GL/glut.h>
+#include <Eigen/OpenGLSupport>
+using namespace Eigen;
+
+int main(int argc, char **argv)
+{
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+ glutInitWindowPosition (0,0);
+ glutInitWindowSize(10, 10);
+
+ if(glutCreateWindow("Eigen") <= 0)
+ {
+ std::cerr << "Unable to create GLUT Window.\n";
+ exit(1);
+ }
+
+ Vector3f v3f;
+ Matrix3f rot;
+ glBegin(GL_POINTS);
+
+ glVertex(v3f);
+ glVertex(2*v3f+v3f);
+ glVertex(rot*v3f);
+
+ glEnd();
+
+ Quaterniond qd;
+ glRotate(qd);
+
+ Matrix4f m44;
+ glLoadMatrix(m44);
+ glMultMatrix(m44);
+
+ return 0;
+}