A taste of functional programmming in Rcpp11

May 23, 2014
By

(This article was first published on R Enthusiast and R/C++ hero, and kindly contributed to R-bloggers)

@kevinushey requested some functional programming in Rcpp11 and provided initial versions of map and filter. map is actually doing exactly the same thing as mapply so I added map as a synonym to mapply so that we can do (see this previous post for details):

// [[Rcpp::export]]
NumericVector mapply_example(NumericVector x, NumericVector y, double z){

    auto fun = [](double a, double b, double c){ return a + b + c ;} ;
    return map( fun, x, y, z ) ;

}

filter takes a sugar expression (e.g. a vector) and a function predicte and only keeps the elements of the vector for which the predicate evaluates to true. Here is a simple example:

// [[Rcpp::export]]
NumericVector filter_example(NumericVector x ){  
    auto positives   = [](double a){ return a >= 0 ;} ;
    return filter(x, positives ) ;
}

I've also put in the negate function. Intuitively enough, it takes a function (e.g. a lambda) and returns a function that negates it. For example, we can expand the previous example using both the positives lambda and a negated version of it:

// [[Rcpp::export]]
List filter_example_2(NumericVector x ){  
    auto positives   = [](double a){ return a >= 0 ;} ;
    return list( 
        _["+"] = filter(x, positives ), 
        _["-"] = filter(x, negate(positives) ) 
    ) ;
}

We can also compose two functions:

// [[Rcpp::export]]
NumericVector filter_example_3(NumericVector x ){  
    auto small  = [](double a){ return a < 4 ;} ;
    auto square = [](double a){ return a * a ;} ;

    return filter(x, compose(square, small) ) ;
}

But since I've been spoiled by magrittr and dplyr, I've put in this alternative way to compose the two functions:

// [[Rcpp::export]]
NumericVector filter_example_4(NumericVector x ){  
    auto small  = [](double a){ return a < 4 ;} ;
    auto square = [](double a){ return a * a ;} ;

    return filter(x, _[square] >> small ) ;
}

_ turns square into a Rcpp::functional::Functoid which implements operator>>. Functoid can also be negated by the operator! :

// [[Rcpp::export]]
NumericVector filter_example_5(NumericVector x ){  
    auto small  = [](double a){ return a < 4 ;} ;
    auto square = [](double a){ return a * a ;} ;
    auto fun    = _[square] >> small  ;

    return filter(x, !fun ) ;
}

I'm not sure this is going to be of any use or even if this will stay, but that was fun.

$ Rcpp11Script /tmp/filter.cpp

> x <- seq(-10, 10, by = 0.5)

> filter_example_1(x)
 [1]  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0  5.5  6.0  6.5  7.0
[16]  7.5  8.0  8.5  9.0  9.5 10.0

> filter_example_2(x)
$`+`
 [1]  0.0  0.5  1.0  1.5  2.0  2.5  3.0  3.5  4.0  4.5  5.0  5.5  6.0  6.5  7.0
[16]  7.5  8.0  8.5  9.0  9.5 10.0

$`-`
 [1] -10.0  -9.5  -9.0  -8.5  -8.0  -7.5  -7.0  -6.5  -6.0  -5.5  -5.0  -4.5
[13]  -4.0  -3.5  -3.0  -2.5  -2.0  -1.5  -1.0  -0.5


> filter_example_3(x)
 [1] -10.0  -9.5  -9.0  -8.5  -8.0  -7.5  -7.0  -6.5  -6.0  -5.5  -5.0  -4.5
[13]  -4.0  -3.5  -3.0  -2.5  -2.0   2.0   2.5   3.0   3.5   4.0   4.5   5.0
[25]   5.5   6.0   6.5   7.0   7.5   8.0   8.5   9.0   9.5  10.0

> filter_example_4(x)
[1] -1.5 -1.0 -0.5  0.0  0.5  1.0  1.5

> filter_example_5(x)
 [1] -10.0  -9.5  -9.0  -8.5  -8.0  -7.5  -7.0  -6.5  -6.0  -5.5  -5.0  -4.5
[13]  -4.0  -3.5  -3.0  -2.5  -2.0   2.0   2.5   3.0   3.5   4.0   4.5   5.0
[25]   5.5   6.0   6.5   7.0   7.5   8.0   8.5   9.0   9.5  10.0

To leave a comment for the author, please follow the link and comment on his blog: R Enthusiast and R/C++ hero.

R-bloggers.com offers daily e-mail updates about R news and tutorials on topics such as: visualization (ggplot2, Boxplots, maps, animation), programming (RStudio, Sweave, LaTeX, SQL, Eclipse, git, hadoop, Web Scraping) statistics (regression, PCA, time series, trading) and more...



If you got this far, why not subscribe for updates from the site? Choose your flavor: e-mail, twitter, RSS, or facebook...

Comments are closed.