Segmentation fault trying to insert values into multidimensional vector - c++

I am not exactly sure what I am doing wrong in my current situation.
The goal of my program is to read in points from a text file and insert them into a grid, then find the shortest distance between the points. However, I am having an issue inserting the points into the grid.
I am supposed to use a multidimensional vector being vector<vector<vector>>, but when I try to insert values into my vector I get a segmentation fault.
Here is what I have:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
struct point
{
double x;
double y;
};
/*Implement the following function
Reads in a file specified by the parameter
Format of file: #of points on first line
remaining (#of points) lines: x-value and y-value of point
one point per line
x-value and y-value are double-precision values and
bounded by the unit square 0.0 <= x,y < 1.0
Should use "spatial hashing" where the #of cells scales with the #of points
and find the distance between the closest pair of points which will be
returned as a double type value
*/
double closestPair(string filename){
std::ifstream infile(filename);
int num_points;
double xval;
double yval;
double shortestDist=0;
//finds number to create size of grid
infile >> num_points;
int b=sqrt(num_points);
double interval=1/b;
//creates grid
vector<vector<vector<point>>> pointTable(b,vector<vector<point>>(b,vector<point>(b)));
while(!infile.eof()){
//reads in x and y value and creates point
point insertPoint;
infile >> xval;
infile >> xval;
insertPoint.x=xval;
insertPoint.y=yval;
//finds where to insert point on grid
int xposition=xval/interval;
int yposition=yval/interval;
//inserts point into grid
pointTable[xposition][yposition].push_back(insertPoint);
}
return shortestDist;
}
In the program, b is supposed to be the amount of 'cells' in the grid we are creating, and it is based off the number of points in the text file, which is read in as the first line of the file. The interval is the distance between each 'cell' since the grid is from 0 to 1, and all the point fit inside of this interval.
An example of a text file that would be read in:
100
0.7977055242431441 0.2842945682533633
0.5069721442290844 0.1745915333250858
0.1056128118010866 0.4655386965548695
0.9452178666802381 0.02164071576711531
0.5801569883701514 0.9551154884313102
0.6541671729612641 0.2084066195646328
0.4077641701397764 0.7837305268045455
0.2547332841431741 0.3687404245068159
0.7625239646028334 0.570257171363553
0.4345602227588827 0.4766713469354918
0.8758058217633901 0.8956599204363177
0.4540800728184122 0.7208285300197294
0.8711559280702514 0.536922895657251
0.1021534045581789 0.771878369218414
0.6185958613568046 0.7020603220891695
0.6981983771672291 0.9621315492131957
0.1865078541824229 0.3070515027607176
0.5637630711621611 0.2438510076494884
0.6491395060966105 0.5066660223152767
0.8585106264720312 0.1199023899047327
0.0600441072577686 0.6150461804657272
0.6988214913343326 0.7960891955643983
0.5097768855624988 0.4483496969949777
Where 100 points would be read in.
I haven't attempted to implement the distance finding part of the algorithm yet because I need to have the points inserted before I do that.
Any help is appreciated, thanks!

Related

Fast element-wise access in Eigen::SparseMatrix in Latent Dirichlet Allocation

I am implementing Latent Dirichlet Allocation (LDA) in Rcpp. In LDA, we need to deal with a huge sparse matrix (e.g. 50 x 3000).
I decided to use SparseMatrix in Eigen. However, since I need access to each cell, computationally expensive .coeffRef slows down my function a lot.
Is there any way to use SparseMatrix while keeping the speed?
What I want to do has four steps,
I know which cell (i,j) I want to access.
I want to know whether the cell (i,j) is 0 or not.
If the cell (i,j) is not 0, I want to know its value.
After doing some analysis with the value in step 2 and 3, I want to update the cell (i,j). In this step, I might need to update the cell (i,j) which originally has 0.
#include <iostream>
#include <Eigen/dense>
#include <Eigen/Sparse>
using namespace std;
using namespace Eigen;
typedef Eigen::Triplet<double> T;
int main(){
Eigen::SparseMatrix<double> spmat;
// Insert in spmat
vector<T> tripletList;
int value;
tripletList.push_back(T(0,1,1));
tripletList.push_back(T(0,3,2));
tripletList.push_back(T(1,5,3));
tripletList.push_back(T(2,4,4));
tripletList.push_back(T(4,1,5));
tripletList.push_back(T(4,5,6));
spmat.resize(5,7); // define size
spmat.setFromTriplets(tripletList.begin(), tripletList.end());
for(int i=0; i<5; i++){ // I am accessing all cells just to clarify I need to access cell
for(int j=0; j<7; j++){
// Check if (i,j) is 0
if(spmat.coeffRef(i,j) != 0){
// Some analysis
value = spmat.coeffRef(i,j)*2; // just an example, more complex in the model
}
spmat.coeffRef(i,j) += value; // update (i,j)
}
}
cout << spmat << endl;
return 0;
}
Since the number of rows is much smaller than the columns, I considered accessing a column and then check the row value, but I couldn't handle SparseMatrix<double>::InnerIterator it(spmat, colid).

