Rcpp запрещает преобразование при использовании any () в операторе if () - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь преобразовать свою функцию R в C ++, используя Rcpp, но я обнаружил ошибки, которые не совсем хорошо понимаю.

Следующий код дает мою функцию R, мою (неудачную) попытку перевести ее и несколько примеров использования в конце (тестирование, что две функции возвращают одно и то же ...)

Функция My R Code:

intersect_rectangles <- function(x_min, x_max, y_min, y_max) {
  rez <- list()
  rez$min <- pmax(x_min, y_min)
  rez$max <- pmin(x_max, y_max)

  if (any(rez$min > rez$max)) {
    return(list(NULL))
  }
  return(rez)
}

Моя попытка создать ту же функцию с помощью Rcpp .

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List Cpp_intersect_rectangles(NumericVector x_min,NumericVector  
x_max,NumericVector  y_min,NumericVector  y_max) {

  // Create a list :
  NumericVector min = pmax(x_min,y_min);
  NumericVector max = pmin(x_max,y_max);
  List L = List::create(R_NilValue);

  if (! any(min > max)) {
    L = List::create(Named("min") = min , _["max"] = max);
  }
  return(L);
}

Я получаю следующие сообщения об ошибках:

/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/include/Rcpp/sugar/logical/SingleLogicalResult.h:36:2: error: implicit instantiation of undefined template 'Rcpp::sugar::forbidden_conversion<false>'
        forbidden_conversion<x>{
        ^
/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/include/Rcpp/sugar/logical/SingleLogicalResult.h:74:40: note: in instantiation of template class 'Rcpp::sugar::conversion_to_bool_is_forbidden<false>' requested here
                conversion_to_bool_is_forbidden<!NA> x ;
                                                     ^
file637e53281965.cpp:13:9: note: in instantiation of member function 'Rcpp::sugar::SingleLogicalResult<true, Rcpp::sugar::Negate_SingleLogicalResult<true, Rcpp::sugar::Any<true, Rcpp::sugar::Comparator<14, Rcpp::sugar::greater<14>, true, Rcpp::Vector<14, PreserveStorage>, true, Rcpp::Vector<14, PreserveStorage> > > > >::operator bool' requested here
    if (! any(min > max))

Если функция Rcpp реализована правильно, то должно работать следующее:

u = rep(0,4)
v = rep(1,4)
w = rep(0.3,4)
x = c(0.8,0.8,3,3)
all.equal(intersect_rectangles(u,v,w,x), Cpp_intersect_rectangles(u,v,w,x))
all.equal(intersect_rectangles(u,v,w,w), Cpp_intersect_rectangles(u,v,w,w))

Не могли бы вы сказать, что не так с моим кодом cpp?

1 Ответ

0 голосов
/ 14 февраля 2019

Причина, по которой код не переводится правильно, связана с тем, как была создана реализация any() Rcpp sugar .В частности, у нас есть следующее:

Фактический тип возвращаемого значения any(X) является экземпляром класса шаблона SingleLogicalResult, но функции is_true и is_false могут использоваться для преобразованиявозвращаемое значение bool.

Per https://thecoatlessprofessor.com/programming/unofficial-rcpp-api-documentation/#any

Поэтому решение состоит в том, чтобы добавить .is_true() к вызову функции any(), например, !any(condition).is_true().

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
List Cpp_intersect_rectangles(NumericVector x_min, NumericVector x_max,
                              NumericVector y_min, NumericVector y_max) {

    // Create a list :
    NumericVector min = pmax(x_min, y_min);
    NumericVector max = pmin(x_max, y_max);
    List L = List::create(R_NilValue);


    if (! any(min > max).is_true()) {
                      // ^^^^^^^^^ Added
        L = List::create(Named("min") = min , _["max"] = max);
    }
    return(L);
}

Затем при тестировании получаем:

u = rep(0,4)
v = rep(1,4)
w = rep(0.3,4)
x = c(0.8,0.8,3,3)
all.equal(intersect_rectangles(u,v,w,x), Cpp_intersect_rectangles(u,v,w,x))
# [1] TRUE
all.equal(intersect_rectangles(u,v,w,w), Cpp_intersect_rectangles(u,v,w,w))
# [1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...