steve@0: package org.qmul.eecs.c4dm.sia;
steve@0:
stevenh@67: import java.util.ArrayList;
steve@0: import java.util.Collections;
steve@0: import java.util.Iterator;
steve@0: import java.util.List;
steve@0:
stevenh@67: import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
steve@0: import org.qmul.eecs.c4dm.sia.model.Datapoint;
stevenh@67: import org.qmul.eecs.c4dm.sia.model.NDimensionalObject;
stevenh@67: import org.qmul.eecs.c4dm.sia.model.SiatecX;
stevenh@13: import org.qmul.eecs.c4dm.sia.model.VectorTable;
steve@0: import org.qmul.eecs.c4dm.sia.model.VectorTableElement;
stevenh@13: import org.qmul.eecs.c4dm.sia.utilities.Display;
steve@0:
steve@0: import com.hp.hpl.jena.ontology.OntModel;
stevenh@43: import com.hp.hpl.jena.ontology.OntModelSpec;
steve@0: import com.hp.hpl.jena.rdf.model.ModelFactory;
steve@0:
steve@0: /**
steve@0: *
stevenh@5: * Title: SiaMain
steve@0: *
steve@0: *
stevenh@67: * Description: An RDF/OWL/Java implementation of the SIA and SIATEC pattern discovery algorithms.
stevenh@67: * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
stevenh@67: * by Meredith, D. and Lemström, K. and Wiggins, G.A.
stevenh@67: * Optionally takes a single command line argument file path to an N3 ontology file, otherwise uses a
stevenh@67: * hardcoded file path.
stevenh@67: * Writes SIA and SIATEC result to stdout and writes the entire RDF model to the TDB dataset described in
stevenh@67: * src/assemblers/tdb-assembler.ttl
steve@0: *
steve@0: *
stevenh@5: * @author Steve Hargreaves, C4DM, Queen Mary University of London
steve@0: */
steve@0: public class SiaMain {
stevenh@43:
stevenh@67: // The ontology loaded as dataset
stevenh@67: public static String ontology = "file:src/rdf/siaTestDatapointOntology.n3";
stevenh@67:
stevenh@67: public void run(String[] args) {
stevenh@67:
stevenh@67: // If a command-line argument was supplied, assume it's the path
stevenh@67: // of an N3 ontology file
stevenh@67: if (args.length == 1)
stevenh@67: ontology = args[0];
steve@0:
stevenh@67: OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
stevenh@67: ontModel.read(ontology, "N3");
stevenh@67:
steve@0: // Create custom sia Datapoint objects
steve@0: List datapoints = SiaDatapointFactory.create(ontModel);
stevenh@5:
stevenh@13: // STEP 1 - Order the datapoints
steve@0: Collections.sort(datapoints);
stevenh@5:
stevenh@86: // Add datapoint order info
stevenh@86: SiaDatapointFactory.assertOrder(datapoints);
stevenh@43:
stevenh@86: // STEP 2 - Compute the SIA vector table
stevenh@86: VectorTable vectorTableW = null;
stevenh@86: try {
stevenh@86: vectorTableW = SiaVectorTableElementFactory.createW(datapoints);
stevenh@86: } catch (DimensionException e) {
stevenh@86: e.printStackTrace();
stevenh@86: System.exit(-1);
stevenh@86: }
stevenh@67:
stevenh@67: // STEP 3 - Create custom SIATEC VectorTableElement objects (V)
stevenh@86: VectorTable vectorTableV = null;
stevenh@86: try {
stevenh@86: vectorTableV = SiaVectorTableElementFactory.createV(datapoints);
stevenh@86: } catch (DimensionException e) {
stevenh@86: e.printStackTrace();
stevenh@86: System.exit(-1);
stevenh@86: }
stevenh@67: List vteListV = vectorTableV.getVteList();
stevenh@5:
stevenh@86: // STEP 4 - Order the VectorTableElement objects
stevenh@67: Collections.sort(vteListV);
steve@0:
stevenh@86: // STEP 5 - Display the SIA (MTP) results
stevenh@86: displaySiaResults(vteListV);
steve@0:
stevenh@86: // STEP 6 - "Vectorize" the MTPs
stevenh@67: int m = vteListV.size();
stevenh@67: int i = 0;
stevenh@67: ArrayList x = new ArrayList();
stevenh@67:
stevenh@67: while (i < m)
stevenh@67: {
stevenh@67: ArrayList q = new ArrayList();
stevenh@67: int j = i + 1;
stevenh@67: while (j < m && (vteListV.get(i).compareToIgnoreDatapoints(vteListV.get(j)) == 0))
stevenh@67: {
stevenh@67: NDimensionalObject vector = vteListV.get(j).getFromDatapoint().subtract(vteListV.get(j - 1).getFromDatapoint());
stevenh@67: q.add(vector);
stevenh@67: j++;
stevenh@67: }
stevenh@67:
stevenh@67: SiatecX iq = new SiatecX();
stevenh@67: iq.setI(i+1);
stevenh@67: iq.setQ(q);
stevenh@67: x.add(iq);
stevenh@67: i = j;
stevenh@67: }
stevenh@67:
stevenh@67: // Sort the elements of x
stevenh@67: Collections.sort(x);
stevenh@67:
stevenh@67: // Rename as y to match algorithm description in paper
stevenh@67: ArrayList y = (ArrayList) x.clone();
stevenh@67:
stevenh@86: // Display results using algorithm figures 23, 24 and 25 of the research paper
stevenh@85: int countTecs = 0;
stevenh@67:
stevenh@67: int r = y.size();
stevenh@67: m = vteListV.size();
stevenh@67: i = 0;
stevenh@67: System.out.println();
stevenh@67: System.out.print("{");
stevenh@67: if (r > 0)
stevenh@67: {
stevenh@67: do
stevenh@67: {
stevenh@67: int j = y.get(i).getI() - 1;
stevenh@67: List iList = new ArrayList();
stevenh@67: while (j < m && (vteListV.get(j).compareToIgnoreDatapoints(vteListV.get(y.get(i).getI() - 1)) == 0))
stevenh@67: {
stevenh@67: iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());
stevenh@67: j++;
stevenh@67: }
stevenh@85: countTecs++;
stevenh@67: System.out.print("<");
stevenh@67: Display.printPattern(iList, datapoints);
stevenh@67:
stevenh@67: System.out.print(",");
stevenh@67: printSetOfTranslators(iList, datapoints, vectorTableW);
stevenh@67: System.out.print(">");
stevenh@67: do
stevenh@67: {
stevenh@67: i++;
stevenh@67: } while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0));
stevenh@67:
stevenh@67: if (i < r)
stevenh@67: {
stevenh@67: System.out.print(",");
stevenh@67: System.out.println();
stevenh@67: }
stevenh@67: } while (i < r);
stevenh@67: }
stevenh@67: System.out.println("}");
stevenh@43:
stevenh@85: System.out.println("Number of TECs: " + countTecs);
stevenh@67: System.out.println("Number of Datapoints (n) = " + datapoints.size() + ", k = 3");
stevenh@5: }
stevenh@5:
stevenh@5: /**
stevenh@5: * @param vteList
stevenh@5: */
stevenh@86: public void displaySiaResults(List vteList) {
stevenh@5: int m = vteList.size();
stevenh@5: int i = 0;
stevenh@5:
stevenh@5: System.out.println();
stevenh@5: System.out.print("{");
stevenh@5:
stevenh@85: int countMtps = 0;
stevenh@5: while (i < m)
stevenh@5: {
stevenh@85: countMtps++;
stevenh@5: System.out.print("<");
stevenh@13: Display.printVector(vteList.get(i));
stevenh@67:
stevenh@5: System.out.print(",{");
stevenh@13: Display.printVector(vteList.get(i).getFromDatapoint());
stevenh@67:
stevenh@5: int j = i + 1;
stevenh@5:
stevenh@5: while (j < m && (vteList.get(i).compareToIgnoreDatapoints(vteList.get(j)) == 0))
stevenh@5: {
stevenh@5: System.out.print(",");
stevenh@13: Display.printVector(vteList.get(j).getFromDatapoint());
stevenh@5: j++;
stevenh@5: }
stevenh@5: System.out.print("}>");
stevenh@5: if (j < m)
stevenh@5: {
stevenh@5: System.out.print(",");
stevenh@5: System.out.println();
stevenh@5: }
stevenh@5: i = j;
stevenh@5: }
stevenh@5: System.out.println("}");
stevenh@85: System.out.println("Number of MTPs: " + countMtps);
stevenh@5: }
stevenh@5:
stevenh@5: /**
stevenh@5: * @param vteIter
stevenh@5: * @param message
stevenh@5: */
stevenh@5: public void displayNDimensionalObjects(Iterator vteIter, String message) {
stevenh@5: System.out.println(message);
stevenh@5: System.out.println("----------");
stevenh@5: while (vteIter.hasNext())
stevenh@5: {
stevenh@5: VectorTableElement vte = vteIter.next();
stevenh@5: System.out.println("from: " + vte.getFromDatapoint().getResource().getLocalName() + " to: " + vte.getToDatapoint().getResource().getLocalName());
steve@0: }
steve@0: }
steve@0:
stevenh@5: /**
stevenh@5: * @param datapointIter
stevenh@5: * @param message
stevenh@5: */
stevenh@5: public void displayDatapoints(Iterator datapointIter, String message) {
stevenh@5: System.out.println(message);
stevenh@5: System.out.println("----------");
stevenh@5: while (datapointIter.hasNext())
stevenh@5: {
stevenh@5: Datapoint datapoint = datapointIter.next();
stevenh@5: System.out.println( datapoint.getResource().getLocalName());
stevenh@5: }
stevenh@5: }
stevenh@5:
stevenh@67: private void printSetOfTranslators(List iList, List datapoints, VectorTable vectorTableW) {
stevenh@67: int p = iList.size();
stevenh@67: int n = datapoints.size();
stevenh@67:
stevenh@67: if (p == 1)
stevenh@67: {
stevenh@67: System.out.print("{");
stevenh@67: Display.printVector(vectorTableW.getVector(iList.get(0), 1));
stevenh@67: for (int k = 2; k <= n; k++)
stevenh@67: {
stevenh@67: System.out.print(",");
stevenh@67: Display.printVector(vectorTableW.getVector(iList.get(0), k));
stevenh@67: }
stevenh@67: System.out.print("}");
stevenh@67: }
stevenh@67: else
stevenh@67: {
stevenh@67: System.out.print("{");
stevenh@67: List jList = new ArrayList();
stevenh@67: for (int k = 0; k < p; k++)
stevenh@67: {
stevenh@67: jList.add(1);
stevenh@67: }
stevenh@67: boolean finished = false;
stevenh@67: boolean first_vector = true;
stevenh@67: int k = 1;
stevenh@67:
stevenh@67: while (!finished)
stevenh@67: {
stevenh@67: if (jList.get(k) <= jList.get(k - 1))
stevenh@67: {
stevenh@67: jList.set(k, jList.get(k - 1) + 1);
stevenh@67: }
stevenh@67:
stevenh@67: while (jList.get(k) <= (n - p + k + 1)
stevenh@67: && (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1)))) < 0))
stevenh@67: {
stevenh@67: jList.set(k, jList.get(k) + 1);
stevenh@67: }
stevenh@67:
stevenh@67: if (jList.get(k) > n - p + k + 1)
stevenh@67: {
stevenh@67: finished = true;
stevenh@67: }
stevenh@67: 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: {
stevenh@67: k = 1;
stevenh@67: jList.set(0, jList.get(0) + 1);
stevenh@67: if (jList.get(0) > n - p + 1)
stevenh@67: {
stevenh@67: finished = true;
stevenh@67: }
stevenh@67: }
stevenh@67: else if (k + 1 == p)
stevenh@67: {
stevenh@67: if (!first_vector)
stevenh@67: {
stevenh@67: System.out.print(",");
stevenh@67: }
stevenh@67: else
stevenh@67: {
stevenh@67: first_vector = false;
stevenh@67: }
stevenh@67:
stevenh@67: Display.printVector(vectorTableW.getVector(iList.get(k), jList.get(k)));
stevenh@67: k = 0;
stevenh@67:
stevenh@67: while (k < p)
stevenh@67: {
stevenh@67: jList.set(k, jList.get(k) + 1);
stevenh@67: if (jList.get(k) > n - p + k +1)
stevenh@67: {
stevenh@67: finished = true;
stevenh@67: k = p -1;
stevenh@67: }
stevenh@67: k++;
stevenh@67: }
stevenh@67: k = 1;
stevenh@67: }
stevenh@67: else
stevenh@67: {
stevenh@67: k++;
stevenh@67: }
stevenh@67: }
stevenh@67: System.out.print("}");
stevenh@67: }
stevenh@67: }
stevenh@67:
stevenh@67: private void printX(ArrayList x) {
stevenh@67: for (SiatecX iq : x)
stevenh@67: {
stevenh@67: System.out.print(iq.getI() + ",");
stevenh@67: for (NDimensionalObject q : iq.getQ())
stevenh@67: {
stevenh@67: System.out.print("<");
stevenh@67: int dimensions = q.getDimensionValues().size();
stevenh@67: for (int dim = 1; dim <= dimensions; dim++)
stevenh@67: {
stevenh@67: try {
stevenh@67: System.out.print(q.getDimensionValue(dim) + (dim == dimensions ? "" : ","));
stevenh@67: } catch (DimensionException e) {
stevenh@67: e.printStackTrace();
stevenh@67: System.exit(1);
stevenh@67: }
stevenh@67: }
stevenh@67: System.out.println(">");
stevenh@67: }
stevenh@67: System.out.println();
stevenh@67: }
stevenh@67: }
stevenh@67:
stevenh@5: /**
stevenh@5: * @param args
stevenh@5: */
steve@0: public static void main(String[] args) {
stevenh@43: long startTime = System.currentTimeMillis();
steve@0: SiaMain app = new SiaMain();
stevenh@67: app.run(args);
stevenh@43: long endTime = System.currentTimeMillis();
stevenh@43: long elapsedTime = endTime - startTime;
stevenh@43: System.out.println("Completed in " + elapsedTime + " ms");
steve@0: }
steve@0:
steve@0: }