mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-05-01 16:24:28 +08:00
miserable half-working state, commiting to a fork just in case, just to perfect
my day, my hard disk would die. Will write a more detailed commit message once it's working.
This commit is contained in:
parent
39d9f0275b
commit
b73e22905d
25
Eigen/Core
25
Eigen/Core
@ -2,7 +2,7 @@
|
|||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||||
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// Eigen is free software; you can redistribute it and/or
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -188,6 +188,7 @@ struct Dense {};
|
|||||||
#include "src/Core/Dot.h"
|
#include "src/Core/Dot.h"
|
||||||
#include "src/Core/StableNorm.h"
|
#include "src/Core/StableNorm.h"
|
||||||
#include "src/Core/MapBase.h"
|
#include "src/Core/MapBase.h"
|
||||||
|
#include "src/Core/Stride.h"
|
||||||
#include "src/Core/Map.h"
|
#include "src/Core/Map.h"
|
||||||
#include "src/Core/Block.h"
|
#include "src/Core/Block.h"
|
||||||
#include "src/Core/VectorBlock.h"
|
#include "src/Core/VectorBlock.h"
|
||||||
@ -222,28 +223,6 @@ struct Dense {};
|
|||||||
#include "src/Core/products/TriangularSolverMatrix.h"
|
#include "src/Core/products/TriangularSolverMatrix.h"
|
||||||
#include "src/Core/BandMatrix.h"
|
#include "src/Core/BandMatrix.h"
|
||||||
|
|
||||||
/** \defgroup Array_Module Array module
|
|
||||||
* \ingroup Core_Module
|
|
||||||
* This module provides several handy features to manipulate matrices as simple array of values.
|
|
||||||
* In addition to listed classes, it defines various methods of the Cwise interface
|
|
||||||
* (accessible from MatrixBase::cwise()), including:
|
|
||||||
* - matrix-scalar sum,
|
|
||||||
* - coeff-wise comparison operators,
|
|
||||||
* - sin, cos, sqrt, pow, exp, log, square, cube, inverse (reciprocal).
|
|
||||||
*
|
|
||||||
* This module also provides various MatrixBase methods, including:
|
|
||||||
* - boolean reductions: \ref MatrixBase::all() "all", \ref MatrixBase::any() "any", \ref MatrixBase::count() "count",
|
|
||||||
* - \ref MatrixBase::Random() "random matrix initialization",
|
|
||||||
* - a \ref MatrixBase::select() "select" function mimicking the trivariate ?: operator,
|
|
||||||
* - \ref MatrixBase::colwise() "column-wise" and \ref MatrixBase::rowwise() "row-wise" reductions,
|
|
||||||
* - \ref MatrixBase::reverse() "matrix reverse",
|
|
||||||
* - \ref MatrixBase::lpNorm() "generic matrix norm".
|
|
||||||
*
|
|
||||||
* \code
|
|
||||||
* #include <Eigen/Core>
|
|
||||||
* \endcode
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "src/Array/Functors.h"
|
#include "src/Array/Functors.h"
|
||||||
#include "src/Array/BooleanRedux.h"
|
#include "src/Array/BooleanRedux.h"
|
||||||
#include "src/Array/Select.h"
|
#include "src/Array/Select.h"
|
||||||
|
@ -37,19 +37,20 @@ struct ei_assign_traits
|
|||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
DstIsAligned = Derived::Flags & AlignedBit,
|
DstIsAligned = Derived::Flags & AlignedBit,
|
||||||
|
DstHasDirectAccess = Derived::Flags & DirectAccessBit,
|
||||||
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
SrcIsAligned = OtherDerived::Flags & AlignedBit,
|
||||||
SrcAlignment = DstIsAligned && SrcIsAligned ? Aligned : Unaligned
|
JointAlignment = DstIsAligned && SrcIsAligned ? Aligned : Unaligned
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum {
|
enum {
|
||||||
InnerSize = int(Derived::Flags)&RowMajorBit
|
InnerSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::SizeAtCompileTime)
|
||||||
? Derived::ColsAtCompileTime
|
: int(Derived::Flags)&RowMajorBit ? int(Derived::ColsAtCompileTime)
|
||||||
: Derived::RowsAtCompileTime,
|
: int(Derived::RowsAtCompileTime),
|
||||||
InnerMaxSize = int(Derived::Flags)&RowMajorBit
|
InnerMaxSize = int(Derived::IsVectorAtCompileTime) ? int(Derived::MaxSizeAtCompileTime)
|
||||||
? Derived::MaxColsAtCompileTime
|
: int(Derived::Flags)&RowMajorBit ? int(Derived::MaxColsAtCompileTime)
|
||||||
: Derived::MaxRowsAtCompileTime,
|
: int(Derived::MaxRowsAtCompileTime),
|
||||||
MaxSizeAtCompileTime = ei_size_at_compile_time<Derived::MaxColsAtCompileTime,Derived::MaxRowsAtCompileTime>::ret,
|
MaxSizeAtCompileTime = Derived::SizeAtCompileTime,
|
||||||
PacketSize = ei_packet_traits<typename Derived::Scalar>::size
|
PacketSize = ei_packet_traits<typename Derived::Scalar>::size
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,11 +61,11 @@ private:
|
|||||||
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0
|
||||||
&& int(DstIsAligned) && int(SrcIsAligned),
|
&& int(DstIsAligned) && int(SrcIsAligned),
|
||||||
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit),
|
||||||
MayLinearVectorize = MightVectorize && MayLinearize
|
MayLinearVectorize = MightVectorize && MayLinearize && DstHasDirectAccess
|
||||||
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
&& (DstIsAligned || MaxSizeAtCompileTime == Dynamic),
|
||||||
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
/* If the destination isn't aligned, we have to do runtime checks and we don't unroll,
|
||||||
so it's only good for large enough sizes. */
|
so it's only good for large enough sizes. */
|
||||||
MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize
|
MaySliceVectorize = MightVectorize && DstHasDirectAccess && int(InnerMaxSize)>=3*PacketSize
|
||||||
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
/* slice vectorization can be slow, so we only want it if the slices are big, which is
|
||||||
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block
|
||||||
in a fixed-size matrix */
|
in a fixed-size matrix */
|
||||||
@ -108,12 +109,13 @@ public:
|
|||||||
{
|
{
|
||||||
EIGEN_DEBUG_VAR(DstIsAligned)
|
EIGEN_DEBUG_VAR(DstIsAligned)
|
||||||
EIGEN_DEBUG_VAR(SrcIsAligned)
|
EIGEN_DEBUG_VAR(SrcIsAligned)
|
||||||
EIGEN_DEBUG_VAR(SrcAlignment)
|
EIGEN_DEBUG_VAR(JointAlignment)
|
||||||
EIGEN_DEBUG_VAR(InnerSize)
|
EIGEN_DEBUG_VAR(InnerSize)
|
||||||
EIGEN_DEBUG_VAR(InnerMaxSize)
|
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||||
EIGEN_DEBUG_VAR(PacketSize)
|
EIGEN_DEBUG_VAR(PacketSize)
|
||||||
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
EIGEN_DEBUG_VAR(StorageOrdersAgree)
|
||||||
EIGEN_DEBUG_VAR(MightVectorize)
|
EIGEN_DEBUG_VAR(MightVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MayLinearize)
|
||||||
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||||
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||||
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
@ -211,12 +213,12 @@ struct ei_assign_innervec_CompleteUnrolling
|
|||||||
col = int(Derived1::Flags)&RowMajorBit
|
col = int(Derived1::Flags)&RowMajorBit
|
||||||
? Index % int(Derived1::ColsAtCompileTime)
|
? Index % int(Derived1::ColsAtCompileTime)
|
||||||
: Index / Derived1::RowsAtCompileTime,
|
: Index / Derived1::RowsAtCompileTime,
|
||||||
SrcAlignment = ei_assign_traits<Derived1,Derived2>::SrcAlignment
|
JointAlignment = ei_assign_traits<Derived1,Derived2>::JointAlignment
|
||||||
};
|
};
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src)
|
||||||
{
|
{
|
||||||
dst.template copyPacket<Derived2, Aligned, SrcAlignment>(row, col, src);
|
dst.template copyPacket<Derived2, Aligned, JointAlignment>(row, col, src);
|
||||||
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2,
|
ei_assign_innervec_CompleteUnrolling<Derived1, Derived2,
|
||||||
Index+ei_packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
|
Index+ei_packet_traits<typename Derived1::Scalar>::size, Stop>::run(dst, src);
|
||||||
}
|
}
|
||||||
@ -264,6 +266,18 @@ template<typename Derived1, typename Derived2>
|
|||||||
struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
|
struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
|
||||||
{
|
{
|
||||||
inline static void run(Derived1 &dst, const Derived2 &src)
|
inline static void run(Derived1 &dst, const Derived2 &src)
|
||||||
|
{
|
||||||
|
if(Derived1::ColsAtCompileTime == 1)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < dst.rows(); ++i)
|
||||||
|
dst.copyCoeff(i, 0, src);
|
||||||
|
}
|
||||||
|
else if(Derived1::RowsAtCompileTime == 1)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < dst.cols(); ++i)
|
||||||
|
dst.copyCoeff(0, i, src);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
const int innerSize = dst.innerSize();
|
const int innerSize = dst.innerSize();
|
||||||
const int outerSize = dst.outerSize();
|
const int outerSize = dst.outerSize();
|
||||||
@ -276,6 +290,7 @@ struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling>
|
|||||||
dst.copyCoeff(i, j, src);
|
dst.copyCoeff(i, j, src);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Derived1, typename Derived2>
|
template<typename Derived1, typename Derived2>
|
||||||
@ -418,7 +433,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling
|
|||||||
|
|
||||||
for(int index = alignedStart; index < alignedEnd; index += packetSize)
|
for(int index = alignedStart; index < alignedEnd; index += packetSize)
|
||||||
{
|
{
|
||||||
dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);
|
dst.template copyPacket<Derived2, Aligned, ei_assign_traits<Derived1,Derived2>::JointAlignment>(index, src);
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
|
ei_unaligned_assign_impl<>::run(src,dst,alignedEnd,size);
|
||||||
@ -452,7 +467,7 @@ struct ei_assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling>
|
|||||||
const int packetAlignedMask = packetSize - 1;
|
const int packetAlignedMask = packetSize - 1;
|
||||||
const int innerSize = dst.innerSize();
|
const int innerSize = dst.innerSize();
|
||||||
const int outerSize = dst.outerSize();
|
const int outerSize = dst.outerSize();
|
||||||
const int alignedStep = (packetSize - dst.stride() % packetSize) & packetAlignedMask;
|
const int alignedStep = (packetSize - dst.outerStride() % packetSize) & packetAlignedMask;
|
||||||
int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
|
int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
|
||||||
: ei_first_aligned(&dst.coeffRef(0,0), innerSize);
|
: ei_first_aligned(&dst.coeffRef(0,0), innerSize);
|
||||||
|
|
||||||
@ -504,6 +519,14 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
|||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
|
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
if(Derived::ColsAtCompileTime == 1)
|
||||||
|
{
|
||||||
|
ei_assert(OtherDerived::RowsAtCompileTime == 1 || other.cols() == 1);
|
||||||
|
}
|
||||||
|
if(Derived::RowsAtCompileTime == 1)
|
||||||
|
{
|
||||||
|
ei_assert(OtherDerived::ColsAtCompileTime == 1 || other.rows() == 1);
|
||||||
|
}
|
||||||
#ifdef EIGEN_DEBUG_ASSIGN
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
ei_assign_traits<Derived, OtherDerived>::debug();
|
ei_assign_traits<Derived, OtherDerived>::debug();
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,6 +80,20 @@ struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename MatrixType, int BlockRows, int BlockCols>
|
||||||
|
struct ei_traits<Block<MatrixType, BlockRows, BlockCols, true> > : ei_traits<Block<MatrixType, BlockRows, BlockCols, false> >
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
InnerStrideAtCompileTime =
|
||||||
|
(BlockRows==1 && !(int(MatrixType::Flags)&RowMajorBit))
|
||||||
|
|| (BlockCols==1 && (int(MatrixType::Flags)&RowMajorBit))
|
||||||
|
? MatrixType::OuterStrideAtCompileTime
|
||||||
|
: MatrixType::InnerStrideAtCompileTime,
|
||||||
|
OuterStrideAtCompileTime =
|
||||||
|
(BlockRows==1||BlockCols==1) ? 0 : MatrixType::OuterStrideAtCompileTime
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessStatus> class Block
|
template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessStatus> class Block
|
||||||
: public MatrixType::template MakeBase< Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >::Type
|
: public MatrixType::template MakeBase< Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >::Type
|
||||||
{
|
{
|
||||||
@ -196,8 +210,8 @@ template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessSta
|
|||||||
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
#ifdef EIGEN_PARSED_BY_DOXYGEN
|
||||||
/** \sa MapBase::data() */
|
/** \sa MapBase::data() */
|
||||||
inline const Scalar* data() const;
|
inline const Scalar* data() const;
|
||||||
/** \sa MapBase::stride() */
|
inline int innerStride() const;
|
||||||
inline int stride() const;
|
inline int outerStride() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -260,17 +274,24 @@ class Block<MatrixType,BlockRows,BlockCols,HasDirectAccess>
|
|||||||
&& startCol >= 0 && blockCols >= 0 && startCol + blockCols <= matrix.cols());
|
&& startCol >= 0 && blockCols >= 0 && startCol + blockCols <= matrix.cols());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \sa MapBase::stride() */
|
/** \sa MapBase::innerStride() */
|
||||||
inline int stride() const
|
inline int innerStride() const
|
||||||
{
|
{
|
||||||
return ((!Base::IsVectorAtCompileTime)
|
return (RowsAtCompileTime==1 && !(int(MatrixType::Flags)&RowMajorBit))
|
||||||
|| (BlockRows==1 && ((Flags&RowMajorBit)==0))
|
|| (ColsAtCompileTime==1 && (int(MatrixType::Flags)&RowMajorBit))
|
||||||
|| (BlockCols==1 && ((Flags&RowMajorBit)==RowMajorBit)))
|
? m_matrix.outerStride()
|
||||||
? m_matrix.stride() : 1;
|
: m_matrix.innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \sa MapBase::outerStride() */
|
||||||
|
inline int outerStride() const
|
||||||
|
{
|
||||||
|
return IsVectorAtCompileTime ? 0 : m_matrix.outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __SUNPRO_CC
|
#ifndef __SUNPRO_CC
|
||||||
// FIXME sunstudio is not friendly with the above friend...
|
// FIXME sunstudio is not friendly with the above friend...
|
||||||
|
// META-FIXME there is no 'friend' keyword around here. Is this obsolete?
|
||||||
protected:
|
protected:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -158,31 +158,60 @@ template<typename Derived> class DenseBase
|
|||||||
* In other words, this function returns
|
* In other words, this function returns
|
||||||
* \code rows()==1 || cols()==1 \endcode
|
* \code rows()==1 || cols()==1 \endcode
|
||||||
* \sa rows(), cols(), IsVectorAtCompileTime. */
|
* \sa rows(), cols(), IsVectorAtCompileTime. */
|
||||||
inline bool isVector() const { return rows()==1 || cols()==1; }
|
|
||||||
/** \returns the size of the storage major dimension,
|
|
||||||
* i.e., the number of columns for a columns major matrix, and the number of rows otherwise */
|
|
||||||
int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); }
|
|
||||||
/** \returns the size of the inner dimension according to the storage order,
|
|
||||||
* i.e., the number of rows for a columns major matrix, and the number of cols otherwise */
|
|
||||||
int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); }
|
|
||||||
|
|
||||||
/** Only plain matrices, not expressions may be resized; therefore the only useful resize method is
|
/** \returns the outer size.
|
||||||
* Matrix::resize(). The present method only asserts that the new size equals the old size, and does
|
*
|
||||||
|
* \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
|
||||||
|
* with respect to the storage order, i.e., the number of columns for a column-major matrix,
|
||||||
|
* and the number of rows for a row-major matrix. */
|
||||||
|
int outerSize() const
|
||||||
|
{
|
||||||
|
return IsVectorAtCompileTime ? 1
|
||||||
|
: (int(Flags)&RowMajorBit) ? this->rows() : this->cols();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the inner size.
|
||||||
|
*
|
||||||
|
* \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
|
||||||
|
* with respect to the storage order, i.e., the number of rows for a column-major matrix,
|
||||||
|
* and the number of columns for a row-major matrix. */
|
||||||
|
int innerSize() const
|
||||||
|
{
|
||||||
|
return IsVectorAtCompileTime ? this->size()
|
||||||
|
: (int(Flags)&RowMajorBit) ? this->cols() : this->rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
|
||||||
|
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
|
||||||
* nothing else.
|
* nothing else.
|
||||||
*/
|
*/
|
||||||
void resize(int size)
|
void resize(int size)
|
||||||
{
|
{
|
||||||
ei_assert(size == this->size()
|
ei_assert(size == this->size()
|
||||||
&& "MatrixBase::resize() does not actually allow to resize.");
|
&& "DenseBase::resize() does not actually allow to resize.");
|
||||||
}
|
}
|
||||||
/** Only plain matrices, not expressions may be resized; therefore the only useful resize method is
|
/** Only plain matrices/arrays, not expressions, may be resized; therefore the only useful resize methods are
|
||||||
* Matrix::resize(). The present method only asserts that the new size equals the old size, and does
|
* Matrix::resize() and Array::resize(). The present method only asserts that the new size equals the old size, and does
|
||||||
* nothing else.
|
* nothing else.
|
||||||
*/
|
*/
|
||||||
void resize(int rows, int cols)
|
void resize(int rows, int cols)
|
||||||
{
|
{
|
||||||
ei_assert(rows == this->rows() && cols == this->cols()
|
ei_assert(rows == this->rows() && cols == this->cols()
|
||||||
&& "MatrixBase::resize() does not actually allow to resize.");
|
&& "DenseBase::resize() does not actually allow to resize.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int innerStride() const
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT(int(Flags)&DirectAccessBit,
|
||||||
|
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)
|
||||||
|
return derived().innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
int outerStride() const
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT(int(Flags)&DirectAccessBit,
|
||||||
|
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)
|
||||||
|
return derived().outerStride();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||||
@ -407,13 +436,6 @@ template<typename Derived> class DenseBase
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
void swap(DenseBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other);
|
void swap(DenseBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other);
|
||||||
|
|
||||||
/** \returns number of elements to skip to pass from one row (resp. column) to another
|
|
||||||
* for a row-major (resp. column-major) matrix.
|
|
||||||
* Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data
|
|
||||||
* of the underlying matrix.
|
|
||||||
*/
|
|
||||||
inline int stride() const { return derived().stride(); }
|
|
||||||
|
|
||||||
inline const NestByValue<Derived> nestByValue() const;
|
inline const NestByValue<Derived> nestByValue() const;
|
||||||
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
inline const ForceAlignedAccess<Derived> forceAlignedAccess() const;
|
||||||
inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
inline ForceAlignedAccess<Derived> forceAlignedAccess();
|
||||||
|
@ -253,13 +253,13 @@ class DenseStorageBase : public _Base<Derived>
|
|||||||
{
|
{
|
||||||
if(RowsAtCompileTime == 1)
|
if(RowsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
ei_assert(other.isVector());
|
ei_assert(other.rows() == 1);
|
||||||
resize(1, other.size());
|
resize(1, other.cols());
|
||||||
}
|
}
|
||||||
else if(ColsAtCompileTime == 1)
|
else if(ColsAtCompileTime == 1)
|
||||||
{
|
{
|
||||||
ei_assert(other.isVector());
|
ei_assert(other.cols() == 1);
|
||||||
resize(other.size(), 1);
|
resize(other.rows(), 1);
|
||||||
}
|
}
|
||||||
else resize(other.rows(), other.cols());
|
else resize(other.rows(), other.cols());
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||||
//
|
//
|
||||||
// Eigen is free software; you can redistribute it and/or
|
// Eigen is free software; you can redistribute it and/or
|
||||||
@ -48,32 +48,59 @@
|
|||||||
*
|
*
|
||||||
* \sa Matrix::Map()
|
* \sa Matrix::Map()
|
||||||
*/
|
*/
|
||||||
template<typename MatrixType, int Options>
|
template<typename MatrixType, int Options, typename StrideType>
|
||||||
struct ei_traits<Map<MatrixType, Options> > : public ei_traits<MatrixType>
|
struct ei_traits<Map<MatrixType, Options, StrideType> >
|
||||||
|
: public ei_traits<MatrixType>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
Flags = (Options&Aligned)==Aligned ? ei_traits<MatrixType>::Flags | AlignedBit
|
Flags0 = ei_traits<MatrixType>::Flags,
|
||||||
: ei_traits<MatrixType>::Flags & ~AlignedBit
|
Flags1 = ((Options&Aligned)==Aligned ? Flags0 | AlignedBit
|
||||||
|
: Flags0 & ~AlignedBit),
|
||||||
|
Flags = int(StrideType::InnerStrideAtCompileTime)==1 ? Flags1 : (Flags1 & ~PacketAccessBit),
|
||||||
|
InnerStrideAtCompileTime = int(StrideType::InnerStrideAtCompileTime) != 0 ? int(StrideType::InnerStrideAtCompileTime) : 1,
|
||||||
|
OuterStrideAtCompileTime =
|
||||||
|
int(StrideType::OuterStrideAtCompileTime != 0) ? int(StrideType::OuterStrideAtCompileTime)
|
||||||
|
: int(MatrixType::IsVectorAtCompileTime) ? int(MatrixType::SizeAtCompileTime)
|
||||||
|
: int(Flags)&RowMajorBit ? int(MatrixType::ColsAtCompileTime)
|
||||||
|
: int(MatrixType::RowsAtCompileTime)
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename MatrixType, int Options> class Map
|
template<typename MatrixType, int Options, typename StrideType> class Map
|
||||||
: public MapBase<Map<MatrixType, Options>,
|
: public MapBase<Map<MatrixType, Options, StrideType>,
|
||||||
typename MatrixType::template MakeBase< Map<MatrixType, Options> >::Type>
|
typename MatrixType::template MakeBase<
|
||||||
|
Map<MatrixType, Options, StrideType>
|
||||||
|
>::Type>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef MapBase<Map,typename MatrixType::template MakeBase<Map>::Type> Base;
|
typedef MapBase<Map,typename MatrixType::template MakeBase<Map>::Type> Base;
|
||||||
|
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Map)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Map)
|
||||||
|
|
||||||
inline int stride() const { return this->innerSize(); }
|
inline int innerStride() const
|
||||||
|
{
|
||||||
|
return StrideType::InnerStrideAtCompileTime != 0 ? m_stride.inner() : 1;
|
||||||
|
}
|
||||||
|
|
||||||
inline Map(const Scalar* data) : Base(data) {}
|
inline int outerStride() const
|
||||||
|
{
|
||||||
|
return StrideType::OuterStrideAtCompileTime != 0 ? m_stride.outer()
|
||||||
|
: IsVectorAtCompileTime ? this->size()
|
||||||
|
: int(Flags)&RowMajorBit ? this->cols()
|
||||||
|
: this->rows();
|
||||||
|
}
|
||||||
|
|
||||||
inline Map(const Scalar* data, int size) : Base(data, size) {}
|
inline Map(const Scalar* data, const StrideType& stride = StrideType())
|
||||||
|
: Base(data), m_stride(stride) {}
|
||||||
|
|
||||||
inline Map(const Scalar* data, int rows, int cols) : Base(data, rows, cols) {}
|
inline Map(const Scalar* data, int size, const StrideType& stride = StrideType())
|
||||||
|
: Base(data, size), m_stride(stride) {}
|
||||||
|
|
||||||
|
inline Map(const Scalar* data, int rows, int cols, const StrideType& stride = StrideType())
|
||||||
|
: Base(data, rows, cols), m_stride(stride) {}
|
||||||
|
|
||||||
|
/*
|
||||||
inline void resize(int rows, int cols)
|
inline void resize(int rows, int cols)
|
||||||
{
|
{
|
||||||
EIGEN_ONLY_USED_FOR_DEBUG(rows);
|
EIGEN_ONLY_USED_FOR_DEBUG(rows);
|
||||||
@ -88,8 +115,12 @@ template<typename MatrixType, int Options> class Map
|
|||||||
EIGEN_ONLY_USED_FOR_DEBUG(size);
|
EIGEN_ONLY_USED_FOR_DEBUG(size);
|
||||||
ei_assert(size == this->size());
|
ei_assert(size == this->size());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
|
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map)
|
||||||
|
|
||||||
|
protected:
|
||||||
|
StrideType m_stride;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
|
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||||
//
|
//
|
||||||
// Eigen is free software; you can redistribute it and/or
|
// Eigen is free software; you can redistribute it and/or
|
||||||
@ -37,12 +37,12 @@ template<typename Derived, typename Base> class MapBase
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// typedef MatrixBase<Derived> Base;
|
|
||||||
enum {
|
enum {
|
||||||
IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0,
|
IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0,
|
||||||
RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
|
RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime,
|
||||||
ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
|
ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime,
|
||||||
SizeAtCompileTime = Base::SizeAtCompileTime
|
SizeAtCompileTime = Base::SizeAtCompileTime,
|
||||||
|
InnerStrideAtCompileTime = ei_traits<Derived>::InnerStrideAtCompileTime
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef typename ei_traits<Derived>::Scalar Scalar;
|
typedef typename ei_traits<Derived>::Scalar Scalar;
|
||||||
@ -52,90 +52,104 @@ template<typename Derived, typename Base> class MapBase
|
|||||||
inline int rows() const { return m_rows.value(); }
|
inline int rows() const { return m_rows.value(); }
|
||||||
inline int cols() const { return m_cols.value(); }
|
inline int cols() const { return m_cols.value(); }
|
||||||
|
|
||||||
/** Returns the leading dimension (for matrices) or the increment (for vectors) to be used with data().
|
/** \returns the pointer increment between two consecutive elements.
|
||||||
*
|
*
|
||||||
* More precisely:
|
* \note For vectors, the storage order is ignored. For matrices (non-vectors), we're looking
|
||||||
* - for a column major matrix it returns the number of elements between two successive columns
|
* at the increment between two consecutive elements within a slice in the inner direction.
|
||||||
* - for a row major matrix it returns the number of elements between two successive rows
|
|
||||||
* - for a vector it returns the number of elements between two successive coefficients
|
|
||||||
* This function has to be used together with the MapBase::data() function.
|
|
||||||
*
|
*
|
||||||
* \sa MapBase::data() */
|
* \sa outerStride(), data(), rowStride(), colStride()
|
||||||
inline int stride() const { return derived().stride(); }
|
*/
|
||||||
|
inline int innerStride() const { return derived().innerStride(); }
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
|
||||||
|
* in a column-major matrix).
|
||||||
|
*
|
||||||
|
* \note For vectors, the storage order is ignored, there is only one inner slice, and so this method returns 1.
|
||||||
|
* For matrices (non-vectors), the notion of inner slice depends on the storage order.
|
||||||
|
*
|
||||||
|
* \sa innerStride(), data(), rowStride(), colStride()
|
||||||
|
*/
|
||||||
|
inline int outerStride() const { return derived().outerStride(); }
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive rows.
|
||||||
|
*
|
||||||
|
* \sa data(), innerStride(), outerStride(), colStride()
|
||||||
|
*/
|
||||||
|
inline int rowStride() const
|
||||||
|
{
|
||||||
|
return (RowsAtCompileTime==1 || IsRowMajor) ? outerStride() : innerStride();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** \returns the pointer increment between two consecutive columns.
|
||||||
|
*
|
||||||
|
* \sa data(), innerStride(), outerStride(), rowStride()
|
||||||
|
*/
|
||||||
|
inline int colStride() const
|
||||||
|
{
|
||||||
|
return (RowsAtCompileTime==1 || IsRowMajor) ? innerStride() : outerStride();
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns a pointer to the first coefficient of the matrix or vector.
|
/** Returns a pointer to the first coefficient of the matrix or vector.
|
||||||
* This function has to be used together with the stride() function.
|
|
||||||
*
|
*
|
||||||
* \sa MapBase::stride() */
|
* \note When addressing this data, make sure to honor the strides returned by innerStride() and outerStride().
|
||||||
|
*
|
||||||
|
* \sa innerStride(), outerStride()
|
||||||
|
*/
|
||||||
inline const Scalar* data() const { return m_data; }
|
inline const Scalar* data() const { return m_data; }
|
||||||
|
|
||||||
inline const Scalar& coeff(int row, int col) const
|
inline const Scalar& coeff(int row, int col) const
|
||||||
{
|
{
|
||||||
if(IsRowMajor)
|
return m_data[col * colStride() + row * rowStride()];
|
||||||
return m_data[col + row * stride()];
|
|
||||||
else // column-major
|
|
||||||
return m_data[row + col * stride()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Scalar& coeffRef(int row, int col)
|
inline Scalar& coeffRef(int row, int col)
|
||||||
{
|
{
|
||||||
if(IsRowMajor)
|
return const_cast<Scalar*>(m_data)[col * colStride() + row * rowStride()];
|
||||||
return const_cast<Scalar*>(m_data)[col + row * stride()];
|
|
||||||
else // column-major
|
|
||||||
return const_cast<Scalar*>(m_data)[row + col * stride()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Scalar& coeff(int index) const
|
inline const Scalar& coeff(int index) const
|
||||||
{
|
{
|
||||||
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
|
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
|
||||||
if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
|
return m_data[index * innerStride()];
|
||||||
return m_data[index];
|
|
||||||
else
|
|
||||||
return m_data[index*stride()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Scalar& coeffRef(int index)
|
inline Scalar& coeffRef(int index)
|
||||||
{
|
{
|
||||||
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
|
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
|
||||||
if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
|
return const_cast<Scalar*>(m_data)[index * innerStride()];
|
||||||
return const_cast<Scalar*>(m_data)[index];
|
|
||||||
else
|
|
||||||
return const_cast<Scalar*>(m_data)[index*stride()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
inline PacketScalar packet(int row, int col) const
|
inline PacketScalar packet(int row, int col) const
|
||||||
{
|
{
|
||||||
return ei_ploadt<Scalar, LoadMode>
|
return ei_ploadt<Scalar, LoadMode>
|
||||||
(m_data + (IsRowMajor ? col + row * stride()
|
(m_data + (col * colStride() + row * rowStride()));
|
||||||
: row + col * stride()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int LoadMode>
|
template<int LoadMode>
|
||||||
inline PacketScalar packet(int index) const
|
inline PacketScalar packet(int index) const
|
||||||
{
|
{
|
||||||
return ei_ploadt<Scalar, LoadMode>(m_data + index);
|
return ei_ploadt<Scalar, LoadMode>(m_data + index * innerStride());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode>
|
template<int StoreMode>
|
||||||
inline void writePacket(int row, int col, const PacketScalar& x)
|
inline void writePacket(int row, int col, const PacketScalar& x)
|
||||||
{
|
{
|
||||||
ei_pstoret<Scalar, PacketScalar, StoreMode>
|
ei_pstoret<Scalar, PacketScalar, StoreMode>
|
||||||
(const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride()
|
(const_cast<Scalar*>(m_data) + (col * colStride() + row * rowStride()), x);
|
||||||
: row + col * stride()), x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int StoreMode>
|
template<int StoreMode>
|
||||||
inline void writePacket(int index, const PacketScalar& x)
|
inline void writePacket(int index, const PacketScalar& x)
|
||||||
{
|
{
|
||||||
ei_pstoret<Scalar, PacketScalar, StoreMode>
|
ei_pstoret<Scalar, PacketScalar, StoreMode>
|
||||||
(const_cast<Scalar*>(m_data) + index, x);
|
(const_cast<Scalar*>(m_data) + index * innerStride(), x);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
inline MapBase(const Scalar* data) : m_data(data), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime)
|
||||||
{
|
{
|
||||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||||
checkDataAlignment();
|
checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MapBase(const Scalar* data, int size)
|
inline MapBase(const Scalar* data, int size)
|
||||||
@ -146,7 +160,7 @@ template<typename Derived, typename Base> class MapBase
|
|||||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||||
ei_assert(size >= 0);
|
ei_assert(size >= 0);
|
||||||
ei_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
|
ei_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
|
||||||
checkDataAlignment();
|
checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MapBase(const Scalar* data, int rows, int cols)
|
inline MapBase(const Scalar* data, int rows, int cols)
|
||||||
@ -155,7 +169,7 @@ template<typename Derived, typename Base> class MapBase
|
|||||||
ei_assert( (data == 0)
|
ei_assert( (data == 0)
|
||||||
|| ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
|| ( rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
|
||||||
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
|
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
|
||||||
checkDataAlignment();
|
checkSanity();
|
||||||
}
|
}
|
||||||
|
|
||||||
Derived& operator=(const MapBase& other)
|
Derived& operator=(const MapBase& other)
|
||||||
@ -167,10 +181,12 @@ template<typename Derived, typename Base> class MapBase
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void checkDataAlignment() const
|
void checkSanity() const
|
||||||
{
|
{
|
||||||
ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit))
|
ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit))
|
||||||
|| ((size_t(m_data)&0xf)==0)) && "data is not aligned");
|
|| ((size_t(m_data)&0xf)==0)) && "data is not aligned");
|
||||||
|
ei_assert( ((!(ei_traits<Derived>::Flags&PacketAccessBit))
|
||||||
|
|| (innerStride()==1)) && "packet access incompatible with inner stride greater than 1");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Scalar* EIGEN_RESTRICT m_data;
|
const Scalar* EIGEN_RESTRICT m_data;
|
||||||
|
@ -120,7 +120,10 @@ struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
|||||||
MaxRowsAtCompileTime = _MaxRows,
|
MaxRowsAtCompileTime = _MaxRows,
|
||||||
MaxColsAtCompileTime = _MaxCols,
|
MaxColsAtCompileTime = _MaxCols,
|
||||||
Flags = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
Flags = ei_compute_matrix_flags<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::ret,
|
||||||
CoeffReadCost = NumTraits<Scalar>::ReadCost
|
CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
||||||
|
InnerStrideAtCompileTime = 1,
|
||||||
|
OuterStrideAtCompileTime = (RowsAtCompileTime==1||ColsAtCompileTime==1) ? 1
|
||||||
|
: (int(Flags)&RowMajorBit) ? RowsAtCompileTime : ColsAtCompileTime
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -318,6 +321,9 @@ class Matrix
|
|||||||
void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
|
void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other)
|
||||||
{ this->_swap(other.derived()); }
|
{ this->_swap(other.derived()); }
|
||||||
|
|
||||||
|
inline int innerStride() const { return 1; }
|
||||||
|
inline int outerStride() const { return this->innerSize(); }
|
||||||
|
|
||||||
/////////// Geometry module ///////////
|
/////////// Geometry module ///////////
|
||||||
|
|
||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
|
@ -336,7 +336,7 @@ template<> struct ei_gemv_selector<OnTheRight,ColMajor,true>
|
|||||||
ei_cache_friendly_product_colmajor_times_vector
|
ei_cache_friendly_product_colmajor_times_vector
|
||||||
<LhsBlasTraits::NeedToConjugate,RhsBlasTraits::NeedToConjugate>(
|
<LhsBlasTraits::NeedToConjugate,RhsBlasTraits::NeedToConjugate>(
|
||||||
dest.size(),
|
dest.size(),
|
||||||
&actualLhs.const_cast_derived().coeffRef(0,0), actualLhs.stride(),
|
&actualLhs.const_cast_derived().coeffRef(0,0), ei_outer_stride_or_outer_size(actualLhs),
|
||||||
actualRhs, actualDest, actualAlpha);
|
actualRhs, actualDest, actualAlpha);
|
||||||
|
|
||||||
if (!EvalToDest)
|
if (!EvalToDest)
|
||||||
@ -381,7 +381,7 @@ template<> struct ei_gemv_selector<OnTheRight,RowMajor,true>
|
|||||||
|
|
||||||
ei_cache_friendly_product_rowmajor_times_vector
|
ei_cache_friendly_product_rowmajor_times_vector
|
||||||
<LhsBlasTraits::NeedToConjugate,RhsBlasTraits::NeedToConjugate>(
|
<LhsBlasTraits::NeedToConjugate,RhsBlasTraits::NeedToConjugate>(
|
||||||
&actualLhs.const_cast_derived().coeffRef(0,0), actualLhs.stride(),
|
&actualLhs.const_cast_derived().coeffRef(0,0), ei_outer_stride_or_outer_size(actualLhs),
|
||||||
rhs_data, prod.rhs().size(), dest, actualAlpha);
|
rhs_data, prod.rhs().size(), dest, actualAlpha);
|
||||||
|
|
||||||
if (!DirectlyUseRhs) ei_aligned_stack_delete(Scalar, rhs_data, prod.rhs().size());
|
if (!DirectlyUseRhs) ei_aligned_stack_delete(Scalar, rhs_data, prod.rhs().size());
|
||||||
|
@ -34,14 +34,9 @@ struct ei_traits<ReturnByValue<Derived> >
|
|||||||
: public ei_traits<typename ei_traits<Derived>::ReturnMatrixType>
|
: public ei_traits<typename ei_traits<Derived>::ReturnMatrixType>
|
||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
// FIXME had to remove the DirectAccessBit for usage like
|
// We're disabling the DirectAccess because e.g. the constructor of
|
||||||
// matrix.inverse().block(...)
|
// the Block-with-DirectAccess expression requires to have a coeffRef method.
|
||||||
// because the Block ctor with direct access
|
// Also, we don't want to have to implement the stride stuff.
|
||||||
// wants to call coeffRef() to get an address, and that fails (infinite recursion) as ReturnByValue
|
|
||||||
// doesnt implement coeffRef().
|
|
||||||
// The fact that I had to do that shows that when doing xpr.block() with a non-direct-access xpr,
|
|
||||||
// even if xpr has the EvalBeforeNestingBit, the block() doesn't use direct access on the evaluated
|
|
||||||
// xpr.
|
|
||||||
Flags = (ei_traits<typename ei_traits<Derived>::ReturnMatrixType>::Flags
|
Flags = (ei_traits<typename ei_traits<Derived>::ReturnMatrixType>::Flags
|
||||||
| EvalBeforeNestingBit) & ~DirectAccessBit
|
| EvalBeforeNestingBit) & ~DirectAccessBit
|
||||||
};
|
};
|
||||||
|
@ -80,6 +80,9 @@ template<typename MatrixType> class Transpose
|
|||||||
typename ei_cleantype<typename MatrixType::Nested>::type&
|
typename ei_cleantype<typename MatrixType::Nested>::type&
|
||||||
nestedExpression() { return m_matrix.const_cast_derived(); }
|
nestedExpression() { return m_matrix.const_cast_derived(); }
|
||||||
|
|
||||||
|
enum { InnerStrideAtCompileTime = ei_inner_stride_at_compile_time<MatrixType>::ret,
|
||||||
|
OuterStrideAtCompileTime = ei_outer_stride_at_compile_time<MatrixType>::ret };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const typename MatrixType::Nested m_matrix;
|
const typename MatrixType::Nested m_matrix;
|
||||||
};
|
};
|
||||||
@ -93,7 +96,8 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
|||||||
typedef typename MatrixType::template MakeBase<Transpose<MatrixType> >::Type Base;
|
typedef typename MatrixType::template MakeBase<Transpose<MatrixType> >::Type Base;
|
||||||
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
||||||
|
|
||||||
inline int stride() const { return derived().nestedExpression().stride(); }
|
inline int innerStride() const { return derived().nestedExpression().innerStride(); }
|
||||||
|
inline int outerStride() const { return derived().nestedExpression().outerStride(); }
|
||||||
inline Scalar* data() { return derived().nestedExpression().data(); }
|
inline Scalar* data() { return derived().nestedExpression().data(); }
|
||||||
inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||||
|
|
||||||
|
@ -147,6 +147,7 @@ class GeneralProduct<Lhs, Rhs, GemmProduct>
|
|||||||
|
|
||||||
const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs);
|
const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs);
|
||||||
const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs);
|
const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs);
|
||||||
|
ei_assert(ei_inner_stride_at_compile_time<ActualLhsType>::ret == 1);
|
||||||
|
|
||||||
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs)
|
Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs)
|
||||||
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
* RhsBlasTraits::extractScalarFactor(m_rhs);
|
||||||
@ -158,9 +159,9 @@ class GeneralProduct<Lhs, Rhs, GemmProduct>
|
|||||||
(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor>
|
(Dest::Flags&RowMajorBit) ? RowMajor : ColMajor>
|
||||||
::run(
|
::run(
|
||||||
this->rows(), this->cols(), lhs.cols(),
|
this->rows(), this->cols(), lhs.cols(),
|
||||||
(const Scalar*)&(lhs.const_cast_derived().coeffRef(0,0)), lhs.stride(),
|
(const Scalar*)&(lhs.const_cast_derived().coeffRef(0,0)), ei_outer_stride_or_outer_size(lhs),
|
||||||
(const Scalar*)&(rhs.const_cast_derived().coeffRef(0,0)), rhs.stride(),
|
(const Scalar*)&(rhs.const_cast_derived().coeffRef(0,0)), ei_outer_stride_or_outer_size(rhs),
|
||||||
(Scalar*)&(dst.coeffRef(0,0)), dst.stride(),
|
(Scalar*)&(dst.coeffRef(0,0)), ei_outer_stride_or_outer_size(dst),
|
||||||
actualAlpha);
|
actualAlpha);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
// This file is part of Eigen, a lightweight C++ template library
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
|
// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>
|
||||||
//
|
//
|
||||||
// Eigen is free software; you can redistribute it and/or
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -60,7 +61,9 @@ template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime=SizeA
|
|||||||
template<typename MatrixType, typename DiagonalType, int ProductOrder> class DiagonalProduct;
|
template<typename MatrixType, typename DiagonalType, int ProductOrder> class DiagonalProduct;
|
||||||
template<typename MatrixType, int Index> class Diagonal;
|
template<typename MatrixType, int Index> class Diagonal;
|
||||||
|
|
||||||
template<typename MatrixType, int Options=Unaligned> class Map;
|
template<int InnerStrideAtCompileTime = Dynamic, int OuterStrideAtCompileTime = Dynamic> class Stride;
|
||||||
|
template<typename MatrixType, int Options=Unaligned, typename StrideType = Stride<0,0> > class Map;
|
||||||
|
|
||||||
template<typename Derived> class TriangularBase;
|
template<typename Derived> class TriangularBase;
|
||||||
template<typename MatrixType, unsigned int Mode> class TriangularView;
|
template<typename MatrixType, unsigned int Mode> class TriangularView;
|
||||||
template<typename MatrixType, unsigned int Mode> class SelfAdjointView;
|
template<typename MatrixType, unsigned int Mode> class SelfAdjointView;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// for linear algebra.
|
// for linear algebra.
|
||||||
//
|
//
|
||||||
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
|
||||||
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
//
|
//
|
||||||
// Eigen is free software; you can redistribute it and/or
|
// Eigen is free software; you can redistribute it and/or
|
||||||
// modify it under the terms of the GNU Lesser General Public
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
@ -46,7 +46,7 @@
|
|||||||
// if native static_assert is enabled, let's use it
|
// if native static_assert is enabled, let's use it
|
||||||
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
#define EIGEN_STATIC_ASSERT(X,MSG) static_assert(X,#MSG);
|
||||||
|
|
||||||
#else // CXX0X
|
#else // not CXX0X
|
||||||
|
|
||||||
template<bool condition>
|
template<bool condition>
|
||||||
struct ei_static_assert {};
|
struct ei_static_assert {};
|
||||||
@ -81,7 +81,8 @@
|
|||||||
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
|
BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER,
|
||||||
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX,
|
THIS_METHOD_IS_ONLY_FOR_DIAGONAL_MATRIX,
|
||||||
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE,
|
THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE,
|
||||||
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES
|
THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES,
|
||||||
|
YOU_ALREADY_SPECIFIED_THIS_STRIDE
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ template<int Value> class ei_int_if_dynamic
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic)
|
EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic)
|
||||||
explicit ei_int_if_dynamic(int) {}
|
explicit ei_int_if_dynamic(int v) { EIGEN_ONLY_USED_FOR_DEBUG(v); ei_assert(v == Value); }
|
||||||
static int value() { return Value; }
|
static int value() { return Value; }
|
||||||
void setValue(int) {}
|
void setValue(int) {}
|
||||||
};
|
};
|
||||||
@ -58,7 +58,7 @@ template<int Value> class ei_int_if_dynamic
|
|||||||
template<> class ei_int_if_dynamic<Dynamic>
|
template<> class ei_int_if_dynamic<Dynamic>
|
||||||
{
|
{
|
||||||
int m_value;
|
int m_value;
|
||||||
ei_int_if_dynamic() {}
|
ei_int_if_dynamic() { ei_assert(false); }
|
||||||
public:
|
public:
|
||||||
explicit ei_int_if_dynamic(int value) : m_value(value) {}
|
explicit ei_int_if_dynamic(int value) : m_value(value) {}
|
||||||
int value() const { return m_value; }
|
int value() const { return m_value; }
|
||||||
|
@ -93,6 +93,7 @@ template<typename MatrixType> void submatrices(const MatrixType& m)
|
|||||||
|
|
||||||
//check block()
|
//check block()
|
||||||
Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
|
Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);
|
||||||
|
|
||||||
RowVectorType br1(m1.block(r1,0,1,cols));
|
RowVectorType br1(m1.block(r1,0,1,cols));
|
||||||
VectorType bc1(m1.block(0,c1,rows,1));
|
VectorType bc1(m1.block(0,c1,rows,1));
|
||||||
VERIFY_IS_APPROX(b1, m1.block(r1,c1,1,1));
|
VERIFY_IS_APPROX(b1, m1.block(r1,c1,1,1));
|
||||||
@ -176,18 +177,30 @@ void compare_using_data_and_stride(const MatrixType& m)
|
|||||||
int rows = m.rows();
|
int rows = m.rows();
|
||||||
int cols = m.cols();
|
int cols = m.cols();
|
||||||
int size = m.size();
|
int size = m.size();
|
||||||
int stride = m.stride();
|
int innerStride = m.innerStride();
|
||||||
|
int outerStride = m.outerStride();
|
||||||
|
int rowStride = m.rowStride();
|
||||||
|
int colStride = m.colStride();
|
||||||
const typename MatrixType::Scalar* data = m.data();
|
const typename MatrixType::Scalar* data = m.data();
|
||||||
|
|
||||||
for(int j=0;j<cols;++j)
|
for(int j=0;j<cols;++j)
|
||||||
for(int i=0;i<rows;++i)
|
for(int i=0;i<rows;++i)
|
||||||
VERIFY_IS_APPROX(m.coeff(i,j), data[(MatrixType::Flags&RowMajorBit) ? i*stride+j : j*stride + i]);
|
VERIFY_IS_APPROX(m.coeff(i,j), data[i*rowStride + j*colStride]);
|
||||||
|
|
||||||
|
if(!MatrixType::IsVectorAtCompileTime)
|
||||||
|
{
|
||||||
|
for(int j=0;j<cols;++j)
|
||||||
|
for(int i=0;i<rows;++i)
|
||||||
|
VERIFY_IS_APPROX(m.coeff(i,j), data[(MatrixType::Flags&RowMajorBit)
|
||||||
|
? i*outerStride + j*innerStride
|
||||||
|
: j*outerStride + i*innerStride]);
|
||||||
|
}
|
||||||
|
|
||||||
if(MatrixType::IsVectorAtCompileTime)
|
if(MatrixType::IsVectorAtCompileTime)
|
||||||
{
|
{
|
||||||
VERIFY_IS_APPROX(stride, int((&m.coeff(1))-(&m.coeff(0))));
|
VERIFY_IS_APPROX(innerStride, int((&m.coeff(1))-(&m.coeff(0))));
|
||||||
for (int i=0;i<size;++i)
|
for (int i=0;i<size;++i)
|
||||||
VERIFY_IS_APPROX(m.coeff(i), data[i*stride]);
|
VERIFY_IS_APPROX(m.coeff(i), data[i*innerStride]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,11 +217,11 @@ void data_and_stride(const MatrixType& m)
|
|||||||
|
|
||||||
MatrixType m1 = MatrixType::Random(rows, cols);
|
MatrixType m1 = MatrixType::Random(rows, cols);
|
||||||
compare_using_data_and_stride(m1.block(r1, c1, r2-r1+1, c2-c1+1));
|
compare_using_data_and_stride(m1.block(r1, c1, r2-r1+1, c2-c1+1));
|
||||||
compare_using_data_and_stride(m1.transpose().block(c1, r1, c2-c1+1, r2-r1+1));
|
//compare_using_data_and_stride(m1.transpose().block(c1, r1, c2-c1+1, r2-r1+1));
|
||||||
compare_using_data_and_stride(m1.row(r1));
|
compare_using_data_and_stride(m1.row(r1));
|
||||||
compare_using_data_and_stride(m1.col(c1));
|
compare_using_data_and_stride(m1.col(c1));
|
||||||
compare_using_data_and_stride(m1.row(r1).transpose());
|
//compare_using_data_and_stride(m1.row(r1).transpose());
|
||||||
compare_using_data_and_stride(m1.col(c1).transpose());
|
//compare_using_data_and_stride(m1.col(c1).transpose());
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_submatrices()
|
void test_submatrices()
|
||||||
@ -223,7 +236,9 @@ void test_submatrices()
|
|||||||
|
|
||||||
CALL_SUBTEST_8( submatrices(Matrix<float,Dynamic,4>(3, 4)) );
|
CALL_SUBTEST_8( submatrices(Matrix<float,Dynamic,4>(3, 4)) );
|
||||||
|
|
||||||
|
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
|
||||||
CALL_SUBTEST_6( data_and_stride(MatrixXf(ei_random(5,50), ei_random(5,50))) );
|
CALL_SUBTEST_6( data_and_stride(MatrixXf(ei_random(5,50), ei_random(5,50))) );
|
||||||
CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(ei_random(5,50), ei_random(5,50))) );
|
CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(ei_random(5,50), ei_random(5,50))) );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user