How do I print integer vector from Rcpp function? In my function, I would like to print IntegerVector a. In R I am calling this function using for example compnz_next(5,3,c(1,2,2))
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerVector compnz_next(int n, int k, IntegerVector a) {
bool more = true;
int i;
static int h = 0;
static int t = 0;
for ( i = 0; i < k; i++ ) {
a[i] = a[i] - 1;
}
if ( 1 < t ) {
h = 0;
}
h = h + 1;
t = a[h-1];
a[h-1] = 0;
a[0] = t - 1;
a[h] = a[h] + 1;
more = ( a[k-1] != ( n - k ) );
Rcout << "a vector is:" << more << std::endl;
for ( i = 0; i < k; i++ ) {
a[i] = a[i] + 1;
}
return a;
}
Try the following line:
Rf_PrintValue(a);
For completeness, and a while later, we now have two more options:
R> library(Rcpp)
R> cppFunction('void printVector(IntegerVector v) { print(v); } ')
R> printVector(c(1L, 3L, 5L))
[1] 1 3 5
This just wraps the Rf_PrintValue() function from R into an easier to type print() function.
R> cppFunction('void printVector2(IntegerVector v) {
+ Rcpp::Rcout << v << std::endl; } ')
R> printVector2(c(1L, 3L, 5L))
1 3 5
R>
The (newer) function is implemented via a proper operator()<< so that we can just use << as with other C++ types. It also work for numeric vectors and matrices.
Related
I'm testing a piece of my code, which is shown below:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericMatrix testOutMat(const int& ncols, const int& nrows, const NumericVector& col_prob){
//Store row and column positions
NumericVector col_pos = no_init(nrows);
NumericVector row_pos = no_init(nrows);
int row_val;
int nz_counter=0;
for(int j=0; j<ncols; ++j){
for(int i=0; i<nrows; ++i){
row_val = R::rbinom(1,col_prob[j]);
Rcout << "i,j: " << i << "," << j << std::endl;
Rcout << "val: " << row_val << std::endl;
if(row_val==1){ //if (i,j)th entry is a 1, save location
row_pos[i] = i;
col_pos[i] = j;
nz_counter += 1;
} else{ //assign as NA
row_pos[i] = NA_REAL;
col_pos[i] = NA_REAL;
}
Rcout << "row_pos[i]: " << row_pos[i] << std::endl;
Rcout << "col_pos[i]: " << col_pos[i] << std::endl;
Rcout << "num non-zeros: " << nz_counter << std::endl;
}
}
NumericMatrix out = no_init(nz_counter,2);
Rcout << "Printing output matrix" << std::endl;
for(int i=0; i<nz_counter; ++i){
if(!Rcpp::NumericVector::is_na(row_pos[i])){
out(i,0) = row_pos[i];
out(i,1) = col_pos[i];
}
Rcout << "row_pos[i]: " << row_pos[i] << std::endl;
Rcout << "col_pos[i]: " << col_pos[i] << std::endl;
}
return out;
}
/*** R
set.seed(1)
res <- testOutMat(ncols=5,nrows=5,col_prob = runif(20, 0.1, 0.2))
*/
From the output, I have that the entries (i,j)={(0,0),(3,1)} are non-zero, so that res should be a 2x2 matrix with 0 0 in the first row and 3 1 in the second. However, I get something very different:
[,1] [,2]
[1,] 64 1024
[2,] 1 4
I suspect that this is due to how I'm handling NAs. The overall goal of the function is to generate the row and column indices for non-zero elements (generated by the call to rbinom).
I've tried debugging this for some time now and I can't seem to get a fix.
The problem here is that you're writing over row_pos and col_pos over and over again (ncols times) without any kind of keeping track of the prior result. That, coupled with your no_init() use, is what's causing the end result you see. We can change your code just a bit to ensure that row_pos and col_pos don't get overwritten:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
IntegerMatrix testOutMat(const int ncols, const int nrows,
const NumericVector& col_prob) {
IntegerMatrix binomial_deviates(nrows, ncols);
IntegerVector row_positions;
IntegerVector col_positions;
int nz_counter = 0;
for ( int j = 0; j < ncols; ++j ) {
binomial_deviates(_, j) = rbinom(nrows, 1, col_prob[j]);
for ( int i = 0; i < nrows; ++i ) {
if ( binomial_deviates(i, j) == 1 ) {
row_positions.push_back(i);
col_positions.push_back(j);
nz_counter += 1;
}
}
}
IntegerMatrix out(nz_counter, 2);
for ( int i = 0; i < nz_counter; ++i ) {
out(i, 0) = row_positions[i];
out(i, 1) = col_positions[i];
}
return out;
}
/*** R
set.seed(1)
res <- testOutMat(ncols=5,nrows=5,col_prob = runif(20, 0.1, 0.2))
*/
Result:
> set.seed(1)
> res <- testOutMat(ncols=5,nrows=5,col_prob = runif(20, 0.1, 0.2))
> res
[,1] [,2]
[1,] 0 0
[2,] 3 1
I am trying to get some results by using Rcpp and this is the code.
#include <Rcpp.h>
#include <math.h>
using namespace Rcpp;
enter code here
// [[Rcpp::export]]
double compssr(NumericMatrix dist, NumericVector x, int n, int p) {
double ssr = 0; double del_sq = 0; double del_ij = 0;
int i, j, ip;
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++) {
for (ip = 0; ip < p; ip++) {
del_sq = del_sq + (x(i, ip) - x(j, ip))*(x(i, ip) - x(j, ip));
if (i == j) del_sq = 0;
}
del_ij = sqrt(del_sq);
ssr = ssr + (dist(i, j) - del_ij)*(dist(i, j) - del_ij);
}}
return ssr;
}
NumericMatrix Scaling_X(NumericVector xbar, NumericMatrix x, double n, double p) {
NumericMatrix Sig_x(p, p);
int i, ii, ip, ip2;
for (ii = 0; ii < n; ii++) {
for (i = 0; i < p; i++) {
x(ii, i) = x(ii, i) - xbar(i);
}}
for (i = 0; i < n; i++) {
for (ip = 0; ip < p; ip++) {
for (ip2 = 0; ip2 < p; ip2++) {
Sig_x(ip, ip2) = Sig_x(ip, ip2) + x(i, ip)*x(i, ip2);
}}}
for (i = 0; i < Sig_x.ncol(); i++) {
for (ii = 0; ii < Sig_x.nrow(); ii++) {
Sig_x(i, ii) = Sig_x(i, ii) / n;
}}
return Sig_x;
}
In fact there are some more functions and the file name of this code is "test.cpp"
And I called this file in R by using
sourceCpp("test.cpp")
There was no error and I could use the function "compssr" the first function(return type: double)
But I couldn't call the function Scaling_X
Is there any error in my code?
I made other functions and I could use the function with return type double, but I couldn't use others(NumericMatrix, NumericVector, List)
You are missing the
// [[Rcpp::export]]
in front of function Scaling_X so the compileAttributes() function does as it has been told: compile both functions, make just one available.
I am trying to generate a random binary matrix and its inverse mod q where q is a power of 2. Sometimes when the determinant of my matrix is invertible modulo q (so the matrix over Z_q is invertible), I am getting the error "InvMod:inverse undefined Aborted (core dumped)" and other times the inverse is computed. What am I doing incorrectly?
#include <iostream>
//NTL files
#include <NTL/ZZ_p.h>
#include <NTL/vec_vec_ZZ_p.h>
#include <NTL/LLL.h>
#include <NTL/matrix.h>
#include <NTL/vector.h>
#include <NTL/tools.h>
#include <NTL/ZZ.h>
#include <NTL/vec_vec_ZZ.h>
using namespace std;
using namespace NTL;
int main(){//task generate a random matrix S with 0/1 entries stored as a ZZ_p matrix, then generate a random, invertible S
int nn = 8;
ZZ n = ZZ(nn);
ZZ N = ZZ(0);
ZZ q; power2(q, 4);
ZZ_p::init(q);
mat_ZZ S; S.SetDims(nn,nn);
for(int i = 0; i<nn; i++){
for(int j = 0; j<nn; j++){
S[i][j] = RandomBits_ZZ(1);
}
}
mat_ZZ_p S1; S1.SetDims(nn,nn);//copy to ZZ_P
mat_ZZ_p R; R.SetDims(nn,nn);//will set to inverse if
cout<<"The random matrix is S = "<<endl; //print S
for(int i = 0; i<nn; i++){
for(int j=0; j<n;j++){
cout<<S[i][j]<<", ";
} cout<<endl;
}
ZZ d; determinant(d,S); ZZ_p d1; conv(d1, d % q);
if(GCD(q,d) == 1){//convert to mod q datatype
for(int i = 0; i<nn; i++){
for(int j = 0; j<nn; j++){
conv(S1[i][j], S[i][j]);
}
}
//let's invert the matrix and print it!
cout<<"The random matrix is R = "<<endl; //print R
R = inv(S1); //mul(R,R,S1);
for(int i = 0; i<nn; i++){
for(int j=0; j<n;j++){
cout<<R[i][j]<<", ";
} cout<<endl;
}
}
cout<<endl<<"det of S is "<<d<<" and this mod q is "<<d1<<endl;
cout<<"Our modulus is "<< q <<endl;
return 0;
}
If the determinant is invertable mod q this only means that there exists an inverse matrix. But the algorithm that computes this matrix can still come to a point where it would need to calculate the inverse of an element that don't has one.
You don't have this problem if q is prime.
By the way, here is a simplified version of your code.
#include <iostream>
//NTL files
#include <NTL/mat_ZZ_p.h>
using namespace std;
using namespace NTL;
int main()
{//task generate a random matrix S with 0/1 entries stored as a ZZ_p matrix, then generate a random, invertible S
int nn = 8;
ZZ q;
power2(q, 4);
ZZ_p::init(q);
mat_ZZ_p S;
S.SetDims(nn, nn);
for(int i = 0; i < nn; i++)
{
for(int j = 0; j < nn; j++)
{
S[i][j] = conv<ZZ_p>(RandomBits_ZZ(1));
}
}
mat_ZZ_p R;
R.SetDims(nn, nn);//will set to inverse if
cout << "The random matrix is S = " << endl << S;
ZZ_p d;
determinant(d, S);
cout << endl << "det(S) = " << d << endl;
cout << "q = " << q << endl;
if(GCD(conv<ZZ>(d), q) == 1)
{
// let's invert the matrix and print it!
R = inv(S);
cout << "The random matrix is R = " << R << endl;
}
return 0;
}
I am trying to index a matrix with names. The usual method gives errors:
NumericMatrix mytest(NumericVector v) {
NumericMatrix ans(v.length(), v.length());
rownames(ans) = v;
float y = ans("1",0);
NumericVector x = ans.row("1");
return (ans);
}
I looked over in Matrix.h and the matrix unit tests in rcpp and couldn't find a similar example. Also this mailing list question didn't provide a method to do it.
Can I write my own code to index the matrix, perhaps using R's internal C interface?
This is by no means a robust solution, but hopefully a jumping off point for you, where operator() is overloaded to handle different combinations of int and string passed as row & column indices:
#include <Rcpp.h>
// [[Rcpp::plugins(cpp11)]]
class MyMat : public Rcpp::NumericMatrix {
public:
MyMat(const Rcpp::NumericMatrix& data_,
const std::vector<std::string>& rnames_,
const std::vector<std::string>& cnames_)
: data(data_),
rnames(rnames_),
cnames(cnames_) {}
double operator()(const std::string& i, const std::string& j) {
typedef std::vector<std::string>::const_iterator cit;
cit it_i = std::find(rnames.begin(), rnames.end(), i);
cit it_j = std::find(cnames.begin(), cnames.end(), j);
int idx_i, idx_j;
if (it_i != rnames.end() ) {
idx_i = it_i - rnames.begin();
} else {
idx_i = rnames.size();
}
if (it_j != cnames.end() ) {
idx_j = it_j - cnames.begin();
} else {
idx_j = cnames.size();
}
return data(idx_i, idx_j);
}
double operator()(const std::string& i, const size_t j) {
typedef std::vector<std::string>::const_iterator cit;
cit it_i = std::find(rnames.begin(), rnames.end(), i);
int idx_i, idx_j;
if (it_i != rnames.end() ) {
idx_i = it_i - rnames.begin();
} else {
idx_i = rnames.size();
}
if (j <= cnames.size() ) {
idx_j = j;
} else {
idx_j = cnames.size();
}
return data(idx_i, idx_j);
}
double operator()(const size_t i, const std::string& j) {
typedef std::vector<std::string>::const_iterator cit;
cit it_j = std::find(cnames.begin(), cnames.end(), j);
int idx_i, idx_j;
if (i <= rnames.size() ) {
idx_i = i;
} else {
idx_i = rnames.size();
}
if (it_j != cnames.end() ) {
idx_j = it_j - cnames.begin();
} else {
idx_j = cnames.size();
}
return data(idx_i, idx_j);
}
double operator()(const int& i, const int& j) {
return data(i, j);
}
private:
Rcpp::NumericMatrix data;
std::vector<std::string> rnames;
std::vector<std::string> cnames;
};
// [[Rcpp::export]]
void test_MyMat(Rcpp::NumericMatrix m)
{
std::vector<std::string> rnames = { "a", "b", "c" };
std::vector<std::string> cnames = { "A", "B", "C" };
MyMat mmObj(m,rnames,cnames);
Rcpp::Rcout << "(Row 1, Column 1)" <<
std::endl;
Rcpp::Rcout << "(b,B) = " << mmObj("b","B") <<
std::endl << "(b,1) = " << mmObj("b",1) <<
std::endl << "(1,B) = " << mmObj(1,"B") <<
std::endl << "(1,1) = " << mmObj(1,1) <<
std::endl;
}
/*** R
x <- matrix(1:9,nrow=3)
test_MyMat(x)
#(Row 1, Column 1)
#(b,B) = 5
#(b,1) = 5
#(1,B) = 5
#(1,1) = 5
x[2,2]
#[1] 5
*/
We only support numeric (row) indices.
You could add a "names" attribute and look up the index in that, and/or add your own accessor methods.
#include <iostream>
#include <vector>
int main()
{
std::vector<std::vector<double> > DV; //2d vector
std::vector<double>temp(8,0.0); //1d vector
temp[0] = 1;
temp[1] = 2;
temp[2] = 3;
temp[3] = 4;
temp[4] = 5;
temp[5] = 6;
temp[6] = 7;
temp[7] = 8;
DV.resize(3, temp);
for (int i = 0; i < DV.size(); i++)
{
for (int j = 0; j < DV.size(); j++)
{
std::cout << DV[i][j];
}
}
std::cin.get();
}
The convertion actually works but it does not give the expected the result. The output should be:
1 2 3
4 5 6
7 8
and it outputs:
123123123
Thanks in advance
I'm not aware of a method to automagically turn a 1D vector into a 2D one. It's not too hard to do manually, though...
typedef std::vector<std::vector<double>> DoubleVector2D;
DoubleVector2D boxed(size_t cols, std::vector<double> values) {
DoubleVector2D result;
for (std::size_t i = 0; i < values.size(); ++i) {
if (i % cols == 0) result.resize(result.size() + 1);
result[i / cols].push_back(values[i]);
}
return result;
}
With that done, you can call boxed(3, temp) to get back a vector of vectors of doubles. At that point, you just have to loop over them.
for (auto row : DV) {
for (auto value : row) {
std::cout << value << ' ';
}
std::cout << "\n";
}
If you're stuck without decent C++11 support, you may need to use counters or iterators.
for (int row = 0; row < DV.size(); ++row) {
for (int col = 0; col < DV[i].size(); ++col) {
std::cout << DV[row][col] << ' ';
}
std::cout << '\n';
}
Change this lines
for (int i = 0; i < DV.size(); i++){
for (int j = 0; j < DV.size(); j++){
std::cout << DV[i][j] << ", ";
}
std::cout << std::endl;
}
Your issue is how you are printing your values to the standard output.