Eigen C ++包装赋值

时间:2015-05-07 15:14:03

标签: c++ eigen

在Matlab中,可以执行以下操作:

% init
a =  1:10;
b = 18:23;

% wrapping assignment
a([8:end 1:3]) = b;

这样的事可能与Eigen有关吗?我希望为循环缓冲类创建一个成员函数,返回一些对Eigen类型的引用,可能是这样的:

VectorXd b(5);
b << 1,2,3,4,5 ;
CircularBuf a( 6 /*capacity*/ );
a.push(1);a.push(2);a.push(3);
// 3 elements in buf
a.pop();a.pop();
// 1 element in buf
// next line probably wraps around internal buffer, depending on impl
a.pushRef( b.size() /*number of elements in ref*/ ) = b;

2 个答案:

答案 0 :(得分:2)

我不确定这是不是你要找的......在我从Jerry Coffin得到答案之后,我想出了这个:

dat2<-reactive({  fichero<-input$fichero

#Si el fichero que leemos no tiene nada devolvemos un Nulo

if (is.null(fichero))
  {return()}

# Leemos el fichero


salida<-read.csv(fichero$salidaapath, header=input$header, sep=input$sep,quote=input$quote,stringsAsFactors=input$stringAsFactors)
   if (input$miss==TRUE) {salida<-salida[complete.cases(salida),]}
   return(salida)

   if (input$fecha==TRUE) {
     if (is.numeric(input$columnscf))
     {
   origen<-sort(salida[,input$columnscf])[1]
   salida[,input$columnscf]<-as.salidae(salida[,input$columnscf,drop=FALSE],format="%d/%m/%Y",origin=origen)
 }
 else {origen<-sort(salida[,input$columnscf])[1] 
 salida[,input$columnscf]<-as.salidae(salida[,input$columnscf,drop=FALSE],format="%d/%m/%Y")}
 return(salida)


  }

     else {return(salida)}
   })



output$choose_columnscf <- renderUI({
    # If missing input, return to avoid error later in function
    if(is.null(input$fichero)|| is.null(input$columns))
    {return()} 
    dat<-data()
    dat<-dat[, input$columns, drop = FALSE]
    dat<-as.data.frame(dat)
    dat<-dat[,varlist(dat,type=c("factor","numeric"))]
    dat<-as.data.frame(dat)
    colnames <- names(dat)

    # Create the checkboxes and select them all by default
    selectInput("columnscf", "Elija la variable categórica", 
                choices  = colnames)
  })

然后你的第一个例子可以写成:

#include <iostream> 
#include <vector>
#include <iterator>
template <class T>
class CircularVector {
    typedef std::vector<T> DVector;
public:
    CircularVector(const DVector& v) : v(v){}
    T at(int i){return v.at(i);}
    int size(){return v.size();}
    class iterator : 
      public std::iterator < std::random_access_iterator_tag, T > {
        CircularVector *vec;
        int index;
    public:
        iterator(CircularVector &d, int index) : vec(&d), index(index) {}
        iterator &operator++() { nextIndex(); return *this; }
        iterator operator++(int) { 
            iterator tmp(*vec, index); nextIndex(); return tmp; 
        }
        iterator operator+(int off) { 
            return iterator(*vec, (index + off)%vec->size()); 
        }
        iterator operator-(int off) { 
            return iterator(*vec, (index - off + vec->size())%vec->size()); 
        }
        T& operator*() { return (*vec).v[index];   }
        bool operator!=(iterator const &other) { return index != other.index; }
        //bool operator<(iterator const &other) { return index < other.index; }
    private:
        void nextIndex(){
            ++index;
            if (index==vec->size()){index=0;}
        }
    };
    iterator begin() { return iterator(*this, 0); }
    //iterator end() { return iterator(*this, size()); }
private:
    DVector v;
};

实际上,我只是好奇尝试它,我相信有更好的方法来实现它。检查索引是否必须在每次增加时都被包装,这不是最有效的方法。显然int main() { std::vector<int> a; std::vector<int> b; for(int i=1;i<11;i++){a.push_back(i);} for(int i=18;i<24;i++){b.push_back(i);} CircularVector<int> ca(a); std::copy(b.begin(),b.end(),ca.begin()+7); // copy elements starting // at index 8 for (int i=0;i<ca.size();i++){std::cout << ca.at(i) << std::endl;} } <对于循环缓冲区并没有多大意义,我决定不实现它们(例如end()将是一个无限循环。但是,不需要将它们用作输入/输出迭代器。

答案 1 :(得分:0)

我有另一个解决方案,如我对this question的回答中所述。答案中公布的代码定义了循环移位的自定义表达式,因此您可以从Eigen的优化中受益。

鉴于上述答案中的circ_shift.h,您可以执行以下操作来实现目标:我希望这有助于......

// main.cpp
#include "stdafx.h"
#include "Eigen/Core"
#include <iostream>
#include "circ_shift.h" // posted in the answer to the other quesiton.

using namespace Eigen;


int main()
{
    VectorXi a(10), b(6);

    a << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
    b << 18, 19, 20, 21, 22, 23;

    std::cout << "a = " << a.transpose() << std::endl << "b = " << b.transpose() << std::endl; 
    circShift(a, 3, 0).block(0, 0, b.size(), 1) = b;
    std::cout << "now: a = " << a.transpose() << std::endl; // prints 21, 22, 23, 4, 5, 6, 7, 18, 19, 20


    return 0;
}