How to compare and extract a closest number from two files in C++

I have a two .txt files. t1.txt contains two columns with coordinates. t2.txt contains three columns (coordinates and some value). I want to extract a third column from t2.txt for coordinates from t1.txt.
Right now my code is looking for the same number in both .txt files. Unfortunately, coordinates are not the same, and I have to find the closest coordinates. How to change my code? I tried to find some information, but I am a very beginner and nothing helps me.
My code:
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
double** alokujPamiec(int,int);
void deleteAlokujPamiec(double**&);
int main()
{
int liczba=0;
fstream plik1("t1.txt",ios::out | ios::in); // 2 columns
fstream plik2("t2.txt", ios::out | ios::in); //3 columns
ofstream plik5("wynik.txt");
plik5 << setprecision(5) << fixed; // precision
int p1=0,p2=0;
char buff[255];
if(plik1.is_open()){
while(plik1.getline(buff,255)){
p1++; // number of lines
}
}else cout <<"Error in opening file 1"<<endl;
if(plik2.is_open()){
while(plik2.getline(buff,255)){
p2++;
}
}else cout <<"Error in opening file 2"<<endl;
cout << "lines in t1.txt" << "\t" <<p1<<endl;
cout << "lines in t2.txt" << "\t" <<p2<<endl;
plik1.close();
plik2.close();
fstream plik3("t1.txt",ios::out | ios::in);
fstream plik4("t2.txt", ios::out | ios::in);
double** dane1 = alokujPamiec(p1, 2);
double** dane2 = alokujPamiec(p2, 3);
int h=1;
cout <<"Loading data...."<<endl;
if(plik4.is_open()){
for(int i=0;i<p2;i++)
{
for(int j=0;j<3;j++){
plik4>>dane2[i][j];
}
}
}else cout << "Error 4"<<endl;
if(plik3.is_open()){
for(int i=0;i<p1;i++)
{
for(int j=0;j<2;j++){
plik3>>dane1[i][j];
}
}
}else cout << "Error 3"<<endl;
cout <<"Comparison and writing... "<<endl;
for(int i=0;i<p1;i++)
{
for(int j=0;j<p2;j++)
{
if(dane1[i][0]==dane2[j][0] && dane1[i][1]==dane2[j][1])
{
plik5<<dane1[i][0]<<"\t"<<dane1[j][1]<<"\t"<<dane2[j][0]<<"\t"<<dane2[i][1]<<"\t"<<dane2[i][2]<<endl;
liczba++;
}
}
}
cout <<"Number of found objects"<<"\t"<<liczba<<endl;
plik3.close();
plik4.close();
plik5.close();
deleteAlokujPamiec(dane1);
deleteAlokujPamiec(dane2);
getchar();
return 0;
}
double ** alokujPamiec(int iloscWierszy, int iloscKolumn)
{
double** tab2d = new double*[iloscWierszy];
double* dumm = new double[iloscWierszy*iloscKolumn];
for ( int i = 0; i < iloscWierszy; i++ )
tab2d[i] = dumm + i*iloscKolumn;
return tab2d;
}
void deleteAlokujPamiec(double**& tab2d) {
delete [] tab2d[0];
delete [] tab2d;
tab2d = 0;
}
The right approach for solving a complicated problem is to break it down. Divide it into several smaller problems, and solve each one individually. When you've solved them all, you have your final result.
Start by defining what "closest" coordinate means. The answer is, of course, the Pythagorean theorem. Given two coordinates, (x1, y1) and (x2, y2), the distance between them is sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)). Your existing code already uses doubles for coordinates, so this will work out quite well, just by plugging in this formula into your code, directly.
So that solves the problem of what "closest" means. The smaller the number, the smaller is the result of the expression. If the result is 0, both coordinates are the same. If you have one coordinate, then a pair of other coordinates, the closest one of the pair is the one whose pythagorean distance is the numerically smaller one.
Next problem: you have one set of coordinates, (x1, y1). Now you have a entire list of other coordinates, that you loaded from another file. How do you find the coordinate from the other file that's closest to (x1, y1)? This now becomes a trivial, simple programming task with a classical solution: loop over each coordinate from the other file. Each coordinate from the other file becomes your (x2, y2). Plug it into the Pythagoren theorem to get the distance, and have your loop keep track of the closest coordinate, to date. The classical solution is to compute the distance to the first coordinate from the other file in advance. Get its distance, then loop over the remaining coordinates, calculating each one's distance, and saving it, and the coordinate, if the calculating distance is smaller, and replace the saved coordinate with this one. Trivial.
At the end of the loop you're left with the coordinate that was closest to (x1, y1). This is now a simple, trivial programming task to implement.
The final step for your solution is to simply do this for every coordinate from the first file. Again, this is now a trivial programming task of simply looping over each coordinate from the first file, and executing the above steps for each one of them; thusly finding each coordinate's closest coordinate from the other file.
Mission accomplished.
Don't rely on comparing doubles with an equal sign: What is the most effective way for float and double comparison?
Also, if(dane1[i][0]==dane2[j][0] & dane1[i][1]==dane2[j][1]) should have && and not &

