2015-02-22 4 views
1

Я новичок в кодировании Rcpp и C++ в целом, поэтому простите меня за задание основных вопросов. Каст часть кодаRcpp Скопируйте векторный код в вектор

// test.cpp 

#include <Rcpp.h> 
using namespace Rcpp; 

// [[Rcpp::export]] 
void testRun() { 
    IntegerVector Grp1 = IntegerVector::create(1,2,3,4); 
    IntegerVector Grp2 = IntegerVector::create(3,4,5,6); 

    Rf_PrintValue(Grp1); 
    Grp1 = Grp2; 
    Rf_PrintValue(Grp1); 
    Grp2[3] = Grp2[3]+1; 
    Rf_PrintValue(Grp1); 
} 

и когда я бегу testrun(), я получаю выход

> Rcpp::sourceCpp('test.cpp') 
> testRun() 
[1] 1 2 3 4 
[1] 3 4 5 6 
[1] 3 4 5 7 

Когда я задаю Gr2 к Gr1 в Gr1 = Gr2, меняя элементы Gr2 после изменения назначения значения в Gr1. Есть ли функция IntegerVectors, которая может делать что-то вроде Gr1 = copy of Gr2, или я должен использовать цикл для этого.

Большое спасибо!

+2

вы имели в виду 'Rcpp :: клон()', как в этом ответе http://stackoverflow.com/a/ 21282929/143305, а также другие? –

ответ

0

В настоящее время происходит очень распространенная ошибка с указателями. Grp1 и Grp2 являются указателями, поэтому установка одного, равного другому, означает, что они указывают на один и тот же массив (и любые изменения в одном массиве будут влиять на другой). Одним из решений было бы использовать итератор для копирования всех значений по одному за раз. Это будет сделано, опуская один IntegerVector, выбирая все значения, а затем выталкивая все элементы из другого IntegerVector в освобожденный IntegerVector.

+1

popping и pushing приведут к резкому повышению производительности для типов Rcpp, поскольку это означает, что много распределений данных и т. Д. –

3

Как указывалось в комментарии, вы могли бы использовать

Grp1 = clone(Grp2) ; 

, но это создаст новый объект R, который затем получить назначенную Grp1, так что вы платите за некоторое выделение памяти и выбросить часть памяти, которая может иметь были использованы, то есть больше работы для сборщика мусора по линии.

Вы также можете просто повторно использовать существующую память из Grp1 с std::copy

std::copy(Grp2.begin(), Grp2.end(), Grp1.begin()) ; 

Другим способом, который, возможно, над верхней частью является использование sapply. Что-то вроде этого:

auto identity = [](double x){ return x; } ; 
Grp1 = sapply(Grp2, identity); 

Но данный Rcpp не sapply over lambdas, вы, вероятно, придется определить identity вне вашей функции для этого подхода, чтобы быть пригодной к использованию.

inline double identity(double x){ 
    return x ; 
} 

FWIW, в Rcpp14 или Rcpp11, вы можете просто сделать:

Grp1 = import(Grp2) ; 
Смежные вопросы