-
Notifications
You must be signed in to change notification settings - Fork 0
/
getSimMatrix.php
223 lines (152 loc) · 5.05 KB
/
getSimMatrix.php
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
<?php
/**
* getSimMatrix.php
* Retrieves the similarity matrix for the given folder.
*
* @author Zeshawn Shaheen
*/
/**
* @module Get Similarity Matrix
*
*/
/**
* @class Get Similarity Matrix
*/
$dir = $_GET['dir'];
//The array to be given to the client
$simMatrix=[];
//First look for simmatrix, if it doesn't exit, then create dir
if ($handle = opendir($dir)) {
if(file_exists($dir.'/simmatrix.json')) {
//load simmatrix.json
$simMatrix = json_decode(file_get_contents($dir.'/simmatrix.json'));
}
else {
//create simmatrix.json
$simMatrix = createSimMatrix($dir, $handle);
}
}
//send simmatrix.json to client
print json_encode($simMatrix);
/**
* Creates the similarity matrix.
* @method createSimMatrix
* @param String $dir Path to the folder where 'simmatrix.json' will be saved.
* @param Resource $handle The opened directory handle.
* @return Array The similarity matrix, an n x n array where n is the number of files in $dir .
*/
function createSimMatrix($dir, $handle) {
//$comArray is array of COM data which is line 1 of all of the files
$comArray = getData($dir, $handle);
/*Apply a similarity algorithm to $comArray based on the
euclidean distance of each index to everyone */
$simMatrix = similarityAlgo($comArray);
//now create the index array
$indiciesArray = [];
for($i=0; $i<count($simMatrix); $i++) {
$indiciesArray[$i] = sort1DSimMatrix($simMatrix[$i]);
}
//Save the index array to a file
file_put_contents($dir.'/simmatrix.json', json_encode($indiciesArray));
return $indiciesArray;
}
/**
* Gets the COM data from each of the files in $dir .
* @method getData
* @param String $dir Path to the folder where the files are located.
* @param Resource $handle The opened directory handle.
* @return Array The raw COM data, an n x 3 array where n is the number of files in $dir .
*/
function getData($dir, $handle) {
//Create an array of all of the COM data within each file in $dir
$listOfFiles = "";
while (false !== ($entry = readdir($handle))) {
// get rid of dotted entries
if ($entry[0] != ".") {
$listOfFiles .= $entry . "NF";
}
}
$listOfFiles = split("NF", $listOfFiles);
//remove the last element in $listOfFiles, which is ""
unset($listOfFiles[count($listOfFiles)-1]);
//Now open the each of the files
$comArray = [];
for ($i=0; $i<count($listOfFiles); $i++) {
$file = fopen($dir.$listOfFiles[$i], "r");
$comLine = fgets($file);
//Split the string 'COM X Y Z' into [COM, X, Y, Z]
$comLine = split(" ", $comLine);
//Remove the 'COM' in the line
array_shift($comLine);
//Now add [X, Y, Z] to the comArray
array_push($comArray, $comLine);
fclose($file);
}
return $comArray;
}
function similarityAlgo($comArray) {
//Calculates the euclidean distance between each points
/**
* EX: $simMatrix[0][1] is the euclidean distance from $comArray[0] and $comArray[1]
* which are the first and second files in the folder respectively.
*/
$simMatrix = [];
$length = count($comArray);
for($i=0; $i<$length; $i++) {
$temp1DArray = [];
for($j=0; $j<$length; $j++) {
array_push($temp1DArray, euclideanDistance($comArray[$i], $comArray[$j]));
}
array_push($simMatrix, $temp1DArray);
}
return $simMatrix;
}
/**
* Computes the euclidean distance between $v1 and $v2
* @method euclideanDistance
* @param Array $v1 A 1 dimensional array of size 3
* @param Array $v2 A 1 dimensional array of size 3.
* @return Float The euclidean distance between $v1 and $v2.
*/
function euclideanDistance($v1, $v2){
return sqrt( (($v1[0]-$v2[0])*($v1[0]-$v2[0]))
+ (($v1[1]-$v2[1])*($v1[1]-$v2[1]))
+ (($v1[2]-$v2[2])*($v1[2]-$v2[2])));
}
/**
* Sorts a 1D array in ascending order, returning an array of indices.
* @method sort1DSimMatrix
* @param Array $simMatrix A 1 dimensional array to be sorted.
* @return Array A sorted array with each element is an index.
*/
function sort1DSimMatrix($simMatrix) {
//Sorts the value of the simMatrix based on indices
$returnArr = [];
$length = count($simMatrix);
for($i=0; $i<$length; $i++) {
//push the index of each
$simMatrix[$i] = [$simMatrix[$i], $i];
}
//Sort the array based on compareAlgo()
usort($simMatrix, "compareAlgo");
//Now extract the indices
for($j=0; $j<$length; $j++) {
//push each row of the indices of $simMatix to $returnArray.
$returnArr[$j] = $simMatrix[$j][1];
}
return $returnArr;
}
/**
* Compares two elements.
* @method compareAlgo
* @param Object $a An element in an array where each element is [float, index].
* @param Object $b An element in an array where each element is [float, index].
* @return Bool True or False based on ascending size.
*/
function compareAlgo($a, $b) {
if ($a[0] == $b[0]) {
return 0;
}
return ($a[0] < $b[0]) ? -1 : 1;
}
?>