Different behaviour each time I try to create a sparse matrix - c++

I am trying to create a sparse matrix from Triplets. Somehow the program below is either printing a matrix containing only zeros or I get
^[[Bterminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc Aborted.
When I add the code at the buttom which is commented out, it starts to work sometimes and sometimes I get again only zeros.
I don't understand this behavior. It seems to be memory related but why should printing out stuff (after commenting in the bottom code) change what happens to the top?
Is there something wrong with my approach? Or is there maybe something wrong with my setup? I just downloaded the latest stable release from http://eigen.tuxfamily.org.
#include <iostream>
#include <Eigen/SparseCore>
#include <Eigen/Dense>
int main()
{
int n = 10;
std::vector<Eigen::Triplet<double> > ijv;
for(int i; i < n; i++)
{
ijv.push_back(Eigen::Triplet<double>(i,i,1));
if(i < n-1)
{
ijv.push_back(Eigen::Triplet<double>(i+1,i,-0.9));
}
}
Eigen::SparseMatrix<double> X(n,n);
X.setFromTriplets(ijv.begin(), ijv.end());
std::cout << Eigen::MatrixXd(X) << std::endl;
/* std::cout << "Row\tCol\tVal" <<std::endl;
for (int k=0; k < X.outerSize(); ++k)
{
for (Eigen::SparseMatrix<double>::InnerIterator it(X,k); it; ++it)
{
std::cout << it.row() << "\t"; // row index
std::cout << it.col() << "\t"; // col index (here it is equal to k)
std::cout << it.value() << std::endl;
}
}
*/
}

Related

threaded for loop reaching values it's not supposed to reach

I'm messing around with multithreading in c++ and here is my code:
#include <iostream>
#include <vector>
#include <string>
#include <thread>
void read(int i);
bool isThreadEnabled;
std::thread threads[100];
int main()
{
isThreadEnabled = true; // I change this to compare the threaded vs non threaded method
if (isThreadEnabled)
{
for (int i = 0;i < 100;i++) //this for loop is what I'm confused about
{
threads[i] = std::thread(read,i);
}
for (int i = 0; i < 100; i++)
{
threads[i].join();
}
}
else
{
for (int i = 0; i < 100; i++)
{
read(i);
}
}
}
void read(int i)
{
int w = 0;
while (true) // wasting cpu cycles to actually see the difference between the threaded and non threaded
{
++w;
if (w == 100000000) break;
}
std::cout << i << std::endl;
}
in the for loop that uses threads the console prints values in a random order ex(5,40,26...) which is expected and totally fine since threads don't run in the same order as they were initiated...
but what confuses me is that the values printed are sometimes more than the maximum value that int i can reach (which is 100), values like 8000,2032,274... are also printed to the console even though i will never reach that number, I don't understand why ?
This line:
std::cout << i << std::endl;
is actually equivalent to
std::cout << i;
std::cout << std::endl;
And thus while thread safe (meaning there's no undefined behaviour), the order of execution is undefined. Given two threads the following execution is possible:
T20: std::cout << 20
T32: std::cout << 32
T20: std::cout << std::endl
T32: std::cout << std::endl
which results in 2032 in console (glued numbers) and an empty line.
The simplest (not necessarily the best) fix for that is to wrap this line with a shared mutex:
{
std::lock_guard lg { mutex };
std::cout << i << std::endl;
}
(the brackets for a separate scope are not needed if the std::cout << i << std::endl; is the last line in the function)

C++ code - problems with сode execution time

there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}

Double vector hides variables

I'm having an interesting problem when I'm accessing a double vector. The idea is that I have deleted all information prior to accessing the vector. A for loop tries to access the vector and successful says that the vector is empty, but when I access the vector point directly it shows that there are variables still in the vector.
Also, the vector was set up like so:
vector<vector<string>> proTable;
Here is the loop attempting to access the vector.
for(int a = 0; a < proTable.size(); a++)
{
for(int b = 0; b < proTable[a].size(); b++)
{
cout << proTable[a][b] << "\t";
}
}
But if I edit the for loop this way it returns the variable inside.
for(int a = 0; a < proTable.size(); a++)
{
for(int b = 0; b < proTable[a].size(); b++)
{
cout << proTable[a][b] << "\t";
}
cout << proTable[0][0];
}
The first prints nothing out. The second prints X which was in the vector before. Also, the vector does not show that it is empty.
This is how I was deleting it if it matters.
void MRelation::RemoveColumn(vector<int> rem)
{
while(!rem.empty())
{
int z = rem[rem.size() - 1];
for(int a = 0; a < proTable.size(); a++)
{
for(int b = z; b < proTable[a].size() - 1; b++)
{
proTable[a][b] = proTable[a][b+1];
}
proTable[a].pop_back();
}
rem.pop_back();
}
}
The vector rem holds the columns that need to be deleted from the table.
I have deleted all information prior to accessing the vector.
Accessing an vector out of bounds has undefined behaviour. Since your vector is empty, proTable[0] is out of bounds. In the line cout << proTable[0][0];, you access proTable[0]. Therefore the behaviour of your program is undefined.
it shows that there are variables still in the vector.
You cannot jump to such conclusion from observing undefined behaviour.
"There are variables still in the vector" was not necessarily the reason why you saw output. You saw output because the behaviour was undefined.
I found out what it was. I you delete the contents of the inner vector but don't delete the vectors themselves then the vector will think that it contains something still and will pull out information that doesn't exist anymore. here is the code I was have problems with. It has been edited with an if statement to correct it.
void MRelation::FinalPrint()
{
if(curTable.size() < 2)
{
ss << "? No\n";
}
else
{
ss << "? Yes(" << curTable.size() - 1 << ")\n";
}
if(!proTable[0].empty()) //This was added in after to correct the problem
{
for(int c = 1; c < proTable.size(); c++)
{
ss << " " << proTable[0][0] << "=" << proTable[c][0];
for(int d = 1; d < proTable[0].size(); d++)
{
ss << ", ";
ss << proTable[0][d] << "=" << proTable[c][d];
}
ss << "\n";
}
}
}
Sorry about not putting everything in context before. I was trying to put in as much relavant information without putting in 300 lines of code.

A c++ program that stores the positions of each bit 1 in a binary sequence

I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!

3 dimensional vector in c++ - partial definition of size before passing to function

I would like to define a 3-dimensional vector of which the first two dimensions are fixed, but I'd want the third one to be dynamically filled by a function called inside a loop.
I am not completely sure whether this is allowed or not, but I have tried to implement it anyway with something like:
#define NUM 6
vector<vector<vector<double> > > foo;
foo.resize(NUM);
for(int j1=0; j1 < NUM; j1++){
foo[j1].resize(NUM);
}
while(<condition>){
fun(foo);
}
where I declare the function fun as
void fun(vector<vector<vector<double> > >& foo){
for(int j1=0; j1<NUM; j1++){
for(int j2=j1+1; j2<NUM; j2++){
if(<condition>){
foo[j1][j2].push_back(<value>);
}
}
}
}
I initially tested this for NUM equal to 5 and everything looked fine, but when I've tried to change it to 6, I've got a segmentation fault.
I have seen that even if I don't try to fill in the 3rd dimension with the push_back (i.e. I comment the push_back line), the simple call to the function which has foo as an argument messes up the dimension of foo, that is if I insert a
cout << foo.size() << endl;
in the while loop, I see that the dimension of foo changes after the first iteration, changing from NUM to a random number.
I've also found that this is platform dependent, as I'm getting the error on Linux Ubuntu, but not on MacOSX. So I guess I am doing something really wrong related to memory allocation, but I don't know exactly what. Could someone explain this to me?
Thank you for your help!
You can actually create a 3D matrix of a fixed number size with 2D matrices also of desired size using a vectors constructor that takes as an argument the number of elements and an element that it'll use to make copies of to fill in the vector. Here's how it'll look like:
#include <iostream>
#include <vector>
int main() {
const size_t NUM = 6;
std::vector< std::vector< std::vector<double> > > Matr(NUM, std::vector< std::vector<double> >(NUM, std::vector<double>()));
std::cout << "num 2D matrices - " << Matr.size() << std::endl;
for(size_t j1 = 0; j1 < Matr.size(); ++j1){
std::cout << "num rows - " << Matr[j1].size() << std::endl;
for(size_t j2 = 0; j2 < Matr[j1].size(); ++j2) {
Matr[j1][j2].push_back(0.09l);
std::cout << "num columns - " << Matr[j1][j2].size() << " ";
}
std::cout << std::endl;
}
return 0;
}
foo.resize(NUM);
for(int j1=0; j1 < NUM; j1++){
foo[j1].resize(NUM);
}
here you are resizing foo[j1], but there is nothing in foo[j1] yet..
so foo[j1] is just a garbage yet.