C++ 如何以非平凡的步伐创建自定义的Eigen::Map类

C++ 如何以非平凡的步伐创建自定义的Eigen::Map类,c++,eigen,C++,Eigen,假设我有一个带有时间序列样本的Eigen::MatrixXf。每行对应一个时间步长,列是当时测量的不同属性 为了进一步处理,我想对该数据应用延时嵌入。这意味着,在时间t时的每个样本x\u t变成x'\u t=(x\u t,x\u(t-1),…,x\u(t-k+1))。因此,将使用先前样本的属性对样本进行扩充 我可以简单地复制矩阵k次,移动行并将它们堆叠在一起,但这会将数据大小增加k倍。我更希望有一个行为类似于这样一个矩阵的对象,但在内部计算原始矩阵中每个系数的索引,并访问相应的原始数据 我曾试图

假设我有一个带有时间序列样本的
Eigen::MatrixXf
。每行对应一个时间步长,列是当时测量的不同属性

为了进一步处理,我想对该数据应用延时嵌入。这意味着,在时间
t
时的每个样本
x\u t
变成
x'\u t=(x\u t,x\u(t-1),…,x\u(t-k+1))
。因此,将使用先前样本的属性对样本进行扩充

我可以简单地复制矩阵
k
次,移动行并将它们堆叠在一起,但这会将数据大小增加
k
倍。我更希望有一个行为类似于这样一个矩阵的对象,但在内部计算原始矩阵中每个系数的索引,并访问相应的原始数据

我曾试图修改
Eigen::MapBase
的代码来创建这样一个类,但它的行为不一致:

#ifndef TIMEDELAYEMBEDDINGMAP_H
#define TIMEDELAYEMBEDDINGMAP_H

#include <Eigen/Core>

#define EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived) \
      EIGEN_STATIC_ASSERT((int(internal::traits<Derived>::Flags) & LinearAccessBit) || Derived::IsVectorAtCompileTime, \
                          YOU_ARE_TRYING_TO_USE_AN_INDEX_BASED_ACCESSOR_ON_AN_EXPRESSION_THAT_DOES_NOT_SUPPORT_THAT)

namespace Eigen
{ 

/** \class TimeDelayEmbeddingMap
  *
  * \brief Wraps data and extends it with time-delay embedding
  */
template<typename Derived> class TimeDelayEmbeddingMap
  : public internal::dense_xpr_base<Derived>::type
{
  public:

    typedef typename internal::dense_xpr_base<Derived>::type Base;
    enum {
      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
      SizeAtCompileTime = Base::SizeAtCompileTime
    };

    typedef typename internal::traits<Derived>::StorageKind StorageKind;
    typedef typename internal::traits<Derived>::Index Index;
    typedef typename internal::traits<Derived>::Scalar Scalar;
    typedef typename internal::packet_traits<Scalar>::type PacketScalar;
    typedef typename NumTraits<Scalar>::Real RealScalar;
    typedef typename internal::conditional<
                         bool(internal::is_lvalue<Derived>::value),
                         Scalar *,
                         const Scalar *>::type
                     PointerType;

    using Base::derived;
//    using Base::RowsAtCompileTime;
//    using Base::ColsAtCompileTime;
//    using Base::SizeAtCompileTime;
    using Base::MaxRowsAtCompileTime;
    using Base::MaxColsAtCompileTime;
    using Base::MaxSizeAtCompileTime;
    using Base::IsVectorAtCompileTime;
    using Base::Flags;
    using Base::IsRowMajor;

    using Base::rows;
    using Base::cols;
    using Base::size;
    using Base::coeff;
    using Base::coeffRef;
    using Base::lazyAssign;
    using Base::eval;

    using Base::innerStride;
    using Base::outerStride;
    using Base::rowStride;
    using Base::colStride;

    using Base::operator=;

    typedef typename Base::CoeffReturnType CoeffReturnType;

    inline Index rows() const { return m_rows.value(); }
    inline Index cols() const { return m_cols.value() * m_k; }
    inline Index size() const { return rows() * cols(); }
    inline unsigned long k() const { return m_k; }

    inline const Scalar* data() const { return m_data; }

    inline const Scalar& coeff(Index rowId, Index colId) const
    {
        Index dt = colId / m_k;
        Index col = colId % m_k;
        Index row = (rowId >= dt) ? rowId - dt : dt - rowId;
        return m_data[col * colStride() + row * rowStride()];
    }

    inline const Scalar& coeffRef(Index rowId, Index colId) const
    {
        Index dt = colId / m_k;
        Index col = colId % m_k;
        Index row = (rowId >= dt) ? rowId - dt : dt - rowId;
        return this->m_data[col * colStride() + row * rowStride()];
    }

    template<int LoadMode>
    inline PacketScalar packet(Index rowId, Index colId) const
    {
        Index dt = colId / m_k;
        Index col = colId % m_k;
        Index row = (rowId >= dt) ? rowId - dt : dt - rowId;
        return internal::ploadt<PacketScalar, LoadMode>
                 (m_data + (col * colStride() + row * rowStride()));
    }

    inline TimeDelayEmbeddingMap(PointerType dataPtr, unsigned long k, Index nbRows, Index nbCols)
            : m_data(dataPtr), m_rows(nbRows), m_cols(nbCols), m_k(k)
    {
      eigen_assert( (dataPtr == 0)
              || (   nbRows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == nbRows)
                  && nbCols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == nbCols)));
      eigen_assert(k > 0);
      checkSanity();
    }

  protected:

    void checkSanity() const
    {
      EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags&PacketAccessBit,
                                        internal::inner_stride_at_compile_time<Derived>::ret==1),
                          PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
      eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)
                   && "input pointer is not aligned on a 16 byte boundary");
    }

    PointerType m_data;
    const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
    const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
    unsigned long m_k;
};

#undef EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS

} // end namespace Eigen

#endif // TIMEDELAYEMBEDDINGMAP_H

它正确地报告有9列,但只打印3列,就像原始矩阵一样。似乎我遗漏了什么,但我对
Eigen
的内部知识不够,无法找出问题所在。

发生的是
操作符发生的是
操作符你定义了
朋友操作符了吗
#include <iostream>
#include "TimeDelayEmbeddingMap.h"

int main()
{
    Eigen::MatrixXf m(10, 3);
    m.setRandom();
    std::cout << m << std::endl << std::endl;

    Eigen::TimeDelayEmbeddingMap<Eigen::MatrixXf> tdm(m.data(), 3, m.rows(), m.cols());
    std::cout << tdm.cols() << std::endl << std::endl << tdm << std::endl;

    return 0;
}
 -0.997497  -0.651784    0.97705
  0.127171   0.717887  -0.108615
 -0.613392   0.421003  -0.761834
  0.617481  0.0270699  -0.990661
  0.170019   -0.39201  -0.982177
-0.0402539  -0.970031   -0.24424
 -0.299417  -0.817194  0.0633259
  0.791925  -0.271096   0.142369
   0.64568  -0.705374   0.203528
   0.49321  -0.668203   0.214331

9

 -0.997497  -0.651784    0.97705
  0.127171   0.717887  -0.108615
 -0.613392   0.421003  -0.761834
  0.617481  0.0270699  -0.990661
  0.170019   -0.39201  -0.982177
-0.0402539  -0.970031   -0.24424
 -0.299417  -0.817194  0.0633259
  0.791925  -0.271096   0.142369
   0.64568  -0.705374   0.203528
   0.49321  -0.668203   0.214331