Обновить переменную в цикле - PullRequest
1 голос
/ 27 января 2020

Я пытаюсь обновить переменную в al oop, но получаю ошибку

stati c Утверждение не удалось: невозможно преобразовать тип в SEXP

Я пытаюсь воспроизвести следующий код R в R cpp:

> v = rep(1, 5)
> for(k in 0:3){
+   v = cumsum(v)
+ }
> print(v)
[1]  1  5 15 35 70

Я предпринял следующие попытки (раскомментирование / комментирование соответствующих фрагментов кода), но все они дают ту же ошибку. Как я могу это сделать и что я делаю не так, пожалуйста?

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector fun() {

  IntegerVector v = rep(1, 5);

  // Attempt 1. 
  for(int k = 0; k < 4; ++k){
    v = cumsum(v);
  }

  // Attempt 2.
  // IntegerVector tempv;
  // for(int k = 0; k < 4; ++k){
  //   tempv = cumsum(v);
  //   v = tempv;
  // }

  // can reproduce error more simply with the following: 
  // so issue is assigning back to variable or change of class?
  // v = cumsum(v);

  // Attempt 3.
  // IntegerVector tempv;
  // for(int k = 0; k < 4; ++k){
  //   tempv = cumsum(v);
  //   v = as<IntegerVector>(tempv);
  // }  

  return v;
}

РЕДАКТИРОВАТЬ:

Хорошо, у меня что-то работает (спасибо это )

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
IntegerVector fun() {

  IntegerVector v = rep(1, 5);
     for(int k = 0; k < 4; ++k){
        std::partial_sum(v.begin(), v.end(), v.begin());
     }
   return v;
}

Итак, я полагаю, что мой вопрос в том, что я делал неправильно раньше? Спасибо

1 Ответ

2 голосов
/ 27 января 2020

Как я уже намекнул в своем предыдущем комментарии, это должно сработать. Как это не так, вы нашли ошибку.

Стоит ли ее исправлять, это другой способ. Всякий раз, когда я вычисляю на или с векторами, я обычно берусь за RcppArmadillo. Итак, вот минимальная (рабочая) версия вашей первой попытки в RcppArmadillo.

Код

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::ivec fun() {
  arma::ivec v(5, arma::fill::ones);

  for (int k=0; k<3; k++) {
    v = arma::cumsum(v);
  }

  return(v);
}

/*** R
fun()
*/

Выход

R> sourceCpp("~/git/stackoverflow/59936632/answer.cpp")

R> fun()
     [,1]
[1,]    1
[2,]    4
[3,]   10
[4,]   20
[5,]   35
R> 

Редактировать

Сделал одно маленькое исправление и заменил более раннюю C ++ 11 curly-init на вызов ones для репликации rep(1,5).

...