Transform a boost::array into NumericVector in Rcpp - c++

In my C++ script (run in R using Rcpp), I defined :
typedef boost::array< double ,3 > state_type;
Now, I want to create a function to transform a state_type variable to a Rcpp::NumericVector variable, and another function that do the inverse. How can do that?
I need to do that in order to use R function into C++.

If you want to have seamless integration you will have to extend Rcpp::as<T>(obj) and Rcpp::wrap(obj). How to do this is covered in the vignette Extending Rcpp. However, there is also an excellent entry in the Rcpp gallery that already covers a very similar case: Converting to and from boost::numeric::ublas::vector<double>.
If you are content with only using state_type and not the general template, then you can use something like this:
#include <RcppCommon.h>
// [[Rcpp::depends(BH)]]
#include <boost/array.hpp>
typedef boost::array< double ,3 > state_type;
namespace Rcpp {
// non-intrusive extension via template specialisation
template <> state_type as(SEXP s);
// non-intrusive extension via template specialisation
template <> SEXP wrap(const state_type &s);
}
#include <Rcpp.h>
// define template specialisations for as and wrap
namespace Rcpp {
template <> state_type as(SEXP stsexp) {
Rcpp::NumericVector st(stsexp);
state_type result;
if (st.size() != result.size()) Rcpp::stop("Incompatible length!");
std::copy(st.begin(), st.end(), result.begin());
return result;
}
template <> SEXP wrap(const state_type &st) {
Rcpp::NumericVector result(st.size());
std::copy(st.begin(), st.end(), result.begin());
return Rcpp::wrap(result);
}
}
// make use of the new possibilities
// [[Rcpp::export]]
state_type alterStateType(state_type &st) {
for (size_t i = 0; i < st.size(); ++i) {
st[i] = i * st[i];
}
return st;
}
/*** R
alterStateType(1:3)
*/

How about
Rcpp::NumericVector boost_array_to_nvec(state_type const& s) {
Rcpp::NumericVector nvec(s.size());
for (size_t i = 0; i < s.size(); ++i) {
nvec[i] = s[i];
}
return nvec;
}
state_type nvec_to_boost_array(Rcpp::NumericVector const& nvec) {
state_type s;
for (size_t i = 0; i < s.size(); ++i) {
s[i] = nvec[i];
}
return s;
}
...
state_type s {0,0,0};
Rcpp::NumericVector nvec = boost_array_to_nvec(s);
s = nvec_to_boost_array(nvec);
If you have to do this a lot of times. This might not be the most efficient way of doing the transformation. But now you have to look that nvec is already allocated to the correct size.
void boost_array_to_nvec(state_type const& s, Rcpp::NumericVector& nvec) {
for (size_t i = 0; i < s.size(); ++i) {
nvec[i] = s[i];
}
}
void nvec_to_boost_array (Rcpp::NumericVector const& nvec, state_type& s) {
for (size_t i = 0; i < s.size(); ++i) {
s[i] = nvec[i];
}
}
...
state_type s {0,0,0};
Rcpp::NumericVector nv(3);
boost_array_to_nvec(s, nv);
nvec_to_boost_array(nv, s);

Related

#define function with variable name

