I'm trying to make a code to implement the direct type 2 realisation structure from Digital Signal Processing in C++.
So what I have is this for a class and of course a header that belongs to it:
#include "DirectType2.h"
DirectType2::DirectType2()
{
}
DirectType2::DirectType2(vector<double> inputBCoefficients, vector<double> inputACoefficients)
{
inputXFunction = inputACoefficients;
inputYFunction = inputBCoefficients;
}
void DirectType2::setInputFunctions(vector<double> inputA, vector<double> inputB)
{
inputXFunction = inputA;
inputYFunction = inputB;
}
vector<double> DirectType2::getInputXFunction()
{
return inputXFunction;
}
vector<double> DirectType2::getInputYFunction()
{
return inputYFunction;
}
double DirectType2::xOfNFunction(unsigned int n)
{
double sum = 0;
for (unsigned int i = 1; i <= n || i < inputXFunction.size(); i++)
{
sum += inputXFunction[i] * xOfNFunction(n - i);
}
double x = inputXFunction[0] + sum;
return x;
}
double DirectType2::wOfNFunction(unsigned int n)
{
double w = 0;
double sum = 0;
for (unsigned int i = 1; (i < n || i < inputXFunction.size()); i++)
{
sum -= inputXFunction[i] * wOfNFunction(n - i);
}
w = inputXFunction[1] - sum;
return w;
}
double DirectType2::yOfNFunction(unsigned int n)
{
double y = 0;
for (unsigned int i = 0; i < n || i < inputYFunction.size(); i++)
{
y += inputYFunction[i] * wOfNFunction(n - i);
}
return y;
}
DirectType2::~DirectType2()
{
}
My source file looks like this:
#include <iostream>
#include "DirectType2.h"
using namespace std;
int main()
{
double myDoubleY[] = { 0.01031, 0.06188, 0.1547, 0.2063, 0.1547, 0.06188, 0.01031 };
double myDoubleX[] = { 1, -1.188, 1.305, -0.6743, 0.2635, -0.05175, 0.005023 };
vector<double> yFunction(myDoubleY, myDoubleY + sizeof(myDoubleY) / sizeof(double));
vector<double> xFunction(myDoubleX, myDoubleX + sizeof(myDoubleX) / sizeof(double));
DirectType2 port(yFunction, xFunction);
cout << "y(n) med n = 6 bliver: " << port.yOfNFunction(6) << endl;
return 0;
}
Now my issue is that when I run this code, a file called "xutility" pops up and throws this exception:
Unhandled exception at 0x01284B77 in Portefølje 2 - forsøg 2.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x00E02F64).
Now of course I understand that it is a stack overflow that happens, but I dont understand why it opens this file and throws an exception from it, seeings as I don't really feel like I ever use this file..
The code snippet that throws the exception is:
const _Ty2& _Get_second() const noexcept
{ // return const reference to second
return (_Myval2);
}
and if I try to let the code continue it says this:
Exception thrown at 0x01284B77 in Portefølje 2 - forsøg 2.exe: 0xC0000005:
Access violation writing location 0x00E00FB4.
Edit:
In the header I have defined two vectors called inputXFunction and inputYFunction both set to contain doubles.
Each of your for-loops should use && instead of || as you need both conditions to be met in order to continue accessing the arrays safely. E.g.:
for (unsigned int i = 1; (i < n && i < inputXFunction.size()); i++)
{
sum -= inputXFunction[i] * wOfNFunction(n - i);
}
instead of:
for (unsigned int i = 1; (i < n || i < inputXFunction.size()); i++)
{
sum -= inputXFunction[i] * wOfNFunction(n - i);
}
Related
I'm trying to solve https://open.kattis.com/problems/rootedsubtrees and part of the solution requires finding the minimum distance between any 2 nodes on the tree. To do this, I'm using Lowest Common Ancestor as a subroutine. Part of my LCA code uses a DFS to traverse the tree. Somehow, running this code on a line graph of size 200000 leads to a segmentation fault during the DFS section of the code.
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
#define fast_cin() \
ios_base::sync_with_stdio(false); \
cin.tie(NULL); \
cout.tie(NULL);
int n, q, idx;
vector<int> adjlist[200009];
vector<int> L, E,
H; // depth at traversal index, node at traversal index, first traversal index of node
void dfs(int cur, int depth) {
cout << "dfs " << cur << " " << idx << endl;
H[cur] = idx;
E[idx] = cur;
L[idx++] = depth;
for (int &nxt : adjlist[cur]) {
if (H[nxt] != -1) continue;
dfs(nxt, depth + 1);
E[idx] = cur; // backtrack to current node
L[idx++] = depth;
}
}
class SparseTable { // OOP style
private:
vi A, P2, L2;
vector<vi> SpT; // the Sparse Table
public:
SparseTable() {} // default constructor
SparseTable(vi &initialA) { // pre-processing routine
A = initialA;
int n = (int)A.size();
int L2_n = (int)log2(n) + 1;
P2.assign(L2_n, 0);
L2.assign(1 << L2_n, 0);
for (int i = 0; i <= L2_n; ++i) {
P2[i] = (1 << i); // to speed up 2^i
L2[(1 << i)] = i; // to speed up log_2(i)
}
for (int i = 2; i < P2[L2_n]; ++i)
if (L2[i] == 0) L2[i] = L2[i - 1]; // to fill in the blanks
// the initialization phase
SpT = vector<vi>(L2[n] + 1, vi(n));
for (int j = 0; j < n; ++j) SpT[0][j] = j; // RMQ of sub array [j..j]
// the two nested loops below have overall time complexity = O(n log n)
for (int i = 1; P2[i] <= n; ++i) // for all i s.t. 2^i <= n
for (int j = 0; j + P2[i] - 1 < n; ++j) { // for all valid j
int x = SpT[i - 1][j]; // [j..j+2^(i-1)-1]
int y = SpT[i - 1][j + P2[i - 1]]; // [j+2^(i-1)..j+2^i-1]
SpT[i][j] = A[x] <= A[y] ? x : y;
}
}
int RMQ(int i, int j) {
int k = L2[j - i + 1]; // 2^k <= (j-i+1)
int x = SpT[k][i]; // covers [i..i+2^k-1]
int y = SpT[k][j - P2[k] + 1]; // covers [j-2^k+1..j]
return A[x] <= A[y] ? x : y;
}
};
int LCA(int u, int v, SparseTable &SpT) {
if (H[u] > H[v]) swap(u, v);
return E[SpT.RMQ(H[u], H[v])];
}
int APSP(int u, int v, SparseTable &SpT) {
int ancestor = LCA(u, v, SpT);
return L[H[u]] + L[H[v]] - 2 * L[H[ancestor]];
}
int main() {
fast_cin();
cin >> n >> q;
L.assign(2 * (n + 9), 0);
E.assign(2 * (n + 9), 0);
H.assign(n + 9, -1);
idx = 0;
int u, v;
for (int i = 0; i < n - 1; i++) {
cin >> u >> v;
u--;
v--;
adjlist[u].emplace_back(v);
adjlist[v].emplace_back(u);
}
dfs(0, 0);
SparseTable SpT(L);
ll d;
while (q--) {
cin >> u >> v;
u--;
v--;
d = (ll) APSP(u, v, SpT) + 1;
cout << (ll) n - d + (d) * (d + 1) / 2 << endl;
}
return 0;
}
Using the following Python Code to generate the input of a large line graph
n = 200000
q = 1
print(n, q)
for i in range(1, n):
print(i, i+1)
print(1, 200000)
I get the following last few lines of output before my program crashes.
.
.
.
dfs 174494 174494
dfs 174495 174495
dfs 174496 174496
dfs 174497 174497
dfs 174498 174498
Segmentation fault (core dumped)
Is the problem an issue of exhausting stack space with the recursion or something else?
You posted a lot of code, but here is one obvious error in the SparseMatrix class:
std::vector<int> P2;
//...
P2.assign(L2_n, 0);
for (int i = 0; i <= L2_n; ++i)
{
P2[i] = (1 << i); // <-- Out of bounds access when i == L2_n
To show you the error, change that line of code to this:
P2.at(i) = (1 << i); // <-- Out of bounds access when i == L2_n
You will now get a std::out_of_range exception thrown.
If you write a loop using <=, that loop will be considered suspicious, since a lot of off-by-one and buffer overrun errors occur with loop conditions written this way.
I believe stack exhaustion was the main problem in running the code on my machine. I re-implemented the DFS in an iterative fashion.
stack<tuple<int, int, bool>> st; // cur, depth, first_time
st.push ({0, 0, 1});
while (!st.empty()) {
auto [cur, depth, first_time] = st.top();
st.pop();
if (first_time){
H[cur] = idx;
}
E[idx] = cur;
L[idx++] = depth;
for (int &nxt : adjlist[cur]) {
if (H[nxt] != -1) continue;
st.push({cur, depth, 0});
st.push({nxt, depth+1, 1});
break;
}
}
and my code was able to run the large testcase on my machine.
I'm not sure is this is relevant to the original question, but after this change, the code still flagged a run-time error on the online judge and I eventually realized that the issue was that the sparse table was using too much memory, so I fixed that by avoiding wasted declared but not used memory spaces in rows of the sparse table. Then the online judge deemed it as being too slow. So I reverted the DFS code back to the recursive version, and it was accepted. Note that the accepted solution actually crashes on my machine when running the large testcase... I guess my machine has a more limited stack space than the online grader.
The accepted solution is here
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
#define fast_cin() \
ios_base::sync_with_stdio(false); \
cin.tie(NULL); \
cout.tie(NULL);
int n, q, idx;
vector<int> adjlist[(int)2e5 + 9];
vector<int> L, E,
H; // depth at traversal index, node at traversal index, first traversal index of node
void dfs(int cur, int depth) {
H[cur] = idx;
E[idx] = cur;
L[idx++] = depth;
for (int &nxt : adjlist[cur]) {
if (H[nxt] != -1) continue;
dfs(nxt, depth + 1);
E[idx] = cur; // backtrack to current node
L[idx++] = depth;
}
}
class SparseTable { // OOP style
private:
vi A, P2, L2;
vector<vi> SpT; // the Sparse Table
public:
SparseTable() {} // default constructor
SparseTable(vi &initialA) { // pre-processing routine
A = initialA;
int n = (int)A.size();
int L2_n = (int)log2(n) + 1;
P2.assign(L2_n + 1, 0);
L2.assign((1 << L2_n) + 1, 0);
for (int i = 0; i <= L2_n; ++i) {
P2[i] = (1 << i); // to speed up 2^i
L2[(1 << i)] = i; // to speed up log_2(i)
}
for (int i = 2; i < P2[L2_n]; ++i)
if (L2[i] == 0) L2[i] = L2[i - 1]; // to fill in the blanks
// the initialization phase
SpT = vector<vi>(L2[n] + 1, vi());
SpT[0] = vi(n, 0);
for (int j = 0; j < n; ++j) SpT[0][j] = j; // RMQ of sub array [j..j]
// the two nested loops below have overall time complexity = O(n log n)
for (int i = 1; P2[i] <= n; ++i) { // for all i s.t. 2^i <= n
SpT[i] = vi(n + 1 - P2[i]); // initialize SpT[i]
for (int j = 0; j + P2[i] - 1 < n; ++j) { // for all valid j
int x = SpT[i - 1][j]; // [j..j+2^(i-1)-1]
int y = SpT[i - 1][j + P2[i - 1]]; // [j+2^(i-1)..j+2^i-1]
SpT[i][j] = A[x] <= A[y] ? x : y;
}
}
}
int RMQ(int i, int j) {
int k = L2[j - i + 1]; // 2^k <= (j-i+1)
int x = SpT[k][i]; // covers [i..i+2^k-1]
int y = SpT[k][j - P2[k] + 1]; // covers [j-2^k+1..j]
return A[x] <= A[y] ? x : y;
}
};
int LCA(int u, int v, SparseTable &SpT) {
if (H[u] > H[v]) swap(u, v);
return E[SpT.RMQ(H[u], H[v])];
}
int APSP(int u, int v, SparseTable &SpT) {
int ancestor = LCA(u, v, SpT);
return L[H[u]] + L[H[v]] - 2 * L[H[ancestor]];
}
int main() {
fast_cin();
cin >> n >> q;
L.assign(2 * (n), 0);
E.assign(2 * (n), 0);
H.assign(n, -1);
idx = 0;
int u, v;
for (int i = 0; i < n - 1; i++) {
cin >> u >> v;
u--;
v--;
adjlist[u].emplace_back(v);
adjlist[v].emplace_back(u);
}
dfs(n - 1, 0);
SparseTable SpT(L);
ll d;
while (q--) {
cin >> u >> v;
u--;
v--;
d = (ll)APSP(u, v, SpT) + 1LL;
cout << (ll)n - d + (d) * (d + 1) / (ll)2 << endl;
}
return 0;
}
I have found this code that solves the Knight's Tour problem.
If I, for example, want to solve a board of size 800x800 I get the following error:
Exception thrown at 0x00007FF6345D3778 in test.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x00000082140C3000).
Unhandled exception at 0x00007FF6345D3778 in test.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x00000082140C3000).
How can I avoid this error? How should I change the Board class such that it can solve a board this big?
I want to be able to write: Board<800> b6 for example.
PS. This code works for small boards.
Thank you very much.
class Board
{
public:
array<pair<int, int>, 8> moves;
array<array<int, N>, N> data;
Board()
{
moves[0] = make_pair(2, 1);
moves[1] = make_pair(1, 2);
moves[2] = make_pair(-1, 2);
moves[3] = make_pair(-2, 1);
moves[4] = make_pair(-2, -1);
moves[5] = make_pair(-1, -2);
moves[6] = make_pair(1, -2);
moves[7] = make_pair(2, -1);
}
array<int, 8> sortMoves(int x, int y) const
{
array<tuple<int, int>, 8> counts;
for (int i = 0; i < 8; ++i)
{
int dx = get<0>(moves[i]);
int dy = get<1>(moves[i]);
int c = 0;
for (int j = 0; j < 8; ++j)
{
int x2 = x + dx + get<0>(moves[j]);
int y2 = y + dy + get<1>(moves[j]);
if (x2 < 0 || x2 >= N || y2 < 0 || y2 >= N)
continue;
if (data[y2][x2] != 0)
continue;
c++;
}
counts[i] = make_tuple(c, i);
}
sort(counts.begin(), counts.end());
array<int, 8> out;
for (int i = 0; i < 8; ++i)
out[i] = get<1>(counts[i]);
return out;
}
void solve(string start)
{
for (int v = 0; v < N; ++v)
for (int u = 0; u < N; ++u)
data[v][u] = 0;
int x0 = start[0] - 'a';
int y0 = N - (start[1] - '0');
data[y0][x0] = 1;
array<tuple<int, int, int, array<int, 8>>, N*N> order;
order[0] = make_tuple(x0, y0, 0, sortMoves(x0, y0));
int n = 0;
while (n < N*N - 1)
{
int x = get<0>(order[n]);
int y = get<1>(order[n]);
bool ok = false;
for (int i = get<2>(order[n]); i < 8; ++i)
{
int dx = moves[get<3>(order[n])[i]].first;
int dy = moves[get<3>(order[n])[i]].second;
if (x + dx < 0 || x + dx >= N || y + dy < 0 || y + dy >= N)
continue;
if (data[y + dy][x + dx] != 0)
continue;
++n;
get<2>(order[n]) = i + 1;
data[y + dy][x + dx] = n + 1;
order[n] = make_tuple(x + dx, y + dy, 0, sortMoves(x + dx, y + dy));
ok = true;
break;
}
if (!ok) // Failed. Backtrack.
{
data[y][x] = 0;
--n;
}
}
}
template<int N>
friend ostream& operator<<(ostream &out, const Board<N> &b);
};
template<int N>
ostream& operator<<(ostream &out, const Board<N> &b)
{
for (int v = 0; v < N; ++v)
{
for (int u = 0; u < N; ++u)
{
if (u != 0) out << ",";
out << setw(3) << b.data[v][u];
}
out << endl;
}
return out;
}
int main{
Board<800> b2;
b2.solve("b5");
cout << b2 << endl;
return 0
}
array<array<int, N>, N> data with N being 800 requires around 2.5 MB of memory.
Board<800> b2 is allocated on the stack.
Depending on the platform the default stack size is around 2-8MB. It looks like you are on windows where the stack size is usually 2MB. As your array is larger than the size of the stack you get a stack overflow.
You need to allocate Board on the heap. e.g.:
int main{
auto b2 = std::make_unique<Board<800>>();
b2->solve("b5");
cout << *b2 << endl;
return 0
}
In the solve function you are also allocating order on the stack. This should be changed to something like this in order to allocate it on the heap:
auto orderPointer = std::make_unique<array<tuple<int, int, int, array<int, 8>>, N*N>>();
// dereference the pointer to make array indexes easier
auto& order = *orderPointer;
I have an Eigen MatrixXd object, called v, and I am facing some problems when trying to access this matrix content. When I only print the content at the console (as in the code), works just as fine. When I try to use the content, the error shows up:
Assertion failed: (row >= 0 && row < rows() && col >= 0 && col < cols()), function operator(), file /usr/local/Cellar/eigen/3.2.4/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h, line 337.
ChosenPoint ** points = new ChosenPoint*[width];
for (int i = 0; i < width; i++)
{
points[i] = new ChosenPoint[height];
for (int j = 0; j < height; j++)
{
points[i][j].setPoint(i, j, false);
points[i][j].setNumberOfFrames(numberOfFrames);
}
}
Matrix<double, 2, 1> v = (aT * a).inverse() * aT * b;
if (v.rows() == 2 && v.cols() == 1)
{
points[x][y].setFlow(v(0,0), v(1,0), frame);
}
And my ChosenPoint class:
typedef struct point
{
double x;
double y;
bool isValid;
} point;
class ChosenPoint
{
public:
ChosenPoint()
{
}
~ChosenPoint()
{
}
void setNumberOfFrames(int numberOfFrames)
{
this->flow = new point[numberOfFrames];
for (int i = 0; i < numberOfFrames; i++)
{
point f;
f.x = 0.0;
f.y = 0.0;
this->flow[i] = f;
}
}
void setPoint(int x, int y, bool isValid)
{
this->pt.x = (double) x;
this->pt.y = (double) y;
this->pt.isValid = isValid;
}
point getPoint()
{
return this->pt;
}
point* getFlow()
{
return this->flow;
}
void setFlow(double &xFlow, double &yFlow, int &position)
{
this->flow[position].x = xFlow;
this->flow[position].y = yFlow;
}
void updateFlow(int position)
{
this->flow[position].x = 2*this->flow[position].x;
this->flow[position].y = 2*this->flow[position].y;
}
void updateFlow(double xFlow, double yFlow, int position)
{
this->flow[position].x = xFlow;
this->flow[position].y = yFlow;
}
point pt;
point *flow;
};
My fault. The problem was with one of the other matrixes that I was using in the project, and took me a while to figure it out. Unfortunately, Eigen doesn`t seem to be really helpful when this happens:
I had 2 matrixes (A and B). The matrix with problem was A (somehow, some data was not loaded into the matrix). But when i multiplied A and B, it generated a new matrix C with some valid results (all my sanity checks were unuseful). I admit I don`t know a lot of Eigen.
Anyway, hope this is helpful for more people like me.
I'm trying to implement a gradient descent algorithm in C++. Here's the code I have so far :
#include <iostream>
double X[] {163,169,158,158,161,172,156,161,154,145};
double Y[] {52, 68, 49, 73, 71, 99, 50, 82, 56, 46 };
double m, p;
int n = sizeof(X)/sizeof(X[0]);
int main(void) {
double alpha = 0.00004; // 0.00007;
m = (Y[1] - Y[0]) / (X[1] - X[0]);
p = Y[0] - m * X[0];
for (int i = 1; i <= 8; i++) {
gradientStep(alpha);
}
return 0;
}
double Loss_function(void) {
double res = 0;
double tmp;
for (int i = 0; i < n; i++) {
tmp = Y[i] - m * X[i] - p;
res += tmp * tmp;
}
return res / 2.0 / (double)n;
}
void gradientStep(double alpha) {
double pg = 0, mg = 0;
for (int i = 0; i < n; i++) {
pg += Y[i] - m * X[i] - p;
mg += X[i] * (Y[i] - m * X[i] - p);
}
p += alpha * pg / n;
m += alpha * mg / n;
}
This code converges towards m = 2.79822, p = -382.666, and an error of 102.88. But if I use my calculator to find out the correct linear regression model, I find that the correct values of m and p should respectively be 1.601 and -191.1.
I also noticed that the algorithm won't converge for alpha > 0.00007, which seems quite low, and the value of p barely changes during the 8 iterations (or even after 2000 iterations).
What's wrong with my code?
Here's a good overview of the algorithm I'm trying to implement. The values of theta0 and theta1 are called p and m in my program.
Other implementation in python
More about the algorithm
This link gives a comprehensive view of the algorithm; it turns out I was following a completely wrong approach.
The following code does not work properly (and I have no plans to work on it further), but should put on track anyone who's confronted to the same problem as me :
#include <vector>
#include <iostream>
typedef std::vector<double> vect;
std::vector<double> y, omega(2, 0), omega2(2, 0);;
std::vector<std::vector<double>> X;
int n = 10;
int main(void) {
/* Initialize x so that each members contains (1, x_i) */
/* Initialize x so that each members contains y_i */
double alpha = 0.00001;
display();
for (int i = 1; i <= 8; i++) {
gradientStep(alpha);
display();
}
return 0;
}
double f_function(const std::vector<double> &x) {
double c;
for (unsigned int i = 0; i < omega.size(); i++) {
c += omega[i] * x[i];
}
return c;
}
void gradientStep(double alpha) {
for (int i = 0; i < n; i++) {
for (unsigned int j = 0; j < X[0].size(); j++) {
omega2[j] -= alpha/(double)n * (f_function(X[i]) - y[i]) * X[i][j];
}
}
omega = omega2;
}
void display(void) {
double res = 0, tmp = 0;
for (int i = 0; i < n; i++) {
tmp = y[i] - f_function(X[i]);
res += tmp * tmp; // Loss functionn
}
std::cout << "omega = ";
for (unsigned int i = 0; i < omega.size(); i++) {
std::cout << "[" << omega[i] << "] ";
}
std::cout << "\tError : " << res * .5/(double)n << std::endl;
}
I'm trying to implement Closest pair of points in C++ according to Cormen book and wikipedia article, I think that algorithm is correct, but it does work only for a very small data. Code is below:
#include <cstdio>
#include <algorithm>
#include <cmath>
#define REP(i,n) for(int i=0;i<n;i++)
using namespace std;
struct point
{
long long x, y;
};
struct dist
{
long long x_1,y_1,x_2,y_2, distance;
} dis;
inline bool OrdX(const point &a, const point &b)
{
if(a.x==b.x)
{
return a.y<b.y;
}
return a.x<b.x;
}
inline int OrdY(const point &a, const point &b)
{
if(a.y==b.y)
{
return a.x<b.x;
}
return a.y<b.y;
}
// is - function that check is a an element of X_L array
inline bool is(const point &a, point *X_L, int p, int k)
{
if(p<=k)
{
int center = (p+k)/2;
if(X_L[center].x == a.x)
{
return true;
}
if(X_L[center].x > a.x)
{
return is(a, X_L, p, center-1);
}
else
{
return is(a, X_L, center+1, k);
}
}
return false;
}
// odl - function takes two points and return distance between them ^2
inline long long odl(const point &a, const point &b)
{
return ((a.x-b.x)*(a.x-b.x))+((a.y-b.y)*(a.y-b.y));
}
int tmp;
// fun - function that returns the pair of closest points using divide & conquer
struct dist fun(int n, point *X, point *Y)
{
// if there are less that 4 points - it checks it using bruteforce
if(n<4)
{
if(odl(X[0], X[1]) < dis.distance)
{
dis.distance = odl(X[0],X[1]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[1].x;
dis.y_2 = X[1].y;
}
if(n==3)
{
if(odl(X[0], X[2]) < dis.distance)
{
dis.distance = odl(X[0],X[2]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[2].x;
dis.y_2 = X[2].y;
}
if(odl(X[1], X[2]) < dis.distance)
{
dis.distance = odl(X[1],X[2]);
dis.x_1 = X[1].x;
dis.y_1 = X[1].y;
dis.x_2 = X[2].x;
dis.y_2 = X[2].y;
}
}
}
// otherwise it divides points into two arrays and runs fun
// recursively foreach part
else
{
int p=n/2;
int PPP = (X[p].x + X[p-1].x)/2;
point *X_L = new point[p];
point *X_R = new point[n-p];
point *Y_L = new point[p];
point *Y_R = new point[n-p];
REP(i,p)
X_L[i] = X[i];
for(int r=p; r<n; r++)
{
X_R[r-p] = X[r];
}
int length_Y_L = 0;
int length_Y_R = 0;
REP(i,n)
{
if(is(Y[i], X_L, 0, p))
{
Y_L[length_Y_L++] = Y[i];
}
else
{
Y_R[length_Y_R++] = Y[i];
}
}
dist D_L = fun(p, X_L, Y_L);
dist D_R = fun(n-p, X_R, Y_R);
dist D;
if(D_L.distance < D_R.distance)
{
D = D_L;
}
else
{
D = D_R;
}
tmp = 0;
point *Y2 = new point[n];
double from = sqrt((double)D.distance);
for(int r=0; r<n; r++)
{
if(Y[r].x > (long long)PPP-from && Y[r].x < (long long)PPP + from)
{
Y2[tmp++] = Y[r];
}
}
//--tmp;
//int xxx = min(7, tmp-r);
int r = 0;
for(int j=1; j<min(7, tmp-r); j++)
{
if(odl(Y2[r], Y2[r+j]) < D.distance)
{
D.distance = odl(Y2[r], Y2[r+j]);
D.x_1 = Y2[r].x;
D.y_1 = Y2[r].y;
D.x_2 = Y2[r+j].x;
D.y_2 = Y2[r+j].y;
}
r++;
}
dis = D;
}
return dis;
}
int main()
{
int n;
n = 7;
point *X = new point[n];
point *Y = new point[n];
for(int i=0; i< 7; i++)
{
X[i].x = 0;
X[i].y = 10*i;
}
/*
REP(i,n)
{
scanf("%lld %lld", &X[i].x, &X[i].y);
}
*/
sort(X, X+n, OrdX);
REP(i,n)
Y[i] = X[i];
sort(Y, Y+n, OrdY);
dis.distance = odl(X[0], X[1]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[1].x;
dis.y_2 = X[1].y;
dist wynik = fun(n, X, Y);
printf(" %lld %lld\n %lld %lld\n", wynik.x_1, wynik.y_1, wynik.x_2, wynik.y_2);
return 0;
}
and I get this error:
malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char
*) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct
malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size)
>= (unsigned long)((((__builtin_offsetof (struct malloc_chunk,
fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t)))
- 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end &
pagemask) == 0)' failed.
I've tried loooking for explanation of this error but can't find anything clear for me :/.
Can You please help me to solve this ? Thanks
The message means you've done something bad with dynamically allocated memory. Perhaps you freed an object twice, or wrote into memory beyond the beginning or end of an array-like dynamically allocated object.
On Linux, the tool valgrind may help pin-point the first place in your program's execution where it made a boo-boo.
By the way, your macro:
#define REP(i,n) for(int i=0;i<n;i++)
is poorly defined. The substitution of n should be parenthesized, because n could be an expression which has the wrong precedence with respect to the < operator. For instance: REP(i, k < m ? z : w). You want:
#define REP(var,n) for(int var=0;var<(n);var++)
The var reminds the programmer that this argument is a variable name, and not an arbitrary expression.
Your function is is redundant; that's just std::binary_search. That would help a lot with #sbi's problem of readability.
There's also quite a bit of redundancy in blocks like
dis.distance = odl(X[0],X[1]);
dis.x_1 = X[0].x;
dis.y_1 = X[0].y;
dis.x_2 = X[1].x;
dis.y_2 = X[1].y;
You can write a simple function dist calcDist(point,point) for this. You should probably move all the point definitions and associated functions to a separate header "point.h", again to keep things readable.
As for the memory issue: first, the arrays X_L and X_R are not really necessary. They contain the same data as X, so you can make them pointers to &(X[0]) and &(X[p) respectively. Y_L and Y_R are shuffled versions, so you do need to the arrays to copy data to. However, if you allocate them with new[], you are responsible for cleanup with delete[]. It looks like you can just use a std::vector<point> Y_L instead. No need to do bookkeeping, vector does that for you. Just call Y_L.push_back(Y[i]).