In converting the example below to a gfor loop. I encountered an error of the type "Invalid dimension for argument 0", the full error message below. However, the error occurs, then the function runs, then the same error. This pattern repeats. I am confused and am wondering if this error is in someway system dependent.
Full error message:
Error in random_shuffle(theta, 5, 1) :
ArrayFire Exception (Invalid input size:203):
In function af_err af_assign_seq(af_array *, const af_array, const unsigned int, const af_seq *, const af_array)
In file src/api/c/assign.cpp:168
Invalid dimension for argument 0
Expected: (outDims.ndims() >= inDims.ndims())
A second problem, the seed fails to change with the input parameter, when using the gfor loop.
#include "RcppArrayFire.h"
using namespace Rcpp;
using namespace RcppArrayFire;
// [[Rcpp::export]]
af::array random_shuffle(const RcppArrayFire::typed_array<f64> theta, int counts, int seed){
const int theta_size = theta.dims()[0];
af::array out(counts, theta_size, f64);
af::array seed_seq = af::seq(seed, seed+counts);
// for(int f = 0; f < counts; f++){
gfor ( af::seq f, counts-1 ){
af::randomEngine engine;
engine.setSeed(af::sum<double>(seed_seq(f)));
af::array index_shuffle(1, u16);
af::array temp_rand(1, f64);
af::array temp_end(1, f64);
af::array shuffled = theta;
// implementation of the Knuth-Fisher-Yates shuffle algo
for(int i = theta_size-1; i > 1; i --){
index_shuffle = af::round(af::randu(1, u16, engine)/(65536/(i+1)));
temp_rand = shuffled(index_shuffle);
temp_end = shuffled(i);
shuffled(index_shuffle) = temp_end;
shuffled(i) = temp_rand;
}
out(f, af::span) = shuffled;
}
return out;
}
/*** R
theta <- 10:20
random_shuffle(theta, 5, 1)
random_shuffle(theta, 5, 2)
*/
Updated with Ralf Stunber's solution, but 'shuffled' samples in Column space.
// [[Rcpp::export]]
af::array random_shuffle2(const RcppArrayFire::typed_array<f64> theta, int counts, int seed) {
int len = theta.dims(0);
af::setSeed(seed);
af::array tmp = af::randu(len, counts, 1);
af::array val, idx;
af::sort(val, idx, tmp, 1);
af::array shuffled = theta(idx);
return af::moddims(shuffled, len, counts);
}
/*** R
random_shuffle2(theta, 5, 1)
*/
Here is a picture of output, sampling with replacement:
In the second part, of 50 repetitions, the samples moves towards anergodic outcome.