Bucket Sort with a custom data structure - c++

My program is tasked with sorting points on an x-y plane, given by the user, according to their distance from the origin using bucket sort. In the instance of having two points with the same distance, the point with the smallest x-coordinate would be selected as the first point. If both the distance and the x-coordinate are the same, the element with the smallest y-coordinate will come first. The output is the points themselves, not their distances. The most logical way I've found to do it so far is to create a custom data structure that houses both the x coordinate, y-coordinate, and its distance in one element. The problem I have at the moment is my current algorithm for standard vectors of doubles, and I have no idea how to convert the sort to fit my needs. Any ideas or suggestions would be helpful.
Here is the layout of the structure:
struct point {
double xc;
double yc;
double dist; };
The current bucket sort, which works fine with vectors of doubles.
void bucketSort(vector<double> &arr) {
int n = B.size();
vector<point> b[n];
for (int i=0; i<n; i++)
{
int bi = n*arr[i];
b[bi].push_back(arr[i]);
}
for (int i=0; i<n; i++)
sort(b[i].begin(), b[i].end());
int index = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < b[i].size(); j++){
arr[index++] = b[i][j]; }
}
}
The entirety of the code, as of now.
using namespace std;
struct point {
double xc;
double yc;
double dist;
};
vector<double> A;
vector<double> B;
double findDistance(double x = 0, double y = 0) {
double x2 = pow(x, 2);
double y2 = pow(y, 2);
double z = x2 + y2;
double final = sqrt(z);
return final;
}
void bucketSort(vector<double> &arr)
{
int n = B.size();
vector<point> b[n];
for (int i=0; i<n; i++)
{
int bi = n*arr[i];
b[bi].push_back(arr[i]);
}
for (int i=0; i<n; i++)
sort(b[i].begin(), b[i].end());
int index = 0;
for (int i = 0; i < n; i++){
for (int j = 0; j < b[i].size(); j++){
arr[index++] = b[i][j]; }
}
}
int main(){
double number; int t = 0;
while (cin >> number){
A.push_back(number); }
struct point C[A.size()];
while (t < A.size()){
C[t / 2].xc = A[t]; C[t / 2].yc = A[t + 1];
C[t / 2].dist = (findDistance(A[t], A[t + 1])); t += 2; }
cout << setprecision(6); cout << fixed; ;
bucketSort(C);
cout << showpos; cout << fixed;
int x = 0;
while (x < (A.size() / 2)){
cout << C[x].xc << " " << C[x].yc << endl;
x++;
}
}
A vector of doubles B is here because initially, I was trying to get it done with multiple vectors of doubles.
Here is a sample of the input:
0.2 0.38
0.6516 -0.1
-0.3 0.41
-0.38 0.2
Sample output:
-0.380000 +0.200000
+0.200000 +0.380000
-0.300000 +0.410000
+0.651600 -0.100000
I realize that point could have a lot more functions added to it to make it more usable in general, but I'm aiming for just enough to get the current job. Any suggestions or help would be greatly appreciated. Please and thank you.

I would suggest one of there 2 options -
make point a class, not an struct, and overload the < operator, thus making the sort work well.
2.use the sort by function instead of the normal sort:
Firstly, add a compare function:
bool comparePoint(point* a, point* b) {
return true if a < b;
}
the function above would compare the 2 points, according to any rules you like, depends on your code.
and instead of the sort use:
std::sort(b[i].begin(), b[i].end(),comparePoint);
that should work for you.

Related

How to make a test with arrays using asserts?

