Created
January 9, 2019 19:16
-
-
Save novoselrok/44c2999aa9d3700f4f0642881dfa1ecc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use Random; | |
| use Time; | |
| use BlockDist; | |
| /* Config variables */ | |
| config const filename = "../data/test_10_10_2.chpl.txt"; | |
| config const outFilename = "out.txt"; | |
| config const k = 2; | |
| config const maxIter = 10; | |
| config const numPoints = 10; | |
| /* Datatypes */ | |
| type Point = 100 * real; | |
| record Cluster { | |
| var size: int; | |
| var pointSum: Point; | |
| var mean: Point; | |
| proc init() {} | |
| proc init(point: Point) { | |
| mean = point; | |
| } | |
| proc distance(p: Point) { | |
| var squaredDiff = (mean - p) ** 2; | |
| var sum = 0.0; | |
| for el in squaredDiff { | |
| sum += el; | |
| } | |
| return sqrt(sum); | |
| } | |
| // Used when reducing clusters | |
| proc addCluster(other: Cluster) { | |
| size += other.size; | |
| pointSum += other.pointSum; | |
| } | |
| proc addPoint(ref p: Point) { | |
| pointSum += p; | |
| size += 1; | |
| } | |
| proc setMean(ref p: Point) { | |
| mean = p; | |
| } | |
| proc calcMean() { | |
| mean = pointSum / size; | |
| } | |
| } | |
| // Used when reducing clusters | |
| proc +(ref c1: Cluster, c2: Cluster) { | |
| c1.addCluster(c2); | |
| return c1; | |
| } | |
| proc main() { | |
| var pointsSpace = {0..#numPoints}; | |
| var pointsDomain = pointsSpace dmapped Block(boundingBox=pointsSpace); | |
| var points: [pointsDomain] Point; | |
| var labels: [pointsDomain] int; | |
| var clustersDomain = {0..#k}; | |
| var clusters: [clustersDomain] Cluster; | |
| /* Read input file */ | |
| var f = open(filename, iomode.r); | |
| var reader = f.reader(); | |
| for i in pointsDomain { | |
| points[i] = reader.read(Point); | |
| } | |
| f.close(); | |
| reader.close(); | |
| var watch: Timer; | |
| watch.start(); | |
| /* Algorithm */ | |
| var randStream = new owned RandomStream(real); | |
| for i in clustersDomain { | |
| var idx: int = (randStream.getNext() * numPoints):int; | |
| clusters[i] = new Cluster(points[idx]); | |
| } | |
| for iteration in 0..#maxIter { | |
| var newClusters: [clustersDomain] Cluster; | |
| coforall L in Locales with (+ reduce newClusters) { | |
| on L { | |
| const indices = points.localSubdomain(); | |
| writeln(here.id); | |
| for i in indices { | |
| writeln(i); | |
| // You have to be careful with tuples since they create copies | |
| ref point = points[i]; | |
| var minIndex = 0; | |
| var minValue = Math.INFINITY; | |
| for (idx, cluster) in zip(clusters.domain, clusters) { | |
| var distance = cluster.distance(point); | |
| if (distance < minValue) { | |
| minValue = distance; | |
| minIndex = idx; | |
| } | |
| } | |
| labels[i] = minIndex; | |
| newClusters[minIndex].addPoint(point); | |
| } | |
| } | |
| } | |
| /* | |
| for cluster in newClusters { | |
| cluster.calcMean(); | |
| } | |
| clusters = newClusters; | |
| */ | |
| } | |
| writeln(watch.elapsed()); | |
| // Output labels | |
| var outf = open(outFilename, iomode.cw); | |
| var writer = outf.writer(); | |
| for lbl in labels { | |
| writer.writeln(lbl); | |
| } | |
| writer.close(); | |
| outf.close(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment