--- /dev/null
+// BEWARE: BETA VERSION\r
+// --------------------\r
+//\r
+// Utilities for arbitrary dimensional points in space. All points are treated as simple value\r
+// arrays. This is done for two reasons:\r
+// - Using value arrays instead of a point class makes all point operations very explicit, which\r
+// makes their usage easier to optimize.\r
+// - A value array is about as universal a format as possible, which makes it easier for\r
+// people to use the k-means code in any project.\r
+// Also contains assertion code that can be disabled if desired.\r
+//\r
+// Author: David Arthur (darthur@gmail.com), 2009\r
+\r
+#ifndef KM_UTILS_H__\r
+#define KM_UTILS_H__\r
+\r
+// Includes\r
+#ifndef CLUSTALO\r
+#include <malloc.h>\r
+#endif\r
+#include <memory.h>\r
+#include <stdlib.h>\r
+\r
+// The data-type used for a single coordinate for points\r
+typedef double Scalar;\r
+\r
+// Point utilities\r
+// ===============\r
+\r
+// Point creation and deletion\r
+inline Scalar *PointAllocate(int d) {\r
+ return (Scalar*)malloc(d * sizeof(Scalar));\r
+}\r
+\r
+inline void PointFree(Scalar *p) {\r
+ free(p);\r
+}\r
+\r
+inline void PointCopy(Scalar *p1, const Scalar *p2, int d) {\r
+ memcpy(p1, p2, d * sizeof(Scalar));\r
+}\r
+\r
+// Point vector tools\r
+inline void PointAdd(Scalar *p1, const Scalar *p2, int d) {\r
+ for (int i = 0; i < d; i++)\r
+ p1[i] += p2[i];\r
+}\r
+\r
+inline void PointScale(Scalar *p, Scalar scale, int d) {\r
+ for (int i = 0; i < d; i++)\r
+ p[i] *= scale;\r
+}\r
+\r
+inline Scalar PointDistSq(const Scalar *p1, const Scalar *p2, int d) {\r
+ Scalar result = 0;\r
+ for (int i = 0; i < d; i++)\r
+ result += (p1[i] - p2[i]) * (p1[i] - p2[i]);\r
+ return result;\r
+}\r
+\r
+// Assertions\r
+// ==========\r
+\r
+// Comment out ENABLE_KMEANS_ASSERTS to turn off ASSERTS for added speed.\r
+#define ENABLE_KMEANS_ASSERTS\r
+#ifdef ENABLE_KMEANS_ASSERTS\r
+int __KMeansAssertionFailure(const char *file, int line, const char *expression);\r
+#define KM_ASSERT(expression) \\r
+ (void)((expression) != 0? 0 : __KMeansAssertionFailure(__FILE__, __LINE__, #expression))\r
+#else\r
+#define KM_ASSERT(expression)\r
+#endif\r
+\r
+// Miscellaneous utilities\r
+// =======================\r
+\r
+// Returns a random integer chosen uniformly from the range [0, n-1]. Note that RAND_MAX could be\r
+// less than n. On Visual Studio, it is only 32767. For larger values of RAND_MAX, we need to be\r
+// careful of overflow.\r
+inline int GetRandom(int n) {\r
+ int u = rand() * RAND_MAX + rand();\r
+ return ((u % n) + n) % n;\r
+}\r
+\r
+#endif\r