I am continually writing something akin to
std::vector< std::vector< double > > A(N, std::vector< double >(M));
and I would like to replace this with something like
matrix A(N,M);
by using a #define directive. I've looked at #define directives and think I can create a function like matrix(A,N,M) that would declare a vector of vectors as follows:
#define matrix(A, N, M) std::vector< std::vector< double > > A(N, std::vector< double >(M))
but I would rather not declare my matrices as matrix(A,N,M), but rather matrix A(N,M). My question is - how do I use the #define directives to account for changing a variable name?
You can use typedef and define type, something like that:
#include <vector>
using namespace std;
int main()
{
int N = 10;
typedef std::vector< std::vector<double> matrix;
matrix A(N, std::vector< double >(N));
return 0;
}
or more safety (if you don't know, that matrix will be right)
int main()
{
int N = 10;
typedef std::vector< std::array<double, 5> > matrix;
matrix A(N, std::array< double , 5 >());
return 0;
}
my wrapper for matrix with vectors
#include <iostream>
#include <vector>
#include <exception>
#include <algorithm>
template< typename T >
class WrapperMatrix
{
public:
WrapperMatrix(const int& weight, const int& length);
void pushLine(const std::vector<T>&&);
void pushColumn(const std::vector<T>&&);
void display();
private:
std::vector<std::vector<T>> matrix;
};
template<typename T>
WrapperMatrix<T>::WrapperMatrix(const int& weight, const int& length)
{
this->matrix = std::vector<std::vector<T>>(weight, std::vector<T>(length));
}
template <typename T>
void WrapperMatrix<T>::pushLine(const std::vector<T>&& newLine)
{
if (newLine.size() == this->matrix.at(0).size())
matrix.emplace_back(std::move(newLine));
else
throw std::invalid_argument("Invalis syntax");
}
template <typename T>
void WrapperMatrix<T>::pushColumn(const std::vector<T>&& newColumn)
{
if (newColumn.size() == this->matrix.size())
{
for (int i = 0; i < matrix.size(); ++i)
matrix.at(i).emplace_back(std::move(newColumn.at(i)));
}
else
throw std::invalid_argument("Invalid syntax");
}
template<typename T>
void WrapperMatrix<T>::display()
{
for (int i = 0; i < matrix.size(); ++i)
{
for (int j = 0; j < matrix.at(0).size(); ++j)
std::cout << matrix.at(i).at(j);
std::cout << std::endl;
}
}
int main()
{
std::vector<int> v1{ 1,2,3,4,5 };
std::vector<int> v2{ 1,2,3,4,5,6 };
std::vector<int> v3{ 2,3,4,5,6 };
WrapperMatrix<int> vw(5,5);
try {
vw.pushLine(std::move(v1));
vw.pushColumn(std::move(v2));
//vw.pushLine(std::move(v3));
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
vw.display();
return 0;
}
Alternative answer to typedef
using matrix = std::vector< std::vector<double>>;
This form can be more readable, especially with function and array types. E.g. using arr10 = Foo[10] is clearer than typedef Foo arra10[10]. The = sign clearly separates what's being defined and how it's defined.
(Ignoring the whole "matrix is not a vector of vectors" discussion)

Undefined reference to a custom function in a worker (C++ and RcppParallel)

I'm new to C++ programming, trying to experiment with Rcpp through R.
I created a function to produce all possible k-mers from a string. It works well in the serial form of it:
#include <Rcpp.h>
#include <string>
#include <iostream>
#include <ctime>
// using namespace Rcpp;
// [[Rcpp::export]]
std::vector< std::string > cpp_kmer( std::string s, int k ){
std::vector< std::string > kmers;
int seq_loop_size = s.length() - k+1;
for ( int z=0; z < seq_loop_size; z++ ) {
std::string kmer;
kmer = s.substr( z, k );
kmers.push_back( kmer ) ;
}
return kmers;
}
However, when I try to use this function in a parallel implementation (using RcppParallel), with the code below:
#include <Rcpp.h>
#include <string>
#include <iostream>
#include <ctime>
using namespace Rcpp;
// [[Rcpp::depends(RcppParallel)]]
#include <RcppParallel.h>
using namespace RcppParallel;
struct p_cpp_kmer : public Worker {
// input string
std::vector< std::string > seqs;
int k;
std::vector< std::string > cpp_kmer( std::string s, int k );
// destination list
List output;
std::string
sub_s;
// initialize with source and destination
p_cpp_kmer(std::vector< std::string > seqs, int k, List output)
: seqs(seqs), k(k), output(output) {}
// calculate k-mers for the range of sequences requested
void operator()(std::size_t begin, std::size_t end) {
for (std::size_t i = begin; i < end; i++)
sub_s = seqs[i];
cpp_kmer(sub_s, k);
}
};
// [[Rcpp::export]]
List par_cpp_kmer(std::vector< std::string > seqs, int k, bool v){
// allocate output list
List outpar(num_seqs);
int num_seqs = seqs.size();
// p_cpp_kmer functor (pass input and output matrixes)
p_cpp_kmer par_kmer(seqs, k, outpar);
parallelFor(0, num_seqs, par_kmer);
return wrap(outpar);
}
std::vector< std::string > cpp_kmer( std::string s, int k ){
std::vector< std::string > kmers;
int seq_loop_size = s.length() - k+1;
for ( int z=0; z < seq_loop_size; z++ ) {
std::string kmer;
kmer = s.substr( z, k );
kmers.push_back( kmer ) ;
}
return kmers;
}
It fails to compile, giving an: undefined reference to p_cpp_kmer::cpp_kmer(std::string, int)' error.
I know it has to do with declaring/referencing the cpp_kmer, but I just can't figure out where/how to do so appropriately (due to my lack of knowledge in C++).
Thank you very much in advance.
What happens is that your p_cpp_kmer struct declares a cpp_kmer method but it is never defined. Instead what is defined later is the free function cpp_kmer.
You declare this method
std::vector< std::string > cpp_kmer( std::string s, int k );
You seem to want to use it:
void operator()(std::size_t begin, std::size_t end) {
for (std::size_t i = begin; i < end; i++)
sub_s = seqs[i];
cpp_kmer(sub_s, k);
}
But instead you define the free function cpp_kmer here:
std::vector< std::string > cpp_kmer( std::string s, int k ){
std::vector< std::string > kmers;
int seq_loop_size = s.length() - k+1;
for ( int z=0; z < seq_loop_size; z++ ) {
std::string kmer;
kmer = s.substr( z, k );
kmers.push_back( kmer ) ;
}
return kmers;
}
You could either remove the definition of the cpp_kmer method in the struct so that the free function is used, or actually define it.
There are additional problems with the code:
In your operator() you discard the result. I guess you mean to have this instead output[i] = cpp_kmer(sub_s, k);
even if you do something like the above the code is unsafe, because output[i] = cpp_kmer(sub_s, k); allocates R objects (each individual R string and the string vector) , that cannot happen in a separate thread.
If you really want to do this in parallel, you need to make sure that you don't allocate any R object in the workers.
Furthermore, writing parallel code is much easier when you consider using C++11 and the tbb library that is underlying RcppParallel. For example:
#include <Rcpp.h>
#include <RcppParallel.h>
using namespace Rcpp;
using namespace RcppParallel;
// [[Rcpp::depends(RcppParallel)]]
// [[Rcpp::plugins(cpp11)]]
using string_vector = std::vector< std::string > ;
using list_string_vector = std::vector<string_vector> ;
// [[Rcpp::export]]
list_string_vector par_cpp_kmer( string_vector seqs, int k, bool v){
int num_seqs = seqs.size() ;
list_string_vector out(num_seqs) ;
tbb::parallel_for( 0, num_seqs, 1, [&seqs,k,&out](int i){
std::string& s = seqs[i] ;
int seq_loop_size = s.length() - k+1;
std::vector<std::string> vec(seq_loop_size) ;
for ( int z=0; z < seq_loop_size; z++ ) {
vec[z] = s.substr( z, k );
}
out[i] = vec ;
}) ;
return out ;
}
This is assuming that std::string can be allocated in separate threads:
> par_cpp_kmer( c("foobar", "blabla"), 3 )
[[1]]
[1] "foo" "oob" "oba" "bar"
[[2]]
[1] "bla" "lab" "abl" "bla"
You probably have an implementation for cpp_kmer for a different struct (or in the public namespace), but you lack an implementation of member function cpp_kmer at your struct p_cpp_kmer. You will have to add an implementation like:
std::vector< std::string > p_cpp_kmer::cpp_kmer( std::string s, int k ) {
// your implementation goes here
}

Define custom stepper for dynamic array in boost

How would I whip up a custom stepper for the ODE integrator in boost? I know how to do that for an array whose size is known at compile time. A simple implementation is like this
#include <boost/array.hpp>
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
typedef boost::array<double, 2> state_type;
template <size_t N>
class euler_stepper {
public:
typedef double value_type;
typedef double time_type;
typedef unsigned short order_type;
typedef boost::numeric::odeint::stepper_tag stepper_category;
static order_type order(void) { return(1); }
template<class System>
void do_step(System system, state_type &x, time_type t, time_type dt) const {
state_type der;
system(x , der);
for(size_t i=0 ; i<x.size(); i++) {
x[i] += dt*der[i];
}
}
};
struct rhs {
void operator()(const state_type &x, state_type &dxdt) const {
for(int i=0; i < x.size(); i++) dxdt[i] = -x[i];
}
};
struct observer {
void operator()(const state_type &x , double t) const {
for(int i=0; i < x.size(); i++) cout << x[i] << '\t';
cout << endl;
}
};
int main(int argc , char **argv) {
double dt = 0.01;
state_type x = {{2.0, 1.0}};
integrate_const(euler_stepper<2>(), rhs(), x, 0.0, 0.1, dt, observer());
return 0;
}
But how should I change the implementation, if I wanted to work with a state_type like this
typedef vector<complex<double>> state_type;
Basically, I would like to pass the size of the state vector as an argument to main.
Thanks,
Zoltán
Try this:
template < typename State >
class euler_stepper {
public:
using state_type = State;
using value_type = typename state_type::value_type;
using time_type = value_type;
using order_type = unsigned short;
using stepper_category = boost::numeric::odeint::stepper_tag;
static order_type order(void) { return(1); }
template<class System>
void do_step( System system , state_type &x , time_type t , time_type dt ) const
{
state_type der;
system(x , der);
for(size_t i=0 ; i<x.size(); i++) {
x[i] += dt*der[i];
}
}
};
You can also fix the state type for your solver, for example:
class euler_stepper
{
public:
using state_type = vector< complex< double > >;
using value_type = double;
using time_type = double;
// ...
};

how to call a templetized vector of records

I'm having a problem getting the syntax right so if someone can help,please?
I have a timing function which take a function and its arguments as a parameters, but I'm not sure how should the call look like.
#include <iostream>
#include <iterator>
#include <random>
#include <vector>
#include<list>
#include<deque>
#include <algorithm>
#include <chrono>
#include <functional>
#include <sstream>
using namespace std;
using namespace std::chrono;
int global_SortType = 1;
template<class F, class A, typename T>
void times(F func, A arg, int n, T typeval) // call func(arg,n)
{
auto t1 = system_clock::now();
func(arg, n, typeval);
auto t2 = system_clock::now();
auto dms = duration_cast<milliseconds>(t2-t1);
cout << "f(x) took " << dms.count() << " milliseconds\n";
}
template<class T>
bool Greater(const T& v1, const T& v2)
{
return false;
}
bool Greater(const int& v1, const int& v2)
{
return v1 > v2;
}
bool Greater(const string& v1, const string& v2)
{
return strcmp(v1.c_str(), v2.c_str()) > 0;
}
template <class T>
struct GreaterThan: public std::binary_function<T, T, bool > {
bool operator () ( const T &ival, const T &newval ) const {
return Greater(ival, newval);
}
};
string random_gen(string& s)
{
string Result; // string which will contain the result
ostringstream convert; // stream used for the conversion
convert << rand();
return convert.str();
}
int random_gen(int& i){
default_random_engine re { std::random_device()() };
uniform_int_distribution<int> dist;
auto r= bind(dist,re);
int x =r();
return x;
}
template<class T>
void print(T& val)
{
}
void print(int& val)
{
cout << val << " ";
}
void print(string& val)
{
cout << val.c_str() << " ";
}
struct Record
{
int v;
string s;
Record(){}
Record(int iv, string ss): v(iv), s(ss)
{
}
};
Record random_gen(Record& r)
{
string stemp;
int i = 0;
return Record(random_gen(i), random_gen(stemp));
}
void print(Record& r)
{
cout<<"int="<<r.v<<" string=";
print(r.s);
}
bool Greater(const Record& r1, const Record& r2)
{
return global_SortType == 1 ? Greater(r1.v, r2.v) : Greater(r1.s, r2.s);
}
template<typename SequenceContainer, class T>
void build_cont(SequenceContainer& seq, int n, T valtype)
{
for(int i=0; i!=n; ++i) {
T gen = random_gen(valtype);
typename SequenceContainer::const_iterator it;
it=find_if(seq.begin(), seq.end(), std::bind2nd(GreaterThan<T>(), gen));
seq.insert(it, gen);
}
for(int i=n-1; i >=0; i--)
{
int gen = i;
if(i > 0)
gen = random_gen(i)%i;
typename SequenceContainer::const_iterator it=seq.begin();
for(int j = 0; j < gen; j++)
it++;
seq.erase(it);
}
}
int main()
{
int n=1000;
vector<int> v;
times(build_cont<std::vector<int>, int>, v, n, 0); // works
vector<string> sv;
string stemp = "";
times(build_cont<std::vector<string>, string>, sv, n, stemp); // works
global_SortType = 1;
vector<Record> rv;
Record rtemp(0, "sfds");
global_SortType = 2;
vector<Record> rsv;
Record rstemp(0, "sfds");
//This one desn't work and I'm not sure of the right syntax
times(build_cont<std::vector<Record>,Record>, sv, n, stemp);
return 0;
}
I'm getting this error
Non-const lvalue reference to type 'vector>' cannot bind to a value of unrelated type 'vector, allocator>>'
and it points to line
func(arg, n, typeval);
Inside this function:
template<typename SequenceContainer, class T>
void build_cont(SequenceContainer& seq, int n, T valtype)
You are using const_iterators rather than iterators to perform insertions and removals. You should change the definition of that function as follows:
template<typename SequenceContainer, class T>
void build_cont(SequenceContainer& seq, int n, T valtype)
{
for(int i=0; i!=n; ++i) {
T gen = random_gen(valtype);
typename SequenceContainer::iterator it;
// ^^^^^^^^
it=find_if(seq.begin(), seq.end(), std::bind2nd(GreaterThan<T>(), gen));
seq.insert(it, gen);
}
for(int i=n-1; i >=0; i--)
{
int gen = i;
if(i > 0)
gen = random_gen(i)%i;
typename SequenceContainer::iterator it=seq.begin();
// ^^^^^^^^
for(int j = 0; j < gen; j++)
it++;
seq.erase(it);
}
}
Also, you forgot to #include the <cstring> standard header, which contains the definition for the strcmp() function. You are using that function inside your Greater() function:
bool Greater(const string& v1, const string& v2)
{
return strcmp(v1.c_str(), v2.c_str()) > 0;
// ^^^^^^
// You need to #include <cstring> before calling this function
}
Moreover, you're invoking function times() with the wrong arguments (sv and stemp):
//This one desn't work and I'm not sure of the right sytax
times(build_cont<std::vector<Record>,Record>, rsv, n, rstemp);
// ^^^ ^^^^^^

Create a subvector from regularly spaced elements of another vector

Very simple question: is there a smart way of creating a subvector from regularly spaced elements of another vector with the STL?
In short, is it possible to write the following code with a STL algorithm:
int inc = 2;
std::vector<double> v_origin;
std::vector<double> v_dest;
for (int i = 0; i < v_origin.size(); i+= inc)
v_dest.push_back(v_origin[i]);
Like I would write in Matlab or Python something like:
v_dest = v_origin[0:inc:end];
As a general solution, you could define a stride iterator. If you use Boost.Range, then it already as a strided range adaptor.
Example:
#include <vector>
#include <iostream>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
int main()
{
int inc = 2;
std::vector<double> v_origin;
std::vector<double> v_dest;
for (int i = 0; i < 10; ++ i)
v_origin.push_back(i);
boost::copy(v_origin | boost::adaptors::strided(2),
std::back_inserter(v_dest));
// ^ In Python: v_dest[] = v_origin[::2]
boost::copy(v_dest, std::ostream_iterator<double>(std::cout, ", "));
}
(Creating another answer as it's a different approach.)
If you just want to push_back a strided slice of another container, and does not intend to use that lst[a:b:c] concept anywhere else, it is probably easier to write a generic copy-like function:
template <typename InputIterator, typename OutputIterator>
void copy_strided(InputIterator begin, InputIterator end,
OutputIterator result, size_t stride)
{
assert(stride >= 1);
for (size_t i = stride; begin != end; ++ i, ++ begin)
{
if (i == stride)
{
*result = *begin;
++ result;
i = 0;
}
}
}
Usage:
#include <vector>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <iterator>
int main()
{
int inc = 2;
std::vector<double> v_origin;
std::vector<double> v_dest;
for (int i = 0; i < 10; ++ i)
v_origin.push_back(i);
copy_strided(v_origin.begin(), v_origin.end(), std::back_inserter(v_dest), inc);
std::copy(v_dest.begin(), v_dest.end(), std::ostream_iterator<double>(std::cout, ", "));
}
struct RemoveNth
{
RemoveNth(int incin)
{
count = 0;
inc = incin;
}
bool operator()(double x )
{
return count++ % inc == 0;
}
int count;
int inc;
};
int main()
{
int inc = 2;
std::vector<double> v_origin;
std::vector<double> v_dest;
for ( int i = 0 ; i < 100; ++i )
v_origin.push_back( i );
v_dest = v_origin;
RemoveNth helper(3);
std::vector<double>::iterator newend =
std::remove_if (v_dest.begin() , v_dest.end(), helper);
v_dest.erase( newend , v_dest.end() );
return 0;
}
Something like above might work.
In C++11 you can use std::copy_if and instead of the separate functor you can use inline lambdas like so
template<typename T, typename U>
void copynth( T begin , T end , U dest , int n )
{
int count = 0;
std::copy_if( begin , end , dest ,
[&count,n]( double x )
{
return count++ % n == 0;
});
}
int main()
{
int inc = 2;
std::vector<double> v_origin;
std::vector<double> v_dest;
for ( int i = 0 ; i < 100; ++i )
v_origin.push_back( i );
int count = 0;
copynth( v_origin.begin() , v_origin.end() , std::back_inserter(v_dest) , 4);
return 0;
}
There does not exist anything in the standard library that is meant for this task specifically.
Below is my own generic implementation. There is a separate implementation for random access iterator and for other input iterators.
#include <iterator>
namespace detail {
template <class SourceIter, class OutIter>
void strided_copy_aux(SourceIter from, SourceIter to, OutIter out, unsigned step, std::random_access_iterator_tag)
{
SourceIter end = (to - from) / step * step + from;
for (; from < end; from += step ) {
*out = *from;
}
if (end < to) {
*out = *end;
}
}
template <class SourceIter, class OutIter>
void strided_copy_aux(SourceIter from, SourceIter to, OutIter out, unsigned step, std::input_iterator_tag)
{
while (from != to) {
*out = *from;
for (unsigned i = 0; i != step; ++i) {
++from;
if (from == to) break;
}
}
}
}
template <class SourceIter, class OutIter>
void strided_copy(SourceIter from, SourceIter to, OutIter out, unsigned step)
{
detail::strided_copy_aux(from, to, out, step, typename std::iterator_traits<SourceIter>::iterator_category());
}
Usage example: http://ideone.com/1Wmq3