Fail to call ones or eye function when using RcppArmadillo - rcpp

I want to use one or eye function in Armadillo to construct matrices or vectors. However, it does not allow me to do so. Here is a sample code:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
SEXP Generate(arma::mat Mat){
arma::mat Mat_2 = ones<mat>(5,6);
}
error message reminds me of use of undeclared idenfier of 'mat'. When I remove <mat>, another massage says use of undeclared idenfier of 'ones'.
I looked up the Armadillo tutorial which includes the ones function. I wonder why my code fails to call it. Did I miss something?

There are a few problems in your code:
Why return SEXP? Use types to your advantage
Why pass Mat in if you do not use it?
No return statement
Somewhat loose use of namespaces.
A cleaned up version follows:
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat Generate(int n=5, int k=6){
arma::mat m = arma::ones<arma::mat>(n,k);
return m;
}
/*** R
Generate()
*/
It compiles and runs fine:
> Rcpp::sourceCpp("~/git/stackoverflow/67006975/answer.cpp")
> Generate()
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 1 1 1
[2,] 1 1 1 1 1 1
[3,] 1 1 1 1 1 1
[4,] 1 1 1 1 1 1
[5,] 1 1 1 1 1 1
>

Related

Problem when using gsl_ran_multinomial in Rcpp

I'm trying to generate multinomial random variables as fast as possible. And I learned that gsl_ran_multinomial could be a good choice. However, I tried to use it based on the answer in this post: https://stackoverflow.com/a/23100665/21039115, and the results were always wrong.
In detail, my code is
// [[Rcpp::export]]
arma::ivec rmvn_gsl(int K, arma::vec prob) {
gsl_rng *s = gsl_rng_alloc(gsl_rng_mt19937); // Create RNG seed
arma::ivec temp(K);
gsl_ran_multinomial(s, K, 1, prob.begin(), (unsigned int *) temp.begin());
gsl_rng_free(s); // Free memory
return temp;
}
And the result was something like
rmvn_gsl(3, c(0.2, 0.7, 0.1))
[,1]
[1,] 1
[2,] 0
[3,] 0
which is ridiculous.
I was wondering if there was any problem exist in the code... I couldn't find any other examples to compare. I appreciate any help!!!
UPDATE:
I found the primary problem here is that I didn't set a random seed, and it seems that gsl has its own default seed (FYI: https://stackoverflow.com/a/32939816/21039115). Once I set the seed by time, the code worked. But I will go with rmultinom since it can even be faster than gsl_ran_multinomial based on microbenchmark.
Anyway, #Dirk Eddelbuettel provided a great example of implementing gsl_ran_multinomial below. Just pay attention to the random seeds issue if someone met the same problem as me.
Here is a complete example taking a double vector of probabilities and returning an unsigned integer vector (at the compiled level) that is mapped to an integer vector by the time we are back in R:
Code
#include <RcppGSL.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
// [[Rcpp::depends(RcppGSL)]]
// [[Rcpp::export]]
std::vector<unsigned int> foo(int n, const std::vector <double> p) {
int k = p.size();
std::vector<unsigned int> nv(k);
gsl_rng_env_setup();
gsl_rng *s = gsl_rng_alloc(gsl_rng_mt19937); // Create RNG instance
gsl_ran_multinomial(s, k, n, &(p[0]), &(nv[0]));
gsl_rng_free(s);
return nv;
}
/*** R
foo(400, c(0.1, 0.2, 0.3, 0.4))
*/
Output
> Rcpp::sourceCpp("~/git/stackoverflow/75165241/answer.cpp")
> foo(400, c(0.1, 0.2, 0.3, 0.4))
[1] 37 80 138 145
>

Invoke the element in `Rcpp::List` for futher use directly