How can I get the vertices of all cells in a container with Voro++ Library?

I try to implement a simple 3d voronoi application with Voro++. I have a container containing particles. After putting all the particles in the container, how can I get the vertices of all voronoicells computed by Voro++.
from the documentation it should be something like this:
http://math.lbl.gov/voro++/examples/polygons/
the doc says:
On line 47, a call is made to the face_vertices routine, which returns information about which vertices comprise each face. It is a vector of integers with a specific format: the first entry is a number k corresponding to the number of vertices making up a face, and this is followed k additional entries describing which vertices make up this face. For example, the sequence (3, 16, 20, 13) would correspond to a triangular face linking vertices 16, 20, and 13 together. On line 48, the vertex positions are returned: this corresponds to a vector of triplets (x, y, z) describing the position of each vertex.
i modified the example script so that it stores every particles cell connections and vertex positions in vectors. but please verify this!
hope this helps!
#include "voro++.hh"
#include "container.hh"
#include <v_compute.hh>
#include <c_loops.hh>
#include <vector>
#include <iostream>
using namespace voro;
int main() {
// Set up constants for the container geometry
const double x_min=-5,x_max=5;
const double y_min=-5,y_max=5;
const double z_min=0,z_max=10;
unsigned int i,j;
int id,nx,ny,nz;
double x,y,z;
std::vector<int> neigh;
voronoicell_neighbor c;
// Set up the number of blocks that the container is divided into
const int n_x=6,n_y=6,n_z=6;
// Create a container with the geometry given above, and make it
// non-periodic in each of the three coordinates. Allocate space for
// eight particles within each computational block
container con(x_min,x_max,y_min,y_max,z_min,z_max,n_x,n_y,n_z,
false,false,false,8);
//Randomly add particles into the container
con.import("pack_six_cube");
// Save the Voronoi network of all the particles to text files
// in gnuplot and POV-Ray formats
con.draw_cells_gnuplot("pack_ten_cube.gnu");
con.draw_cells_pov("pack_ten_cube_v.pov");
// Output the particles in POV-Ray format
con.draw_particles_pov("pack_ten_cube_p.pov");
// Loop over all particles in the container and compute each Voronoi
// cell
c_loop_all cl(con);
int dimension = 0;
if(cl.start()) do if(con.compute_cell(c,cl)) {
dimension+=1;
} while (cl.inc());
std::vector<std::vector<int> > face_connections(dimension);
std::vector<std::vector<double> > vertex_positions(dimension);
int counter = 0;
if(cl.start()) do if(con.compute_cell(c,cl)) {
cl.pos(x,y,z);id=cl.pid();
std::vector<int> f_vert;
std::vector<double> v;
// Gather information about the computed Voronoi cell
c.neighbors(neigh);
c.face_vertices(f_vert);
c.vertices(x,y,z,v);
face_connections[counter] = f_vert;
vertex_positions[counter] = v;
std::cout << f_vert.size() << std::endl;
std::cout << v.size() << std::endl;
counter += 1;
} while (cl.inc());
}
Regards, Lukas

Parallelizing recursive function using OpenMP in C++

