Два вектора равны в RcppArmadillo? - PullRequest
0 голосов
/ 14 мая 2018

В моей функции я хочу сравнить строки в матрице, используя ==, но это не работает.

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
double accept(arma::mat x){
  int b=x.n_rows;
  arma::vec B(b-1);B.zeros();
  for(int i=0;i<b-1;i++){
    arma::rowvec a1;arma::rowvec a2;
    if(x.row(i)==x.row(i+1)){
      B[i]=0;
    }else{
      B[i]=1;
    }
  }
  double bb;bb=sum(B)/(b-1);
  return(bb);
}

Сообщение об ошибке:

c: / Rtools / mingw_64 / bin / g ++ -std = gnu ++ 11 -I "C: /Users/songxl/DOCUME~1/R/R-35~1.0RC/include" -DNDEBUG -I. ./inst/include -fopenmp -I "C: /Users/songxl/Documents/R/R-3.5.0rc/library/Rcpp/include" -I "C: /Users/songxl/Documents/R/R-3.5 .0rc / library / RcppArmadillo / включает "-I" E: / adptive / block "-O2 -Wall -mtune = универсальный -c acp.cpp -o acp.o acp.cpp: в функции 'double accept (arma :: mat)': acp.cpp: 10: 16: ошибка: не удалось преобразовать 'arma :: operator == (const T1 &, const T2 &) [with T1 = arma :: subview_row; T2 = arma :: subview_row; имя типа arma :: enable_if2 <(arma :: is_arma_type :: value && arma :: is_arma_type :: value), const arma :: mtGlue> :: result = const arma :: mtGlue, arma :: subview_row, arma :: glue_rel_eq> ] (( (const arma :: subview_row ) (& arma :: Mat :: row (arma :: uword) [с eT = double; arma :: uword = unsigned int] (((arma: : uword) (i + 1)))))) 'from' arma :: enable_if2, arma :: subview_row, arma :: glue_rel_eq>> :: result {aka const arma :: mtGlue, arma :: subview_row, arma: : glue_rel_eq>} 'в' bool ' если (x.row (я) == x.row (г + 1)) { ^ make: *** [acp.o] Ошибка 1

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Вместо использования техники сокращения Дирка, я бы порекомендовал использовать встроенную функцию arma :: ок_эквивалентности () , к которой не применимо @ mtall.

Идея в том, чтобы проверить, находятся ли значения в окрестности эпсилона, определенной допуском. Например, пусть скаляры x и y считаются равными, если |x − y| ≤ tol.

Пример реализации

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

// [[Rcpp::export]]
double accept(arma::mat x){
  int b = x.n_rows;
  arma::vec B = arma::zeros<arma::vec>(b-1);

  for(int i = 0; i < b - 1; ++i){

    bool same_vec = approx_equal(x.row(i), x.row(i+1), "absdiff", 0.002);

    if(same_vec) {
      B[i] = 0;
    } else {
      B[i] = 1;
    }

  }

  double bb = sum(B)/(b-1);

  return bb;
}

Тест:

x = matrix(rep(1:10, 2), ncol = 2)
accept(x)
# [1] 1
0 голосов
/ 14 мая 2018

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

Поэтому я переписал это как sum(abs(diff(a1,a2))) < eps;не стесняйтесь использовать другое значение эпсилона:

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
double accept(arma::mat x){
  int b = x.n_rows;
  arma::vec B(b-1);
  B.zeros();
  for (int i=0;i<b-1;i++){
    arma::rowvec a1 = x.row(i);
    arma::rowvec a2 = x.row(i+1);
    if (sum(abs(a1-a2)) < 1e-8) {
      B[i]=0;
    }else{
      B[i]=1;
    }
  }
  double bb = sum(B) / (b-1);
  return(bb);
}

В противном случае вы были очень близки.

...