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]