NamelessGods
NamelessGods

Reputation: 197

Why is '&' operator not working in RcppArmadillo

I am trying to obtain a logical vector from two other logical vectors connected through elementwise '&':

//[[Rcpp::export]]
arma::uvec test1(arma::vec t1, double R1, double R2){
arma::uvec t = (t1 >= R1) & (t1 < R2);
return t;
}

It returns the following error while I try to compile

error: no match for 'operator&' (operand types are 'arma::enable_if2<true, const arma::mtOp<unsigned int, arma::Col<double>, arma::op_rel_gteq_post> >::result {aka const arma::mtOp<unsigned int, arma::Col<double>, arma::op_rel_gteq_post>}' and 'arma::enable_if2<true, const arma::mtOp<unsigned int, arma::Col<double>, arma::op_rel_lt_post> >::result {aka const arma::mtOp<unsigned int, arma::Col<double>, arma::op_rel_lt_post>}')
arma::uvec t = (t1 >= R1) & (t1 < R2);
                          ^

I have no idea what was going on. I am guessing that Armadillo does things differently. But I can't find any sources to help me clear things out. Any help would be appreciated! Thank you very much!

Upvotes: 0

Views: 462

Answers (1)

duckmayr
duckmayr

Reputation: 16940

I have no idea what was going on. I am guessing that Armadillo does things differently. But I can't find any sources to help me clear things out.

The ultimate source here is the Armadillo docs. If you go down to the section on operators, you'll see that the & operator is not one of those listed among the "[o]verloaded operators for Mat, Col, Row and Cube classes." So, if you want such an operator you'll have to code it up yourself (or see if someone else already has it floating around the internet). There is such an operator for Rcpp::NumericVectors:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::LogicalVector test1(const Rcpp::NumericVector& t1, double R1, double R2){
    return (t1 >= R1) & (t1 < R2);
}
test1(1:10, 3, 7)
# [1] FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
# [9] FALSE FALSE

Of course, that doesn't help much if the rest of your code really relies on Armadillo.

Update: Just Use &&

As pointed out by mtall in the comments, the && operator actually is available, even though it's not discussed in the Armadillo docs (maybe it's not as ultimate of a source as I thought).

So, just change your code to the following:

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

//[[Rcpp::export]]
arma::uvec test1(arma::vec t1, double R1, double R2){
    arma::uvec t = (t1 >= R1) && (t1 < R2);
    return t;
}

and it works how I believe you want it to based on your question and response to comments:

test1(1:10, 3, 7)
      [,1]
 [1,]    0
 [2,]    0
 [3,]    1
 [4,]    1
 [5,]    1
 [6,]    1
 [7,]    0
 [8,]    0
 [9,]    0
[10,]    0

Upvotes: 3

Related Questions