In an application, I use List to contain some variables (double, arma::mat and other types), and then take the arma::mat component in this list for futher use directly, such as matrix addition. However, some error is thrown.
Below is a toy example to throw the same error as I met:
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
arma::mat f(){
arma::mat x = arma::randn(3, 4) ;
List y = List::create( ::Named("a") = arma::randn(3, 4) ) ;
return x - y["a"] ;
}
The error information is
ambiguous overload for 'operator-' (operand types are 'arma::mat'
{aka 'arma::Mat<double>'} and 'Rcpp::Vector<19>::NameProxy' {aka
'Rcpp::internal::generic_name_proxy<19, Rcpp::PreserveStorage>'})
Is there any way to use the y["a"] directly in numerical computation?
You need cast back from the SEXP type you create when adding to an (R or Rcpp, it's the same) List. Correcting that and adding a missing exports tag gives us what is below where I also added the sample invocation (another nice feature).
Code
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
arma::mat f(){
arma::mat x = arma::randn(3, 4) ;
List y = List::create( ::Named("a") = arma::randn(3, 4) ) ;
return x - Rcpp::as<arma::mat>(y["a"]);
}
/*** R
set.seed(42) # reproducible RNG draws
f()
*/
Output
> Rcpp::sourceCpp("~/git/stackoverflow/71612260/answer.cpp")
>
set.seed(42) # reproducible RNG draws
>
f()
[,1] [,2] [,3] [,4]
[1,] -0.471335 -2.337283 1.205825 0.537811
[2,] 0.119150 1.251941 0.486474 -0.513627
[3,] 3.309860 -0.654003 -0.146678 -0.835439
>

syncronizing 2 threads c++ linux

i have such code
#include <iostream>
#include <thread>
#include <mutex>
#include <iostream>
#include <unistd.h>
using namespace std;
bool isRunning;
mutex locker;
void threadFunc(int num) {
while(isRunning) {
locker.lock();
cout << num << endl;
locker.unlock();
sleep(1);
}
}
int main(int argc, char *argv[])
{
isRunning = true;
thread thr1(threadFunc,1);
thread thr2(threadFunc,2);
cout << "Hello World!" << endl;
thr1.join();
thr2.join();
return 0;
}
when running this code i'm waiting to get output like:
1
2
1
2
1
2
1
2
...
but i dont't get that and get something like this instead:
1
2
1
2
2 <--- why so?
1
2
1
and if i run this code on Windows with replacing #include <unistd.h> to #include <windows.h> and sleep(1) to Sleep(1000) the output i get is exactly what i want, i.e. 1212121212.
So why is so and how to achieve the same result on linux?
It pertains to the scheduling of threads. Sometime one thread may be executing faster. Apparently, thread 2 is executing faster once and so you are getting ... 1 2 2 ... Nothing wrong with that because mutex is only ensuring that only one thread is printing count at a time and nothing more. There are uncertainties like when a thread is going to sleep and when it is woken up, etc. All this may not be taking exactly the same time in the two threads all the time.
For having the threads execute alternately, a different semaphore arrangement is needed. For example, let there be two semaphores, s1 and s2. Let the initial values of s1 and s2 be 1 and zero respectively. Consider the following pseudo code:
// Thread 1:
P (s1)
print number
V (s2)
// Thread 2:
P (s2)
print number
V (s1)

Error using Rcpp::Nullable with RcppArmadillo types

I'm using RcppArmadillo in my R package and I would like to use the Rcpp::Nullable in the parameter list.
NumericVector d_snb(NumericVector& x,
Nullable<arma::mat> size_param = R_NilValue,
const int& infinite = 100000, const bool& log_v = false)
This gives an error like:
Error: package or namespace load failed for ‘packagex’ in dyn.load(file, DLLpath = DLLpath, ...): unable to load shared object '/usr/local/lib/R/3.4/site-library/packagex/libs/packagex.so': dlopen(/usr/local/lib/R/3.4/site-library/packagex/libs/packagex.so, 6):
Symbol not found: __Z5d_snbRN4Rcpp6VectorILi14ENS_15PreserveStorageEEENS_8NullableIS2_EES5_S5_RKiRKb
Referenced from: /usr/local/lib/R/3.4/site-library/packagex/libs/packagex.so
Expected in: flat namespace in /usr/local/lib/R/3.4/site-library/packagex/libs/packagex.so
Error: loading failed
Execution halted
The only possible solution right now seems to get the parameter as NumericVector and then get contents and then cast it into Armadillo types.
NumericVector d_snb(NumericVector& x,
Nullable<NumericVector> size_param = R_NilValue ...)
{
...
if(size_param.isNotNull()) {
arma::mat test(NumericVector(size_param));
param_check++;
}
...
}
This gives a warning:
d_snb.cpp:36:21: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
arma::mat test(NumericVector(size_param));
^~~~~~~~~~~~~~~~~~~~~~~~~~~
d_snb.cpp:36:22: note: add a pair of parentheses to declare a variable
arma::mat test(NumericVector(size_param));
^
( )
1 warning generated.
What's the best way to go about this ?
Yes, Rcpp::Nullable<> works only around SEXP-based Rcpp types.
So you have to do the two-step procedure you found. But I think you can do one simpler: arma::mat test = Rcpp::as<arma::mat>(size_param);
Here is a complete example which compiles (but does 'nothing'):
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
void d_snb(Rcpp::NumericVector& x,
Rcpp::Nullable<Rcpp::NumericVector> size_param = R_NilValue) {
if (size_param.isNotNull()) {
arma::vec test = Rcpp::as<arma::vec>(size_param);
test.print("vector");
}
Rcpp::Rcout << x << std::endl;
}
And a quick demo:
R> sourceCpp("/tmp/so44102346.cpp")
R> d_snb(c(1,2,3))
1 2 3
R> d_snb(c(1,2,3), c(4,5,6))
vector
4.0000
5.0000
6.0000
1 2 3
R>

How to convert vtk legacy files to vtu format

I want to convert legacy .vtk files into binary files, preferably .vtu files, because I am using an Unstructured Grid.
To do so I adapted the ConvertFile-Example from http://www.vtk.org/Wiki/VTK/Examples/Cxx/IO/ConvertFile
#include <string>
#include <vtkSmartPointer.h>
#include <vtkGenericDataObjectReader.h>
#include <vtkVersion.h>
#include <vtkXMLUnstructuredGridWriter.h>
#include <vtkUnstructuredGrid.h>
int main(int argc, char *argv[])
{
if(argc < 3)
{
std::cerr << "Required arguments: input.vtk output.vtu" << std::endl;
return EXIT_FAILURE;
}
std::string inputFileName = argv[1];
std::string outputFileName = argv[2];
vtkSmartPointer<vtkGenericDataObjectReader> reader = vtkSmartPointer<vtkGenericDataObjectReader>::New();
reader->SetFileName(inputFileName.c_str());
reader->Update();
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName(outputFileName.c_str());
writer->SetInputConnection(reader->GetOutputPort());
writer->Update();
return EXIT_SUCCESS;
}
But when I use this to convert my legacy file, I lose all Cell Data after the first set. In this minimal example of my legacy file Scal_1 is in the .vtu file but Scal_2 is not.
# vtk DataFile Version 3.1
Lattice Boltzmann data
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 9 INT
0 0 0 1 0 0 2 0 0
0 1 0 1 1 0 2 1 0
0 2 0 1 2 0 2 2 0
CELLS 4 20
4 0 1 3 4
4 1 2 4 5
4 3 4 6 7
4 4 5 7 8
CELL_TYPES 4
8 8 8 8
CELL_DATA 4
SCALARS Scal_1 DOUBLE
LOOKUP_TABLE default
1 2 1 0
SCALARS Scal_2 DOUBLE
LOOKUP_TABLE default
1 3 2 1
I am still new to vtk. Should I use another reader or writer? Or is something completely wrong?
The issue here is that the reader you chose is getting confused by having the input file containing 2 cell data arrays both marked as scalars. So with this the reader only outputs one cell data array. My suggestion is to use ParaView, specifically the pvpython executable, to convert the files. The corresponding Python code would look something like:
from paraview.simple import *
r = LegacyVTKReader( FileNames=['input.vtk'] )
w = XMLUnstructuredGridWriter()
w.FileName = 'output.vtu'
w.UpdatePipeline()
You can just use meshio (a project of mine). Install with
pip3 install meshio
and run
meshio-convert in.vtk out.vtu

Resources