I'm trying to write a test for a program that adds the product of matrices A and X to the matrix Y.
But I got the error:
"Identifier is required"
I couldn't solve or find a solution to this problem, so I ask for help here.
At first, I thought that the problem is that I compare it with the wrong array. Then I tried to pass other arguments. Dismembered my code into several functions. But still, nothing happened.
#include<iostream>
#include<cassert>
using namespace std;
void axpy(int n, int m, int k, int **A, int **X, int **Y)
{
int i, j, q;
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
{
for (q = 0; q < k; q++)
{
Y[i][j] += A[i][q] * X[q][j];
}
}
}
cout << "Product of matrices\n";
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
cout << Y[i][j] << " ";
cout << "\n";
}
}
void TestAxpy()
{
int P[2][2] = { {13,11},{27,21} };
assert(axpy(2,2,2,[1,2][3,4],[4,3][2,1],[5,6][7,8]) == P);
}
int main()
{
int n, m, k, i, j, q;
cout << "Enter number of rows of matrix X and columns of matrix A: ";
cin >> k;
cout << "Enter number of rows of matrix A and Y: ";
cin >> n;
cout << "Enter number of columns of matrix X and Y: ";
cin >> m;
int **A = new int *[k];
for (i = 0; i < k; i++)
A[i] = new int[n];
int **X = new int *[m];
for (i = 0; i < m; i++)
X[i] = new int[k];
int **Y = new int *[m];
for (i = 0; i < m; i++)
Y[i] = new int[n];
cout << "Enter elements of matrix A: ";
for (i = 0; i < n; i++)
for (j = 0; j < k; j++)
cin >> A[i][j];
cout << "Enter elements of matrix X: ";
for (i = 0; i < k; i++)
for (j = 0; j < m; j++)
cin >> X[i][j];
cout << "Enter elements of matrix Y: ";
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
cin >> Y[i][j];
axpy(n, m, k, A, X, Y);
TestAxpy();
system("pause");
return 0;
}
I wanted to get a 2x2 matrix with the results of [13, 11] [27 21]. The input I used such as:
Enter number of rows of matrix X and columns of matrix A: 2
Enter number of rows of matrix A and Y: 2
Enter number of columns of matrix X and Y: 2
Enter elements of matrix A: 1 2 3 4
Enter elements of matrix X: 4 3 2 1
Enter elements of matrix Y: 5 6 7 8
This seems like a mix of C and C++. In C++ it is rare you need to use raw "C" arrays, almost always std::vector<> or std::array<> will be a better choice. There is also matrix in the boost library which will store exactly what you need.
In terms of your specific code there are two issues:
Pointers to pointers (**) are no the same thing as two dimension arrays. They are a two-layer indirection. The first are pointers to locations in memory that store the second layer in memory. See below for how it would need to work to be able to call axpy. Again would strongly recommend looking at std::vector or boost libraries.
The "==" operator won't work that way for C arrays. You need to specify how you want the comparison to happen. As written it will at best just compare memory address, but more likely will produce an error.
void TestAxpy()
{
int P[2][2] = { {13,11},{27,21} };
int A1[2] = {1,2};
int A2[2] = {3,4};
int* A[2] = { A1, A2 };
int X1[2] = {4,3};
int X2[2] = {2,1};
int *X[2] = { X1, X2 };
int Y1[2];
int Y2[2];
int *Y[2] = {Y1, Y2 };
axpy(2,2,2,A,X,Y);
//assert(Y == P); //C++ doesn't know how to do this.
}

Using C-style Arrays with Eigen for Matrix Inverse

