[Home]Voidious/WaveReader

Robo Home | Voidious | Changes | Preferences | AllPages

Showing revision 2
Difference (from revision 2 to revision 2) (minor diff)
(The revisions are identical or unavailable.)
The analysis portion of my recent Segmentation Research. This program uses data recorded with WaveRecorder to try and find optimal Segmentation slices for a GuessFactorTargeting bot.

Much of the code is very stringy, but the core methods are pretty clean and efficient. A lot of it is just kind of a sandbox to try this stuff. I may get to cleaning it up later once I'm more familiar with what I want to be doing with it.

--

package voidious.test;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

/** 
 * WaveReader.java
 * 
 * Some GuessFactorTargeting analysis by Voidious.
 *
 * This code is open source, released under the RoboWiki Public Code License:
 * http://robowiki.net/cgi-bin/robowiki?RWPCL
 */

public class WaveReader {
//	public static double _ln2 = Math.log(2);
	public HashMap<String, ArrayList> waveSets;
	public static String baseDir = 
		"/Users/pcupka/eclipse_workspace/WaveRecorder.data/max/";

	public WaveReader() {
		waveSets = new HashMap<String, ArrayList>();
	}
	
	public static void main(String[] args) {
		boolean useRatio = false;
		if (args.length > 0) {
			useRatio = true;
		}
		
		WaveReader wr = new WaveReader();
		
		String[] files = {"cig5000.txt", "dm5000.txt", "sparrow5000.txt",
			"floodmini5000.txt", "rmb5000.txt", "aspid5000.txt",
			"dt5000.txt", "fhqw5000.txt", "funky5000.txt", "taow5000.txt",
			"tron5000.txt"};

		wr.clearData();
		for (int x = 0; x < files.length; x++) {
			String thisFile = files[x];
			System.out.print("Loading file: " + thisFile + "... ");
			
//			wr.loadData(thisFile);
			wr.loadDataFiringOnly(thisFile);

			System.out.println("Done!");
		}

/*
		for (int y = 1; y <= 4; y++) {
			System.out.println("----\nLateralVelocity, " + y + " segments.");
			ThresholdData td;
			if (useRatio) {
				td = wr.findBestLatVelSlicesTwoRatioAll(y, 0.2f, 37, 0, 8);
			} else {
				td = wr.findBestLatVelSlicesTwoAll(y, 0.2f, 37, 0, 8);					
			}
			
			System.out.print("Slices: " + round(td.slices[0], 1));
			for (int z = 1; z < td.slices.length; z++) {
				System.out.print(" / " + round(td.slices[z], 1));		
			}
			System.out.println();
			System.out.println("Entropy: " + td.origEntropy + " / " + td.entropy);			
			if (useRatio) {
				System.out.println("Gain Ratio: " + td.gainRatio);			
			}
		}

		for (int y = 1; y <= 4; y++) {
			System.out.println("----\nDistance, " + y + " segments.");
			ThresholdData td;
			if (useRatio) {
				td = wr.findBestDistanceSlicesTwoRatioAll(y, 25, 37, 0, 1000);
			} else {
				td = wr.findBestDistanceSlicesTwoAll(y, 25, 37, 0, 1000);					
			}
			
			System.out.print("Slices: " + round(td.slices[0], 0));
			for (int z = 1; z < td.slices.length; z++) {
				System.out.print(" / " + round(td.slices[z], 0));		
			}
			System.out.println();
			System.out.println("Entropy: " + td.origEntropy + " / " + td.entropy);			
			if (useRatio) {
				System.out.println("Gain Ratio: " + td.gainRatio);			
			}
		}

		for (int y = 1; y <= 4; y++) {
			System.out.println("----\nWall Distance, " + y + " segments.");
			ThresholdData td;
			if (useRatio) {
				td = wr.findBestWallDistanceSlicesTwoRatioAll(y, 0.025f, 37, 0, 1);
			} else {
				td = wr.findBestWallDistanceSlicesTwoAll(y, 0.025f, 37, 0, 1);
			}
			
			System.out.print("Slices: " + round(td.slices[0], 3));
			for (int z = 1; z < td.slices.length; z++) {
				System.out.print(" / " + round(td.slices[z], 3));		
			}
			System.out.println();
			System.out.println("Entropy: " + td.origEntropy + " / " + td.entropy);			
			if (useRatio) {
				System.out.println("Gain Ratio: " + td.gainRatio);			
			}
		}

		for (int y = 1; y <= 4; y++) {
			System.out.println("----\nVChangeTime, " + y + " segments.");
			ThresholdData td;
			if (useRatio) {
				td = wr.findBestVChangeTimeSlicesTwoRatioAll(y, 0.025f, 37, 0, 1.2f);
			} else {
				td = wr.findBestVChangeTimeSlicesTwoAll(y, 0.025f, 37, 0, 1.2f);
			}
			
			System.out.print("Slices: " + round(td.slices[0], 3));
			for (int z = 1; z < td.slices.length; z++) {
				System.out.print(" / " + round(td.slices[z], 3));		
			}
			System.out.println();
			System.out.println("Entropy: " + td.origEntropy + " / " + td.entropy);			
			if (useRatio) {
				System.out.println("Gain Ratio: " + td.gainRatio);			
			}
		}

		System.out.println("----");
*/
	
		System.out.println("Unsegmented entropy: " + 
				wr.evaluateUnsegmentedSet(37));

		wr.findBestLatVelDistanceWallDistanceVChangeTimeSlicesTwoAll(2, 37);
		wr.findBestLatVelDistanceWallDistanceVChangeTimeSlicesTwoAll(3, 37);
		wr.findBestLatVelDistanceWallDistanceVChangeTimeSlicesTwoAll(4, 37);
		wr.findBestLatVelDistanceWallDistanceVChangeTimeSlicesTwoAll(5, 37);
	}
	
	public void clearData() {
		waveSets = new HashMap<String, ArrayList>();
	}
	
