view src/org/qmul/eecs/c4dm/sia/SiaMain.java @ 86:8277be90601f

no a pure java version of SIATEC - no RDF/OWL/SPARQL used apart from initially reading data from an RDF file removed all references to SPARQL queries (no longer used) removed all references to TDB database (no longer used)
author stevenh
date Sat, 31 Aug 2013 17:26:11 +0100
parents 00e46306eaa8
children ef5c4c8546fe
line wrap: on
line source
package org.qmul.eecs.c4dm.sia;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.qmul.eecs.c4dm.sia.exceptions.DimensionException;
import org.qmul.eecs.c4dm.sia.model.Datapoint;
import org.qmul.eecs.c4dm.sia.model.NDimensionalObject;
import org.qmul.eecs.c4dm.sia.model.SiaDataset;
import org.qmul.eecs.c4dm.sia.model.SiatecX;
import org.qmul.eecs.c4dm.sia.model.VectorTable;
import org.qmul.eecs.c4dm.sia.model.VectorTableElement;
import org.qmul.eecs.c4dm.sia.utilities.Display;

import com.hp.hpl.jena.ontology.OntClass;
import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.update.UpdateAction;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

/**
 * <p>
 * Title: SiaMain
 * </p>
 * <p>
 * Description: An RDF/OWL/Java implementation of the SIA and SIATEC pattern discovery algorithms.
 * See "Algorithms for discovering repeated patterns in multidimensional representations of polyphonic music"
 * by Meredith, D. and Lemstr&ouml;m, K. and Wiggins, G.A.
 * Optionally takes a single command line argument file path to an N3 ontology file, otherwise uses a
 * hardcoded file path.
 * Writes SIA and SIATEC result to stdout and writes the entire RDF model to the TDB dataset described in
 * src/assemblers/tdb-assembler.ttl
 * </p>
 * 
 * @author Steve Hargreaves, C4DM, Queen Mary University of London
 */
public class SiaMain {
	
	// The ontology loaded as dataset
	public static String ontology = "file:src/rdf/siaTestDatapointOntology.n3";

	public void run(String[] args) {
		
		// If a command-line argument was supplied, assume it's the path
		// of an N3 ontology file
		if (args.length == 1)
			ontology = args[0];

		OntModel ontModel = ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM);
		ontModel.read(ontology, "N3");						

		// Create custom sia Datapoint objects
		List<Datapoint> datapoints = SiaDatapointFactory.create(ontModel);
		
		// STEP 1 - Order the datapoints
		Collections.sort(datapoints);

		// Add datapoint order info
		SiaDatapointFactory.assertOrder(datapoints);

        // STEP 2 - Compute the SIA vector table
		VectorTable vectorTableW = null;
		try {
			vectorTableW = SiaVectorTableElementFactory.createW(datapoints);
		} catch (DimensionException e) {
			e.printStackTrace();
			System.exit(-1);
		}

		// STEP 3 - Create custom SIATEC VectorTableElement objects (V)
		VectorTable vectorTableV = null;
		try {
			vectorTableV = SiaVectorTableElementFactory.createV(datapoints);
		} catch (DimensionException e) {
			e.printStackTrace();
			System.exit(-1);
		}
		List<VectorTableElement> vteListV = vectorTableV.getVteList();

		// STEP 4 - Order the VectorTableElement objects
		Collections.sort(vteListV);

		// STEP 5 - Display the SIA (MTP) results
		displaySiaResults(vteListV);

		// STEP 6 - "Vectorize" the MTPs
		int m = vteListV.size();
		int i = 0;
		ArrayList<SiatecX> x = new ArrayList<SiatecX>();
		
		while (i < m)
		{
			ArrayList<NDimensionalObject> q = new ArrayList<NDimensionalObject>();
			int j = i + 1;
			while (j < m && (vteListV.get(i).compareToIgnoreDatapoints(vteListV.get(j)) == 0))
			{
				NDimensionalObject vector = vteListV.get(j).getFromDatapoint().subtract(vteListV.get(j - 1).getFromDatapoint());
				q.add(vector);
				j++;
			}
			
			SiatecX iq = new SiatecX();
			iq.setI(i+1);
			iq.setQ(q);
			x.add(iq);
			i = j;
		}
		
		// Sort the elements of x
		Collections.sort(x);
		
		// Rename as y to match algorithm description in paper
		ArrayList<SiatecX> y = (ArrayList<SiatecX>) x.clone();
		
		// Display results using algorithm figures 23, 24 and 25 of the research paper		
		int countTecs = 0;

		int r = y.size();
		m = vteListV.size();
		i = 0;
		System.out.println();
		System.out.print("{");
		if (r > 0)
		{
			do
			{
				int j = y.get(i).getI() - 1;
				List<Integer> iList = new ArrayList<Integer>();
				while (j < m && (vteListV.get(j).compareToIgnoreDatapoints(vteListV.get(y.get(i).getI() - 1)) == 0))
				{
					iList.add(vteListV.get(j).getFromDatapoint().getOrderedIndex());					
					j++;
				}
				countTecs++;
				System.out.print("<");
				Display.printPattern(iList, datapoints);
				
				System.out.print(",");
				printSetOfTranslators(iList, datapoints, vectorTableW);
				System.out.print(">");
				do
				{
					i++;
				} while (i < r && (y.get(i).compareToIgnoreI(y.get(i - 1)) == 0));
				
				if (i < r)
				{
					System.out.print(",");
					System.out.println();
				}
			} while (i < r);
		}
		System.out.println("}");
		
