steve@0
|
1 package org.qmul.eecs.c4dm.sia;
|
steve@0
|
2
|
stevenh@67
|
3 import java.util.ArrayList;
|
steve@0
|
4 import java.util.Collections;
|
steve@0
|
5 import java.util.Iterator;
|
steve@0
|
6 import java.util.List;
|
steve@0
|
7
|
stevenh@67
|
8 import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
|
steve@0
|
9 import org.qmul.eecs.c4dm.sia.model.Datapoint;
|
stevenh@67
|
10 import org.qmul.eecs.c4dm.sia.model.NDimensionalObject;
|
stevenh@67
|
11 import org.qmul.eecs.c4dm.sia.model.SiatecX;
|
stevenh@13
|
12 import org.qmul.eecs.c4dm.sia.model.VectorTable;
|
steve@0
|
13 import org.qmul.eecs.c4dm.sia.model.VectorTableElement;
|
stevenh@13
|
14 import org.qmul.eecs.c4dm.sia.utilities.Display;
|
steve@0
|
15
|
steve@0
|
16 import com.hp.hpl.jena.ontology.OntModel;
|
stevenh@43
|
17 import com.hp.hpl.jena.ontology.OntModelSpec;
|
steve@0
|
18 import com.hp.hpl.jena.rdf.model.ModelFactory;
|
steve@0
|
19
|
steve@0
|
20 /**
|
steve@0
|
21 * <p>
|
stevenh@5
|
22 * Title: SiaMain
|
steve@0
|
23 * </p>
|
steve@0
|
24 * <p>
|
stevenh@67
|
25 * Description: An RDF/OWL/Java implementation of the SIA and SIATEC pattern discovery algorithms.
|
stevenh@67
|
26 * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
|
stevenh@67
|
27 * by Meredith, D. and Lemström, K. and Wiggins, G.A.
|
stevenh@67
|
28 * Optionally takes a single command line argument file path to an N3 ontology file, otherwise uses a
|
stevenh@67
|
29 * hardcoded file path.
|
stevenh@67
|
30 * Writes SIA and SIATEC result to stdout and writes the entire RDF model to the TDB dataset described in
|
stevenh@67
|
31 * src/assemblers/tdb-assembler.ttl
|
steve@0
|
32 * </p>
|
steve@0
|
33 *
|
stevenh@5
|
34 * @author Steve Hargreaves, C4DM, Queen Mary University of London
|
steve@0
|
35 */
|
steve@0
|
36 public class SiaMain {
|
stevenh@43
|
37
|
stevenh@67
|
38 // The ontology loaded as dataset
|
stevenh@67
|
39 public static String ontology = "file:src/rdf/siaTestDatapointOntology.n3";
|
stevenh@67
|
40
|
stevenh@67
|
41 public void run(String[] args) {
|
stevenh@67
|
42
|
stevenh@67
|
43 // If a command-line argument was supplied, assume it's the path
|
stevenh@67
|
44 // of an N3 ontology file
|
stevenh@67
|
45 if (args.length == 1)
|
stevenh@67
|
46 ontology = args[0];
|
steve@0
|
47
|
stevenh@67
|
48 OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
|
stevenh@67
|
49 ontModel.read(ontology, "N3");
|
stevenh@67
|
50
|
steve@0
|
51 // Create custom sia Datapoint objects
|
steve@0
|
52 List<Datapoint> datapoints = SiaDatapointFactory.create(ontModel);
|
stevenh@5
|
53
|
stevenh@13
|
54 // STEP 1 - Order the datapoints
|
steve@0
|
55 Collections.sort(datapoints);
|
stevenh@5
|
56
|
stevenh@86
|
57 // Add datapoint order info
|
stevenh@86
|
58 SiaDatapointFactory.assertOrder(datapoints);
|
stevenh@43
|
59
|
stevenh@86
|
60 // STEP 2 - Compute the SIA vector table
|
stevenh@86
|
61 VectorTable vectorTableW = null;
|
stevenh@86
|
62 try {
|
stevenh@86
|
63 vectorTableW = SiaVectorTableElementFactory.createW(datapoints);
|
stevenh@86
|
64 } catch (DimensionException e) {
|
stevenh@86
|
65 e.printStackTrace();
|
stevenh@86
|
66 System.exit(-1);
|
stevenh@86
|
67 }
|
stevenh@67
|
68
|
stevenh@67
|
69 // STEP 3 - Create custom SIATEC VectorTableElement objects (V)
|
stevenh@86
|
70 VectorTable vectorTableV = null;
|
stevenh@86
|
71 try {
|
stevenh@86
|
72 vectorTableV = SiaVectorTableElementFactory.createV(datapoints);
|
stevenh@86
|
73 } catch (DimensionException e) {
|
stevenh@86
|
74 e.printStackTrace();
|
stevenh@86
|
75 System.exit(-1);
|
stevenh@86
|
76 }
|
stevenh@67
|
77 List<VectorTableElement> vteListV = vectorTableV.getVteList();
|
stevenh@5
|
78
|
stevenh@86
|
79 // STEP 4 - Order the VectorTableElement objects
|
stevenh@67
|
80 Collections.sort(vteListV);
|
steve@0
|
81
|
stevenh@86
|
82 // STEP 5 - Display the SIA (MTP) results
|
stevenh@86
|
83 displaySiaResults(vteListV);
|
steve@0
|
84
|
stevenh@86
|
85 // STEP 6 - "Vectorize" the MTPs
|
stevenh@67
|
86 int m = vteListV.size();
|
stevenh@67
|
87 int i = 0;
|
stevenh@67
|
88 ArrayList<SiatecX> x = new ArrayList<SiatecX>();
|
stevenh@67
|
89
|
stevenh@67
|
90 while (i < m)
|
stevenh@67
|
91 {
|
stevenh@67
|
92 ArrayList<NDimensionalObject> q = new ArrayList<NDimensionalObject>();
|
stevenh@67
|
93 int j = i + 1;
|
stevenh@67
|
94 while (j < m && (vteListV.get(i).compareToIgnoreDatapoints(vteListV.get(j)) == 0))
|
stevenh@67
|
95 {
|
stevenh@67
|
96 NDimensionalObject vector = vteListV.get(j).getFromDatapoint().subtract(vteListV.get(j - 1).getFromDatapoint());
|
stevenh@67
|
97 q.add(vector);
|
stevenh@67
|
98 j++;
|
stevenh@67
|
99 }
|
stevenh@67
|
100
|
stevenh@67
|
101 SiatecX iq = new SiatecX();
|
stevenh@67
|
102 iq.setI(i+1);
|
stevenh@67
|
103 iq.setQ(q);
|
stevenh@67
|
104 x.add(iq);
|
stevenh@67
|
105 i = j;
|
stevenh@67
|
106 }
|
stevenh@67
|
107
|
stevenh@67
|
108 // Sort the elements of x
|
stevenh@67
|
109 Collections.sort(x);
|
stevenh@67
|
110
|
stevenh@67
|
111 // Rename as y to match algorithm description in paper
|
stevenh@67
|
112 ArrayList<SiatecX> y = (ArrayList<SiatecX>) x.clone();
|
stevenh@67
|
113
|
stevenh@86
|
114 // Display results using algorithm figures 23, 24 and 25 of the research paper
|
stevenh@85
|
115 int countTecs = 0;
|
stevenh@67
|
116
|
stevenh@67
|
117 int r = y.size();
|
stevenh@67
|
118 m = vteListV.size();
|
stevenh@67
|
119 i = 0;
|
stevenh@67
|
120 System.out.println();
|
stevenh@67
|
121 System.out.print("{");
|
stevenh@67
|
122 if (r > 0)
|
stevenh@67
|
123 {
|
stevenh@67
|
124 do
|
stevenh@67
|
125 {
|
stevenh@67
|
126 int j = y.get(i).getI() - 1;
|
stevenh@67
|
127 List<Integer> iList = new ArrayList<Integer>();
|
stevenh@67
|
128 while (j < m && (vteListV.get(j).compareToIgnoreDatapoints(vteListV.get(y.get(i).getI() - 1)) == 0))
|
stevenh@67
|
129 {
|
stevenh@67
|
130 iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());
|
stevenh@67
|
131 j++;
|
stevenh@67
|
132 }
|
stevenh@85
|
133 countTecs++;
|
stevenh@67
|
134 System.out.print("<");
|
stevenh@67
|
135 Display.printPattern(iList, datapoints);
|
stevenh@67
|
136
|
stevenh@67
|
137 System.out.print(",");
|
stevenh@67
|
138 printSetOfTranslators(iList, datapoints, vectorTableW);
|
stevenh@67
|
139 System.out.print(">");
|
stevenh@67
|
140 do
|
stevenh@67
|
141 {
|
stevenh@67
|
142 i++;
|
stevenh@67
|
143 } while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0));
|
stevenh@67
|
144
|
stevenh@67
|
145 if (i < r)
|
stevenh@67
|
146 {
|
stevenh@67
|
147 System.out.print(",");
|
stevenh@67
|
148 System.out.println();
|
stevenh@67
|
149 }
|
stevenh@67
|
150 } while (i < r);
|
stevenh@67
|
151 }
|
stevenh@67
|
152 System.out.println("}");
|
stevenh@43
|
153
|
stevenh@85
|
154 System.out.println("Number of TECs: " + countTecs);
|
stevenh@67
|
155 System.out.println("Number of Datapoints (n) = " + datapoints.size() + ", k = 3");
|
stevenh@5
|
156 }
|
stevenh@5
|
157
|
stevenh@5
|
158 /**
|
stevenh@5
|
159 * @param vteList
|
stevenh@5
|
160 */
|
stevenh@86
|
161 public void displaySiaResults(List<VectorTableElement> vteList) {
|
stevenh@5
|
162 int m = vteList.size();
|
stevenh@5
|
163 int i = 0;
|
stevenh@5
|
164
|
stevenh@5
|
165 System.out.println();
|
stevenh@5
|
166 System.out.print("{");
|
stevenh@5
|
167
|
stevenh@85
|
168 int countMtps = 0;
|
stevenh@5
|
169 while (i < m)
|
stevenh@5
|
170 {
|
stevenh@85
|
171 countMtps++;
|
stevenh@5
|
172 System.out.print("<");
|
stevenh@13
|
173 Display.printVector(vteList.get(i));
|
stevenh@67
|
174
|
stevenh@5
|
175 System.out.print(",{");
|
stevenh@13
|
176 Display.printVector(vteList.get(i).getFromDatapoint());
|
stevenh@67
|
177
|
stevenh@5
|
178 int j = i + 1;
|
stevenh@5
|
179
|
stevenh@5
|
180 while (j < m && (vteList.get(i).compareToIgnoreDatapoints(vteList.get(j)) == 0))
|
stevenh@5
|
181 {
|
stevenh@5
|
182 System.out.print(",");
|
stevenh@13
|
183 Display.printVector(vteList.get(j).getFromDatapoint());
|
stevenh@5
|
184 j++;
|
stevenh@5
|
185 }
|
stevenh@5
|
186 System.out.print("}>");
|
stevenh@5
|
187 if (j < m)
|
stevenh@5
|
188 {
|
stevenh@5
|
189 System.out.print(",");
|
stevenh@5
|
190 System.out.println();
|
stevenh@5
|
191 }
|
stevenh@5
|
192 i = j;
|
stevenh@5
|
193 }
|
stevenh@5
|
194 System.out.println("}");
|
stevenh@85
|
195 System.out.println("Number of MTPs: " + countMtps);
|
stevenh@5
|
196 }
|
stevenh@5
|
197
|
stevenh@5
|
198 /**
|
stevenh@5
|
199 * @param vteIter
|
stevenh@5
|
200 * @param message
|
stevenh@5
|
201 */
|
stevenh@5
|
202 public void displayNDimensionalObjects(Iterator<VectorTableElement> vteIter, String message) {
|
stevenh@5
|
203 System.out.println(message);
|
stevenh@5
|
204 System.out.println("----------");
|
stevenh@5
|
205 while (vteIter.hasNext())
|
stevenh@5
|
206 {
|
stevenh@5
|
207 VectorTableElement vte = vteIter.next();
|
stevenh@5
|
208 System.out.println("from: " + vte.getFromDatapoint().getResource().getLocalName() + " to: " + vte.getToDatapoint().getResource().getLocalName());
|
steve@0
|
209 }
|
steve@0
|
210 }
|
steve@0
|
211
|
stevenh@5
|
212 /**
|
stevenh@5
|
213 * @param datapointIter
|
stevenh@5
|
214 * @param message
|
stevenh@5
|
215 */
|
stevenh@5
|
216 public void displayDatapoints(Iterator<Datapoint> datapointIter, String message) {
|
stevenh@5
|
217 System.out.println(message);
|
stevenh@5
|
218 System.out.println("----------");
|
stevenh@5
|
219 while (datapointIter.hasNext())
|
stevenh@5
|
220 {
|
stevenh@5
|
221 Datapoint datapoint = datapointIter.next();
|
stevenh@5
|
222 System.out.println( datapoint.getResource().getLocalName());
|
stevenh@5
|
223 }
|
stevenh@5
|
224 }
|
stevenh@5
|
225
|
stevenh@67
|
226 private void printSetOfTranslators(List<Integer> iList, List<Datapoint> datapoints, VectorTable vectorTableW) {
|
stevenh@67
|
227 int p = iList.size();
|
stevenh@67
|
228 int n = datapoints.size();
|
stevenh@67
|
229
|
stevenh@67
|
230 if (p == 1)
|
stevenh@67
|
231 {
|
stevenh@67
|
232 System.out.print("{");
|
stevenh@67
|
233 Display.printVector(vectorTableW.getVector(iList.get(0), 1));
|
stevenh@67
|
234 for (int k = 2; k <= n; k++)
|
stevenh@67
|
235 {
|
stevenh@67
|
236 System.out.print(",");
|
stevenh@67
|
237 Display.printVector(vectorTableW.getVector(iList.get(0), k));
|
stevenh@67
|
238 }
|
stevenh@67
|
239 System.out.print("}");
|
stevenh@67
|
240 }
|
stevenh@67
|
241 else
|
stevenh@67
|
242 {
|
stevenh@67
|
243 System.out.print("{");
|
stevenh@67
|
244 List<Integer> jList = new ArrayList<Integer>();
|
stevenh@67
|
245 for (int k = 0; k < p; k++)
|
stevenh@67
|
246 {
|
stevenh@67
|
247 jList.add(1);
|
stevenh@67
|
248 }
|
stevenh@67
|
249 boolean finished = false;
|
stevenh@67
|
250 boolean first_vector = true;
|
stevenh@67
|
251 int k = 1;
|
stevenh@67
|
252
|
stevenh@67
|
253 while (!finished)
|
stevenh@67
|
254 {
|
stevenh@67
|
255 if (jList.get(k) <= jList.get(k - 1))
|
stevenh@67
|
256 {
|
stevenh@67
|
257 jList.set(k, jList.get(k - 1) + 1);
|
stevenh@67
|
258 }
|
stevenh@67
|
259
|
stevenh@67
|
260 while (jList.get(k) <= (n - p + k + 1)
|
stevenh@67
|
261 && (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1)))) < 0))
|
stevenh@67
|
262 {
|
stevenh@67
|
263 jList.set(k, jList.get(k) + 1);
|
stevenh@67
|
264 }
|
stevenh@67
|
265
|
stevenh@67
|
266 if (jList.get(k) > n - p + k + 1)
|
stevenh@67
|
267 {
|
stevenh@67
|
268 finished = true;
|
stevenh@67
|
269 }
|
stevenh@67
|
270 else if (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1)))) > 0)
|
stevenh@67
|
271 {
|
stevenh@67
|
272 k = 1;
|
stevenh@67
|
273 jList.set(0, jList.get(0) + 1);
|
stevenh@67
|
274 if (jList.get(0) > n - p + 1)
|
stevenh@67
|
275 {
|
stevenh@67
|
276 finished = true;
|
stevenh@67
|
277 }
|
stevenh@67
|
278 }
|
stevenh@67
|
279 else if (k + 1 == p)
|
stevenh@67
|
280 {
|
stevenh@67
|
281 if (!first_vector)
|
stevenh@67
|
282 {
|
stevenh@67
|
283 System.out.print(",");
|
stevenh@67
|
284 }
|
stevenh@67
|
285 else
|
stevenh@67
|
286 {
|
stevenh@67
|
287 first_vector = false;
|
stevenh@67
|
288 }
|
stevenh@67
|
289
|
stevenh@67
|
290 Display.printVector(vectorTableW.getVector(iList.get(k), jList.get(k)));
|
stevenh@67
|
291 k = 0;
|
stevenh@67
|
292
|
stevenh@67
|
293 while (k < p)
|
stevenh@67
|
294 {
|
stevenh@67
|
295 jList.set(k, jList.get(k) + 1);
|
stevenh@67
|
296 if (jList.get(k) > n - p + k +1)
|
stevenh@67
|
297 {
|
stevenh@67
|
298 finished = true;
|
stevenh@67
|
299 k = p -1;
|
stevenh@67
|
300 }
|
stevenh@67
|
301 k++;
|
stevenh@67
|
302 }
|
stevenh@67
|
303 k = 1;
|
stevenh@67
|
304 }
|
stevenh@67
|
305 else
|
stevenh@67
|
306 {
|
stevenh@67
|
307 k++;
|
stevenh@67
|
308 }
|
stevenh@67
|
309 }
|
stevenh@67
|
310 System.out.print("}");
|
stevenh@67
|
311 }
|
stevenh@67
|
312 }
|
stevenh@67
|
313
|
stevenh@67
|
314 private void printX(ArrayList<SiatecX> x) {
|
stevenh@67
|
315 for (SiatecX iq : x)
|
stevenh@67
|
316 {
|
stevenh@67
|
317 System.out.print(iq.getI() + ",");
|
stevenh@67
|
318 for (NDimensionalObject q : iq.getQ())
|
stevenh@67
|
319 {
|
stevenh@67
|
320 System.out.print("<");
|
stevenh@67
|
321 int dimensions = q.getDimensionValues().size();
|
stevenh@67
|
322 for (int dim = 1; dim <= dimensions; dim++)
|
stevenh@67
|
323 {
|
stevenh@67
|
324 try {
|
stevenh@67
|
325 System.out.print(q.getDimensionValue(dim) + (dim == dimensions ? "" : ","));
|
stevenh@67
|
326 } catch (DimensionException e) {
|
stevenh@67
|
327 e.printStackTrace();
|
stevenh@67
|
328 System.exit(1);
|
stevenh@67
|
329 }
|
stevenh@67
|
330 }
|
stevenh@67
|
331 System.out.println(">");
|
stevenh@67
|
332 }
|
stevenh@67
|
333 System.out.println();
|
stevenh@67
|
334 }
|
stevenh@67
|
335 }
|
stevenh@67
|
336
|
stevenh@5
|
337 /**
|
stevenh@5
|
338 * @param args
|
stevenh@5
|
339 */
|
steve@0
|
340 public static void main(String[] args) {
|
stevenh@43
|
341 long startTime = System.currentTimeMillis();
|
steve@0
|
342 SiaMain app = new SiaMain();
|
stevenh@67
|
343 app.run(args);
|
stevenh@43
|
344 long endTime = System.currentTimeMillis();
|
stevenh@43
|
345 long elapsedTime = endTime - startTime;
|
stevenh@43
|
346 System.out.println("Completed in " + elapsedTime + " ms");
|
steve@0
|
347 }
|
steve@0
|
348
|
steve@0
|
349 }
|