I have about 1000 lines of code that I wrote in C for a linear programming solver (interior point algorithm). I realized that I need to use Eigen to calculate a matrix inverse, so now I am running my code in C++ instead (runs just fine, it seems). Now I have a bunch of arrays declared in C format, for example: A[30][30];
In my program, I do a bunch of matrix calculations and then need to find an inverse of a matrix at some point, let's call it matrix L[30][30]. To use Eigen, I need to have it in a special Eigen matrix format to call the function m.inverse like this:
//cout << "The inverse of L is:\n" << L.inverse() << endl;
My goal is to find a way... ANY way, to get my data from L to a format that Eigen will accept so I can run this thing. I've spent the last 2 hours researching this and have come up with nothing. :-( I'm fairly new to C, so please be as thorough as you can. I want the most simple method possible. I've read about mappings, but I'm not very clear on pointers sadly (which seems to be an integral part). Is there a way to just loop through each row and column and copy them into an Eigen matrix?
While I'm asking, will I need to take the resultant Eigen matrix and turn it back into a C array? How would that process work? Thanks in advance for any help! I've spent about 50-60 hours on this and it's due this week! This is the LAST thing I need to do and I'll be done with my term project. It's a math class, so the programming side of things are a little fuzzy for me but I'm learning a lot.
Possibly relevant information:
-Running on Windows 10 i7 processor Sony VAIO
-Compiling with CodeBlocks in C++, but originally written in C
-This code is all in a while loop that may be iterated through 10 times or so.
-The matrix inverse needs to be calculated for this matrix L each iteration, and the data will be different each time.
Please help! I'm willing to learn, but I need guidance and this class is online so I have virtually none. Thanks so much in advance!
Edit - I saw this and tried to implement it to no avail, but it seems like the solution if I can figure this out:
"Suppose you have an array with double values of size nRows x nCols.
double *X; // non-NULL pointer to some data
You can create an nRows x nCols size double matrix using the Map functionality like this:
MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );
The Map operation maps the existing memory region into the Eigen’s data structures. A single line like this allows to avoid to write ugly code of matrix creation, for loop with copying each element in good order etc."
This seems to be a nice solution, but I am clueless on how to do anything with that "double *X" that says to "point to some data". I began looking up pointers and such and it didn't help clarify - I saw all kinds of things about pointing to multi-dimensional arrays that didn't seem to help.
I also don't quite understand the format of the second line. Is every capital X there just going to be the same as the matrix *X in the line before? What would I need to declare/create for that? Or is there an easier way that all of this?
EDIT2: Here is what I have in my program, essentially - this is significantly shrunken down, sorry if it's still too long.
#include <iostream>
#include <Eigen/Dense>
using namespace Eigen;
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
typedef Matrix<double, 30, 30> Matrix30d;
double L[30][30] ={{0}};
double Ax[30][30] = {{0}}; //[A] times [x]
double At[30][30] = {{0}}; //A transpose
double ct[30][30] = {{0}}; //c transpose
double x[30][30] = {{0}}; //primal solution
double w[30][30] = {{0}}; //omega, dual solution
double s[30][30] = {{0}}; //dual slack
double u[30][30] = {{0}}; //[c]t - [A]t x [w] - [s]
double Atxw[30][30] = {{0}}; //A transpose times omega
double t[30][30] = {{0}}; //RHS - [A]x[x]
double v[30][30] = {{0}}; //mu - xij * sij
double p[30][30] = {{0}}; //vij / xij
double D2[30][30] = {{0}}; //diagonal of xij/sij
double AD2[30][30] = {{0}}; //[A] x [D2]
double AD2xAt[30][30] = {{0}}; //[AD2] x [At]
double uminp[30][30] = {{0}}; //[u] - [p]
double AD2xuminp[30][30] = {{0}}; //[AD2] x [uminp]
double z[30][30] = {{0}}; //[AD2] x [uminp] + [t]
double Atxdw[30][30] = {{0}}; //[At] x [dw]
double xt[30][30] = {{0}}; //x transpose
double bt[30][30] = {{0}}; //b transpose
Matrix30d Inv; //C++ style matrix for Eigen, maybe needed?
int main(){
int r1; //rows of A
int c1; //columns of A
int i; //row and column counters
int j;
int k;
double sum = 0;
double size; //size of square matrix being inverted [L]
double *pointer[30][30];
FILE *myLPproblem;
myLPproblem = fopen("LPproblem.txt", "r"); //Opens file and reads in data
float firstLine[4];
int Anz;
for (i = 0; i < 4; i++)
{
fscanf(myLPproblem, "%f", &firstLine[i]);
}
r1 = firstLine[0];
c1 = firstLine[1];
Anz = firstLine[2];
double A[r1][c1];
double b[r1][1];
double c[1][c1];
int Ap[c1+1];
int Ai[Anz];
double Ax2[Anz];
for(i=0; i<r1; i++){
for(j=0; j<c1; j++){
A[i][j]=0;
}
}
for (i = 0; i < (c1 + 1); i++)
{
fscanf(myLPproblem, "%d", &Ap[i]);
}
for (i = 0; i < (Anz); i++)
{
fscanf(myLPproblem, "%d", &Ai[i]);
}
for (i = 0; i < (Anz); i++)
{
fscanf(myLPproblem, "%lf", &Ax2[i]);
}
for (i = 0; i < (r1); i++)
{
fscanf(myLPproblem, "%lf", &b[i][0]);
}
for (i = 0; i < (c1); i++)
{
fscanf(myLPproblem, "%lf", &c[0][i]);
}
fclose(myLPproblem);
int row;
double xval;
int Apj;
int Apj2;
for(j=0; j<c1; j++){
Apj = Ap[j];
Apj2 = Ap[j+1];
for(i=Apj; i<Apj2; i++){
row = Ai[i];
xval = Ax2[i];
A[row][j] = xval;
}
}
size = r1;
for(i=0; i<c1; i++) //Create c transpose
{
ct[i][0] = c[0][i];
}
for(i=0; i<r1; i++) //Create b transpose
{
bt[i][0] = b[0][i];
}
for(i=0; i<c1; i++) //Create A transpose
{
for(j=0; j<r1; j++)
{
At[i][j] = A[j][i];
}
}
while(1){ //Main loop for iterations
for (i = 0; i <= r1; i++) { //Multiply [A] times [x]
for (j = 0; j <= 1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + A[i][k] * x[k][j];
}
Ax[i][j] = sum;
}
}
sum = 0; //Multiply [At] times [w]
for (i = 0; i <= c1; i++){
for (j = 0; j <= 1; j++) {
sum = 0;
for (k = 0; k <= r1; k++) {
sum = sum + At[i][k] * w[k][j];
}
Atxw[i][j] = sum;
}
}
for(i=0; i<c1; i++) //Subtraction to create matrix u
{for(j=0; j<1; j++)
{
u[i][j] = (ct[i][j]) - (Atxw[i][j]) - (s[i][j]);
}
}
for(i=0; i<r1; i++) //Subtraction to create matrix t
{for(j=0; j<1; j++)
{
t[i][j] = (b[i][j]) - (Ax[i][j]);
}
}
for(i=0; i<c1; i++) //Subtract and multiply to make matrix v
{for(j=0; j<1; j++)
{
v[i][j] = mu - x[i][j]*s[i][j];
}
}
for(i=0; i<c1; i++) //create matrix p
{for(j=0; j<1; j++)
{
p[i][j] = v[i][j] / x[i][j];
}
}
for(i=0; i<c1; i++) //create matrix D2
{for(j=0; j<c1; j++)
{
if(i == j){
D2[i][j] = x[i][0] / s[i][0];
}else{
D2[i][j] = 0;
}
}
}
sum = 0;
for (i = 0; i <= r1; i++) { //Multiply [A] times [D2]
for (j = 0; j <= c1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + A[i][k] * D2[k][j];
}
AD2[i][j] = sum;
}
}
sum = 0;
for (i = 0; i <= r1; i++) { //Multiply [AD2] times [At], to be inverted!
for (j = 0; j <= r1; j++) {
sum = 0;
for (k = 0; k <= c1; k++) {
sum = sum + AD2[i][k] * At[k][j];
}
AD2xAt[i][j] = sum;
}
}
//Here is where I need to calculate the inverse (and determinant probably) of matrix AD2xAt. I'd like to inverse to then be stored as [L].
//cout << "The determinant of AD2xAt is " << AD2xAt.determinant() << endl;
//cout << "The inverse of AD2xAt is:\n" << AD2xAt.inverse() << endl;
printf("\n\nThe inverse of AD2xAt, L, is : \n\n"); //print matrix L
for (i=0; i<size; i++)
{
for (j=0; j<size; j++)
{
printf("%.3f\t",AD2xAt[i][j]);
}
printf("\n");
}
}
return 0;
}
In a nutshell, it reads matrices from a file, calculates a bunch of matrices, then needs to invert AD2xAt and store it as L. The critical part is at the end, where I need to take the inverse (scroll to the bottom - I have it commented).
Have you tried
Map<MatrixXd>(A[0],30,30).inverse() ??
– ggael
What you're proposing seems like it would be doing both at once or
something?
Right, the Map<MatrixXd>() returns the Eigen's MatrixXd, on which the method inverse() is called.
May I ask what the [0] is after A?
[0] is the array subscript operator [] designating the 0-th element; A[0] is the initial row of the matrix A[30][30] and is converted to the pointer to A[0][0] corresponding to the X you saw.