		System.out.println("Number of TECs: " + countTecs);
    	System.out.println("Number of Datapoints (n) = " + 		datapoints.size() + ", k = 3");
	}

	/**
	 * @param vteList
	 */
	public void displaySiaResults(List<VectorTableElement> vteList) {
		int m = vteList.size();
		int i = 0;
		
		System.out.println();
		System.out.print("{");
		
		int countMtps = 0;
		while (i < m)
		{
			countMtps++;
			System.out.print("<");
			Display.printVector(vteList.get(i));
			
			System.out.print(",{");
			Display.printVector(vteList.get(i).getFromDatapoint());

			int j = i + 1;
						
			while (j < m && (vteList.get(i).compareToIgnoreDatapoints(vteList.get(j)) == 0))
			{
				System.out.print(",");
				Display.printVector(vteList.get(j).getFromDatapoint());
				j++;
			}
			System.out.print("}>");
			if (j < m)
			{
				System.out.print(",");
				System.out.println();
			}
			i = j;
		}
		System.out.println("}");
		System.out.println("Number of MTPs: " + countMtps);
	}

	/**
	 * @param vteIter
	 * @param message
	 */
	public void displayNDimensionalObjects(Iterator<VectorTableElement> vteIter, String message) {
		System.out.println(message);
		System.out.println("----------");
		while (vteIter.hasNext())
		{
			VectorTableElement vte = vteIter.next();
			System.out.println("from: " + vte.getFromDatapoint().getResource().getLocalName() + " to: " + vte.getToDatapoint().getResource().getLocalName());			
		}
	}

	/**
	 * @param datapointIter
	 * @param message
	 */
	public void displayDatapoints(Iterator<Datapoint> datapointIter, String message) {
		System.out.println(message);
		System.out.println("----------");
		while (datapointIter.hasNext())
		{
			Datapoint datapoint = datapointIter.next();
			System.out.println( datapoint.getResource().getLocalName());			
		}
	}

	private void printSetOfTranslators(List<Integer> iList, List<Datapoint> datapoints, VectorTable vectorTableW) {
		int p = iList.size();
		int n = datapoints.size();

		if (p == 1)
		{
			System.out.print("{");
			Display.printVector(vectorTableW.getVector(iList.get(0), 1));
			for (int k = 2; k <= n; k++)
			{
				System.out.print(",");
				Display.printVector(vectorTableW.getVector(iList.get(0), k));
			}
			System.out.print("}");
		}
		else
		{
			System.out.print("{");
			List<Integer> jList = new ArrayList<Integer>();
			for (int k = 0; k < p; k++)
			{
				jList.add(1);
			}
			boolean finished = false;
			boolean first_vector = true;
			int k = 1;

			while (!finished)
			{
				if (jList.get(k) <= jList.get(k - 1))
				{
					jList.set(k, jList.get(k - 1) + 1);
				}
				
				while (jList.get(k) <= (n - p + k + 1)
						&& (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1)))) < 0))
				{
					jList.set(k, jList.get(k) + 1);
				}
				
				if (jList.get(k) > n - p + k + 1)
				{
					finished = true;
				}
				else if (((VectorTableElement)vectorTableW.getVector(iList.get(k), jList.get(k))).compareToIgnoreDatapoints(((VectorTableElement)vectorTableW.getVector(iList.get(k - 1), jList.get(k - 1)))) > 0)
				{
					k = 1;
					jList.set(0, jList.get(0) + 1);
					if (jList.get(0) > n - p + 1)
					{
						finished = true;
					}
				}
				else if (k + 1 == p)
				{
					if (!first_vector)
					{
						System.out.print(",");
					}
					else
					{
						first_vector = false;
					}
					
					Display.printVector(vectorTableW.getVector(iList.get(k), jList.get(k)));
					k = 0;
					
					while (k < p)
					{
						jList.set(k, jList.get(k) + 1);
						if (jList.get(k) > n - p + k +1)
						{
							finished = true;
							k = p -1;
						}
						k++;
					}
					k = 1;
				}
				else
				{
					k++;
				}
			}
			System.out.print("}");
		}
	}

	private void printX(ArrayList<SiatecX> x) {
		for (SiatecX iq : x)
		{
			System.out.print(iq.getI() + ",");
			for (NDimensionalObject q : iq.getQ())
			{
				System.out.print("<");
				int dimensions = q.getDimensionValues().size();
				for (int dim = 1; dim <= dimensions; dim++)
				{
					try {
						System.out.print(q.getDimensionValue(dim) + (dim == dimensions ? "" : ","));
					} catch (DimensionException e) {
						e.printStackTrace();
						System.exit(1);
					}
				}
				System.out.println(">");
			}
			System.out.println();
		}
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		long startTime = System.currentTimeMillis();
		SiaMain app = new SiaMain();
		app.run(args);
		long endTime = System.currentTimeMillis();
		long elapsedTime = endTime - startTime;
		System.out.println("Completed in " + elapsedTime + " ms");
	}

}