1 // BEWARE: BETA VERSION
\r
2 // --------------------
\r
4 // Utilities for arbitrary dimensional points in space. All points are treated as simple value
\r
5 // arrays. This is done for two reasons:
\r
6 // - Using value arrays instead of a point class makes all point operations very explicit, which
\r
7 // makes their usage easier to optimize.
\r
8 // - A value array is about as universal a format as possible, which makes it easier for
\r
9 // people to use the k-means code in any project.
\r
10 // Also contains assertion code that can be disabled if desired.
\r
12 // Author: David Arthur (darthur@gmail.com), 2009
\r
14 #ifndef KM_UTILS_H__
\r
15 #define KM_UTILS_H__
\r
24 // The data-type used for a single coordinate for points
\r
25 typedef double Scalar;
\r
30 // Point creation and deletion
\r
31 inline Scalar *PointAllocate(int d) {
\r
32 return (Scalar*)malloc(d * sizeof(Scalar));
\r
35 inline void PointFree(Scalar *p) {
\r
39 inline void PointCopy(Scalar *p1, const Scalar *p2, int d) {
\r
40 memcpy(p1, p2, d * sizeof(Scalar));
\r
43 // Point vector tools
\r
44 inline void PointAdd(Scalar *p1, const Scalar *p2, int d) {
\r
45 for (int i = 0; i < d; i++)
\r
49 inline void PointScale(Scalar *p, Scalar scale, int d) {
\r
50 for (int i = 0; i < d; i++)
\r
54 inline Scalar PointDistSq(const Scalar *p1, const Scalar *p2, int d) {
\r
56 for (int i = 0; i < d; i++)
\r
57 result += (p1[i] - p2[i]) * (p1[i] - p2[i]);
\r
64 // Comment out ENABLE_KMEANS_ASSERTS to turn off ASSERTS for added speed.
\r
65 #define ENABLE_KMEANS_ASSERTS
\r
66 #ifdef ENABLE_KMEANS_ASSERTS
\r
67 int __KMeansAssertionFailure(const char *file, int line, const char *expression);
\r
68 #define KM_ASSERT(expression) \
\r
69 (void)((expression) != 0? 0 : __KMeansAssertionFailure(__FILE__, __LINE__, #expression))
\r
71 #define KM_ASSERT(expression)
\r
74 // Miscellaneous utilities
\r
75 // =======================
\r
77 // Returns a random integer chosen uniformly from the range [0, n-1]. Note that RAND_MAX could be
\r
78 // less than n. On Visual Studio, it is only 32767. For larger values of RAND_MAX, we need to be
\r
79 // careful of overflow.
\r
80 inline int GetRandom(int n) {
\r
81 int u = rand() * RAND_MAX + rand();
\r
82 return ((u % n) + n) % n;
\r