Numerical Integration with Trapezoidal rule c++

I'm attempting to implement a Trapezoidal rule that utilizes previous function evaluations in order to avoid redundant computation. Two things: a) computed results are not converging and I'm a little unsure of why. I'll post of the mathematics behind why I think that the algorithm should yield convergence if it's wanted, and b) the do while loop is terminating at n=8 and I've been unable to figure that one out as well; it should be running until n>128? (n is the number of subintervals) My code is below. Thanks in advance!
void NestedTrap(int n) //Trapezoidal with reuse of function evaluations
{
double a,b; //interval end points
double x[n+1]; //equally spaced nodes
double c[n]; //midpoints
double T; //Initial integral evaluation
double T2; //Evaluation with reuse of previous function evaluations
double h, h2; //step sizes for T and T2
double temp1, temp2;
std::cout <<"Enter interval end points (lesser first; enter 999 for pi & 999.2 for pi/2 & 999.4 for pi/4): ";
std::cin >> a >> b;
if (b == 999)
{
b = M_PI;
}
if (a == 999)
{
a = M_PI;
}
if (b == 999.4)
{
b = M_PI/4;
}
if (a == 999.4)
{
a = M_PI/4;
}
if (b == 999.2)
{
b = M_PI/2;
}
if (a == 999.2)
{
a = M_PI/2;
}
h = (b-a)/n;
T = 0;
temp1 = 0;
temp2 = 0;
for (int i=0; i<=n; i++)
{
x[i] = 0;
}
for (int i=0; i<n; i++)
{
x[i+1] = x[i] + h;
}
for (int i=1; i<n; i++)
{
temp1 += I1(x[i]);
}
T = (h/2)*exp(x[0]) + (h/2)*exp(x[n]) + (h*temp1);
std::cout << "T_" << n <<": " << T << std::endl;
do
{
temp2 = 0;
n = 2*n;
h2 = (b-a)/(n);
for (int i=0; i<n; i++)
{
c[i] = 0;
}
for (int i=1; i<=n; i++)
{
c[i] = a + h2*(i-0.5);
//std::cout << c[i] << std::endl;
}
for (int i=0; i<n; i++)
{
temp2 += exp(c[i]);
}
T2 = (T/2) + h2*temp2;
std::cout << "T_" << n <<": " << T2 << std::endl;
T = T2;
} while (n <= 128);
}
You create arrays of size n here
double x[n+1]; //equally spaced nodes
double c[n]; //midpoints
(note that this is not valid c++)
then you increase n here:
n = 2*n;
then you write past the end of your array here:
for (int i=0; i<n; i++)
{
c[i] = 0;
}
which causes undefined behaviour (probably overwrites some other variables)

