How to get integer rownames in Rcpp? - c++

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
*/

Related

Why mlpack(c/c++) can't support arma::fmat, but support arma::mat since they are only difference on float and double?

I am beginer for mlpack, only for using some argorithms for my project c/c++ tensorflow to match some python implementation, but i encountered the following error:
float inputFeature[] = {31500, 136.423,135.978,123.432,122.918,116.481,115.454,106.831,104.674,101.54 };
arma::fmat mat(inputFeature, 1, 10, true, false);
mlpack::data::StandardScaler scaler;
arma::fmat outputMat;
scaler.Fit<arma::fmat>(mat);
The above reported the mismatch errors between two operand(... with vec),
error: no match for \u2018operator=\u2019 (operand types are \u2018arma::vec\u2019 {aka \u2018arma::Col\u2019} and \u2018arma::enable_if2<true, const arma::Oparma::Mat<float, arma::op_mean> >::result\u2019 {aka \u2018const arma::Oparma::Mat<float, arma::op_mean>\u2019})
...
The mlpack code:
template<typename MatType>
void Fit(const MatType& input)
{
itemMean = arma::mean(input, 1);
itemStdDev = arma::stddev(input, 1, 1);
// Handle zeros in scale vector.
itemStdDev.for_each([](arma::vec::elem_type& val) { val =
(val == 0) ? 1 : val; });
}
If my used for standardscaler is not consistent with arma rule.
I don't know if standardscaler is only support the types of double above, but, arma::Mat fmat, arma::Mat mat, have only difference on raw type(double & float), and it is less materials for Armadillo on google.
Welcom give suggestion!
Regards

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());

Getting Blob data in caffe

I am trying to plot layer out of caffe as follow.
int ncols = (int)(sqrt (blob.channels()));
int nrows;
if(blob.channels()%ncols!=0){
nrows = ncols+1;
}
int Rows = nrows*blob.height();
int Cols = ncols*blob.width();
cv::Mat image = cv::Mat::zeros(Rows+nrows, Cols+ncols, CV_32FC1);
///////Plotting output of individual layer
if(blob.height()>1 && blob.width()>1){
cv::Size ss(blob.width(), blob.height());
Dtype* data = blob.mutable_cpu_data();
int r=0; int c=0;
for(int k=0; k < blob.channels(); k++)
{
cv::Mat channel(ss, CV_32FC1, data);
channel.copyTo(image(cv::Rect(c*blob.width()+1, r*blob.height()+1, blob.width(), blob.height())));
c++;
if(c>0 &&c%ncols==0){
r++;
c=0;
}
channel.release();
data += ss.area();
}
}
For that I have error as
CXX src/caffe/net.cpp
src/caffe/net.cpp: In instantiation of ‘void caffe::Net<Dtype>::ForwardDebugInfo(int) [with Dtype = float]’:
src/caffe/net.cpp:1040:1: required from here
src/caffe/net.cpp:632:49: error: passing ‘const caffe::Blob<float>’ as ‘this’ argument discards qualifiers [-fpermissive]
Dtype* data = blob.mutable_cpu_data();
^
In file included from ./include/caffe/layer.hpp:8:0,
from src/caffe/net.cpp:11:
./include/caffe/blob.hpp:225:10: note: in call to ‘Dtype* caffe::Blob<Dtype>::mutable_cpu_data() [with Dtype = float]’
Dtype* mutable_cpu_data();
^
src/caffe/net.cpp: In instantiation of ‘void caffe::Net<Dtype>::ForwardDebugInfo(int) [with Dtype = double]’:
src/caffe/net.cpp:1040:1: required from here
src/caffe/net.cpp:632:49: error: passing ‘const caffe::Blob<double>’ as ‘this’ argument discards qualifiers [-fpermissive]
Dtype* data = blob.mutable_cpu_data();
^
In file included from ./include/caffe/layer.hpp:8:0,
from src/caffe/net.cpp:11:
./include/caffe/blob.hpp:225:10: note: in call to ‘Dtype* caffe::Blob<Dtype>::mutable_cpu_data() [with Dtype = double]’
Dtype* mutable_cpu_data();
^
Makefile:575: recipe for target '.build_debug/src/caffe/net.o' failed
make: *** [.build_debug/src/caffe/net.o] Error 1
What does that error means?
Earlier version of caffe, it was fine. I did it before.
Now what could be the error?
That error translates as "You pass a const object as this argument to a non-const method mutable_cpu_data"
const Dtype* cpu_data() const;
Dtype* mutable_cpu_data();
"Passing an object as this argument" suggests use of operators . or -> to access object's method and use of operator().
If you do that, you potentially can change const object, so it's an error, unless permissive mode engaged.

request for member ‘begin’ in ‘ionDistance’, which is of non-class type ‘float*’

I have written the code below and I am receiving the error. What am I doing wrong?
float sampledEnergies ( float ionDistance[], float ionEnergy[])
{
float samTime[1000];
float simPos[1000];
float closeEnergy[1000];
float close;
int maxSamples = chamberLength / (driftVel * adcSampleRate);
for (int i = 0; i < maxSamples; i++)
{
samTime[i] = i * adcSampleRate;
simPos[i] = chamberLength - (driftVel * samTime[i]);
printf("%.2f\t%.2f\n",samTime[i],simPos[i]);
close = lower_bound(ionDistance.begin(),ionDistance.end(), simPos[i]);
for (int j = 0; j < maxSamples; j++)
{
if (close = ionDistance[j])
{
closeEnergy[i] = ionEnergy[j];
}
}
}
}
The above is the code and the error is as follows.
TBraggSimulation_v1.cpp: In function ‘float sampledEnergies(float*, float*)’:
TBraggSimulation_v1.cpp:37: error: request for member ‘begin’ in ‘ionDistance’, which is of non-class type ‘float*’
TBraggSimulation_v1.cpp:37: error: request for member ‘end’ in ‘ionDistance’, which is of non-class type ‘float*’
Your ionDistance is a pointer (to a first element of an array) and not a standard-library container. Your code tries to call begin and end, which are only defined for containers.
To obtain a range of iterators for a pointer, use:
lower_bound(ionDistance, ionDistance + n, simPos[i]);
Here n is the number of elements in your ionDistance array. I don't understand your code enough to suggest it's equal to maxSamples; if it's not, add a parameter to your function:
float sampledEnergies ( float ionDistance[], float ionEnergy[], size_t numIons)
{
lower_bound(ionDistance,ionDistance + numIons, simPos[i]);
}

Changing R code to Rcpp code

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.