5
5
6
6
import Foundation
7
7
8
- // Need a container to easily hold 2 Dimensional Vector2Ds
9
- class Vector2D : CustomStringConvertible {
10
- var x : Float = 0.0 // x-Coordinate of Vector2D
11
- var y : Float = 0.0 // y-Coordinate of Vector2D
8
+ // Need a container to easily hold N Dimensional Vectors
9
+ class VectorND : CustomStringConvertible {
10
+ private var length : Int = 0
11
+ private var data : [ Float ] = [ Float ] ( )
12
12
13
- init ( x : Float , y : Float ) {
14
- self . x = x
15
- self . y = y
13
+ init ( d : [ Float ] ) {
14
+ self . data = d
15
+ self . length = d . count
16
16
}
17
17
18
- var description : String {
19
- return " Vector2D ( \( self . x ) , \( self . y ) ) "
20
- }
18
+ var description : String { return " VectorND ( \( self . data ) " }
19
+ func getData ( ) -> [ Float ] { return data }
20
+ func getLength ( ) -> Int { return length }
21
21
}
22
22
23
- // Ability to use std operators on Vector2D object
24
- func + ( left: Vector2D , right: Vector2D ) -> Vector2D {
25
- return Vector2D ( x: left. x + right. x, y: left. y + right. y)
23
+ // Ability to use std operators on VectorND object
24
+ func + ( left: VectorND , right: VectorND ) -> VectorND {
25
+ var results = [ Float] ( count: left. getLength ( ) , repeatedValue: 0.0 )
26
+ for idx in 0 ..< left. getLength ( ) {
27
+ results [ idx] = left. getData ( ) [ idx] + right. getData ( ) [ idx]
28
+ }
29
+ return VectorND ( d: results)
26
30
}
27
- func += ( inout left: Vector2D , right: Vector2D ) {
31
+ func += ( inout left: VectorND , right: VectorND ) {
28
32
left = left + right
29
33
}
30
- func / ( left: Vector2D , right: Float ) -> Vector2D {
31
- return Vector2D ( x: left. x / right, y: left. y / right)
34
+ func / ( left: VectorND , right: Float ) -> VectorND {
35
+ var results = [ Float] ( count: left. getLength ( ) , repeatedValue: 0.0 )
36
+ for (idx, value) in left. getData ( ) . enumerate ( ) {
37
+ results [ idx] = value / right
38
+ }
39
+ return VectorND ( d: results)
32
40
}
33
- func /= ( inout left: Vector2D , right: Float ) {
41
+ func /= ( inout left: VectorND , right: Float ) {
34
42
left = left / right
35
43
}
36
44
@@ -49,16 +57,20 @@ extension Array {
49
57
}
50
58
}
51
59
52
- // Calculates the Euclidean distance between two Vector2Ds
53
- func euclidean( v1: Vector2D , v2: Vector2D ) -> Float {
54
- return sqrt ( pow ( ( v1. x - v2. x) , 2.0 ) + pow( ( v1. y - v2. y) , 2.0 ) )
60
+ // Calculates the Euclidean distance between two VectorNDs
61
+ func euclidean( v1: VectorND , v2: VectorND ) -> Float {
62
+ var result : Float = 0.0
63
+ for idx in 0 ..< v1. getLength ( ) {
64
+ result += pow ( v1. getData ( ) [ idx] - v2. getData ( ) [ idx] , 2.0 )
65
+ }
66
+ return sqrt ( result)
55
67
}
56
68
57
69
// Get the INDEX of nearest Center to X
58
- func nearestCenter( x: Vector2D , Centers: [ Vector2D ] ) -> Int {
70
+ func nearestCenter( x: VectorND , Centers: [ VectorND ] ) -> Int {
59
71
var nearestDist = FLT_MAX
60
72
var minIndex : Int = 0 ;
61
- // Calculate the distance from Vector2D X to all the centers
73
+ // Calculate the distance from VectorND X to all the centers
62
74
for (idx, c) in Centers . enumerate ( ) {
63
75
let dist = euclidean ( x, v2: c)
64
76
if dist < nearestDist {
@@ -69,19 +81,20 @@ func nearestCenter(x: Vector2D, Centers: [Vector2D]) -> Int {
69
81
return minIndex
70
82
}
71
83
72
- func kNN( numCenters: Int , convergeDist: Float , points: [ Vector2D ] ) -> [ Vector2D ] {
84
+ func kNN( numCenters: Int , convergeDist: Float , points: [ VectorND ] ) -> [ VectorND ] {
73
85
var centerMoveDist : Float = 0.0
86
+ let zeros = [ Float] ( count: points [ 0 ] . getLength ( ) , repeatedValue: 0.0 )
74
87
75
- // 1. Choose k Random Vector2Ds as the initial centers
76
- var kCenters : [ Vector2D ] = points. choose ( numCenters)
88
+ // 1. Choose k Random VectorNDs as the initial centers
89
+ var kCenters : [ VectorND ] = points. choose ( numCenters)
77
90
78
91
// do following steps until convergence
79
92
repeat {
80
93
var cnts = [ Float] ( count: numCenters, repeatedValue: 0.0 )
81
- var nCenters = [ Vector2D ] ( count: numCenters, repeatedValue: Vector2D ( x : 0 , y : 0 ) )
82
- // 2. Assign Vector2Ds to centers
83
- // a. Determine which center each Vector2D is closest to
84
- // b. Record how many Vector2Ds are assigned to each center
94
+ var nCenters = [ VectorND ] ( count: numCenters, repeatedValue: VectorND ( d : zeros ) )
95
+ // 2. Assign VectorNDs to centers
96
+ // a. Determine which center each VectorND is closest to
97
+ // b. Record how many VectorNDs are assigned to each center
85
98
for p in points {
86
99
let c = nearestCenter ( p, Centers: kCenters)
87
100
cnts [ c] ++
@@ -102,15 +115,16 @@ func kNN(numCenters: Int, convergeDist: Float, points: [Vector2D]) -> [Vector2D]
102
115
} while ( centerMoveDist > convergeDist)
103
116
return kCenters
104
117
}
105
- var points = [ Vector2D] ( )
106
- let lim = 50
118
+
119
+ var points = [ VectorND] ( )
120
+ let lim = 10
107
121
for _ in 0 ..< lim {
108
122
let x = Float ( arc4random_uniform ( UInt32 ( lim) ) )
109
123
let y = Float ( arc4random_uniform ( UInt32 ( lim) ) )
110
- points. append ( Vector2D ( x : Float ( x ) , y: y ) )
124
+ points. append ( VectorND ( d : [ x , y] ) )
111
125
}
112
126
113
127
print ( " \n Centers " )
114
- for c in kNN ( 10 , convergeDist: 0.1 , points: points) {
128
+ for c in kNN ( 3 , convergeDist: 0.1 , points: points) {
115
129
print ( c)
116
- }
130
+ }
0 commit comments