Selection Sorting Using 2 Arrays

Suppose I want to take an array of pointers that point to x, y, z coordinates such as:
(1, 2, 4)
(2, 3, 8)
(3, 5, 1)
Then I wanted to take each of those values and compare the distance from point (1, 2, 3) and then sort the distance from each point in descending order.
How would I do that? This is the code I have so far. But I dont know how to get the second array to point back to the original values. Any help would be great.
void sortPointsByDistanceFromRefPoint(Points* points, Point* ref_point)
{
double *array;
double x0,y0,z0;
x0 =ref_point->x;
y0 =ref_point->y;
z0 =ref_point->z;
Point** point_array = points-> point_array;
int num_points = points->num_points;
array = new double[num_points];
double distance;
double x,y,z;
for (int i = 0; i< num_points; i++)
{
Point* point = point_array[i];
x = point->x;
y = point ->y;
z = point ->z;
distance = sqrt( pow((x-x0),2) + pow((y- y0),2) + pow((z-z0),2));
array[i] = distance;
}
double tmp;
for( int i = 0; i < num_points; i++)
cout << array[i] << " " << endl;
cout << endl;
cout << endl;
for (int i = 0; i < num_points -1; i++)
for (int j = i+1; j < num_points; j++)
if (array[i] > array[j])
{
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
}
for( int i = 0; i < num_points; i++)
cout << array[i] << " " << endl;
cout << endl;
delete [] array;
}
When you swap the values in array using
tmp = array[i];
array[i] = array[j];
array[j] = tmp;
also swap the values(pointers) in point_array:
Point* tmpPoint = point_array[i];
point_array[i] = point_array[j];
point_array[j] = tmpPoint;
First you need to iterate over both arrays at the same time and calculate their distances. As you calculated their distances you can add them to a list, or another array. But while you are adding the distances to the list, add them in sorted order. You can have a method AddDistance(double distance). The first incoming distance goes into the sorted array as the first element. Then when the next one comes, you check it's value and compare it to all the other elements in the array. Here is pseudo code that can do the job for you:
double sortedDistances[100];
int sortedDistancesSize;
void InsertDistance(double distance)
{
int i=0;
for(i=0; i < sortedDistancesSize, sortedDistances[i] < distance; ++i);
InsertNewDistance(distance, i);
}
Your InsertNewDistance method should insert the given distance at position "i" and shift the contents of the array after position "i" to the right.

