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
Related
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 made a prim's algorithm but whenever i try to use the code it give me the same matrix back. In general it isn't minimizing. Can anyone check the code and let me know why it isn't minimizing my matrix
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <list>
#include <cstdlib>
#include <iomanip>
#include <limits.h>
int minKey(int n,int key[], bool mst[])
{
// Initialize min value
int min = INT_MAX, min_index;
for (int i = 0; i < n; i++)
if (mst[i] == false && key[i] < min)
min = key[i], min_index = i;
return min_index;
}
void print(int n,int **matrix)
{
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++) // print the matrix
{
cout << setw(2) << matrix[i][j] << " ";
}
cout << endl;
}
}
int **gen_random_graph(int n)
{
srand(time(0));
int **adj_matrix = new int*[n];
for(int i = 0; i < n; i++)
{
for (int j = i; j < n; j++) //generating a N x N matrix based on the # of vertex input
{
adj_matrix[i] = new int[n];
}
}
for(int u = 0; u < n; u++)
{
for (int v = u; v < n; v++) //decide whether it has an edge or not
{
bool edgeOrNot = rand() % 2;
adj_matrix[u][v] = adj_matrix[v][u] = edgeOrNot;
cout << u << " " << v << " " << adj_matrix[u][v] << endl;
if(adj_matrix[u][v] == true)
{
adj_matrix[v][u] = true;
if(u == v) //We can't have i = j in an undirected graph
{
adj_matrix[u][v] = -1;
}
cout << u << " " << v << " " << adj_matrix[u][v] << endl;
}
else
{
adj_matrix[v][u] = adj_matrix[u][v] = -1;
cout << u << " " << v << " " << adj_matrix[u][v] << "else" << endl;
}
}
}
for(int i = 0; i < n; i++)
{
for(int j = i; j < n; j++) //create the N x N with edges and sets the weight between the edge randomly
{
if(adj_matrix[i][j] == true)
{
int weight = rand() % 10 + 1;
adj_matrix[i][j] = adj_matrix[j][i] = weight;
cout << " ( " << i << "," << j << " ) " << "weight: " << adj_matrix[i][j] << endl;
}
}
}
print(n,adj_matrix);
return (adj_matrix);
}
void solve_mst_prim_matrix(int n, int **matrix)
{
int parent[n]; // Array to store constructed MST
int key[n]; // Key values used to pick minimum weight edge in cut
bool mstSet[n]; // To represent set of vertices not yet included in MST
// Initialize all keys as INFINITE
for (int i = 0; i < n; i++)
{
key[i] = INT_MAX, mstSet[i] = false;
}
// Always include first 1st vertex in MST.
key[0] = 0; // Make key 0 so that this vertex is picked as first vertex
parent[0] = -1; // First node is always root of MST
// The MST will have n vertices
for (int count = 0; count < n-1; count++)
{
// Pick the minimum key vertex from the set of vertices
// not yet included in MST
int u = minKey(n,key, mstSet);
// Add the picked vertex to the MST Set
mstSet[u] = true;
// Update key value and parent index of the adjacent vertices of
// the picked vertex. Consider only those vertices which are not yet
// included in MST
for (int v = 0; v < n; v++)
// matrix[u][v] is non zero only for adjacent vertices of m
// mstSet[v] is false for vertices not yet included in MST
// Update the key only if matrix[u][v] is smaller than key[v]
if (matrix[u][v] && mstSet[v] == false && matrix[u][v] < key[v])
parent[v] = u, key[v] = matrix[u][v];
}
cout << endl;
print(n,matrix);
}
int main()
{
int N;
cout << "Enter number of vertices" << endl;
cin >> N;
int **matrix = gen_random_graph(N);
solve_mst_prim_matrix(N, matrix);
return 0;
}
Correct me if I'm wrong, but after reading your code, you did not even change any value of **matrix in your solve_mst_prim_matrix function. So it basically prints the same thing..
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.
#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.
I have a vector of TrainingSets(struct below) called data
class TrainingSet
{
public:
int time;
float input[2];
float output[3*NUM_TRACKING_POINTS];
TrainingSet(int t, float in[2], float out[3*NUM_TRACKING_POINTS])
{
time = t;
for (int i = 0; i < 2; i++)
input[i] = in[i];
for (int i = 0; i < 3*NUM_TRACKING_POINTS; i++)
output[i] = out[i];
}
TrainingSet()
{
}
};
And then I try to take the contents of this Vector, and put them into CvMats for the purpose of training a Neural Network.
int datasize = data.size();
float** in = new float*[datasize];
float** out = new float*[datasize];
for (int i = 0; i < datasize; i++) {
in[i] = new float[2*TIME_STEPS];
out[i] = new float[3*NUM_TRACKING_POINTS];
}
for ( int i = 0 ; i < datasize; i ++)
{
// get the first set in the sequence.
TrainingSet tset = data.front();
data.pop();
// get the inputs
in[i] = new float[2*TIME_STEPS];
in[i][0] = tset.input[0];
in[i][1] = tset.input[1];
// get the outputs
out[i] = new float[3*NUM_TRACKING_POINTS];
for (int j = 0; j < 3*NUM_TRACKING_POINTS; j++)
out[i][j] = tset.output[j];
for (int j = 2; j < 2*TIME_STEPS; j++)
{
if (i == 0)
in[i][j] = 0.0f;
else
in[i][j] = in[i - 1][j - 2];
}
}
// make matrices from data.
CvMat *trainInput = cvCreateMat(datasize, 2*TIME_STEPS, CV_32FC1);
cvInitMatHeader(trainInput, datasize, 2*TIME_STEPS, CV_32FC1, in);
CvMat *trainOutput = cvCreateMat(datasize, 3*NUM_TRACKING_POINTS, CV_32FC1);
cvInitMatHeader(trainOutput, datasize, 3*NUM_TRACKING_POINTS, CV_32FC1, out);
for (int x = 0; x < datasize; x++)
{
cout << "IN: ";
for (int y = 0; y < 2*TIME_STEPS; y++)
cout << cvmGet(trainInput, x, y) << " ";
cout << endl << "IN: ";
for (int y = 0; y < 2*TIME_STEPS; y++)
cout << in[x][y] << " ";
cout << endl << "OUT: ";
for (int y = 0; y < 3 * NUM_TRACKING_POINTS; y++)
cout << cvmGet(trainOutput, x, y) << " ";
cout << endl << "OUT: ";
for (int y = 0; y < 3 * NUM_TRACKING_POINTS; y++)
cout << out[x][y] << " ";
cout << endl << endl;
}
That last forloop is to check to see if the matrices contents are the data I just fed it, but they don't match. The Matrices seem to have completely different data.
Any thoughts on what is going wrong?
Seems to me that in and out are not a contiguous array, but an array of pointers.
I think the cvMat needs a contiguous memory array to be able to operate on it.
Also once you create the array, you don't need to create a CvMat from it, just
use the
CvSetData( header, data ).