Changing R code to Rcpp code - c++

So I have some R code that I wrote that is terribly slow that I wanted to change into C++ code using the Rcpp library. However, I am getting an error message when trying to use it and I cannot seem to locate where the error is occurring. Any help is greatly appreciated!
Here is the original code:
#Necessary packages to run
library(Rcpp)
library(mvtnorm)
#Here are the variables I will be working with
x = c(0.53137100,0.75357474,0.87904120,0.29727488,0.00000000,0.00000000,
0.00000000,0.00000000,0.00000000,0.04059217)
y = c(4.873500,3.896917,1.258215,5.776484,12.475491,5.273784,13.803158,
4.472204,2.629839,6.689242)
front = c(NA,NA,3,NA,NA,NA,NA,NA,9,NA)
all.preds = c(0.596905183,0.027696850,1.005666896,0.007688514,3.900000000)
x = x[!is.na(front)]
y = y[!is.na(front)]
mu = c(all.preds[1],all.preds[3])
sigma = matrix(c(all.preds[2],0,0,all.preds[4]),nrow=2)
z = rmvnorm(10000,mu,sigma)
z[,1] = sapply(z[,1],function(x){max(x,0)})
temp = 1:nrow(z)
for(i in 1:length(temp)){
cond1 = z[i,2]!=min(z[which(z[,1]==z[i,1]),2])
cond2 = z[i,1]!=min(z[which(z[,2]==z[i,2]),1])
for(n in 1:length(x)){
if((z[i,1]>x[n] & z[i,2]>y[n]) | (z[i,1]==x[n] & cond1) | (z[i,2]==y[n] & cond2)){
temp[i] = NA
break
}
}
}
and here is the new Rcpp code that I wrote:
#Necessary packages to run
library(Rcpp)
library(mvtnorm)
#Here are the variables I will be working with
x = c(0.53137100,0.75357474,0.87904120,0.29727488,0.00000000,0.00000000,
0.00000000,0.00000000,0.00000000,0.04059217)
y = c(4.873500,3.896917,1.258215,5.776484,12.475491,5.273784,13.803158,
4.472204,2.629839,6.689242)
front = c(NA,NA,3,NA,NA,NA,NA,NA,9,NA)
all.preds = c(0.596905183,0.027696850,1.005666896,0.007688514,3.900000000)
x = x[!is.na(front)]
y = y[!is.na(front)]
mu = c(all.preds[1],all.preds[3])
sigma = matrix(c(all.preds[2],0,0,all.preds[4]),nrow=2)
z = rmvnorm(10000,mu,sigma)
z[,1] = sapply(z[,1],function(x){max(x,0)})
cppFunction('
int prop(NumericMatrix z, NumericVector x, NumericVector y) {
int nrow = z.nrow();
int n = x.size();
int temp;
for (int i = 0; i < nrow; i++) {
bool cond1 = z(i,2)!=min(z(which(z(,1)==z[i,1]),2));
bool cond2 = z(i,1)!=min(z(which(z(,2)==z[i,2]),1));
for (int j; j < n; j++) {
if((z(i,1)>x[n] && z(i,2)>y[n]) || (z(i,1)==x[n] && cond1) || (z(i,2)==y[n] && cond2)) {
temp[i] = 0;
break;
}
}
}
return temp;
}
')
The error message that I receive is the following:
g++ -m64 -I"C:/PROGRA~1/R/R-30~1.1/include" -DNDEBUG -I"C:/Users/BabakP/Documents/R/win-library/3.0/Rcpp/include" -I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall -mtune=core2 -c file7444c995de6.cpp -o file7444c995de6.o file7444c995de6.cpp: In function 'int prop(Rcpp::NumericMatrix, Rcpp::NumericVector, Rcpp::NumericVector)': file7444c995de6.cpp:13:40: error: expected primary-expression before ',' token file7444c995de6.cpp:13:49: warning: left operand of comma operator has no effect [-Wunused-value] file7444c995de6.cpp:13:51: error: 'which' was not declared in this scope file7444c995de6.cpp:14:40: error: expected primary-expression before ',' token file7444c995de6.cpp:14:49: warning: left operand of comma operator has no effect [-Wunused-value] file7444c995de6.cpp:18:15: error: invalid types 'int[int]' for array subscript make: *** [file7444c995de6.o] Error 1
Error in sourceCpp(code = code, env = env, rebuild = rebuild, showOutput = showOutput, :
Error 1 occurred building shared library.

Related

call of overloaded isnan(double&) is ambiguous

I'm attempting to compile shapeit - https://github.com/odelaneau/shapeit4
The most recent gcc I have available is 5.3.1
When I run make, the following error trace is shown:
g++ -std=c++11 -O3 -mavx2 -mfma -c src/main.cpp -o obj/main.o -Isrc -I/local/src/htslib-1.3.2/htslib -I/local/include/boost
In file included from src/phaser/phaser_header.h:29:0,
from src/main.cpp:23:
src/models/haplotype_segment_single.h: In member function ‘bool
haplotype_segment_single::TRANS_DIP_MULT()’:
src/models/haplotype_segment_single.h:556:25: error: call of overloaded ‘isnan(double&)’ is ambiguous
return (isnan(sumDProbs) || isinf(sumDProbs) || sumDProbs < numeric_limits<double>::min());
^
In file included from /usr/include/features.h:375:0,
from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/x86_64-redhat-linux/bits/os_defines.h:39,
from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/x86_64-redhat-linux/bits/c++config.h:2255,
from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/bits/stl_algobase.h:59,
from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/vector:60,
from src/utils/otools.h:26,
from src/phaser/phaser_header.h:27,
from src/main.cpp:23:
/usr/include/bits/mathcalls.h:235:1: note: candidate: int isnan(double)
__MATHDECL_1 (int,isnan,, (_Mdouble_ __value)) __attribute__ ((__const__));
^
In file included from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/random:38:0,
from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/bits/stl_algo.h:66,
from /opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/algorithm:62,
from src/utils/otools.h:35,
from src/phaser/phaser_header.h:27,
from src/main.cpp:23:
/opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/cmath:634:3: note: candidate: constexpr bool std::isnan(long double)
isnan(long double __x)
^
/opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/cmath:630:3: note: candidate: constexpr bool std::isnan(double)
isnan(double __x)
^
/opt/rh/devtoolset-4/root/usr/include/c++/5.3.1/cmath:626:3: note: candidate: constexpr bool std::isnan(float)
isnan(float __x)
^
In file included from src/phaser/phaser_header.h:29:0,
from src/main.cpp:23:
I attempted to replace the isnan(sumDProbs) call with std::isnan(sumDProbs) or with ::isnan(sumDProbs). Both of these finished compiling, but the resulting binary threw an Illegal Instruction. Is there a different namespace I should be using to clarify the isnan call?
This is el7 with the devtoolset-4 activated because el7 has gcc 4.8.5. I activate using scl enable devtoolset-4 -- bash and then run the compile commands.
I do not have a using namespace std; included.
This is the line that's throwing the ambiguous error:
https://github.com/odelaneau/shapeit4/blob/master/src/models/haplotype_segment_single.h#L556
bool haplotype_segment_single::TRANS_HAP() {
sumHProbs = 0.0f;
unsigned int curr_rel_segment_index = curr_segment_index-segment_first;
yt = M.getForwardTransProb(AlphaLocus[curr_rel_segment_index - 1], curr_abs_locus);
nt = 1.0f - yt;
//float fact1 = M.nt[curr_abs_locus-1] / AlphaSumSum[curr_rel_segment_index - 1];
float fact1 = nt / AlphaSumSum[curr_rel_segment_index - 1];
fill_n(HProbs, HAP_NUMBER*HAP_NUMBER, 0.0f);
for (int h1 = 0 ; h1 < HAP_NUMBER ; h1++) {
//float fact2 = (AlphaSum[curr_rel_segment_index-1][h1]/AlphaSumSum[curr_rel_segment_index-1]) * M.t[curr_abs_locus - 1] / n_cond_haps;
float fact2 = (AlphaSum[curr_rel_segment_index-1][h1]/AlphaSumSum[curr_rel_segment_index-1]) * yt / n_cond_haps;
for (int k = 0 ; k < n_cond_haps ; k ++) {
for (int h2 = 0 ; h2 < HAP_NUMBER ; h2++) HProbs[h1*HAP_NUMBER+h2]+=((Alpha[curr_rel_segment_index-1][k*HAP_NUMBER + h1]*fact1 + fact2)*prob[k*HAP_NUMBER+h2]);
}
sumHProbs += HProbs[h1*HAP_NUMBER+0]+HProbs[h1*HAP_NUMBER+1]+HProbs[h1*HAP_NUMBER+2]+HProbs[h1*HAP_NUMBER+3]+HProbs[h1*HAP_NUMBER+4]+HProbs[h1*HAP_NUMBER+5]+HProbs[h1*HAP_NUMBER+6]+HProbs[h1*HAP_NUMBER+7];
}
return (isnan(sumHProbs) || isinf(sumHProbs) || sumHProbs < numeric_limits<float>::min());
}
Do I need to change this line:
return (isnan(sumHProbs) || isinf(sumHProbs) || sumHProbs < numeric_limits<float>::min());
to
return (isnan((double)sumHProbs) || isinf(sumHProbs) || sumHProbs < numeric_limits<float>::min());

How to read data in vtkDataArray?

I am ver new to VTK.
This is part of my code:
vtkDataSetReader *rdr = vtkDataSetReader::New();
rdr->SetFileName("proj7b.vtk");
rdr->SetScalarsName("hardyglobal");
rdr->Update();
int dims[3];
vtkRectilinearGrid *rgrid = (vtkRectilinearGrid *) rdr->GetOutput();
rgrid->GetDimensions(dims);
vtkDataArray *dataArray;
dataArray = vtkDoubleArray::New();
dataArray = rgrid->GetPointData()->GetScalars()->GetVoidPointer(0);
for(i=0;i<10;i++)
{
cout<<"here----------"<<endl;
cout<<" "<<dataArray[i]<<" ";
}
I want to read the data into my vtkDataArray. But this code cannot be compile:
proj7b.cxx:525:15: error:
assigning to 'vtkDataArray *' from incompatible type 'void *'
dataArray = rgrid->GetPointData()->GetScalars()->GetVoidPointer(0);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Is there anyone knows how to read data into vtkDataArray?
Vtk provides the method for it, you don't need to use the "low level" method:
rgrid->GetPointData()->GetArray(0)
or
rgrid->GetPointData()->GetArray("arrayname")
It works the same way for FieldData and CellData ( http://www.vtk.org/doc/release/6.2/html/classvtkFieldData.html)
What you get is a vtkArray, not a simple c++ array, so you will have to read it like:
cout<<" "<<dataArray->GetValue(i) <<" ";
There are a lot of examples in the wiki http://www.vtk.org/Wiki/VTK/Examples/Cxx
please see this page: https://cloud.tencent.com/developer/ask/sof/148655
void doSomething(vtkSmartPointer<vtkDataArray> dataArray)
{
vtkIdType numTuples = dataArray->GetNumberOfTuples();
for (vtkIdType tupleIdx = 0; tupleIdx < numTuples; ++tupleIdx)
{
double* tuple = dataArray->GetTuple(tupleIdx);
for (int j = 0; j < /*¿¿¿???*/; ++j)
{
double var = tuple[j];
// Do something with var
// Carefull don't go out of bounds
}
}
}

How to get integer rownames in Rcpp?

Working off of these two posts
1. Convert char to int in C and C++
2. http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2010-July/000932.html
I'm trying to get the rownames from an Rcpp Matrix (NumericMatrix, etc) as an IntegerVector.
In R, this would be:
as.integer(rownames(x)) # where x is a matrix
I've tried casting in two different ways and am getting different compilation errors:
attempt 1
cppFunction('IntegerVector rownames1(NumericMatrix x) {
List dimnames = x.attr("dimnames");
CharacterVector rownames = dimnames[0];
IntegerVector out(dimnames.size());
for (int i= 0; i < out.size(); i++) {
out[i] = (int) rownames[i]; // cast via (int)
}
return (IntegerVector) dimnames[0];}')
file1b9c6dec3c12.cpp: In function 'Rcpp::IntegerVector rownames1(Rcpp::NumericMatrix)':
file1b9c6dec3c12.cpp:11:40: error: invalid cast from type 'Rcpp::Vector<16>::Proxy {aka Rcpp::internal::string_proxy<16>}' to type 'int'
make: *** [file1b9c6dec3c12.o] Error 1
Warning message:
running command 'make -f "C:/PROGRA~1/R/R-32~1.2/etc/x64/Makeconf" -f "C:/PROGRA~1/R/R-32~1.2/share/make/winshlib.mk" SHLIB_LDFLAGS='$(SHLIB_CXXLDFLAGS)' SHLIB_LD='$(SHLIB_CXXLD)' SHLIB="sourceCpp_23.dll" WIN=64 TCLBIN=64 OBJECTS="file1b9c6dec3c12.o"' had status 2
attempt 2
cppFunction('IntegerVector rownames1(NumericMatrix x) {
List dimnames = x.attr("dimnames");
CharacterVector rownames = dimnames[0];
IntegerVector out(dimnames.size());
for (int i= 0; i < out.size(); i++) {
out[i] = rownames[i] + "0"; // cast as suggested in SO post linked above
}
return (IntegerVector) dimnames[0];}')
file1b9c71d25b92.cpp: In function 'Rcpp::IntegerVector rownames1(Rcpp::NumericMatrix)':
file1b9c71d25b92.cpp:11:38: error: ambiguous overload for 'operator-' in 'Rcpp::Vector::operator [with int RTYPE = 16, StoragePolicy = Rcpp::PreserveStorage, Rcpp::Vector::Proxy = Rcpp::internal::string_proxy<16>, R_xlen_t = long long int](((long long int)i)) - "0"'
file1b9c71d25b92.cpp:11:38: note: candidates are:
file1b9c71d25b92.cpp:11:38: note: operator-(const char*, const char*)
file1b9c71d25b92.cpp:11:38: note: operator-(const char*, const char*)
file1b9c71d25b92.cpp:11:38: note: operator-(char*, char*)
make: *** [file1b9c71d25b92.o] Error 1
Warning message:
running command 'make -f "C:/PROGRA~1/R/R-32~1.2/etc/x64/Makeconf" -f "C:/PROGRA~1/R/R-32~1.2/share/make/winshlib.mk" SHLIB_LDFLAGS='$(SHLIB_CXXLDFLAGS)' SHLIB_LD='$(SHLIB_CXXLD)' SHLIB="sourceCpp_21.dll" WIN=64 TCLBIN=64 OBJECTS="file1b9c71d25b92.o"' had status 2
Any help appreciated!
You can use the cstdlib function atoi to convert from const char* to int. For example,
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::IntegerVector rownames1(Rcpp::NumericMatrix x) {
Rcpp::List dimnames = x.attr("dimnames");
Rcpp::CharacterVector rownames = dimnames[0];
Rcpp::IntegerVector out(rownames.size());
std::transform(rownames.begin(), rownames.end(), out.begin(), std::atoi);
return out;
}
/*** R
M <- matrix(
1.5:16.5, nrow = 4,
dimnames = list(1:4, 1:4))
##
R> all.equal(rownames1(M), as.integer(row.names(M)))
#[1] TRUE
*/

Basic Block instrumentation

I want to insert a counter to record how many times the basic block executed.
The steps I took:
I write an LLVM instrumentation pass named BlockProfiling.cpp
I compile it with:
$ g++ -c BlockProfiling.cpp _i/usr/local/include `llvm-config --cxxflag`
it generates a file named BlockPrpfiling.o
I run:
$ g++ -shared -o BlockProfiling.so BlockProfiling.o -L/usr/local/lib `llvm-config --ldflags -libs`
it generates a shared library named BlockProfiling.so
I use it to instrument my file test.bc and generate test.bb.bc:
$opt -load=./BlockProfiling.so -insert-bb-profling test.bc -o test.bb.bc
I use llvm-diff to confirm it's done.
But when I use lli to execute test.bb.bc, there comes an error said:
LLVM ERROR: Program used external function 'llvm_start_func_profiling' which could not be resolved!
Any solutions?
The llvm version is 3.3 and here is my code:
namespace{
struct BlockProfiler: public ModulePass{
static char ID;
BlockProfiler():ModulePass(ID) {
initializeBlock ProfilerPass(*Registry::getPassRegistry());
}
virtual bool runOnModule(Module &M);
}; //end of function profiling pass
} //end of namespace
char BlockProfiler::ID = 0 ;
INITIALIZE_PASS(BlockProfiler, "insert-block-profiling",
"Insert instrumentation for profiling", false, false )
ModulePass *llvm::createBlockProfilerPass() {return new BlockProfiler() ; }
//static RegisterPass<BlockProfilerPass> Y("insert-block-profiling",
"Insert instrumentation for block profiling");
bool BlockProfiler::runOnModule(Module &M){
Function *Main = M.getFunction("main") ;
if(Main == 0)
{
errs()<<" WARING: cannot insert block profiling into a module"
<<" with no main function. \n" ;
return false ; // no main, no instrumentation, and no modify
}
unsigned NumBlocks = 0;
for(Module::iterator I = M.begin(), E = M.end(); I != E ; ++I)
NumBlocks += I->size();
Type *ATy = ArrayType::get(Type::getInt32Ty(M.getContext()), NumBlocks) ;
GlobalVariable *Counters =
new GlobalVariable(M, ATy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), "BlockProCounters") ;
//Instrument all of the blocks
unsigned i = 0;
for(Module::iterator I = M.begin(), E = M.end(); I != E; ++I){
for(Function::iterator BB = I->begin(), E = I->end() ; BB != E; ++BB )
//Insert counter at the start of the block
IncrementCounterInBlock(BB, i++, Counters);
}
//add the initialization call to main
InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters);
return true;
}

C++0x Initializer Lists and Direct3D 9 Vertex Declaration

I am wanting to resolve the following warning when concatenating a vertex declaration for use in Direct3D 9.0
int elements = 1 + useNormals + useTextures + useColors + 1;
D3DVERTEXELEMENT9 customvertex[elements];
customvertex[0] = POSITIONELEMENT;
int i = 1;
if (useNormals) { customvertex[i] = NORMALELEMENT; i += 1; }
if (useTextures) { customvertex[i] = TEXTUREELEMENT; i += 1; }
if (useColors) { customvertex[i] = COLORELEMENT; i += 1; }
customvertex[i] = D3DDECL_END();
The very last line is the one that produces the following warning when compiled with MinGW.
Graphics_Systems/Direct3D9/DX9model.cpp:340:20: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]