Trouble passing 2D array in C++ 8 Puzzle

For some reason I can't get the distance function to work. Could someone explain to me what I am doing wrong?
Main Function:
#include <iostream>
#include <cmath>
using namespace std;
int distance(int**, int);
int main()
{
int m;
int goal [3][3] = { {1,2,3},{4,5,6},{7,8,0}};
const int N = 3;
int intial[N][N];
cout << "Enter in values: \n";
for(int i=0; i<3; i++) //This loops on the rows.
{
for(int j=0; j<3; j++) //This loops on the columns
{
cin >> intial[i][j];
}
}
cout << goal[0][0] << "\n" ;
m = distance(intial,N);
system("PAUSE");
return 0;
}
Manhattan Distance calculation!
int distance(int** array,int N)
{
int MSum = 0;
for (int x = 0; x < N; x++){ //Transversing rows(i)
for (int y = 0; y < N; y++) { //traversing colums (j)
int value = array[x][y]; // sets int to the value of space on board
if (value != 0) { // Don't compute MD for element 0
int targetX = (value - 1) / N; // expected x-coordinate (row)
int targetY = (value - 1) % N; // expected y-coordinate (col)
int dx = x - targetX; // x-distance to expected coordinate
int dy = y - targetY; // y-distance to expected coordinate
MSum += abs(dx) +abs(dy);
}
}
}
int m = MSum;
return m;
}
This looks basically correct as far as logic goes. The array you pass in should be compatible with the function declaration and implementation. Here is a sample declaration:
int distance(int array[3][3],int N);