在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;
答案 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;
}