no message

cmurphy [2009-07-07 21:00:04]
no message
Filename
util/Adder.java
util/Adder2.java
util/Adder3.java
util/ArffPermutor.java
util/CalcManhattanDist.java
util/CalcSimilarManhattanDist.java
util/CalculateTimeStats.java
util/CheckSameTimes.java
util/CompareEvents.java
util/CompareJSimOutput.java
util/CompareJSimSequence.java
util/ManhattanDistEst.java
util/Multiplier.java
util/Multiplier2.java
util/Multiplier3.java
util/Mutator.java
util/Mutator2.java
util/Negator.java
util/Negator3.java
util/OneDiff.java
util/Permutor.java
util/TTest.java
diff --git a/util/Adder.java b/util/Adder.java
new file mode 100644
index 0000000..6d6c5e1
--- /dev/null
+++ b/util/Adder.java
@@ -0,0 +1,146 @@
+import java.util.*;
+import java.io.*;
+
+/*
+ * This class adds values to a CSV data file
+ */
+
+public class Adder
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".a";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void add(int factor)
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, ",");
+
+	    while (tok.hasMoreTokens())
+	    {
+		if (newLine != "") newLine += ",";
+
+		String value = tok.nextToken();
+
+		// don't change the last token (the label)
+		if (tok.hasMoreTokens())
+		{
+		    try
+		    {
+			// see if it's a floating point number
+			float x = Float.parseFloat(value);
+			// if we got here, it is
+			x += factor;
+			value = "" + x;
+		    }
+		    catch (NumberFormatException e) { }
+		}
+
+		newLine += value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename, int factor)
+    {
+	read(filename);
+	add(factor);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    int factor = Integer.parseInt(args[1]);
+	    new Adder().go(filename, factor);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Adder2.java b/util/Adder2.java
new file mode 100644
index 0000000..44d58e5
--- /dev/null
+++ b/util/Adder2.java
@@ -0,0 +1,146 @@
+import java.util.*;
+import java.io.*;
+
+/**
+ * This is a class for adding a value to a data file.
+ * It works for sparse data formats in the attr:value format.
+ */
+
+public class Adder2
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".a";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void add(int factor)
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, " ");
+
+	    // ignore the first token, which is the label
+	    newLine += tok.nextToken();
+
+	    while (tok.hasMoreTokens())
+	    {
+		String value = tok.nextToken();
+
+		// separate the attribute number
+		String attr = value.split(":")[0];
+
+		value = value.split(":")[1];
+
+		// see if it's a floating point number
+		double x = Double.parseDouble(value);
+		// if we got here, it is
+		x += factor;
+		value = "" + x;
+
+		newLine += " " + attr + ":" + value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename, int factor)
+    {
+	read(filename);
+	add(factor);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    int factor = Integer.parseInt(args[1]);
+	    new Adder2().go(filename, factor);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    //System.out.println("You didn't specify a file");
+	    e.printStackTrace();
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Adder3.java b/util/Adder3.java
new file mode 100644
index 0000000..732bdfb
--- /dev/null
+++ b/util/Adder3.java
@@ -0,0 +1,149 @@
+import java.util.*;
+import java.io.*;
+
+/**
+ * This only adds a value to the first N fields.
+ */
+
+public class Adder3
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".a";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void add(int factor)
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, ",");
+
+	    int count = 0;
+
+	    while (tok.hasMoreTokens())
+	    {
+		count++;
+		if (newLine != "") newLine += ",";
+
+		String value = tok.nextToken();
+
+		// don't change the last token (the label)
+		if (tok.hasMoreTokens() && count <= 3)
+		{
+		    try
+		    {
+			// see if it's a floating point number
+			float x = Float.parseFloat(value);
+			// if we got here, it is
+			x += factor;
+			value = "" + x;
+		    }
+		    catch (NumberFormatException e) { }
+		}
+
+		newLine += value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename, int factor)
+    {
+	read(filename);
+	add(factor);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    int factor = Integer.parseInt(args[1]);
+	    new Adder3().go(filename, factor);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/ArffPermutor.java b/util/ArffPermutor.java
new file mode 100644
index 0000000..0d4b49d
--- /dev/null
+++ b/util/ArffPermutor.java
@@ -0,0 +1,122 @@
+import java.util.*;
+import java.io.*;
+
+public class ArffPermutor
+{
+    private ArrayList<String> header = new ArrayList<String>();
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // tracks whether we're reading the header or the data
+	    boolean inHeader = true;
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the appropriate list
+		if (inHeader) header.add(line);
+		else lines.add(line);
+
+		// once we get to the @DATA entry, we're no longer in the header
+		if (line.startsWith("@DATA"))
+		{
+		    inHeader = false;
+		}
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".p";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    // write out the header
+	    for (String line : header)
+		out.println(line);
+
+	    // now the rest of it
+	    for (String line : lines)
+		out.println(line);
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void randomize()
+    {
+	for (int i = 0; i < lines.size() * 3; i++)
+	{
+	    int index = (int)(Math.random() * lines.size());
+	    String line = lines.get(index);
+	    lines.remove(index);
+	    lines.add(line);
+	}
+    }
+
+    public void go(String filename)
+    {
+	read(filename);
+	randomize();
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    new ArffPermutor().go(filename);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/CalcManhattanDist.java b/util/CalcManhattanDist.java
new file mode 100644
index 0000000..bec4544
--- /dev/null
+++ b/util/CalcManhattanDist.java
@@ -0,0 +1,181 @@
+import java.util.Scanner;
+import java.io.*;
+
+/*************************************
+Calculates the Manhattan Distances between the output trace in the first argument
+and the output traces in all the other arguments. Provides average, min, and max
+normalized equivalences.
+************************************/
+
+public class CalcManhattanDist
+{
+    public void run(String[] args)
+    {
+	if (args.length < 2)
+	{
+	    System.out.println("Need to specify at least two files!");
+	    return;
+	}
+	else
+	{
+	    // the file to which everything will be compared
+	    String file = args[0];
+
+	    // keeps track of the total normalized equivalence values
+	    double total = 0;
+
+	    // the min and max
+	    double min = 1;
+	    double max = 0;
+
+	    // for standard dev
+	    double[] values = new double[args.length-1];
+
+	    // keeps track of how many data points we have
+	    int count = 0;
+
+	    // loop through the rest of the array of filenames
+	    for (int i = 1; i < args.length; i++)
+	    {
+		double equiv = getStats(file, args[i]);
+		if (equiv == -1)
+		{
+		    System.out.println("ERROR! " + file + " and " + args[i] + " have different events");
+		}
+		else
+		{
+		    total += equiv;
+		    if (equiv < min) min = equiv;
+		    if (equiv > max) max = equiv;
+		    values[count++] = equiv;
+		}
+	    }
+
+	    System.out.println("---------------------------------------");
+	    System.out.println("Number of similar files: " + count);
+	    double average = total / count;
+	    System.out.println("Average normalized equiv: " + average);
+	    System.out.println("Min: " + min);
+	    System.out.println("Max: " + max);
+
+
+	    // now the standard deviation
+	    double totalDist = 0;
+	    for (int i = 0; i < count; i++)
+	    {
+		totalDist += (values[i] - average)*(values[i] - average);
+	    }
+	    double stdDev = Math.sqrt(totalDist/count);
+	    System.out.println("Std Dev: " + stdDev);
+
+	}
+
+    }
+
+    private double getStats(String file1, String file2)
+    {
+	try
+	{
+	    // create the Scanner
+	    Scanner scan = new Scanner(new File(file1));
+
+	    // there may be error messages and such
+	    // just get the Scanner into a state where it ignores those
+	    String line = null;
+
+	    // line counter
+	    int count = 0;
+
+	    // number of lines to ignore
+	    int ignore = 0;
+
+	    // once we found a line that starts with "0", we know we're into the trace
+	    boolean stop = false;
+	    while (!stop)
+	    {
+		line = scan.nextLine();
+		count++;
+		if (line.startsWith("0")) { stop = true; }
+		else ignore++;
+	    }
+
+	    // tracks the total distance
+	    int totalDist = 0;
+
+	    // now take each non-blank line and find its location in file2
+	    while (scan.hasNext())
+	    {
+		line = scan.nextLine();
+		if (line.trim().equals("") == false)
+		{
+		    count++;
+		    // only consider the message part after the time and id
+		    line = line.split(";")[1].trim();
+		    //System.out.println("Looking for: " + line + ".");
+		    // now get the location in file2
+		    int dist = findLineNumber(line, file2);
+		    // a return value of -1 means it's not found... that's bad
+		    if (dist == -1)
+		    {
+			System.out.println("LINE NOT FOUND: Line " + count + ": " + line);
+			return -1;
+		    }
+		    else
+		    {
+			//System.out.println("Line number " + count + " in file2 is " + dist);
+			totalDist += Math.abs(count-dist);
+		    }
+		}
+	    }
+
+	    System.out.println("Manhattan distance for " + file2 + " is " + totalDist);
+
+	    // calculate normalized equivalence
+	    int totalLines = count - ignore;
+	    //System.out.println("Total #lines is " + (count-ignore));
+	    double normalizedEquiv = 1.0 - ((double)totalDist*2)/(totalLines*totalLines);
+	    System.out.println("Normalized equiv is for " + file2 + " is " + normalizedEquiv);
+	    return normalizedEquiv;
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	return -1;
+
+    }
+
+
+    public int findLineNumber(String line, String file)
+    {
+	int lineNum = -1;
+	Scanner in = null;
+	try
+	{
+	    in = new Scanner(new File(file));
+	    int count = 0;
+
+	    while (in.hasNext())
+	    {
+		count++;
+
+		String thisLine = in.nextLine();
+		if (thisLine.contains(";"))
+		{
+		    thisLine = thisLine.split(";")[1].trim();
+		    //System.out.println("comparing: " + thisLine + ". to " + line + ".");
+		    if (thisLine.equals(line)) return count;
+		}
+	    }
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	finally { in.close(); }
+
+	// the default return value indicates that the line was not found
+	return -1;
+    }
+
+
+    public static void main(String[] args)
+    {
+	new CalcManhattanDist().run(args);
+    }
+
+}
\ No newline at end of file
diff --git a/util/CalcSimilarManhattanDist.java b/util/CalcSimilarManhattanDist.java
new file mode 100644
index 0000000..2ea5c04
--- /dev/null
+++ b/util/CalcSimilarManhattanDist.java
@@ -0,0 +1,233 @@
+import java.util.Scanner;
+import java.util.ArrayList;
+import java.io.*;
+
+/*************************************
+Calculates the Manhattan Distances between the output trace in the first argument
+and the output traces in all the other arguments, BUT ONLY CONSIDERS THE PARTS
+THAT ARE SIMILAR, ie the events that occur in both. Useful for comparing the
+traces that include Choice steps.
+
+Provides average, min, and max normalized equivalences.
+************************************/
+
+public class CalcSimilarManhattanDist
+{
+    public void run(String[] args)
+    {
+	if (args.length < 2)
+	{
+	    System.out.println("Need to specify at least two files!");
+	    return;
+	}
+	else
+	{
+	    // the file to which everything will be compared
+	    String file = args[0];
+
+	    // keeps track of the total normalized equivalence values
+	    double total = 0;
+
+	    // the min and max
+	    double min = 1;
+	    double max = 0;
+
+	    // for standard dev
+	    double[] values = new double[args.length-1];
+
+	    // keeps track of how many data points we have
+	    int count = 0;
+
+	    // loop through the rest of the array of filenames
+	    for (int i = 1; i < args.length; i++)
+	    {
+		double equiv = getStats(file, args[i]);
+		if (equiv == -1)
+		{
+		    System.out.println("ERROR! " + file + " and " + args[i] + " have different events");
+		}
+		else
+		{
+		    total += equiv;
+		    if (equiv < min) min = equiv;
+		    if (equiv > max) max = equiv;
+		    values[count++] = equiv;
+		}
+	    }
+
+	    System.out.println("---------------------------------------");
+	    System.out.println("Number of similar files: " + count);
+	    double average = total / count;
+	    System.out.println("Average normalized equiv: " + average);
+	    System.out.println("Min: " + min);
+	    System.out.println("Max: " + max);
+
+
+	    // now the standard deviation
+	    double totalDist = 0;
+	    for (int i = 0; i < count; i++)
+	    {
+		totalDist += (values[i] - average)*(values[i] - average);
+	    }
+	    double stdDev = Math.sqrt(totalDist/count);
+	    System.out.println("Std Dev: " + stdDev);
+
+	}
+
+    }
+
+
+
+
+    private double getStats(String file1, String file2)
+    {
+	try
+	{
+	    // create the Scanner
+	    Scanner scan = new Scanner(new File(file1));
+
+	    // there may be error messages and such
+	    // just get the Scanner into a state where it ignores those
+	    String line = null;
+
+	    // once we found a line that starts with "0", we know we're into the trace
+	    boolean stop = false;
+	    while (!stop)
+	    {
+		line = scan.nextLine();
+		if (line.startsWith("0")) { stop = true; }
+	    }
+
+	    // tracks the lines in file1
+	    ArrayList<String> file1Lines = new ArrayList<String>();
+
+	    // now take each non-blank line and find its location in file2
+	    while (scan.hasNext())
+	    {
+		line = scan.nextLine();
+		if (line.trim().equals("") == false)
+		{
+		    // only consider the message part after the time and id
+		    line = line.split(";")[1].trim();
+		    //System.out.println("Looking for: " + line + ".");
+		    int dist = findLineNumber(line, file2);
+		    if (dist != -1)
+		    {
+			//System.out.println(line + " appears in both files");
+			file1Lines.add(line);
+		    }
+		}
+	    }
+
+	    // finds the lines in file2 that appear in file1
+	    ArrayList<String> file2Lines = getLines(file1Lines, file2);
+
+	    if (file1Lines.size() != file2Lines.size()) System.out.println("SIZES ARE DIFFERENT");
+
+	    // tracks the total distance
+	    int totalDist = 0;
+
+	    // calculate the distance
+	    for (int i = 0; i < file1Lines.size(); i++)
+	    {
+		String line1 = file1Lines.get(i);
+		if (file2Lines.contains(line1) == false)
+		{
+		    System.out.println("ERROR " + line1 + " not found in file2Lines");
+		}
+		else
+		{
+		    totalDist += Math.abs(file2Lines.indexOf(line1) - i);
+		}
+	    }
+
+	    System.out.println("Manhattan distance for " + file2 + " is " + totalDist);
+
+	    // calculate normalized equivalence
+	    int totalLines = file1Lines.size();
+	    double normalizedEquiv = 1.0 - ((double)totalDist*2)/(totalLines*totalLines);
+	    System.out.println("Normalized equiv is for " + file2 + " is " + normalizedEquiv);
+	    return normalizedEquiv;
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	return -1;
+
+    }
+
+    private ArrayList<String> getLines(ArrayList<String> lines, String file)
+    {
+	ArrayList<String> myLines = new ArrayList<String>();
+
+	Scanner in = null;
+
+	try
+	{
+	    in = new Scanner(new File(file));
+
+	    // ignore anything before the line that starts with 0
+	    boolean stop = false;
+	    while (!stop)
+	    {
+		if (in.nextLine().startsWith("0")) stop = true;
+	    }
+
+	    while (in.hasNext())
+	    {
+		String line = in.nextLine();
+		// make sure the line's not empty
+		if (line.trim().equals("") == false)
+		{
+		    // only care about the event part (after the semicolon)
+		    line = line.split(";")[1].trim();
+		    // if the line is in the arraylist, add it
+		    if (lines.contains(line))
+		    {
+			myLines.add(line);
+		    }
+		}
+	    }
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	finally { in.close(); }
+
+	return myLines;
+    }
+
+
+
+    public int findLineNumber(String line, String file)
+    {
+	int lineNum = -1;
+	Scanner in = null;
+	try
+	{
+	    in = new Scanner(new File(file));
+	    int count = 0;
+
+	    while (in.hasNext())
+	    {
+		count++;
+
+		String thisLine = in.nextLine();
+		if (thisLine.contains(";"))
+		{
+		    thisLine = thisLine.split(";")[1].trim();
+		    //System.out.println("comparing: " + thisLine + ". to " + line + ".");
+		    if (thisLine.equals(line)) return count;
+		}
+	    }
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	finally { in.close(); }
+
+	// the default return value indicates that the line was not found
+	return -1;
+    }
+
+
+    public static void main(String[] args)
+    {
+	new CalcSimilarManhattanDist().run(args);
+    }
+
+}
\ No newline at end of file
diff --git a/util/CalculateTimeStats.java b/util/CalculateTimeStats.java
new file mode 100644
index 0000000..e8a839e
--- /dev/null
+++ b/util/CalculateTimeStats.java
@@ -0,0 +1,95 @@
+import java.util.Scanner;
+import java.io.*;
+
+/**
+
+Takes a set of trace files and finds the average, min, and max of how long each
+takes, as well as the standard deviation.
+
+Assumes that the last line contains the time followed by a colon.
+
+ */
+
+
+public class CalculateTimeStats
+{
+    String[] files;
+    int[] values;
+
+    public CalculateTimeStats(String[] a)
+    {
+	files = a;
+	values = new int[files.length];
+    }
+
+    public void run()
+    {
+	// track the running sum
+	int totalTime = 0;
+	int min = 10000000, max = 0;
+
+	// get the time from each file, and track the min and max
+	for (int i = 0; i < files.length; i++)
+	{
+	    int time = getTime(files[i]);
+	    values[i] = time;
+	    totalTime += time;
+
+	    if (time < min) min = time;
+	    if (time > max) max = time;
+	}
+
+	System.out.println("-----------------------------");
+
+	// calculate the mean
+	double average = ((double)totalTime)/files.length;
+	System.out.println("Average: " + average);
+
+	// now the standard deviation
+	double totalDist = 0;
+	for (int i = 0; i < values.length; i++)
+	{
+	    totalDist += (values[i] - average)*(values[i] - average);
+	}
+	double stdDev = Math.sqrt(totalDist/values.length);
+	System.out.println("Std Dev: " + stdDev);
+
+	// min and max
+	System.out.println("Min: " + min);
+	System.out.println("Max: " + max);
+
+    }
+
+
+    private int getTime(String file)
+    {
+	int time = 0;
+	String lastTime = null;
+	try
+	{
+	    Scanner in = new Scanner(new File(file));
+	    while (in.hasNext())
+	    {
+		String line = in.nextLine();
+		//System.out.println(line);
+		if (line.contains(":"))
+		{
+		    lastTime = line;
+		}
+	    }
+	    time = Integer.parseInt(lastTime.split(":")[0].trim());
+	    System.out.println(file + ": " + time);
+	}
+	catch (Exception e) { e.printStackTrace(); }
+
+	return time;
+
+    }
+
+
+    public static void main(String[] args)
+    {
+	new CalculateTimeStats(args).run();
+    }
+
+}
\ No newline at end of file
diff --git a/util/CheckSameTimes.java b/util/CheckSameTimes.java
new file mode 100644
index 0000000..00ca6ab
--- /dev/null
+++ b/util/CheckSameTimes.java
@@ -0,0 +1,126 @@
+import java.util.Scanner;
+import java.io.*;
+
+/*********************************
+
+Compares the output trace in the first argument to those in the other arguments.
+Checks that any event that happens at time T in the first trace also happens at
+time T in the second trace (but doesn't care about the overall sequence in the trace).
+
+Useful for "parallel" simulations when the timing is deterministic but the ordering
+of events in the trace is not.
+
+Assumes the time is before the colon and the event is after the semicolon.
+
+ ********************************/
+
+public class CheckSameTimes
+{
+    public void run(String[] args)
+    {
+	if (args.length < 2)
+	{
+	    System.out.println("Need to specify at least two files!");
+	    return;
+	}
+	else
+	{
+	    // the file to which everything will be compared
+	    String file = args[0];
+
+	    // loop through the rest of the array of filenames
+	    for (int i = 1; i < args.length; i++)
+	    {
+		boolean success = checkSameTimes(file, args[i]);
+		if (success) System.out.println(file + " and " + args[i] + " have the same event timings");
+		else System.out.println(file + " and " + args[i] + " are different");
+	    }
+	}
+
+    }
+
+    public boolean checkSameTimes(String file1, String file2)
+    {
+	Scanner scan = null;
+	try
+	{
+	    // create the Scanner
+	    scan = new Scanner(new File(file1));
+
+	    // there may be error messages and such
+	    // just get the Scanner into a state where it ignores those
+	    String line = null;
+
+	    // once we found a line that starts with "0", we know we're into the trace
+	    boolean stop = false;
+	    while (!stop)
+	    {
+		line = scan.nextLine();
+		if (line.startsWith("0")) stop = true;
+	    }
+
+	    // now take each non-blank line and find its location in file2
+	    while (scan.hasNext())
+	    {
+		line = scan.nextLine();
+		if (line.trim().equals("") == false)
+		{
+		    String time = line.split(":")[0];
+		    String event = line.split(";")[1].trim();
+		    //System.out.println("Looking for: " + event + ".");
+		    // now get the location in file2
+		    String othertime = findTime(event, file2);
+		    if (othertime == null)
+		    {
+			System.out.println(event + " not found in " + file2);
+			return false;
+		    }
+		    else if (time.equals(othertime) == false)
+		    {
+			System.out.println("Timing is different: " + time + " in " + file1 + "; " + othertime + " in " + file2);
+			return false;
+		    }
+		}
+	    }
+
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	finally { scan.close(); }
+	return true;
+
+    }
+
+
+    public String findTime(String target, String file)
+    {
+	Scanner in = null;
+	try
+	{
+	    in = new Scanner(new File(file));
+
+	    while (in.hasNext())
+	    {
+		String line = in.nextLine();
+		if (line.contains(":") && line.contains(";"))
+		{
+		    String time = line.split(":")[0];
+		    String event = line.split(";")[1].trim();
+		    //System.out.println("comparing: " + event + ". to " + target + ".");
+		    if (event.equals(target)) return time;
+		}
+	    }
+	}
+	catch (Exception e) { e.printStackTrace(); }
+	finally { in.close(); }
+
+	// the default return value indicates that the line was not found
+	return null;
+    }
+
+
+    public static void main(String[] args)
+    {
+	new CheckSameTimes().run(args);
+    }
+
+}
\ No newline at end of file
diff --git a/util/CompareEvents.java b/util/CompareEvents.java
new file mode 100644
index 0000000..03c9536
--- /dev/null
+++ b/util/CompareEvents.java
@@ -0,0 +1,97 @@
+import java.util.Scanner;
+import java.util.ArrayList;
+import java.io.*;
+
+
+/*********************************
+
+Compares the output trace in the first argument to those in the other arguments.
+Reports how many events in the first also happen in the second by looking at
+which steps are actually "started".
+
+Useful for "choice" simulations when we want to see how close two traces are.
+
+Assumes the time is before the colon and the event is after the semicolon.
+
+ ********************************/
+
+public class CompareEvents
+{
+    public void run(String[] args)
+    {
+	if (args.length < 2)
+	{
+	    System.out.println("Need to specify at least two files!");
+	    return;
+	}
+	else
+	{
+	    // the file to which everything will be compared
+	    String file = args[0];
+
+	    ArrayList<String> events = getEvents(file);
+	    System.out.println(file + " has " + events.size() + " events");
+
+	    // loop through the rest of the array of filenames
+	    for (int i = 1; i < args.length; i++)
+	    {
+		int eventsInCommon = compareEvents(events, getEvents(args[i]));
+		if (events.size() == eventsInCommon) System.out.println(file + " and " + args[i] + " have the same events");
+		else System.out.println(file + " and " + args[i] + " are different by " + (events.size()-eventsInCommon));
+	    }
+	}
+
+    }
+
+
+    // finds all the lines in the file that end with "started"
+    public ArrayList<String> getEvents(String file)
+    {
+	ArrayList<String> events = new ArrayList<String>();
+	Scanner scan = null;
+	try
+	{
+	    scan = new Scanner(new File(file));
+
+	    String line;
+
+	    while(scan.hasNext())
+	    {
+		line = scan.nextLine().trim();
+		if (line.endsWith("started"))
+		{
+		    events.add(line.split(";")[1].trim());
+		}
+	    }
+
+	}
+	catch (Exception e) { }
+
+	return events;
+    }
+
+
+    public int compareEvents(ArrayList<String> list1, ArrayList<String> list2)
+    {
+	int count = 0;
+
+	for (String event : list1)
+	{
+	    // System.out.println("Looking for " + event);
+	    if (list2.contains(event))
+	    {
+		// System.out.println("Found it");
+		count++;
+	    }
+	}
+
+	return count;
+    }
+
+
+    public static void main(String[] args)
+    {
+	new CompareEvents().run(args);
+    }
+
+}
\ No newline at end of file
diff --git a/util/CompareJSimOutput.java b/util/CompareJSimOutput.java
new file mode 100644
index 0000000..36f524a
--- /dev/null
+++ b/util/CompareJSimOutput.java
@@ -0,0 +1,120 @@
+import java.util.Scanner;
+import java.io.*;
+
+/*************
+
+Compares the first specified file to multiple output trace files
+to make sure they're exactly the same.
+
+Makes no assumptions about the format of the output.
+
+ ************/
+
+
+public class CompareJSimOutput
+{
+    public boolean compare(String line1, String line2)
+    {
+	return line1.equals(line2);
+    }
+
+
+    public void run(String[] args)
+    {
+	String file1 = args[0];
+
+	for (int i = 1; i < args.length; i++)
+	{
+	    System.out.println("Comparing " + file1 + " to " + args[i]);
+	    if (compareFiles(file1, args[i]))
+	    {
+		System.out.println("Files are equal");
+	    }
+	    else
+	    {
+		System.out.println("Files are different");
+	    }
+	}
+    }
+
+    public boolean compareFiles(String file1, String file2)
+    {
+	try
+	{
+	    // create the Scanners
+	    Scanner scan1 = new Scanner(new File(file1));
+	    Scanner scan2 = new Scanner(new File(file2));
+
+	    // there may be error messages and such
+	    // just get each Scanner into a state where it ignores those
+	    String line1 = null;
+	    String line2 = null;
+
+	    int count1 = 0;
+	    int count2 = 0;
+
+	    boolean stop = false;
+	    while (!stop)
+	    {
+		line1 = scan1.nextLine();
+		count1++;
+		if (line1.startsWith("0")) stop = true;
+	    }
+
+	    stop = false;
+	    while (!stop)
+	    {
+		line2 = scan2.nextLine();
+		count2++;
+		if (line2.startsWith("0")) stop = true;
+	    }
+
+	    if (compare(line1, line2) == false)
+	    {
+		    System.out.println("DIFF FOUND!");
+		    System.out.println("File 1 (line " + count1 + "): " + line1);
+		    System.out.println("File 2 (line " + count2 + "): " + line2);
+		    return false;
+	    }
+
+	    // now keep reading until one or both are out of lines
+	    while (scan1.hasNext() && scan2.hasNext())
+	    {
+		line1 = scan1.nextLine();
+		count1++;
+
+		line2 = scan2.nextLine();
+		count2++;
+
+		// compare the two lines
+		if (compare(line1, line2) == false)
+		{
+		    System.out.println("DIFF FOUND!");
+		    System.out.println("File 1 (line " + count1 + "): " + line1);
+		    System.out.println("File 2 (line " + count2 + "): " + line2);
+		    return false;
+		}
+	    }
+
+	    // make sure they both had the same number of lines
+	    if (scan1.hasNext() || scan2.hasNext())
+	    {
+		System.out.println("Different number of lines!");
+		return false;
+	    }
+
+	    //System.out.println("Done. No differences found");
+
+	}
+	catch (Exception e) { e.printStackTrace(); }
+
+	return true;
+    }
+
+
+    public static void main(String[] args)
+    {
+	new CompareJSimOutput().run(args);
+    }
+
+}
\ No newline at end of file
diff --git a/util/CompareJSimSequence.java b/util/CompareJSimSequence.java
new file mode 100644
index 0000000..98bb78c
--- /dev/null
+++ b/util/CompareJSimSequence.java
@@ -0,0 +1,39 @@
+import java.util.Scanner;
+import java.io.*;
+
+/****************
+
+Compares two output trace files to check that the sequence of events is exactly the same.
+But does not consider the timing of events.
+
+This is useful for when the trace is deterministic but the timing is not.
+
+Assumes that the event is after the semicolon.
+
+ **************/
+
+public class CompareJSimSequence extends CompareJSimOutput
+{
+    public boolean compare(String line1, String line2)
+    {
+	// ONLY COMPARE THE EVENTS, NOT THE TIME
+
+	if (line1.trim().equals("") == false && line2.trim().equals("") == false)
+	{
+	    // just take whatever is after the semicolon
+	    String event1 = line1.split(";")[1].trim();
+	    String event2 = line2.split(";")[1].trim();
+
+	    return event1.equals(event2);
+	}
+	else
+	    return true;
+    }
+
+    public static void main(String[] args)
+    {
+	new CompareJSimSequence().run(args);
+    }
+
+}
+
diff --git a/util/ManhattanDistEst.java b/util/ManhattanDistEst.java
new file mode 100644
index 0000000..a57af04
--- /dev/null
+++ b/util/ManhattanDistEst.java
@@ -0,0 +1,73 @@
+public class ManhattanDistEst
+{
+    private static final int ITERATIONS = 100000;
+
+    public static void main(String[] args)
+    {
+	int numElements = Integer.parseInt(args[0]);
+
+	int targetDist = Integer.parseInt(args[1]);
+
+	compute(numElements, targetDist);
+    }
+
+    public static void compute(int numElements, int targetDistance)
+    {
+	// create an array of elements
+	int[] elements = new int[numElements];
+	for (int i = 0; i < numElements; i++)
+	    elements[i] = i;
+
+	// keep track of the number of lists with a shorter distance
+	int numCloser = 0;
+
+	// the minimum distance observed
+	int min = numElements * numElements / 2;
+
+	// the maximum distance observed
+	int max = 0;
+
+	// create randomizations of the list, calculate distance, and compare
+	for (int i = 0; i < ITERATIONS; i++)
+	{
+	    // create a permutation of the list
+	    for (int j = 0; j < numElements; j++)
+	    {
+		int swap = (int)(Math.random()*numElements);
+		int temp = elements[j];
+		elements[j] = elements[swap];
+		elements[swap] = temp;
+	    }
+
+	    // calculate the distance
+	    int dist = 0;
+	    for (int j = 0; j < numElements; j++)
+	    {
+		dist += Math.abs(elements[j] - j);
+	    }
+
+	    // update the min and max
+	    if (dist < min)
+		min = dist;
+	    if (dist > max)
+		max = dist;
+
+	    // now see if this randomization is closer
+	    //System.out.println("Distance is " + dist);
+	    if (dist < targetDistance)
+		numCloser++;
+	}
+
+	// report the results
+	System.out.println(numCloser + " out of " + ITERATIONS + " had a distance closer than " + targetDistance);
+	System.out.println("Confidence is " + (1 - (double)numCloser/ITERATIONS));
+	System.out.println("Min: " + min + "; Max: " + max);
+
+
+
+
+    }
+
+
+
+}
\ No newline at end of file
diff --git a/util/Multiplier.java b/util/Multiplier.java
new file mode 100644
index 0000000..dc6a52f
--- /dev/null
+++ b/util/Multiplier.java
@@ -0,0 +1,146 @@
+import java.util.*;
+import java.io.*;
+
+/*
+ * This multiplies values in a CSV data file
+ */
+
+public class Multiplier
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".m";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void multiply(int factor)
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, ",");
+
+	    while (tok.hasMoreTokens())
+	    {
+		if (newLine != "") newLine += ",";
+
+		String value = tok.nextToken();
+
+		// don't change the last token (the label)
+		if (tok.hasMoreTokens())
+		{
+		    try
+		    {
+			// see if it's a floating point number
+			float x = Float.parseFloat(value);
+			// if we got here, it is
+			x *= factor;
+			value = "" + x;
+		    }
+		    catch (NumberFormatException e) { }
+		}
+
+		newLine += value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename, int factor)
+    {
+	read(filename);
+	multiply(factor);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    int factor = Integer.parseInt(args[1]);
+	    new Multiplier().go(filename, factor);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Multiplier2.java b/util/Multiplier2.java
new file mode 100644
index 0000000..155612d
--- /dev/null
+++ b/util/Multiplier2.java
@@ -0,0 +1,145 @@
+import java.util.*;
+import java.io.*;
+
+/*
+ * This multiplies values in a file in the sparse attr:value format
+ */
+
+public class Multiplier2
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".m";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void multiply(int factor)
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, " ");
+
+	    // ignore the first token, which is the label
+	    newLine += tok.nextToken();
+
+	    while (tok.hasMoreTokens())
+	    {
+		String value = tok.nextToken();
+
+		// separate the attribute number
+		String attr = value.split(":")[0];
+
+		value = value.split(":")[1];
+
+		// see if it's a floating point number
+		double x = Double.parseDouble(value);
+		// if we got here, it is
+		x *= factor;
+		value = "" + x;
+
+		newLine += " " + attr + ":" + value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename, int factor)
+    {
+	read(filename);
+	multiply(factor);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    int factor = Integer.parseInt(args[1]);
+	    new Multiplier2().go(filename, factor);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    //System.out.println("You didn't specify a file");
+	    e.printStackTrace();
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Multiplier3.java b/util/Multiplier3.java
new file mode 100644
index 0000000..10516da
--- /dev/null
+++ b/util/Multiplier3.java
@@ -0,0 +1,150 @@
+import java.util.*;
+import java.io.*;
+
+/*
+ * This multiplies only the first three values in each row
+ * in a CSV data file
+ */
+
+public class Multiplier3
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".m";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void multiply(int factor)
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, ",");
+
+	    int count = 0;
+
+	    while (tok.hasMoreTokens())
+	    {
+		count++;
+		if (newLine != "") newLine += ",";
+
+		String value = tok.nextToken();
+
+		// don't change the last token (the label)
+		if (tok.hasMoreTokens() && count <= 3)
+		{
+		    try
+		    {
+			// see if it's a floating point number
+			float x = Float.parseFloat(value);
+			// if we got here, it is
+			x *= factor;
+			value = "" + x;
+		    }
+		    catch (NumberFormatException e) { }
+		}
+
+		newLine += value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename, int factor)
+    {
+	read(filename);
+	multiply(factor);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    int factor = Integer.parseInt(args[1]);
+	    new Multiplier3().go(filename, factor);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Mutator.java b/util/Mutator.java
new file mode 100644
index 0000000..f30ca40
--- /dev/null
+++ b/util/Mutator.java
@@ -0,0 +1,152 @@
+import java.util.*;
+import java.io.*;
+
+/*
+ * Mutates boolean operators
+ */
+
+public class Mutator
+{
+    private int mutations = 0; // counts the number of mutations to make
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+
+		// see if it contains an operator to mutate
+		if (canMutate(line))
+		    mutations++;
+	    }
+
+	    System.out.println("Mutation count is " + mutations);
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// figure out the name of the file (without its extension)
+	String name = filename.split("[.]")[0];
+
+	System.out.println("Name is " +  name);
+
+	for (int i = 0; i < mutations; i++)
+	{
+	    int count = -1; // keeps track of the number of ops seen so far
+	    try
+	    {
+		// update the name
+		String myName = name + i;
+
+		// create the File
+		File file = new File(filename.replace(name, myName));
+
+		// initialize the PrintWriter
+		out = new PrintWriter(file);
+
+		for (String line : lines)
+		{
+		    // if the line contains the filename, replace it
+		    /*
+		    if (line.contains(" " + name + " ")) line = line.replace(" " + name + " ", " " + myName + " ");
+		    if (line.contains(name + ".this")) line = line.replace(name, myName);
+		    if (line.contains(name + "(")) line = line.replace(name, myName);
+		    */
+
+		    // see if this line can be mutated
+		    if (canMutate(line))
+		    {
+			// if so, increase the counter
+			count++;
+
+			// if we're at the right version number, mutate the line
+			if (count == i)
+			    out.println(mutate(line));
+			else
+			    out.println(line);
+		    }
+		    else
+		    {
+			out.println(line);
+		    }
+		}
+
+	    }
+	    catch (Exception e)
+	    {
+		e.printStackTrace();
+		return;
+	    }
+	    finally
+	    {
+		try { out.flush(); } catch (Exception e) { }
+		try { out.close(); } catch (Exception e) { }
+	    }
+	}
+    }
+
+
+    private boolean canMutate(String line)
+    {
+	return line.contains(" < ") || (line.contains(">") && (line.contains("->") == false)) || line.contains("==") || line.contains("!=") || line.contains("||") || line.contains("&&");
+    }
+
+    private String mutate(String line)
+    {
+	if (line.contains(" < ")) return line.replace(" < ", " > ");
+	else if (line.contains(">") && (line.contains("->") == false)) return line.replace(">", "<");
+	else if (line.contains("==")) return line.replace("==", "!=");
+	else if (line.contains("!=")) return line.replace("!=", "==");
+	else if (line.contains("||")) return line.replace("||", "&&");
+	else if (line.contains("&&")) return line.replace("&&", "||");
+	else return line; // rut roh
+    }
+
+    public void go(String filename)
+    {
+	read(filename);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    new Mutator().go(filename);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Mutator2.java b/util/Mutator2.java
new file mode 100644
index 0000000..5ae56a0
--- /dev/null
+++ b/util/Mutator2.java
@@ -0,0 +1,176 @@
+import java.util.*;
+import java.io.*;
+
+/*
+ * Mutates math operators
+ */
+
+public class Mutator2
+{
+    private int mutations = 0; // counts the number of mutations to make
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    boolean inComment = false;
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+
+		if (line.contains("/*")) inComment = true;
+
+		// see if it contains an operator to mutate
+		if (!inComment && line.contains("//") == false && canMutate(line))
+		    mutations++;
+
+		if (line.contains("*/")) inComment = false;
+	    }
+
+	    System.out.println("Mutation count is " + mutations);
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// figure out the name of the file (without its extension)
+	String name = filename.split("[.]")[0];
+
+	// check to make sure this is working right
+	int check = 0;
+
+	for (int i = 0; i < mutations; i++)
+	{
+	    int count = -1; // keeps track of the number of ops seen so far
+	    try
+	    {
+		// update the name
+		String myName = name + i;
+
+		// create the File
+		File file = new File(filename.replace(name, myName));
+
+		// tracks whether or not we're in a comment
+		boolean inComment = false;
+
+		// initialize the PrintWriter
+		out = new PrintWriter(file);
+
+		for (String line : lines)
+		{
+		    /*
+		    // if the line contains the filename, replace it
+		    if (line.contains(" " + name + " ")) line = line.replace(" " + name + " ", " " + myName + " ");
+		    if (line.contains(name + ".this")) line = line.replace(name, myName);
+		    if (line.contains(name + "(")) line = line.replace(name, myName);
+
+		    // just for SMO
+		    if (line.contains("BinarySMO ") || line.contains("BinarySMO[")) line = line.replace(name, myName);
+		    */
+
+		    // start of the comment
+		    if (line.contains("/*")) inComment = true;
+
+		    // see if this line can be mutated
+		    if (!inComment && line.contains("//") == false && canMutate(line))
+		    {
+			// if so, increase the counter
+			count++;
+
+			// if we're at the right version number, mutate the line
+			if (count == i)
+			{
+			    out.println(mutate(line));
+			    check++;
+			}
+			else
+			    out.println(line);
+		    }
+		    else
+		    {
+			out.println(line);
+		    }
+
+		    // end of the comment
+		    if (line.contains("*/")) inComment = false;
+		}
+
+	    }
+	    catch (Exception e)
+	    {
+		e.printStackTrace();
+		return;
+	    }
+	    finally
+	    {
+		try { out.flush(); } catch (Exception e) { }
+		try { out.close(); } catch (Exception e) { }
+	    }
+	}
+
+	System.out.println("Final count is " + check);
+    }
+
+
+    private boolean canMutate(String line)
+    {
+	return line.contains("\"") == false && (line.contains("+") || (line.contains("-") && line.contains("->") == false) || line.contains(" * ") || line.contains("/"));
+    }
+
+    private String mutate(String line)
+    {
+	if (line.contains("++")) return line.replace("++", "--");
+	else if (line.contains("--")) return line.replace("--", "++");
+	else if (line.contains("+")) return line.replace("+", "-");
+	else if (line.contains("-") && line.contains("->") == false) return line.replace("-", "+");
+	else if (line.contains(" * ")) return line.replace(" * ", "/");
+	else if (line.contains("/")) return line.replace("/", "*");
+	else return line; // rut roh
+    }
+
+    public void go(String filename)
+    {
+	read(filename);
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    new Mutator2().go(filename);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Negator.java b/util/Negator.java
new file mode 100644
index 0000000..75ca9c3
--- /dev/null
+++ b/util/Negator.java
@@ -0,0 +1,141 @@
+import java.util.*;
+import java.io.*;
+
+public class Negator
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".n";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void negate()
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, ",");
+
+	    while (tok.hasMoreTokens())
+	    {
+		if (newLine != "") newLine += ",";
+
+		String value = tok.nextToken();
+
+		// we don't want to change the last token (the label)
+		// if there are more tokens, this isn't the last one
+		if (tok.hasMoreTokens())
+		{
+		    try
+		    {
+			// see if it's a floating point number
+			Float.parseFloat(value);
+			// if we got here, it is
+			if (value.startsWith("-")) value = value.substring(1, value.length());
+			else value = "-" + value;
+		    }
+		    catch (NumberFormatException e) { }
+		}
+		newLine += value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename)
+    {
+	read(filename);
+	negate();
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    new Negator().go(filename);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Negator3.java b/util/Negator3.java
new file mode 100644
index 0000000..ad8d5bf
--- /dev/null
+++ b/util/Negator3.java
@@ -0,0 +1,145 @@
+import java.util.*;
+import java.io.*;
+
+public class Negator3
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".n";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void negate()
+    {
+	ArrayList<String> newLines = new ArrayList<String>();
+	StringTokenizer tok;
+	String line, newLine;
+
+	for (int i = 0; i < lines.size(); i++)
+	{
+	    line = lines.get(i);
+
+	    newLine = "";
+	    tok = new StringTokenizer(line, ",");
+
+	    int count = 0;
+
+	    while (tok.hasMoreTokens())
+	    {
+		count ++;
+
+		if (newLine != "") newLine += ",";
+
+		String value = tok.nextToken();
+
+		// we don't want to change the last token (the label)
+		// if there are more tokens, this isn't the last one
+		if (tok.hasMoreTokens() && count <= 3)
+		{
+		    try
+		    {
+			// see if it's a floating point number
+			Float.parseFloat(value);
+			// if we got here, it is
+			if (value.startsWith("-")) value = value.substring(1, value.length());
+			else value = "-" + value;
+		    }
+		    catch (NumberFormatException e) { }
+		}
+		newLine += value;
+	    }
+
+	    //System.out.println("newLine " + newLine);
+	    newLines.add(newLine);
+	}
+
+	lines = newLines;
+
+    }
+
+    public void go(String filename)
+    {
+	read(filename);
+	negate();
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    new Negator3().go(filename);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/OneDiff.java b/util/OneDiff.java
new file mode 100644
index 0000000..0082e56
--- /dev/null
+++ b/util/OneDiff.java
@@ -0,0 +1,83 @@
+import java.util.*;
+import java.io.*;
+
+public class OneDiff
+{
+
+    public void read(String name1, String name2)
+    {
+	Scanner in1 = null, in2 = null;
+
+	try
+	{
+	    File file1 = new File(name1);
+	    in1 = new Scanner(file1);
+	}
+	catch (Exception e)
+	{
+	    System.out.println("ERROR: Cannot read file " + name1);
+	    return;
+	}
+
+	try
+	{
+	    File file2 = new File(name2);
+	    in2 = new Scanner(file2);
+	}
+	catch (Exception e)
+	{
+	    System.out.println("ERROR: Cannot read file " + name2);
+	    return;
+	}
+
+
+	int line = 0;
+
+	// keep reading while there is more to read
+	while (in1.hasNext() && in2.hasNext())
+	{
+	    line++;
+
+	    // read an entire line
+	    String line1 = in1.nextLine();
+	    String line2 = in2.nextLine();
+
+	    if (line1.equals(line2) == false)
+	    {
+		System.out.println("DIFF FOUND: line " + line);
+		System.out.println("File 1: " + line1);
+		System.out.println("File 2: " + line2);
+		return;
+	    }
+	}
+
+	if (in1.hasNext() || in2.hasNext())
+	{
+	    System.out.println("DIFFERENT FILE LENGTHS");
+	}
+	else
+	{
+	    System.out.println("ok");
+	}
+
+
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename1 = args[0];
+	    String filename2 = args[1];
+	    new OneDiff().read(filename1, filename2);
+      	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/Permutor.java b/util/Permutor.java
new file mode 100644
index 0000000..15d8a72
--- /dev/null
+++ b/util/Permutor.java
@@ -0,0 +1,108 @@
+import java.util.*;
+import java.io.*;
+
+public class Permutor
+{
+    private ArrayList<String> lines = new ArrayList<String>();
+
+    public void read(String name)
+    {
+	try
+	{
+	    // first, create the File object
+	    File file = new File(name);
+
+	    // now create the Scanner using the File
+	    Scanner in = new Scanner(file);
+
+	    // keep reading while there is more to read
+	    while (in.hasNext())
+	    {
+		// read an entire line
+		String line = in.nextLine();
+
+		// print it to the screen
+		//System.out.println(line);
+
+		// add it to the arraylist
+		lines.add(line);
+	    }
+
+	}
+	catch (FileNotFoundException e)
+	{
+	    System.out.println(name + " doesn't exist");
+	}
+    }
+
+    public void write(String filename)
+    {
+	// create a null PrintWriter outside the try block
+	PrintWriter out = null;
+
+	// update the name
+	String myName = filename + ".p";
+
+	try
+	{
+	    // create the File
+	    File file = new File(myName);
+
+	    // initialize the PrintWriter
+	    out = new PrintWriter(file);
+
+	    for (String line : lines)
+	    {
+		out.println(line);
+	    }
+
+	}
+	catch (Exception e)
+	{
+	    e.printStackTrace();
+	    return;
+	}
+	finally
+	{
+	    try { out.flush(); } catch (Exception e) { }
+	    try { out.close(); } catch (Exception e) { }
+	}
+
+    }
+
+
+    private void randomize()
+    {
+	for (int i = 0; i < lines.size() * 3; i++)
+	{
+	    int index = (int)(Math.random() * lines.size());
+	    String line = lines.get(index);
+	    lines.remove(index);
+	    lines.add(line);
+	}
+    }
+
+    public void go(String filename)
+    {
+	read(filename);
+	randomize();
+	write(filename);
+    }
+
+
+    public static void main(String[] args)
+    {
+	try
+        {
+	    // read the filename from the command line
+	    String filename = args[0];
+	    new Permutor().go(filename);
+      	}
+	catch (ArrayIndexOutOfBoundsException e)
+	{
+	    System.out.println("You didn't specify a file");
+	}
+    }
+
+
+}
\ No newline at end of file
diff --git a/util/TTest.java b/util/TTest.java
new file mode 100644
index 0000000..61d552e
--- /dev/null
+++ b/util/TTest.java
@@ -0,0 +1,36 @@
+/*
+Does the calculations for a Student's t-test.
+*/
+
+public class TTest
+{
+    public static double ttest(double x1, double s1, double x2, double s2, double n)
+    {
+	double s = Math.sqrt((s1*s1+s2*s2)/n);
+
+	double t = (x1 - x2)/(s); // * Math.sqrt(2/n));
+
+	return t;
+    }
+
+    public static void main(String[] args)
+    {
+	try
+	{
+	    double x1 = Double.parseDouble(args[0]);
+	    double s1 = Double.parseDouble(args[1]);
+	    double x2 = Double.parseDouble(args[2]);
+	    double s2 = Double.parseDouble(args[3]);
+	    double n = Double.parseDouble(args[4]);
+
+	    System.out.println("t-value = " + TTest.ttest(x1, s1, x2, s2, n));
+	}
+	catch (Exception e)
+	{
+	    System.out.println("Usage: java TTest x1 s1 x2 s2 n");
+	}
+
+
+    }
+
+}
\ No newline at end of file