Векторизованный log1p () в RcppArmadillo - PullRequest
0 голосов
/ 07 ноября 2018

Как правильно применить log1p() ко всему arma::vec? Кажется, что есть векторизованные версии log() и exp(), но не log1p(). Я обнаружил, что есть синтаксический сахар для NumericVector, поэтому я в итоге конвертирую arma::vec в NumericVector, применяя log1p(), а затем конвертируя обратно:

#include <RcppArmadillo.h>

using namespace Rcpp;

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::vec test_log1p( arma::vec v )
{
  // arma::vec res = log1p(v);         // results in a compilation error
  NumericVector v1 = log1p( wrap(v) );
  arma::vec res = as<arma::vec>(v1);
  return res;
}

Есть ли более элегантный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Используйте возможности .transform () или .for_each () , доступные для векторов и матриц Армадилло. Пример:

v.transform( [](double val) { return log1p(val); } );

или

v.for_each( [](double& val) { val = log1p(val); } );  // note the & character

Возможно, вам придется использовать префикс std: std::log1p() вместо log1p().

0 голосов
/ 07 ноября 2018

Дьявол, опять же, в деталях.

Для начала, у RcppArmadillo нет 'Sugar', поэтому ваши рассуждения ошибочны - вы не можете просто посмотреть на функции Rcpp Sugar, которые работают на Rcpp::NumericVector.

Опять же, можно конвертировать, как вы. Но вы выбрали дорогую конверсию. Посмотрите на продвинутые конструкторы, явно использующие память - копии не нужны.

Гораздо более простым и более прямым (но локальным) подходом было бы просто добавить небольшую локальную встроенную функцию. Вот что я бы сделал :) Сделано за несколько минут.

Наконец, у нас есть несколько одноуровневых проектов, которые обобщают Rcpp Sugar над всем, что может потребовать итераторов. Это «высокая дорога», и это может сделать с некоторым новым развитием. Может быть, начать в этом репо .

...