I have the following recursive program which I would like to parallelize using OpenMP:
#include <iostream>
#include <cmath>
#include <numeric>
#include <vector>
#include <algorithm>
#include <thread>
#include <omp.h>
// Determines if a point of dimension point.size() is within the sphere
bool isPointWithinSphere(std::vector<int> point, const double &radius) {
// Since we know that the sphere is centered at the origin, we can simply
// find the euclidean distance (square root of the sum of squares) and check to
// see if it is less than or equal to the length of the radius
//square each element inside the point vector
std::transform(point.begin(), point.end(), point.begin(), [](auto &x){return std::pow(x,2);});
//find the square root of the sum of squares and check if it is less than or equal to the radius
return std::sqrt(std::accumulate(point.begin(), point.end(), 0, std::plus<int>())) <= radius;
}
// Counts the number of lattice points inside the sphere( all points (x1 .... xn) such that xi is an integer )
// The algorithm: If the radius is a floating point value, first find the floor of the radius and cast it to
// an integer. For example, if the radius is 2.43 then the only integer points we must check are those between
// -2 and 2. We generate these points by simulating n - nested loops using recursion and passing each point
// in to the boolean function isPointWithinSphere(...), if the function returns true, we add one to the count
// (we have found a lattice point on the sphere).
int countLatticePoints(std::vector<int> point, const double radius, const int dimension, int count = 0) {
const int R = static_cast<int>(std::floor(radius));
#pragma omp parallel for
for(int i = -R; i <= R; i++) {
point.push_back(i);
if(point.size() == dimension){
if(isPointWithinSphere(point, radius)) count++;
}else count = countLatticePoints(point, radius, dimension, count);
point.pop_back();
}
return count;
}
int main(int argc, char ** argv) {
std::vector<int> vec;
#pragma omp parallel
std::cout << countLatticePoints(vec, 5, 7) << std::endl;
return 0;
}
I have tried adding a parallel region within the main function as well as parallelizing the for loop within countLatticePoints yet I see hardly any improvement gained from parallelizing vs running the algorithm sequentially.
Any help / advice would be appreciated in terms of other OpenMP strategies that I can use.
I'll take the advice route. Before trying to make your program faster using threads, you first want to make it faster in the single threaded case. There are several improvements you can make. You're making a lot of copies of your point vectors, which incurs a lot of expensive memory allocations.
Pass point into isPointWithinSphere as a reference. Then, rather than two loops, use one loop to square and accumulate the each element in point. Then, when checking the radius, compare the square of the distance rather than the distance. This avoids the sqrt call and replaces it with a simple square.
countLatticePoints should also take point by reference. Rather than calling point.size(), subtract 1 from dimension each time you recurse, then just check for dimension == 1 instead of computing the size.
With all that, if you still want/need to introduce threading, you'll need to make some adjustments due to passing point by reference. countLatticePoint will need to have two variants, the initial call that has the OpenMP directive in it, and the recursive one that does not have them.
The #pragma omp parallel in main won't do anything because there is only one block of code to execute.

Working with coordinates x y

I need to read from a file coordinates of points. The file looks like this:
x0 y0
x1 y1
....
Then find center and diameter of the smallest enclosing circle. But I stucked in the beginning.
I don't know how to hold coordinates and decided to choose array of structures. I've read coordinates into structure.
I'm going to make 4 conditions:
1 - There is one point and you can't find the smallest enclosing circle.
2 - There are 2 points. Now the task is to find distance between them and its center.
3 - There are 3 points.
4 - More than 3 points. Use of special algorithm
I tried to use vector. I don't know how to use my points (elements of vector) later in functions etc.
#include "stdafx.h"
#include <stdio.h>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
// Distance
float distance(){
return sqrt((point[0].x * point[1].x) + (point[0].y * point[1].y));
}
struct Points
{
float x, y;
};
int _tmain(int argc, _TCHAR* argv[])
{
vector<Points> point;
Points tmp;
ifstream fin("Points.txt");
if (!fin.is_open())
cout << "Cannot open the file \n";
else{
while (fin >> tmp.x >> tmp.y){
point.push_back(tmp);
cout << tmp.x << tmp.y << endl;
}
fin.close();
}
return 0;
}
I would name the struct something like Point rather than Points,
since a single instance of the struct holds only one pair of x,y coordinates.
Then a suitable distance function might be something like
float distance(const Point& point1, const Point& point2)
{
return sqrt((point1.x * point2.x) + (point1.y * point2.y));
}
You can get the distance between any two points in your input set like this:
distance(point[i], point[j])
You might also want to measure the distances from your input points to
a point that is not in the set, such as a point where you think the center
of the circle might be. For example,
distance(point[i], candidate_center_of_circle)
If it were my code, I would likely make Point a class and give it a
member function for distance so that I could write something like
candidate_center_of_circle.distanceTo(point[i])
By the way, I might name the variable points rather than point
because it is a vector that holds multiple instances of Point.
If you intend to write things like point[i] a lot you might not like
points[i], but if you are mostly going to make STL iterators over the vector
then you would have something like this:
for (std::vector<Point>::const_iterator it = points.begin(); it != points.end(); ++it)