	public void loadData(String filename) {
		ArrayList<Wave> waves = new ArrayList<Wave>();
		File f = new File(baseDir + filename);

		try {
			BufferedReader br = new BufferedReader(new FileReader(f));
		
			while (br.ready()) {
				String nextLine = br.readLine();
				if (nextLine != null) {
					waves.add(parseRecord(nextLine));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error in loadData(" + f + ")");
		}
		
		waveSets.put(filename, waves);
	}

	public void loadDataFiringOnly(String filename) {
		ArrayList<Wave> waves = new ArrayList<Wave>();
		File f = new File(baseDir + filename);

		try {
			BufferedReader br = new BufferedReader(new FileReader(f));
		
			while (br.ready()) {
				String nextLine = br.readLine();
				if (nextLine != null) {
					Wave w = parseRecord(nextLine);
					if (w.firing) {
						waves.add(w);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error in loadData(" + f + ")");
		}
		
		waveSets.put(filename, waves);
	}

	public Wave parseRecord(String record) {
		String[] fields = record.split(" : ");
		
		Wave w = new Wave();
		
		w.roundNum = (byte)Integer.parseInt(fields[0]);
		w.firing = (Integer.parseInt(fields[1]) == 1);
		w.orientation = (byte)Integer.parseInt(fields[2]);
		w.guessFactor = (float)Double.parseDouble(fields[3]);
		w.velocity = (float)Double.parseDouble(fields[4]);
		w.latVel = (float)Double.parseDouble(fields[5]);
		w.accel = (byte)Integer.parseInt(fields[6]);
		w.timeSinceVChange = Integer.parseInt(fields[7]);
		w.distance = (float)Double.parseDouble(fields[8]);
		w.wallDistance = (float)Double.parseDouble(fields[9]);
		w.relativeHeading = (float)Double.parseDouble(fields[10]);
		
		return w;
	}
	
 	public void findBestLatVelDistanceWallDistanceVChangeTimeSlicesTwoAll(
 		int attrSlices, int gfSlices) {
 	 	 	 	 	 	 		
 	 	DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];

 	 	Iterator iter = waveSets.keySet().iterator();
 	 	
 	 	int gIndex = 0;
 	 	while (iter.hasNext()) {
 	 	  	String filename = (String)iter.next();
 	 	  	drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetLatVel(filename, gfSlices));
 	 	}
 	 	 	 	 	 	 
 	 	int[] baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 	 	 		 		
 	 	ThresholdData latVelData = findBestAttrSlices(drtg, attrSlices,
 	 	 	0.25f, gfSlices, 0, 8, baseCounts);

 	 	float[] latVelSlices = new float[attrSlices + 1];
 	 	for (int x = 0; x < attrSlices; x++) {
 	 		latVelSlices[x] = latVelData.slices[x]; 	 		
 	 	}
 	 	latVelSlices[attrSlices] = Float.POSITIVE_INFINITY;
 	 	
 	 	float[] distSlices = new float[attrSlices + 1]; 	
 	 	drtg = new DataRecordTwoGroup[waveSets.size() * (attrSlices + 1)];
 	 	
 	 	for (int z = 0; z < latVelSlices.length; z++) {
 	 	 	iter = waveSets.keySet().iterator();

 	 	 	gIndex = 0;
 	 	 	while (iter.hasNext()) {
 	 	 	  	String filename = (String)iter.next();

 	 	 	  	ArrayList waves = waveSets.get(filename);
 	 			DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
 	 			
 	 			int tempIndex = 0;
 	 			
 	 			for (int x = 0; x < waves.size(); x++) {
 	 				Wave w = (Wave)waves.get(x);
 	 				if (w.latVel < latVelSlices[z] && 
 	 					(z == 0 || w.latVel >= latVelSlices[z-1])) {
 	 					drt[tempIndex++] = parseWaveDistance(w, gfSlices);
 	 				}
 	 			}
 	 			
 	 			drt = trimDataSet(drt, tempIndex);
 	 			
 	 			drtg[(z * waveSets.size()) + gIndex] = new DataRecordTwoGroup(gIndex, drt);
 	 			gIndex++;
 	 	 	}
 	 	}

 	 	baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 	 	 	 		 		
 	 	ThresholdData distData = findBestAttrSlices(drtg, attrSlices,
 	 	 	25, gfSlices, 0, 1000, baseCounts);
 	 	 	
 	 	for (int x = 0; x < attrSlices; x++) {
 	 		distSlices[x] = distData.slices[x]; 	 		
 	 	}
 	 	distSlices[attrSlices] = Float.POSITIVE_INFINITY;

 	 	
 	 	float[] walldistSlices = new float[attrSlices + 1]; 	
 	 	drtg = new DataRecordTwoGroup[waveSets.size() * (attrSlices + 1) * (attrSlices + 1)];
 	 	
 	 	for (int z = 0; z < latVelSlices.length; z++) {
 	 	 	for (int a = 0; a < distSlices.length; a++) {
 	 	 	 	iter = waveSets.keySet().iterator();

 	 	 	 	gIndex = 0;
 	 	 	 	while (iter.hasNext()) {
 	 	 	 	  	String filename = (String)iter.next();

 	 	 	 	  	ArrayList waves = waveSets.get(filename);
 	 	 			DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
 	 	 			
 	 	 			int tempIndex = 0;
 	 	 			
 	 	 			for (int x = 0; x < waves.size(); x++) {
 	 	 				Wave w = (Wave)waves.get(x);
 	 	 				if (w.latVel < latVelSlices[z] && 
 	 	 					(z == 0 || w.latVel >= latVelSlices[z-1]) &&
 	 	 					w.distance < distSlices[a] &&
 	 	 					(a == 0 || w.distance >= distSlices[a-1])) {
 	 	 					drt[tempIndex++] = parseWaveWallDistance(w, gfSlices);
 	 	 				}
 	 	 			}
 	 	 			
 	 	 			drt = trimDataSet(drt, tempIndex);
 	 	 			
 	 	 			drtg[((a + z * distSlices.length) * waveSets.size()) + gIndex] = new DataRecordTwoGroup(gIndex, drt);
 	 	 			gIndex++;
 	 	 	 	}
 	 	 	}
 	 	}
 	 	
 	 	baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 	 	 	 		 		
 	 	ThresholdData walldistData = findBestAttrSlices(drtg, attrSlices,
 	 	 	0.05f, gfSlices, 0, 1.2f, baseCounts);
 	 	 	
 	 	for (int x = 0; x < attrSlices; x++) {
 	 		walldistSlices[x] = walldistData.slices[x]; 	 		
 	 	}
 	 	walldistSlices[attrSlices] = Float.POSITIVE_INFINITY;

 	 	
 	 	float[] vchangeSlices = new float[attrSlices + 1]; 	
 	 	drtg = new DataRecordTwoGroup[waveSets.size() * (attrSlices + 1) * 
 	 	    (attrSlices + 1) * (attrSlices + 1)];
 	 	
 	 	for (int z = 0; z < latVelSlices.length; z++) {
 	 	 	for (int a = 0; a < distSlices.length; a++) {
 	 	 	 	for (int b = 0; b < walldistSlices.length; b++) {
 	 	 	 	 	iter = waveSets.keySet().iterator();

 	 	 	 	 	gIndex = 0;
 	 	 	 	 	while (iter.hasNext()) {
 	 	 	 	 	  	String filename = (String)iter.next();

 	 	 	 	 	  	ArrayList waves = waveSets.get(filename);
 	 	 	 			DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
 	 	 	 			
 	 	 	 			int tempIndex = 0;
 	 	 	 			
 	 	 	 			for (int x = 0; x < waves.size(); x++) {
 	 	 	 				Wave w = (Wave)waves.get(x);
 	 	 	 				if (w.latVel < latVelSlices[z] && 
 	 	 	 					(z == 0 || w.latVel >= latVelSlices[z-1]) &&
 	 	 	 					w.distance < distSlices[a] &&
 	 	 	 					(a == 0 || w.distance >= distSlices[a-1]) &&
 	 	 	 					w.wallDistance < walldistSlices[b] &&
 	 	 	 					(b == 0 || w.wallDistance >= walldistSlices[b-1])) {
 	 	 	 					DataRecordTwo drtTemp = parseWaveVChangeTime(w, gfSlices);
 	 	 	 					if (drtTemp != null) {
 	 	 	 						drt[tempIndex++] = drtTemp;
 	 	 	 					}
 	 	 	 				}
 	 	 	 			}
 	 	 	 			
 	 	 	 			drt = trimDataSet(drt, tempIndex);
 	 	 	 			
 	 	 	 			drtg[((b + a * walldistSlices.length + z * distSlices.length * walldistSlices.length) * waveSets.size()) + gIndex] = new DataRecordTwoGroup(gIndex, drt);
 	 	 	 			gIndex++;
 	 	 	 	 	}
 	 	 	 	}
 	 	 	}
 	 	}
 	 	
 	 	baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 	 	 	 		 		
 	 	ThresholdData vchangeData = findBestAttrSlices(drtg, attrSlices,
 	 	 	0.05f, gfSlices, 0, 1.2f, baseCounts);
 	 	 	
 	 	for (int x = 0; x < attrSlices; x++) {
 	 		vchangeSlices[x] = vchangeData.slices[x]; 	 		
 	 	}
 	 	vchangeSlices[attrSlices] = Float.POSITIVE_INFINITY;
 	 	
		System.out.print("LatVel Slices: " + round(latVelSlices[0], 2));
		for (int z = 1; z < latVelSlices.length - 1; z++) {
			System.out.print(" / " + round(latVelSlices[z], 2));		
		}
		System.out.println();

		System.out.print("Distance Slices: " + round(distSlices[0], 0));
		for (int z = 1; z < distSlices.length - 1; z++) {
			System.out.print(" / " + round(distSlices[z], 0));		
		}
		System.out.println();

		System.out.print("WallDistance Slices: " + round(walldistSlices[0], 2));
		for (int z = 1; z < walldistSlices.length - 1; z++) {
			System.out.print(" / " + round(walldistSlices[z], 2));		
		}
		System.out.println();

		System.out.print("VChangeTime Slices: " + round(vchangeSlices[0], 2));
		for (int z = 1; z < vchangeSlices.length - 1; z++) {
			System.out.print(" / " + round(vchangeSlices[z], 2));		
		}
		System.out.println();

		System.out.println("Final entropy: " + vchangeData.entropy);
 	}

 	public ThresholdData findBestLatVelSlicesTwo(String filename, int attrSlices, 
 		float attrIncrement, int gfSlices, float lowBound, float highBound) {
		return findBestAttrSlices(dataSetLatVel(filename, gfSlices), attrSlices,
			attrIncrement, gfSlices, lowBound, highBound);
	}

 	public ThresholdData findBestLatVelSlicesTwoRatio(String filename, int attrSlices, 
 		float attrIncrement, int gfSlices, float lowBound, float highBound) {
		return findBestAttrSlicesRatio(dataSetLatVel(filename, gfSlices), attrSlices,
			attrIncrement, gfSlices, lowBound, highBound);
	}

 	public ThresholdData findBestLatVelSlicesTwoAll(int attrSlices, 
 	 	float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 	 	 	 	 		
 	 	DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 	 	 	 	 		
 	 	Iterator iter = waveSets.keySet().iterator();
 	 	 	 	 	 		
 	 	int gIndex = 0;
 	 	while (iter.hasNext()) {
 	 	  	String filename = (String)iter.next();
 	 	  	drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetLatVel(filename, gfSlices));
 	 	}
 	 	 	 	 	 
 	 	int[] baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 	 		 		
 	 	return findBestAttrSlices(drtg, attrSlices,
 	  	 	attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	}
 	
 	public ThresholdData findBestLatVelSlicesTwoRatioAll(int attrSlices, 
 		float attrIncrement, int gfSlices, float lowBound, float highBound) {
 		
 		DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 		
 		Iterator iter = waveSets.keySet().iterator();
 		
 		int gIndex = 0;
 		while (iter.hasNext()) {
 			String filename = (String)iter.next();
 			drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetLatVel(filename, gfSlices));
 		}
 		
 		int[] baseCounts = new int[drtg.length];
 		for (int x = 0; x < drtg.length; x++) {
 			baseCounts[x] = drtg[x].dataSet.length;
 		}
 		 		
		return findBestAttrSlicesRatio(drtg, attrSlices,
			attrIncrement, gfSlices, lowBound, highBound, baseCounts);
	}

 	public ThresholdData findBestDistanceSlicesTwo(String filename, int attrSlices, 
 	 	float attrIncrement, int gfSlices, float lowBound, float highBound) {
 		return findBestAttrSlices(dataSetDistance(filename, gfSlices), attrSlices,
 			attrIncrement, gfSlices, lowBound, highBound);
	}

 	public ThresholdData findBestDistanceSlicesTwoRatio(String filename, int attrSlices, 
 	 	 	float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 		return findBestAttrSlicesRatio(dataSetDistance(filename, gfSlices), attrSlices,
 	 			attrIncrement, gfSlices, lowBound, highBound);
	}
 	
 	public ThresholdData findBestDistanceSlicesTwoAll(int attrSlices, 
 	 	 float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 	 	 	 		
 	 	 DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 	 	 	 		
 	 	 Iterator iter = waveSets.keySet().iterator();
 	 	 	 	 		
 	 	 int gIndex = 0;
 	 	 while (iter.hasNext()) {
 	 	 	 String filename = (String)iter.next();
 	 	  	 drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetDistance(filename, gfSlices));
 	 	 }
 	 	 	 	 
 	 	 int[] baseCounts = new int[drtg.length];
 	 	 for (int x = 0; x < drtg.length; x++) {
 	 	 	baseCounts[x] = drtg[x].dataSet.length;
 	 	 }
 	 	 	 	 		 		
 	 	 return findBestAttrSlices(drtg, attrSlices,
 	 	 	attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	}
 	
 	public ThresholdData findBestDistanceSlicesTwoRatioAll(int attrSlices, 
 	 	float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 		
 	 	DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 		
 	 	Iterator iter = waveSets.keySet().iterator();
 	 		
 	 	int gIndex = 0;
 	 	while (iter.hasNext()) {
 	 		String filename = (String)iter.next();
 	 		drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetDistance(filename, gfSlices));
 	 	}
 	 	
 		int[] baseCounts = new int[drtg.length];
 		for (int x = 0; x < drtg.length; x++) {
 			baseCounts[x] = drtg[x].dataSet.length;
 		}
 	 		 		
 		return findBestAttrSlicesRatio(drtg, attrSlices,
 			attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	}

 	public ThresholdData findBestWallDistanceSlicesTwo(String filename, int attrSlices, 
 	 	float attrIncrement, int gfSlices, float lowBound, float highBound) {
 		return findBestAttrSlices(dataSetWallDistance(filename, gfSlices), attrSlices,
 			attrIncrement, gfSlices, lowBound, highBound);
	}

 	public ThresholdData findBestWallDistanceSlicesTwoRatio(String filename, int attrSlices, 
 	 	float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 	return findBestAttrSlicesRatio(dataSetWallDistance(filename, gfSlices), attrSlices,
 	 		attrIncrement, gfSlices, lowBound, highBound);
 	}
 	
 	public ThresholdData findBestWallDistanceSlicesTwoAll(int attrSlices, 
 	  	 float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 	 	 		
 	 	 DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 	 	 		
 	 	 Iterator iter = waveSets.keySet().iterator();
 	 	 	 		
 	 	 int gIndex = 0;
 	 	 while (iter.hasNext()) {
 	 		 String filename = (String)iter.next();
 	 	 	 drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetWallDistance(filename, gfSlices));
 	 	 }
 	 	 	 
 	  	int[] baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 		 		
 	 	return findBestAttrSlices(drtg, attrSlices,
 	 		attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	}
 	
 	public ThresholdData findBestWallDistanceSlicesTwoRatioAll(int attrSlices, 
 	 	 float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 	 		
 	 	 DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 	 		
 	 	 Iterator iter = waveSets.keySet().iterator();
 	 	 		
 	 	 int gIndex = 0;
 	 	 while (iter.hasNext()) {
 	 	 	String filename = (String)iter.next();
 	 	 	drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetWallDistance(filename, gfSlices));
 	 	 }
 	 	 
  		int[] baseCounts = new int[drtg.length];
 		for (int x = 0; x < drtg.length; x++) {
 			baseCounts[x] = drtg[x].dataSet.length;
 		}
 	 	 		 		
 	 	 return findBestAttrSlicesRatio(drtg, attrSlices,
 	 		attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	}
 	
 	public ThresholdData findBestVChangeTimeSlicesTwoAll(int attrSlices, 
 		float attrIncrement, int gfSlices, float lowBound, float highBound) {
	 		
 		DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 	 	 	 		
 	 	Iterator iter = waveSets.keySet().iterator();
 	 	 	 	 		
 	 	int gIndex = 0;
 	 	while (iter.hasNext()) {
 	 		String filename = (String)iter.next();
 	 	 	drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetVChangeTime(filename, gfSlices));
 	 	}
 	 	 	 	 
 	 	int[] baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 		 		
 	 	return findBestAttrSlices(drtg, attrSlices,
 	 		attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	}

	public ThresholdData findBestVChangeTimeSlicesTwoRatioAll(int attrSlices, 
		float attrIncrement, int gfSlices, float lowBound, float highBound) {
 		 		
 	 	DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
 	 	 	 	 	 		
 	 	Iterator iter = waveSets.keySet().iterator();
 	 	 	 	 	 		
 	 	int gIndex = 0;
 	 	while (iter.hasNext()) {
 	 		String filename = (String)iter.next();
 	 	 	drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetVChangeTime(filename, gfSlices));
 	 	}
 	 	 	 	 	 
 	 	int[] baseCounts = new int[drtg.length];
 	 	for (int x = 0; x < drtg.length; x++) {
 	 		baseCounts[x] = drtg[x].dataSet.length;
 	 	}
 	 	 	 	 	 		 		
 	 	return findBestAttrSlicesRatio(drtg, attrSlices,
 	 		attrIncrement, gfSlices, lowBound, highBound, baseCounts);
 	 }
	
	public float evaluateUnsegmentedSet(int gfSlices) {
 	 	DataRecordTwoGroup[] drtg = new DataRecordTwoGroup[waveSets.size()];
	 		
 	 	Iterator iter = waveSets.keySet().iterator();
 	 		
 	 	int gIndex = 0;
 	 	while (iter.hasNext()) {
 	 		String filename = (String)iter.next();
 	 		drtg[gIndex++] = new DataRecordTwoGroup(gIndex, dataSetDistance(filename, gfSlices));
 	 	}
 	 	
 		int[] baseCounts = new int[drtg.length];
 		for (int x = 0; x < drtg.length; x++) {
 			baseCounts[x] = drtg[x].dataSet.length;
 		}
 		
 		return calculateEntropy(drtg, baseCounts);		
	}
	
 	public float evaluateSegmentationSet(float[] LATVEL_SLICES,
 		float[] DISTANCE_SLICES, float[] WALLDISTANCE_SLICES,
 		float[] VCHANGETIME_SLICES, float[] ACCEL_SLICES, int gfSlices) {
 		
 		int numSegments = LATVEL_SLICES.length * DISTANCE_SLICES.length *
 			WALLDISTANCE_SLICES.length * VCHANGETIME_SLICES.length * 
 			ACCEL_SLICES.length;
 		
 		DataRecordTwoGroup[] dg = new DataRecordTwoGroup[numSegments * waveSets.size()];
 	 	int[] dataSetLengths = new int[numSegments * waveSets.size()];

 	 	Iterator iter = waveSets.keySet().iterator();
 	 	 	 	 	 	 		
 	 	int gIndex = 0;
	 	while (iter.hasNext()) {
	 		String filename = (String)iter.next();
 	 		ArrayList waves = waveSets.get(filename);
 	 		
 	 	 	for (int a = 0; a < LATVEL_SLICES.length; a++) {
 	 			for (int b = 0; b < DISTANCE_SLICES.length; b++) {
 	 				for (int c = 0; c < WALLDISTANCE_SLICES.length; c++) {
 	 					for (int d = 0; d < VCHANGETIME_SLICES.length; d++) {
 	 						for (int e = 0; e < ACCEL_SLICES.length; e++, gIndex++) {
 	 							if (dg[gIndex] == null) {
 	 								dg[gIndex] = new DataRecordTwoGroup(gIndex,
 	 									new DataRecordTwo[200]);
 	 							} 
 	 							 	 							
 	 							for (int x = 0; x < waves.size(); x++) {
 	 	 							if (dg[gIndex].dataSet.length <= dataSetLengths[gIndex] + 1) {
 	 	 								DataRecordTwo[] newSet = new DataRecordTwo[dg[gIndex].dataSet.length * 2];
 	 	 								for (int z = 0; z < dg[gIndex].dataSet.length; z++) {
 	 	 									newSet[z] = dg[gIndex].dataSet[z];
 	 	 								}
 	 	 								
 	 	 								dg[gIndex].dataSet = newSet;
 	 	 							}

 	 	 							Wave w = (Wave)waves.get(x);
 	 	 							double vChange = ((double)w.timeSinceVChange) / (w.distance / 11);
 	 								if (w.latVel < LATVEL_SLICES[a] && (a == 0 || w.latVel > LATVEL_SLICES[a-1]) &&
 	 									w.distance < DISTANCE_SLICES[b] && (b == 0 || w.distance > DISTANCE_SLICES[b-1]) &&
 	 									w.wallDistance < WALLDISTANCE_SLICES[c] && (c == 0 || w.wallDistance > WALLDISTANCE_SLICES[c-1]) &&
 	 									vChange < VCHANGETIME_SLICES[d] && (d == 0 || vChange > VCHANGETIME_SLICES[d-1]) &&
 	 									w.accel <  ACCEL_SLICES[e] && (e == 0 || w.accel > ACCEL_SLICES[e-1])) {
 	 									dg[gIndex].dataSet[dataSetLengths[gIndex]++] =
 	 										new DataRecordTwo((float)gIndex, gfIndex(w.guessFactor, gfSlices));
  	 								}
 	 							}
 	 						}
 	 					}
 	 				}
 	 			}
 	 		}
 	 	}
	 	
 	 	return calculateEntropy(dg, dataSetLengths);
 	}
 	
 	public ThresholdData findBestAttrSlices(DataRecordTwo[] ds,
 		int attrSlices, float attrIncrement, int gfSlices, float lowBound, float highBound) {
 			
		DataRecordTwo[] ds1 = new DataRecordTwo[ds.length];
		DataRecordTwo[] ds2 = new DataRecordTwo[ds.length];
			              
		float origEntropy = calculateEntropy(ds);
		float bestEntropy = Float.POSITIVE_INFINITY;
		
		float[] slices = new float[attrSlices];
		
		for (float t1 = lowBound + attrIncrement; t1 < highBound; 
			t1 += attrIncrement) {
			int ds1Index = 0, ds2Index = 0;
			
			for (int x = 0; x < ds.length; x++) {
				DataRecordTwo dr = ds[x];
				if (dr.attr1 < t1) {
					ds1[ds1Index++] = dr;
				} else {
					ds2[ds2Index++] = dr;
				}
			}
					
			float newEntropy = 
					((((float)ds1Index) / ds.length) * 
						calculateEntropy(trimDataSet(ds1, ds1Index)));
			
			if (attrSlices == 1) {
				newEntropy += ((((float)ds2Index) / ds.length) *
					calculateEntropy(trimDataSet(ds2, ds2Index)));

				if (newEntropy < bestEntropy) {
					bestEntropy = newEntropy;
					slices[0] = t1;
				}
			} else {
				ThresholdData td = findBestAttrSlices(
					trimDataSet(ds2, ds2Index), attrSlices - 1, attrIncrement,
					gfSlices, t1, highBound);
					
				newEntropy += ((((float)ds2Index) / ds.length) *
					td.entropy);

				if (newEntropy < bestEntropy) {
					bestEntropy = newEntropy;
					slices[0] = t1;
					for (int i = 0; i < td.slices.length; i++) {
						slices[i+1] = td.slices[i];
					}
				}
			}				
		}
		
		return new ThresholdData(slices, bestEntropy, origEntropy);
	}
 	
 	public ThresholdData findBestAttrSlicesRatio(DataRecordTwo[] ds,
		int attrSlices, float attrIncrement, int gfSlices, float lowBound, float highBound) {
 	 			
 		DataRecordTwo[] ds1 = new DataRecordTwo[ds.length];
 		DataRecordTwo[] ds2 = new DataRecordTwo[ds.length];
 
 		float origEntropy = calculateEntropy(ds);
 				
		float bestRatio = Float.NEGATIVE_INFINITY;
		float bestEntropy = Float.POSITIVE_INFINITY;
		
		float[] slices = new float[attrSlices];
		
		for (float t1 = lowBound + attrIncrement; t1 < highBound; 
			t1 += attrIncrement) {
			int ds1Index = 0, ds2Index = 0;
			
			for (int x = 0; x < ds.length; x++) {
				DataRecordTwo dr = ds[x];
				if (dr.attr1 < t1) {
					ds1[ds1Index++] = dr;
				} else {
					ds2[ds2Index++] = dr;
				}
			}
					
			float newEntropy = 
					((((float)ds1Index) / ds.length) * 
						calculateEntropy(trimDataSet(ds1, ds1Index)));
			
			if (attrSlices == 1) {
				newEntropy += ((((float)ds2Index) / ds.length) *
					calculateEntropy(trimDataSet(ds2, ds2Index)));

				float[] tempSlices = new float[1];
				tempSlices[0] = t1;
				
				float gainRatio = (origEntropy - newEntropy)
					/ calculateSplitInformation(ds, tempSlices);

				if (gainRatio > bestRatio) {
					bestRatio = gainRatio;
					slices[0] = t1;
					bestEntropy = newEntropy;
				}
			} else {
				ThresholdData td = findBestAttrSlicesRatio(
					trimDataSet(ds2, ds2Index), attrSlices - 1, attrIncrement,
					gfSlices, t1, highBound);
					
				newEntropy += ((((float)ds2Index) / ds.length) *
					td.entropy);

				float[] tempSlices = new float[attrSlices];
				tempSlices[0] = t1;
				for (int i = 0; i < td.slices.length; i++) {
					tempSlices[i+1] = td.slices[i];
				}
				
				float gainRatio = (origEntropy - newEntropy)
					/ calculateSplitInformation(ds, tempSlices);

				if (gainRatio > bestRatio) {
					bestRatio = gainRatio;
					slices = tempSlices;
					bestEntropy = newEntropy;
				}
			}			
		}
	
		return new ThresholdData(slices, bestEntropy, origEntropy, bestRatio);
			
	}

 	public ThresholdData findBestAttrSlices(DataRecordTwoGroup[] dg,
 	 	int attrSlices, float attrIncrement, int gfSlices, float lowBound, 
 	 	float highBound, int[] baseCounts) {
 	 	 	 			 	 	 		
 		float origEntropy = calculateEntropy(dg, baseCounts);
 		 				
 		float bestGain = Float.NEGATIVE_INFINITY;
		float bestEntropy = Float.POSITIVE_INFINITY;

	 	DataRecordTwoGroup[] dg1 = new DataRecordTwoGroup[dg.length];
	 	DataRecordTwoGroup[] dg2 = new DataRecordTwoGroup[dg.length];
		
	 	for (int x = 0; x < dg.length; x++) {
	 		dg1[x] = new DataRecordTwoGroup(dg[x].group, 
	 			new DataRecordTwo[dg[x].dataSet.length]);
	 		dg2[x] = new DataRecordTwoGroup(dg[x].group, 
	 	 		new DataRecordTwo[dg[x].dataSet.length]);
	 	}

		float[] slices = new float[attrSlices];

		for (float t1 = lowBound + attrIncrement; t1 < highBound; 
			t1 += attrIncrement) {

			int dg1Count = 0;
			int dg2Count = 0;

			int[] trimCounts1 = new int[dg.length];
			int[] trimCounts2 = new int[dg.length];
			
			for (int z = 0; z < dg.length; z++) {
				int ds1Index = 0, ds2Index = 0;
			
				for (int x = 0; x < baseCounts[z]; x++) {
					DataRecordTwo dr = dg[z].dataSet[x];
					if (dr.attr1 < t1) {
						dg1[z].dataSet[ds1Index++] = dr;
						dg1Count++;
					} else {
						dg2[z].dataSet[ds2Index++] = dr;
						dg2Count++;
					}
				}

				trimCounts1[z] = ds1Index;
				trimCounts2[z] = ds2Index;
			}
					
			float newEntropy = 
					((((float)dg1Count) / (dg1Count + dg2Count)) * 
						calculateEntropy(dg1, trimCounts1));
			
			if (attrSlices == 1) {
				newEntropy += ((((float)dg2Count) / (dg1Count + dg2Count)) * 
						calculateEntropy(dg2, trimCounts2));

				float[] tempSlices = new float[1];
				tempSlices[0] = t1;
				
				float infoGain = (origEntropy - newEntropy);

				if (infoGain > bestGain) {
					bestGain = infoGain;
					slices[0] = t1;
					bestEntropy = newEntropy;
				}
			} else {
				ThresholdData td = findBestAttrSlices(
					dg2, attrSlices - 1, attrIncrement,
					gfSlices, t1, highBound, trimCounts2);
					
				newEntropy += ((((float)dg2Count) / (dg1Count + dg2Count)) *
					td.entropy);

				float[] tempSlices = new float[attrSlices];
				tempSlices[0] = t1;
				for (int i = 0; i < td.slices.length; i++) {
					tempSlices[i+1] = td.slices[i];
				}
				
				float infoGain = (origEntropy - newEntropy);

				if (infoGain > bestGain) {
					bestGain = infoGain;
					slices = tempSlices;
					bestEntropy = newEntropy;
				}
			}			
		}
	
		return new ThresholdData(slices, bestEntropy, origEntropy, 0);
	}

 	public ThresholdData findBestAttrSlicesRatio(DataRecordTwoGroup[] dg,
 		int attrSlices, float attrIncrement, int gfSlices, float lowBound, 
 		float highBound, int[] baseCounts) {
 	 	 			 	 	 		
	 	float origEntropy = calculateEntropy(dg, baseCounts);
	 				
		float bestRatio = Float.NEGATIVE_INFINITY;
		float bestEntropy = Float.POSITIVE_INFINITY;

 	 	DataRecordTwoGroup[] dg1 = new DataRecordTwoGroup[dg.length];
 	 	DataRecordTwoGroup[] dg2 = new DataRecordTwoGroup[dg.length];
	
 	 	for (int x = 0; x < dg.length; x++) {
 	 		dg1[x] = new DataRecordTwoGroup(dg[x].group, 
 	 			new DataRecordTwo[dg[x].dataSet.length]);
 	 		dg2[x] = new DataRecordTwoGroup(dg[x].group, 
 	 	 		new DataRecordTwo[dg[x].dataSet.length]);
 	 	}

		float[] slices = new float[attrSlices];

		for (float t1 = lowBound + attrIncrement; t1 < highBound; 
			t1 += attrIncrement) {

			int dg1Count = 0;
			int dg2Count = 0;

			int[] trimCounts1 = new int[dg.length];
			int[] trimCounts2 = new int[dg.length];
			
			for (int z = 0; z < dg.length; z++) {
				int ds1Index = 0, ds2Index = 0;
			
				for (int x = 0; x < baseCounts[z]; x++) {
					DataRecordTwo dr = dg[z].dataSet[x];
					if (dr.attr1 < t1) {
						dg1[z].dataSet[ds1Index++] = dr;
						dg1Count++;
					} else {
						dg2[z].dataSet[ds2Index++] = dr;
						dg2Count++;
					}
				}

				trimCounts1[z] = ds1Index;
				trimCounts2[z] = ds2Index;
			}
					
			float newEntropy = 
					((((float)dg1Count) / (dg1Count + dg2Count)) * 
						calculateEntropy(dg1, trimCounts1));
			
			if (attrSlices == 1) {
				newEntropy += ((((float)dg2Count) / (dg1Count + dg2Count)) * 
						calculateEntropy(dg2, trimCounts2));

				float[] tempSlices = new float[1];
				tempSlices[0] = t1;
				
				float gainRatio = (origEntropy - newEntropy)
					/ calculateSplitInformation(dg, tempSlices, baseCounts);

				if (gainRatio > bestRatio) {
					bestRatio = gainRatio;
					slices[0] = t1;
					bestEntropy = newEntropy;
				}
			} else {
				ThresholdData td = findBestAttrSlicesRatio(
					dg2, attrSlices - 1, attrIncrement,
					gfSlices, t1, highBound, trimCounts2);
					
				newEntropy += ((((float)dg2Count) / (dg1Count + dg2Count)) *
					td.entropy);

				float[] tempSlices = new float[attrSlices];
				tempSlices[0] = t1;
				for (int i = 0; i < td.slices.length; i++) {
					tempSlices[i+1] = td.slices[i];
				}
				
				float gainRatio = (origEntropy - newEntropy)
					/ calculateSplitInformation(dg, tempSlices, baseCounts);

				if (gainRatio > bestRatio) {
					bestRatio = gainRatio;
					slices = tempSlices;
					bestEntropy = newEntropy;
				}
			}			
		}
	
		return new ThresholdData(slices, bestEntropy, origEntropy, bestRatio);
	}
 	
	public DataRecordTwo[] dataSetLatVel(String filename, int gfSlices) {
		ArrayList waves = waveSets.get(filename);	
		DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
		
		for (int x = 0; x < waves.size(); x++) {
			drt[x] = parseWaveLatVel((Wave)waves.get(x), gfSlices);
		}		
		
		return drt;
	}

	public DataRecordTwo[] dataSetDistance(String filename, int gfSlices) {
		ArrayList waves = waveSets.get(filename);
		DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
		
		for (int x = 0; x < waves.size(); x++) {
			drt[x] = parseWaveDistance((Wave)waves.get(x), gfSlices);
		}
		
		return drt;
	}
	
	public DataRecordTwo[] dataSetWallDistance(String filename, int gfSlices) {
		ArrayList waves = waveSets.get(filename);
		DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
		
		for (int x = 0; x < waves.size(); x++) {
			drt[x] = parseWaveWallDistance((Wave)waves.get(x), gfSlices);
		}		
		
		return drt;
	}
	
	public DataRecordTwo[] dataSetVChangeTime(String filename, int gfSlices) {
		ArrayList waves = waveSets.get(filename);
		DataRecordTwo[] drt = new DataRecordTwo[waves.size()];
		
		int skips = 0;
		
		for (int x = 0; x < waves.size(); x++) {
			Wave w = (Wave)waves.get(x);
			
			if (w.accel == 1) {
				drt[x - skips] = parseWaveVChangeTime(w, gfSlices);
			} else {
				skips++;
			}
		}
	
		return trimDataSet(drt, drt.length - skips);
	}
	
	public DataRecordTwo parseWaveLatVel(Wave w, int gfSlices) {
		DataRecordTwo drt = new DataRecordTwo();
			                                  
		drt.attr1 = w.latVel;
		drt.output = (int) limit(0, 
			Math.round(w.guessFactor * ((gfSlices - 1) / 2) + (gfSlices - 1)),
			gfSlices - 1);
		
		return drt;
	}
	
	public DataRecordTwo parseWaveDistance(Wave w, int gfSlices) {
		DataRecordTwo drt = new DataRecordTwo();
			                                  
		drt.attr1 = w.distance;
		drt.output = (int) limit(0, 
			Math.round(w.guessFactor * ((gfSlices - 1) / 2) + (gfSlices - 1)),
			gfSlices - 1);
		
		return drt;
	}
	
	public DataRecordTwo parseWaveWallDistance(Wave w, int gfSlices) {
		DataRecordTwo drt = new DataRecordTwo();
			                                  
		drt.attr1 = w.wallDistance;
		drt.output = (int) limit(0, 
			Math.round(w.guessFactor * ((gfSlices - 1) / 2) + (gfSlices - 1)),
			gfSlices - 1);
		
		return drt;
	}

	public DataRecordTwo parseWaveVChangeTime(Wave w, int gfSlices) {
		DataRecordTwo drt = new DataRecordTwo();
		
		if (w.accel != 1) {
			return null;
		}
			                                  
		drt.attr1 = ((float)w.timeSinceVChange) / (w.distance / 11);
		drt.output = (int) limit(0, 
			Math.round(w.guessFactor * ((gfSlices - 1) / 2) + (gfSlices - 1)),
			gfSlices - 1);
		
		return drt;
	}
	
	// CREDIT: Taken from PEZ's CassiusClay
	// http://robowiki.net?CassiusClay
    public static int index(float[] slices, float v) {
    	for (int i = 0; i < slices.length; i++) {
    	    if (v < slices[i]) {
    	    	return i;
    	    }
    	}
    	
    	return slices.length;
    }
    
    public static int gfIndex(float guessFactor, int gfSlices) {
    	return (int) limit(0, 
    			Math.round(guessFactor * ((gfSlices - 1) / 2) + (gfSlices - 1)),
    			gfSlices - 1);
    }
    
    private static float limit(float min, float value, float max) {
        return Math.max(min, Math.min(value, max));
    }

    public float calculateEntropy(DataRecordTwo[] d) {   	
    	return calculateEntropy(d, d.length);
    }
    
    public float calculateEntropy(DataRecordTwo[] d, int dataSetLength) {   	
    	int min = 0, max = 0;
    	for (int x = 0; x < dataSetLength; x++) {
    		if (x == 0) {
    			min = max = d[x].output;
    		} else {
    			if (d[x].output > max) {
    				max = d[x].output;
    			}
    			if (d[x].output < min) {
    				min = d[x].output;
    			}
    		}
    	}
    	
    	float[] counts = new float[max - min + 1];
    	
    	for (int x = 0; x < dataSetLength; x++) {
    		counts[d[x].output - min]++;
    	}
    	
    	float entropy = 0;
    	for (int x = 0; x < counts.length; x++) {
    		if (counts[x] != 0) {
    			entropy += (counts[x] / dataSetLength) * Math.log((1 / (counts[x] / dataSetLength)));
    		}
    	}

    	return entropy;
    }
    
    public float calculateEntropy(DataRecordTwoGroup[] dg, int[] dataSetLengths) {
    	float totalEntropy = 0;
    	long groupCount = 0;
    	for (int x = 0; x < dg.length; x++) {
    		if (dg[x] != null) {
    			totalEntropy += calculateEntropy(dg[x].dataSet, dataSetLengths[x]) 
    				* dataSetLengths[x];
    			groupCount += dataSetLengths[x];
    		}
    	}
    	
    	return totalEntropy / groupCount;
    }

    public float calculateSplitInformation(DataRecordTwo[] d, 
        	float[] slices) {   	
    	return calculateSplitInformation(d, slices, d.length);
    }
    
    public float calculateSplitInformation(DataRecordTwo[] d, 
    	float[] slices, int dataSetLength) {   	

    	long[] sliceCounts = new long[slices.length+1];

    	for (int x = 0; x < dataSetLength; x++) {
    		sliceCounts[index(slices, d[x].attr1)]++;
    	}
    	
    	float splitInformation = 0;
    	for (int x = 0; x < sliceCounts.length; x++) {
    		float ratio = ((float)sliceCounts[x]) / dataSetLength;
    		if (sliceCounts[x] != 0) {
    			splitInformation -= ratio * Math.log(ratio);
    		}
    	}
    	
    	return splitInformation;
    }

    public float calculateSplitInformation(DataRecordTwoGroup[] dg,
    	float[] slices, int[] baseCounts) {
    	float totalSplitInformation = 0;
    	long groupCount = 0;
    	
    	for (int x = 0; x < dg.length; x++) {
    		if (dg[x] != null) {
    			totalSplitInformation += calculateSplitInformation(dg[x].dataSet,
    				slices, baseCounts[x]) * baseCounts[x];
    			groupCount += baseCounts[x];
    		}
    	}
    	
    	return totalSplitInformation / groupCount;
    }
    
    public DataRecordTwo[] trimDataSet(DataRecordTwo[] ds, int size) {
    	DataRecordTwo[] newArray = new DataRecordTwo[size];
    	
    	for (int x = 0; x < size; x++) {
    		newArray[x] = ds[x]; 
    	}
    	
    	return newArray;
    }
    
    public DataRecordTwoGroup[] trimDataSets(DataRecordTwoGroup[] dg,
    	int[] sizes) {
    	
    	DataRecordTwoGroup[] newDg = new DataRecordTwoGroup[dg.length];
    	for (int x = 0; x < dg.length; x++) {
    		newDg[x] = new DataRecordTwoGroup(dg[x].group, 
    			trimDataSet(dg[x].dataSet, sizes[x]));
    	}
    	
    	return newDg;
    }
    
    private static double round(double d, int i) {
    	long powerTen = 1;
    	
    	for (int x = 0; x < i; x++) {
    		powerTen *= 10;
    	}
    	
    	return ((double)Math.round(d * powerTen)) / powerTen;
    }
    
    /*
    public static float log2(float d) {
    	return _ln2 * Math.log(d);
    }
    */
}

class Wave {
    byte orientation, roundNum, accel;
    int timeSinceVChange;
    float velocity, distance, latVel, wallDistance, relativeHeading;
    boolean firing = false;
    float guessFactor;
}

class DataRecordTwoGroup {
	int group;
	DataRecordTwo[] dataSet;

