This question already has an answer here:
Assigning Rcpp objects into an Rcpp List yields duplicates of the last element
(1 answer)
Closed 4 years ago.
I want to create a list of matrices that I am updating in a loop and return it to R. I have
std::vector<IntegerMatrix> zb_list;
and
IntegerMatrix tb(J,nmax), zb(J,nmax);
before the loop. Inside the loop, I update zb and then have
zb_list.push_back(zb);
I also have
Rcout << (zb_list[itr]) << "\n";
Rcout << (zb) << "\n\n";
where itr counts the iterations. These both confirm that zb is changing inside the loop and zb_list keeps track of it.
Then I return zb_list after the loop. When accessing the result in R, the list contains copies of the same zb, the last one computed in the loop. I suspect there is some pass by reference going on... but can't figure it out. I don't have a good understanding of what is going on (tried to use return(wrap(zb_list))without luck) but clearly something is wrong. Also used List zb_list; for defining it which doesn't help. Any suggestions?
EDiT: Here is the minimal working example:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List test_weird(int ITRmax=2) {
IntegerMatrix zb(2,2);
std::vector<IntegerMatrix> zb_list;
int itr = 0;
while (itr < ITRmax) {
zb( (1+itr)%2 ,(1+itr)%2 ) ++ ;
zb_list.push_back(zb);
Rcout << (zb) << (zb_list[itr]) << "\n\n";
++itr;
}
return List::create(_["zb"] = zb,
_["zb_list"] = zb_list);
}
/*** R
res <- test_weird()
res$zb_list
*/
This the output when the look is running:
0 0
0 1
0 0
0 1
1 0
0 1
1 0
0 1
... and this is the output from R:
> res$zb_list
[[1]]
[,1] [,2]
[1,] 1 0
[2,] 0 1
[[2]]
[,1] [,2]
[1,] 1 0
[2,] 0 1
As you can see both items in the list are the last zb in the loop.
The problem is that push_back(something) makes a copy of something. But if something is a pointer, than subsequent changes will effect all copies of that pointer. In plain C++:
#include <vector>
#include <iostream>
int main() {
std::vector<int*> v;
int* p = new int;
for (int i = 0; i < 2; ++i) {
*p = i;
v.push_back(p);
std::cout << *p << " " << *v[i] << std::endl;
}
std::cout << *v[0] << " " << *v[1] << std::endl;
return 0;
}
produces
$ ./pointer_fun
0 0
1 1
1 1
So if the something is a pointer (like object), which is the case for all Rcpp objects, then you need a deep copy/clone of the object, i.e.
zb_list.push_back(clone(zb));
Related
My pointer array doesn't store my data correctly. I created a file that stored 10 integers, and it only stored the 10th and prints it out 10 times.
Any help would be appreciated, and I apologize if formatting is incorrect as this is my first time using this site.
void displayPointer(vector<int*>& ptrvect) {
for (int i = 0; i <= ptrvect.size() - 1; i++) {
cout << setw(6) << *ptrvect[i];
}
}
void displayArray(vector<int>& vect) {
for (int i = 0; i <= vect.size() - 1; i++) {
cout << setw(6) << vect[i];
}
}
int main(){
ifstream myfile("arrayData.txt");
int values;
vector<int> vect;
vector<int*> ptrvect;
while (myfile >> values) {
ptrvect.push_back(&values);
vect.push_back(values);
}
displayArray(vect);
cout << endl;
displayPointer(ptrvect);
}
The purpose of my code is to sort a pointer vector and leave my original vector untouched, but I realized my pointer vector only has one unique integer from my list before the sorting even occurs.
Ex: arrayData.txt values are 1 3 9 4 8 2 10 48 3 21 and only 21 is printed 10 times when my displayPointer function is called.
I found a strange behavior of C ternary operator (?:).
In the following code, the expected values of both b and c should be 0, but b is -2.
I checked the C operator precedence, and made sure minus(-) is higher than greater than or equal to (>=), which is higher than the conditional operator (?:). Could anyone kindly explain why the values of b and c are different?
#include <iostream>
#include <vector>
using std::vector;
using std::cout;
using std::endl;
int main() {
int i;
vector<int> a;
for (i = 0; i < 29; ++i)
a.push_back(i);
int b = 27 - a.size() >= 0 ? 27 - a.size() : 0;
int c = 27 - 29 >=0 ? 27 - 29 : 0;
cout << b << endl;
cout << c << endl;
return 0;
}
After looking on the document page of vector, the return type of method size() is size_t which is equal to an unsigned long long.
So, when you do 27 - a.size() this will cause overflow, making the result of the 27 - a.size() >= 0 operator be True. It got nothing to do with C operator precedence.
To prove that, you can do:
#include <iostream>
using std::cout;
using std::endl;
int main() {
unsigned long long tmp = 29;
cout << 27 - tmp << endl; //(this will be a super large integer.)
return 0;
}
Solution:
The solution is simple, you can simply add a typecasting (int) before a.size() in the condition of the ternary operator.
It can be looks like this:
int b = 27 - (int) a.size() >= 0 ? 27 - a.size() : 0;
I have been trying to solve a problem from coursera.
Problem description: Given an undirected graph with 𝑛 vertices and 𝑚 edges, check whether it is bipartite.
Input Format. A graph is given in the standard format.
Constraints. 1 ≤ 𝑛 ≤ 105, 0 ≤ 𝑚 ≤ 105.
Output Format. Output 1 if the graph is bipartite and 0 otherwise.
Input:
4 4
1 2
4 1
2 3
3 1
Output:
0
Input:
5 4
5 2
4 2
3 4
1 4
Output:
1
I came up with a solution in c++ that looks like
#include <bits/stdc++.h>
using namespace std;
#define vvi vector<vector<int>>
#define vi vector<int>
#define qi queue<int>
int bfs(vvi adj, int s, vi &disc, vi &dist)
{
disc[s] = 1; dist[s] = 0;
qi q;
q.push(s);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i: adj[u])
{
if(!disc[i])
{
disc[i] = 1;
q.push(i);
dist[i] = dist[u]+1;
}else if(dist[u]==dist[i])
{
return 0;
}
}
}
return 1;
}
bool isBipartite(vvi adj, vi &disc, vi &dist)
{
for(int i=0;i<adj.size();++i)
{
if(!disc[i])
{
if(!bfs(adj, i, disc, dist))
{
return 0;
}
}
}
return 1;
}
int main()
{
int n, m;
cin >> n >> m;
vvi adj(n);
for(int i=0;i<m;++i)
{
int x, y;
cin >> x >> y;
adj[x-1].push_back(y-1);
adj[y-1].push_back(x-1);
}
vi dist(n);
vi disc(n, 0);
cout << isBipartite(adj, disc, dist);
}
But this solution is generating wrong answer on test case 3. Can anyone figure out what I have missed in that code?
Thanks in advance. ♥
Your logic seems flawless, there is a possible cause of error: you don't pass adj parameter as a reference. This mean that for every call of bfs method the graph will be copied. If 3rd test case is an isolated graph (no edges) that would be bad. Sometimes runtime error and memory exceeded error are treated by the online judge as a non existent wrong answer.
I have an Eigen Vector. I would want to cat it recursively. For example
Eigen::Vector3d vec;
vec << 5, 6, 7;
Eigen::VectorXd vecCat;
for(int i=0;i<3;i++)
vecCat << vec(i),0,0;
cout<<vecCat<<endl;
so that the final output would be
vecCat= 5 0 0 6 0 0 7 0 0
I am getting an error if I do the above way. Can anyone help me?
As I said in the comment, I will not explain how one could use the CommaInitializer iteratively. But here is a solution using Eigen::Map:
Eigen::Vector3d vec;
vec << 5,6,7;
Eigen::VectorXd vecCat = Eigen::VectorXd::Zero(9); // result vector
{
// map vector to 3x3 matrix:
Eigen::Map<Eigen::MatrixXd> map(vecCat.data(), 3,3);
map.row(0) = vec.transpose(); // set top elements to elements of vec
}
std::cout << vecCat.transpose() << '\n';
If row(0) is everything you need to modify in map you can alternatively (instead of the { } block) write:
Eigen::MatrixXd::Map(vecCat.data(), 3, 3).row(0) = vec.transpose();
I am looking for a good way to round an int in Qt to the nearest 5.
e.g:
8 -> 10
12 -> 10
13 -> 15
15 -> 15
17 -> 15
and so on
Rounding in C++ to the nearest integer number usually is done via:
static_cast<int>(number + 0.5);
Now, to round it to the next 5, I would bring it into the system where we can apply this rounding rule (i.e. 5 -> 1, 6 -> 1.2) and then bring it back into the system where 5 really is 5:
int roundToNearestFive(int number)
{
return static_cast<int>(number / 5. + .5) * 5;
}
I find this formulation easiest.
Here a possible solution:
#include<iostream>
int toNearest5(int i) {
int r = i%5, o = 0;
if(r) {
o = r/5. >= .5 ? 5 : 0;
}
return (i-r+o);
}
int main() {
using namespace std;
cout << toNearest5(8) << endl;
cout << toNearest5(12) << endl;
cout << toNearest5(13) << endl;
cout << toNearest5(15) << endl;
cout << toNearest5(17) << endl;
}
The idea is to get the number and round it to the lowest multiple of 5 (you can do that by removing the remainder), that is:
int remainder = i%5;
int rounded = i - remainder;
Now, you can check the remainder and add 5 to the rounded number if the remainder is greater than 2.5, otherwise add 0.
In order to check it, I've divided the remainder by 5 (its upper bound), so that to get a number in [0,1[ and check it with 0.5 to know how to round the original number.
It follows a more compact version of the same function:
int toNearest5(int i) {
int j = i%5;
return (i - j + (j/5. >= .5 ? 5 : 0));
}
I don't know if the Qt framework offers something similar out of the box, but it's a matter of an one line function, you can easily write it for yourself.