两个向量在RcppArmadillo中相等吗?

时间:2018-05-14 08:21:28

标签: c++ rcpp armadillo

在我的函数中,我想通过use ==比较矩阵中的行,但它不起作用。

#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/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 / include“-I”E:/ adptive / block“-O2 -Wall -mtune = generic -c acp.cpp -o acp.o   acp.cpp:在函数'double accept(arma :: mat)'中:   acp.cpp:10:16:错误:无法转换'arma :: operator ==(const T1&amp;,const T2&amp;)[与T1 = arma :: subview_row; T2 = arma :: subview_row; typename arma :: enable_if2&lt;(arma :: is_arma_type :: value&amp;&amp; arma :: is_arma_type :: value),const arma :: mtGlue&gt; :: result = const arma :: mtGlue,arma :: subview_row,arma :: glue_rel_eq&gt;](((const arma :: subview_row )(&amp; arma :: Mat :: row(arma :: uword)[with eT = double; arma :: uword = unsigned int ](((arma :: uword)(i + 1))))))'from'arma :: enable_if2,arma :: subview_row,arma :: glue_rel_eq&gt; &gt; ::结果{aka const arma :: mtGlue,arma :: subview_row,arma :: glue_rel_eq&gt;}'到'bool'        如果(x.row(ⅰ)== x.row(I + 1)){                   ^   make:*** [acp.o]错误1

2 个答案:

答案 0 :(得分:1)

看起来平等比较不起作用。 (关于浮点数难以解决的原因,有一个很长的故事,请参阅what every computer scientist should know about floating point。)

所以我把它重写为sum(abs(diff(a1,a2))) < eps;随意使用不同的epsilon值:

#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);
}

否则你非常接近。

答案 1 :(得分:1)

我建议不要使用Dirk的简化技术,而是建议使用内置的arma::approx_equal()函数,而不是@mtall。

这里的想法是检查值是否在由容差定义的epsilon邻域内。例如,如果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