forked from tum-db/user-defined-operators
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcreate_points.cpp
102 lines (92 loc) · 2.77 KB
/
create_points.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <array>
#include <atomic>
#include <cmath>
#include <cstdint>
#include <random>
//---------------------------------------------------------------------------
#include <udo/UDOperator.hpp>
//---------------------------------------------------------------------------
using namespace std;
//---------------------------------------------------------------------------
/// The output of this operator
struct Output {
/// The x dimension of the point
double x;
/// The y dimension of the point
double y;
/// The cluster id from the cluster this point belongs to
uint32_t clusterId;
};
//---------------------------------------------------------------------------
/// A 2D point
struct Point2D {
/// The x dimension
double x;
/// The y dimension
double y;
};
//---------------------------------------------------------------------------
/// A generator for random 2D Points with a cluster id
class CreatePoints : public udo::UDOperator<udo::EmptyTuple, Output> {
private:
/// The fixed cluster centers
static constexpr array<Point2D, 10> clusterCenters{{
{0.0, 0.0},
{40.0, 0.0},
{0.0, -40.0},
{-40.0, 0.0},
{0.0, 40.0},
{50.0, 44.0},
{40.0, -80.0},
{-30.0, -50.0},
}};
/// The standard deviations for the clusters
static constexpr array<double, 10> stdDevs{
5.0,
5.0,
5.0,
5.0,
5.0,
7.0,
8.0,
1.0,
};
/// The proportion of points that should belong to this cluster
static constexpr array<double, 10> clusterPointsProportions{
1.0 / 8,
1.0 / 8,
1.0 / 8,
1.0 / 8,
1.0 / 8,
1.0 / 64,
1.0 / 64 * 15,
1.0 / 8,
};
/// The number of points that should be generated
uint64_t numPoints;
/// The next cluster that should be generated
atomic<uint32_t> nextClusterId = 0;
public:
/// Constructor
explicit CreatePoints(uint64_t numPoints) : numPoints(numPoints) {}
/// Produce the output
bool postProduce(LocalState& /*localState*/) {
auto clusterId = nextClusterId.fetch_add(1);
if (clusterId >= clusterCenters.size())
return true;
uint64_t seed = 42 + clusterId;
mt19937_64 gen(seed);
normal_distribution xDist(clusterCenters[clusterId].x, stdDevs[clusterId]);
normal_distribution yDist(clusterCenters[clusterId].y, stdDevs[clusterId]);
uint64_t numClusterPoints = ceil(numPoints * clusterPointsProportions[clusterId]);
for (uint64_t i = 0; i < numClusterPoints; ++i) {
Output output;
output.x = xDist(gen);
output.y = yDist(gen);
output.clusterId = clusterId;
produceOutputTuple(output);
}
return false;
}
};
//---------------------------------------------------------------------------