	public DataRecordTwoGroup() { }

	public DataRecordTwoGroup(int g, DataRecordTwo[] ds) {
		group = g;
		dataSet = ds;
	}
	
	public Object clone() {
		DataRecordTwo[] newDs = new DataRecordTwo[dataSet.length];
		for (int x = 0; x < dataSet.length; x++) {
			newDs[x] = (DataRecordTwo)dataSet[x].clone();
		}
		
		return new DataRecordTwoGroup(group, newDs);
	}
}

class DataRecordTwo {
	float attr1;
	int output;

	public DataRecordTwo() { }
	
	public DataRecordTwo(float a, int o) {
		attr1 = a;
		output = o;
	}
	
	public Object clone() {
		return new DataRecordTwo(attr1, output);
	}
	
}

class ThresholdData {
	public ThresholdData(float[] sl, float en, float oe) {
		slices = sl;
		entropy = en;
		origEntropy = oe;
	}

	public ThresholdData(float[] sl, float en, float oe, float gr) {
		slices = sl;
		entropy = en;
		origEntropy = oe;
		gainRatio = gr;
	}

	float[] slices;
	float entropy;
	float origEntropy;
	float gainRatio;
	
	public float infoGain() {
		return origEntropy - entropy;
	}
}

/*	
public float[] findBestLatVelSlices(int latSlices, int gfSlices) {
	DataRecordTwo[] ds = dataSetLatVel(gfSlices);
	
	DataRecordTwo[] ds1 = new DataRecordTwo[ds.length];
	DataRecordTwo[] ds2 = new DataRecordTwo[ds.length];
	DataRecordTwo[] ds3 = new DataRecordTwo[ds.length];
	DataRecordTwo[] ds4 = new DataRecordTwo[ds.length];
	              
	float origEntropy = calculateEntropy(ds);
	
	// hard code this for now
	float latVelIncrement = 0.5;
	
	float bestEntropy = Double.POSITIVE_INFINITY;
	
	float[] slices = new float[3];
	
	for (float t1 = latVelIncrement; t1 < 8; t1 += latVelIncrement) {
	for (float t2 = t1 + latVelIncrement; t2 < 8; t2 += latVelIncrement) {
	for (float t3 = t2 + latVelIncrement; t3 < 8; t3 += latVelIncrement) {

		int ds1Index = 0, ds2Index = 0, ds3Index = 0, ds4Index = 0;
		
		for (int x = 0; x < ds.length; x++) {
			DataRecordTwo dr = ds[x];
			if (dr.attr1 < t1) {
				ds1[ds1Index++] = dr;
			} else if (dr.attr1 < t2) {
				ds2[ds2Index++] = dr;
			} else if (dr.attr1 < t3) {
				ds3[ds3Index++] = dr;
			} else {
				ds4[ds4Index++] = dr;
			}
		}
				
		float newEntropy =
			((((float)ds1Index) / ds.length) * 
				calculateEntropy(trimDataSet(ds1, ds1Index))) +
			((((float)ds2Index) / ds.length) *
				calculateEntropy(trimDataSet(ds2, ds2Index))) +
			((((float)ds3Index) / ds.length) *
				calculateEntropy(trimDataSet(ds3, ds3Index))) +
			((((float)ds4Index) / ds.length) *
				calculateEntropy(trimDataSet(ds4, ds4Index)));
		
		if (newEntropy < bestEntropy) {
			bestEntropy = newEntropy;
			slices[0] = t1;
			slices[1] = t2;
			slices[2] = t3;
		}
	}
	}
	}
	
	float infoGain = origEntropy - bestEntropy;
	
	System.out.println("Entropy 1: " + origEntropy);
	System.out.println("Info gain: " + infoGain);
	System.out.println("Entropy 2: " + bestEntropy);
	System.out.println("Best Slices: " + slices[0] + " / " + slices[1] +
			" / " + slices[2]);
			
	return slices;
}
*/

Robo Home | Voidious | Changes | Preferences | AllPages
Edit revision 2 of this page | View other revisions | View current revision
Edited October 18, 2006 17:47 EST by Voidious (diff)
Search: