stevenh@14
|
1 package org.qmul.eecs.c4dm.sia;
|
stevenh@14
|
2
|
stevenh@14
|
3 import java.util.ArrayList;
|
stevenh@14
|
4 import java.util.Collections;
|
stevenh@14
|
5 import java.util.List;
|
stevenh@14
|
6
|
stevenh@14
|
7 import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
|
stevenh@14
|
8 import org.qmul.eecs.c4dm.sia.model.Datapoint;
|
stevenh@14
|
9 import org.qmul.eecs.c4dm.sia.model.NDimensionalObject;
|
stevenh@14
|
10 import org.qmul.eecs.c4dm.sia.model.SiatecX;
|
stevenh@14
|
11 import org.qmul.eecs.c4dm.sia.model.VectorTable;
|
stevenh@14
|
12 import org.qmul.eecs.c4dm.sia.model.VectorTableElement;
|
stevenh@14
|
13 import org.qmul.eecs.c4dm.sia.utilities.Display;
|
stevenh@14
|
14
|
stevenh@14
|
15 import com.hp.hpl.jena.ontology.OntModel;
|
stevenh@44
|
16 import com.hp.hpl.jena.ontology.OntModelSpec;
|
stevenh@44
|
17 import com.hp.hpl.jena.query.Dataset;
|
stevenh@44
|
18 import com.hp.hpl.jena.query.ReadWrite;
|
stevenh@14
|
19 import com.hp.hpl.jena.rdf.model.Model;
|
stevenh@14
|
20 import com.hp.hpl.jena.rdf.model.ModelFactory;
|
stevenh@44
|
21 import com.hp.hpl.jena.tdb.TDBFactory;
|
stevenh@44
|
22 import com.hp.hpl.jena.update.UpdateAction;
|
stevenh@14
|
23
|
stevenh@14
|
24 /**
|
stevenh@14
|
25 * <p>
|
stevenh@14
|
26 * Title: SiaTecMain
|
stevenh@14
|
27 * </p>
|
stevenh@14
|
28 * <p>
|
stevenh@14
|
29 * Description: An RDF/OWL/Java implementation of the SIATEC pattern discovery algorithm.
|
stevenh@14
|
30 * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
|
stevenh@14
|
31 * by Meredith, D. and Lemström, K. and Wiggins, G.A.
|
stevenh@14
|
32 * </p>
|
stevenh@14
|
33 *
|
stevenh@14
|
34 * @author Steve Hargreaves, C4DM, Queen Mary University of London
|
stevenh@14
|
35 */
|
stevenh@14
|
36 public class SiaTecMain {
|
stevenh@14
|
37
|
stevenh@44
|
38 // UPDATE queries
|
stevenh@44
|
39 private static final String insertSiatecVectorTableBNodesQuery = "file:src/sparql/insert_siatec_vector_table_bnodes.sparql";
|
stevenh@44
|
40 private static final String insertVectorTableDetailsQuery = "file:src/sparql/insert_vector_table_details.sparql";
|
stevenh@14
|
41
|
stevenh@14
|
42 public void run() {
|
stevenh@14
|
43
|
stevenh@44
|
44 // Obtain a dataset context
|
stevenh@44
|
45 Dataset dataset = TDBFactory.assembleDataset(SiaMain.assemblerFile);
|
stevenh@14
|
46
|
stevenh@44
|
47 // Get the sia graph, as a model, from the dataset
|
stevenh@44
|
48 Model siaModel = dataset.getNamedModel(SiaMain.graph);
|
stevenh@14
|
49
|
stevenh@44
|
50 OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, siaModel);
|
stevenh@14
|
51
|
stevenh@14
|
52 // Create custom sia Datapoint objects
|
stevenh@14
|
53 List<Datapoint> datapoints = SiaDatapointFactory.create(ontModel);
|
stevenh@14
|
54
|
stevenh@14
|
55 // STEP 1 - Order the datapoints
|
stevenh@14
|
56 Collections.sort(datapoints);
|
stevenh@14
|
57
|
stevenh@14
|
58 // Add datapoint order info to model
|
stevenh@14
|
59 SiaDatapointFactory.assertOrder(ontModel, datapoints);
|
stevenh@14
|
60
|
stevenh@44
|
61 // STEP 2 - Compute the vector table
|
stevenh@44
|
62 // Run all the UPDATE queries
|
stevenh@44
|
63 UpdateAction.readExecute(insertSiatecVectorTableBNodesQuery, ontModel);
|
stevenh@44
|
64 UpdateAction.readExecute(insertVectorTableDetailsQuery, ontModel);
|
stevenh@44
|
65
|
stevenh@14
|
66 VectorTable vectorTableW = SiaVectorTableElementFactory.createW(ontModel, datapoints);
|
stevenh@14
|
67
|
stevenh@14
|
68 // STEP 3 - Create custom SIATEC VectorTableElement objects (V)
|
stevenh@14
|
69 VectorTable vectorTableV = SiaVectorTableElementFactory.createV(ontModel, datapoints);
|
stevenh@14
|
70 List<VectorTableElement> vteListV = vectorTableV.getVteList();
|
stevenh@14
|
71
|
stevenh@14
|
72 // STEP 4 - Sort V
|
stevenh@14
|
73 Collections.sort(vteListV);
|
stevenh@14
|
74
|
stevenh@14
|
75 // Add vector table element order info to model
|
stevenh@14
|
76 SiaVectorTableElementFactory.assertOrder(ontModel, vteListV);
|
stevenh@14
|
77
|
stevenh@14
|
78 // STEP 5 - "Vectorize" the MTPs
|
stevenh@14
|
79 int m = vteListV.size();
|
stevenh@14
|
80 int i = 0;
|
stevenh@14
|
81 ArrayList<SiatecX> x = new ArrayList<SiatecX>();
|
stevenh@14
|
82
|
stevenh@14
|
83 while (i < m)
|
stevenh@14
|
84 {
|
stevenh@14
|
85 ArrayList<NDimensionalObject> q = new ArrayList<NDimensionalObject>();
|
stevenh@14
|
86 int j = i + 1;
|
stevenh@14
|
87 while (j < m && (vteListV.get(i).compareToIgnoreDatapoints(vteListV.get(j)) == 0))
|
stevenh@14
|
88 {
|
stevenh@14
|
89 NDimensionalObject vector = vteListV.get(j).getFromDatapoint().subtract(vteListV.get(j - 1).getFromDatapoint());
|
stevenh@14
|
90 q.add(vector);
|
stevenh@14
|
91 j++;
|
stevenh@14
|
92 }
|
stevenh@14
|
93
|
stevenh@14
|
94 SiatecX iq = new SiatecX();
|
stevenh@14
|
95 iq.setI(i+1);
|
stevenh@14
|
96 iq.setQ(q);
|
stevenh@14
|
97 x.add(iq);
|
stevenh@14
|
98 i = j;
|
stevenh@14
|
99 }
|
stevenh@14
|
100
|
stevenh@14
|
101 // Sort the elements of x
|
stevenh@14
|
102 Collections.sort(x);
|
stevenh@14
|
103
|
stevenh@14
|
104 // Rename as y to match algorithm description in paper
|
stevenh@14
|
105 ArrayList<SiatecX> y = (ArrayList<SiatecX>) x.clone();
|
stevenh@14
|
106
|
stevenh@14
|
107 // Display results using algorithm figures 23, 24 and 25 of the research paper
|
stevenh@14
|
108 int r = y.size();
|
stevenh@14
|
109 m = vteListV.size();
|
stevenh@15
|
110 i = 0;
|
stevenh@14
|
111 System.out.println();
|
stevenh@14
|
112 System.out.print("{");
|
stevenh@15
|
113 if (r > 0)
|
stevenh@14
|
114 {
|
stevenh@14
|
115 do
|
stevenh@14
|
116 {
|
stevenh@15
|
117 int j = y.get(i).getI() - 1;
|
stevenh@14
|
118 List<Integer> iList = new ArrayList<Integer>();
|
stevenh@44
|
119 while (j < m && (vteListV.get(j).compareToIgnoreDatapoints(vteListV.get(y.get(i).getI() - 1)) == 0))
|
stevenh@14
|
120 {
|
stevenh@14
|
121 iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());
|
stevenh@14
|
122 j++;
|
stevenh@14
|
123 }
|
stevenh@14
|
124 System.out.print("<");
|
stevenh@14
|
125 Display.printPattern(iList, datapoints);
|
stevenh@14
|
126 System.out.print(",");
|
stevenh@14
|
127 printSetOfTranslators(iList, datapoints, vectorTableW);
|
stevenh@14
|
128 System.out.print(">");
|
stevenh@14
|
129 do
|
stevenh@14
|
130 {
|
stevenh@14
|
131 i++;
|
stevenh@15
|
132 } while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0));
|
stevenh@14
|
133
|
stevenh@15
|
134 if (i < r)
|
stevenh@14
|
135 {
|
stevenh@14
|
136 System.out.print(",");
|
stevenh@14
|
137 System.out.println();
|
stevenh@14
|
138 }
|
stevenh@15
|
139 } while (i < r);
|
stevenh@14
|
140 }
|
stevenh@14
|
141 System.out.println("}");
|
stevenh@14
|
142
|
stevenh@44
|
143 // Write the model to the TDB dataset
|
stevenh@44
|
144 dataset.begin(ReadWrite.WRITE) ;
|
stevenh@44
|
145 try {
|
stevenh@44
|
146 dataset.replaceNamedModel(SiaMain.graph, ontModel);
|
stevenh@44
|
147 dataset.commit();
|
stevenh@44
|
148 System.out.println("dataset.commit() done");
|
stevenh@44
|
149 } finally {
|
stevenh@44
|
150 dataset.end();
|
stevenh@44
|
151 System.out.println("dataset.end() done");
|
stevenh@44
|
152 }
|
stevenh@14
|
153
|
stevenh@44
|
154 dataset.close();
|
stevenh@44
|
155 System.out.println("dataset.close() done");
|
stevenh@44
|
156
|
stevenh@44
|
157 System.out.println("Number of Datapoints (n) = " + datapoints.size() + ", k = 3");
|
stevenh@14
|
158 }
|
stevenh@14
|
159
|
stevenh@14
|
160 private void printSetOfTranslators(List<Integer> iList, List<Datapoint> datapoints, VectorTable vectorTableW) {
|
stevenh@14
|
161 int p = iList.size();
|
stevenh@14
|
162 int n = datapoints.size();
|
stevenh@14
|
163
|
stevenh@14
|
164 if (p == 1)
|
stevenh@14
|
165 {
|
stevenh@14
|
166 System.out.print("{");
|
stevenh@14
|
167 Display.printVector(vectorTableW.getVector(iList.get(0), 1));
|
stevenh@14
|
168 for (int k = 2; k <= n; k++)
|
stevenh@14
|
169 {
|
stevenh@14
|
170 System.out.print(",");
|
stevenh@14
|
171 Display.printVector(vectorTableW.getVector(iList.get(0), k));
|
stevenh@14
|
172 }
|
stevenh@14
|
173 System.out.print("}");
|
stevenh@14
|
174 }
|
stevenh@14
|
175 else
|
stevenh@14
|
176 {
|
stevenh@14
|
177 System.out.print("{");
|
stevenh@14
|
178 List<Integer> jList = new ArrayList<Integer>();
|
stevenh@14
|
179 for (int k = 0; k < p; k++)
|
stevenh@14
|
180 {
|
stevenh@14
|
181 jList.add(1);
|
stevenh@14
|
182 }
|
stevenh@14
|
183 boolean finished = false;
|
stevenh@14
|
184 boolean first_vector = true;
|
stevenh@14
|
185 int k = 1;
|
stevenh@14
|
186
|
stevenh@14
|
187 while (!finished)
|
stevenh@14
|
188 {
|
stevenh@14
|
189 if (jList.get(k) <= jList.get(k - 1))
|
stevenh@14
|
190 {
|
stevenh@14
|
191 jList.set(k, jList.get(k - 1) + 1);
|
stevenh@14
|
192 }
|
stevenh@14
|
193
|
stevenh@14
|
194 while (jList.get(k) <= (n - p + k + 1)
|
stevenh@44
|
195 && (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1)))) < 0))
|
stevenh@14
|
196 {
|
stevenh@14
|
197 jList.set(k, jList.get(k) + 1);
|
stevenh@14
|
198 }
|
stevenh@14
|
199
|
stevenh@14
|
200 if (jList.get(k) > n - p + k + 1)
|
stevenh@14
|
201 {
|
stevenh@14
|
202 finished = true;
|
stevenh@14
|
203 }
|
stevenh@44
|
204 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@14
|
205 {
|
stevenh@14
|
206 k = 1;
|
stevenh@14
|
207 jList.set(0, jList.get(0) + 1);
|
stevenh@14
|
208 if (jList.get(0) > n - p + 1)
|
stevenh@14
|
209 {
|
stevenh@14
|
210 finished = true;
|
stevenh@14
|
211 }
|
stevenh@14
|
212 }
|
stevenh@14
|
213 else if (k + 1 == p)
|
stevenh@14
|
214 {
|
stevenh@14
|
215 if (!first_vector)
|
stevenh@14
|
216 {
|
stevenh@14
|
217 System.out.print(",");
|
stevenh@14
|
218 }
|
stevenh@14
|
219 else
|
stevenh@14
|
220 {
|
stevenh@14
|
221 first_vector = false;
|
stevenh@14
|
222 }
|
stevenh@14
|
223
|
stevenh@14
|
224 Display.printVector(vectorTableW.getVector(iList.get(k), jList.get(k)));
|
stevenh@14
|
225 k = 0;
|
stevenh@14
|
226
|
stevenh@14
|
227 while (k < p)
|
stevenh@14
|
228 {
|
stevenh@14
|
229 jList.set(k, jList.get(k) + 1);
|
stevenh@14
|
230 if (jList.get(k) > n - p + k +1)
|
stevenh@14
|
231 {
|
stevenh@14
|
232 finished = true;
|
stevenh@14
|
233 k = p -1;
|
stevenh@14
|
234 }
|
stevenh@14
|
235 k++;
|
stevenh@14
|
236 }
|
stevenh@14
|
237 k = 1;
|
stevenh@14
|
238 }
|
stevenh@14
|
239 else
|
stevenh@14
|
240 {
|
stevenh@14
|
241 k++;
|
stevenh@14
|
242 }
|
stevenh@14
|
243 }
|
stevenh@14
|
244 System.out.print("}");
|
stevenh@14
|
245 }
|
stevenh@14
|
246 }
|
stevenh@14
|
247
|
stevenh@14
|
248 private void printX(ArrayList<SiatecX> x) {
|
stevenh@14
|
249 for (SiatecX iq : x)
|
stevenh@14
|
250 {
|
stevenh@14
|
251 System.out.print(iq.getI() + ",");
|
stevenh@14
|
252 for (NDimensionalObject q : iq.getQ())
|
stevenh@14
|
253 {
|
stevenh@14
|
254 System.out.print("<");
|
stevenh@14
|
255 int dimensions = q.getDimensionValues().size();
|
stevenh@14
|
256 for (int dim = 1; dim <= dimensions; dim++)
|
stevenh@14
|
257 {
|
stevenh@14
|
258 try {
|
stevenh@14
|
259 System.out.print(q.getDimensionValue(dim) + (dim == dimensions ? "" : ","));
|
stevenh@14
|
260 } catch (DimensionException e) {
|
stevenh@14
|
261 e.printStackTrace();
|
stevenh@14
|
262 System.exit(1);
|
stevenh@14
|
263 }
|
stevenh@14
|
264 }
|
stevenh@14
|
265 System.out.println(">");
|
stevenh@14
|
266 }
|
stevenh@14
|
267 System.out.println();
|
stevenh@14
|
268 }
|
stevenh@14
|
269 }
|
stevenh@14
|
270
|
stevenh@14
|
271 /**
|
stevenh@14
|
272 * @param args
|
stevenh@14
|
273 */
|
stevenh@14
|
274 public static void main(String[] args) {
|
stevenh@44
|
275 long startTime = System.currentTimeMillis();
|
stevenh@14
|
276 SiaTecMain app = new SiaTecMain();
|
stevenh@14
|
277 app.run();
|
stevenh@44
|
278 long endTime = System.currentTimeMillis();
|
stevenh@44
|
279 long elapsedTime = endTime - startTime;
|
stevenh@44
|
280 System.out.println("Completed in " + elapsedTime + " ms");
|
stevenh@14
|
281 }
|
stevenh@14
|
282
|
stevenh@14
|
283 }
|