эффективный пример из модифицированного объекта arma :: vec - PullRequest
0 голосов
/ 27 июня 2018

Я использую Rcpp для ускорения кода R. Тем не менее, я действительно борюсь с типами - поскольку они чужды в R. Вот упрощенная версия того, что я пытаюсь сделать:

#include <RcppArmadillo.h>
#include <algorithm>
//[[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
using namespace arma;

// [[Rcpp::export]]
NumericVector fun(SEXP Pk, int k, int i, const vec& a, const mat& D) {
  // this is dummy version of my actual function - with actual arguments.;
  // I'm guessing SEXP is going to need to be replaced with something else when it's called from C++ not R.;
  return D.col(i);
}

// [[Rcpp::export]]
NumericVector f(const arma::vec& assignment, char k, int B, const mat& D) {
    uvec k_ind = find(assignment == k);
    NumericVector output(assignment.size());  // for dummy output.

    uvec::iterator k_itr = k_ind.begin();

    for(; k_itr != k_ind.end(); ++k_itr) {
        // this is R code, as I don't know the best way to do this in C++;
        k_rep = sample(c(assignment[assignment != k], -1), size = B, replace = TRUE);

        output = fun(k_rep, k, *k_itr, assignment, D);
        // do something with output;
    }

    // compile result, ultimately return a List (after I figure out how to do that.  For right now, I'll cheat and return the last output);
    return output;
}

Часть, с которой я борюсь, - это случайная выборка assignment. Я знаю, что sample был реализован в Rarmadillo. Однако я вижу два подхода к этому, и я не уверен, какой из них более эффективен / выполним.

Подход 1:

  • Составить таблицу значений assignment. Замените assignment == k на -1 и установите его "count" равным 1.
  • выборка из таблицы «Имена» с вероятностью, пропорциональной счету.

Подход 2:

  • Скопируйте соответствующее подмножество вектора assignment в новый вектор с дополнительной точкой для -1.
  • Выборка из скопированного вектора с равными вероятностями.

Я хочу сказать, что подход 1 был бы более эффективным, за исключением того, что assignment в настоящее время имеет тип arma::vec, и я не уверен, как составить таблицу из этого - или сколько там стоит чтобы преобразовать его в более совместимый формат. Я думаю, что мог бы реализовать Подход 2, но я надеюсь избежать дорогостоящей копии.

Спасибо за любые идеи, которые вы можете предоставить.

1 Ответ

0 голосов
/ 28 июня 2018

объявление многих переменных не согласуется с присваиваемым вами присваиванием, например, присваивание = k невозможно сравнить, поскольку присваивание имеет реальное значение, а k - символ. поскольку квест написан плохо, я могу сменить тип переменных. этот компилятор ..

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

// [[Rcpp::export]]
arma::vec fun(const Rcpp::NumericVector& Pk, int k, unsigned int i, const arma::ivec& a, const arma::mat& D)
{
  return D.col(i);
}

// [[Rcpp::export]]
Rcpp::NumericMatrix f(const arma::ivec& assignment, int k, unsigned int B, const arma::mat& D) 
{
  arma::uvec k_ind = find(assignment == k);
  arma::ivec KK = assignment(find(assignment != k));
  //these 2 row are for KK = c(assignment[assignment != k], -1)  
  //I dont know what is this -1 is for, why -1 ? maybe you dont need it.
     KK.insert_rows(KK.n_rows, 1);
     KK(KK.n_rows - 1) = -1;

  arma::uvec k_ind_not = find(assignment != k);
  Rcpp::NumericVector k_rep(B);
  arma::mat output(D.n_rows,k_ind.n_rows);  // for dummy output.

  for(unsigned int i =0; i < k_ind.n_rows ; i++) 
  {
    k_rep = Rcpp::RcppArmadillo::sample(KK, B, true);

    output(arma::span::all, i) = fun(k_rep, k, i, assignment, D);
    // do something with output;
  }

  // compile result, ultimately return a List (after I figure out how to do that.  For right now, I'll cheat and return the last output);
  return Rcpp::wrap(output);
}

это не оптимизировано (так как вопрос фальшивый), это плохо написано, потому что я думаю, что R будет достаточно быстрым при поиске индекса вектора (так что делайте это в R и реализуйте только весело в Rcpp) .. .бесполезно тратить время здесь, есть другие проблемы, которые требуют решателя, реализованного в Rcpp, а не этот поиск ... но это бесполезный вопрос, поскольку вы запрашиваете больше алгоритма, чем, например, сигнатуру функции

...