********************************************
        CS521 MonoPolarityBitSequence (MPBS)

                           Steve Talbot
                          talbste@iit.edu
                           847.436.0815

		  README

********************************************

1) System Requirements

(a) Developed on system: Mobile IntelŪ PentiumŪ 4 processor 1.8 GHz-M 
    MS Windows XP Operating System

(b) NOTE: This application has not been tested / or compiled on a 
    Unix / Linux machine.


2) Files

(a) "..\CS521_MonoPolarityBitSequence_Talbot_Steve.zip"

	This archive contains:

		 - this README file, 

		- "combinations" folder, which contains the source code, 

	Right-click this file.  Select "Extract files".  Keep the 
	default settings presented in the window that appears.
	Select the directory in which to extract the files from 
	this archive.  Click "OK".

	This files will be extracted to the location that you 
	have chosen.


(b) "..\combinations"

	".metadata"

	"combinations"

		"combinations"

			"MonoPolarityBitSequence.java"


3) Response Time

	In the MS Excel Spreadsheet "Message Id Field Combinations_Counts vs Time.xls", the response time of performing "printCounts()"
	is examined.

	The input to the method "printCounts", "fieldSize", is plotted against the time required to perform the method.  The "x" axis is labeled
	"fieldSize", and the "y" axis is labeled "Time (sec)".  "fieldSizes" are shown ranging from 1 up to 11, with values greater than 11 requiring
	an unreasonable response time to perform.  The reason for this unreasonable response time is determined below.

	The data from the spreadsheet show that the response time increases exponentially with increasing "fieldSize".  This indicates that 
	the current implementation is unreasonable for "fieldSize" > 11.

	Using the "Add Trendline" feature, a trendline was added to the data, and the resultant equation for the trendline was produced:

		y = 0.0287*e^0.9304*(x)

	with "x" = 29 (the 29-bit message id fieldSize):

		y = 0.0287*e^0.9304*(29) = 14991389560 sec

	using unit conversion: 

		(1 min/60 sec * 1 hr/60 min * 1 day/24 hrs * 1 year/365days) = 31536000 sec/year

	finally, converting to years: 

		14991389560 sec / (31536000 sec/year) = 475.37 years

	Therefore, it is seen that if the trendline is accurate, "475 years" is an unreasonable response time to determine the number of illegal
	message id combination for a "fieldSize" of 29.

	This indicates that for "fieldSize" <= 11, the program is adequate, but a new implementation is preferred for "fieldSize" > 11.
	Also, in general an analytical equation is obviously preferred over the computational solution if the computational solution for
	"fieldSize" > 11 cannot be resolved.

4) Methods

	The file "MonoPolarityBitSequence.java" is the source of the "public static void main()" method.

	This Class is currently set up to invoke the following methods:


		"printAllCounts( maxFieldLengths )"
	
			NOTE: "maxFieldLengths" > 11 requires unreasonable amount of time to generate ..

			This method prints out the "counts" of the number of combinations of bit-sequences
			that have mono-polarity bit sequences which are embedded within them
			(only unique combos are counted) ..
		
			print out the "counts" for ALL fieldLengths, from 1 up to "maxFieldLength" ..

			i.e.: "maxFieldLength = 3" ..

			count[1/1]: 2
			=============
			count[1/2]: 4
			count[2/2]: 2
			=============
			count[1/3]: 8
			count[2/3]: 6
			count[3/3]: 2


		"printCounts( int fieldLength )"

			NOTE: "maxFieldLengths" > 11 requires unreasonable amount of time to generate ..

			This method prints out the "counts" of the number of combinations of bit-sequences
			that have mono-polarity bit sequences which are embedded within them
			(only unique combos are counted) ..
		
			print out only "counts" for "fieldLength" given ..

			i.e.: "maxFieldLength = 3" ..

			count[1/3]: 8
			count[2/3]: 6
			count[3/3]: 2


		"printAllCombosTable( Vector<String> combos )"

			Print the combos as a table.

			"combos" should first be created by invoking "makeCombos_SomeBitsConstrained()"
			outside of this method, and then invoking 


		"printAllCombosAsOneRow( Vector<String> combos )"
			
			Print "combos" out as a single line.


		"printUniqueCombosTable( Vector<String> allCombos )"
		
			Print the "unique" combos as a table (non-unique combos replaced with placeholder).


		"makeCombos_SomeBitsConstrained( int fieldLength, int bitsConstrained )"

			NOTE: "maxFieldLengths" > 11 requires unreasonable amount of time to generate ..

			Generates values to fill up the "allCombos" and "uniqueCombos" collections.
			After these collections are filled, use "print" methods to print the collections
			or print the "counts" of the collections.
			
			"fieldLength" is the length of the field, in bits.

			"bitsConstrained" is the number of "constrained" bits in the field.

		
		"getCount_SomeBitsConstrained( int fieldLength, int bitsConstrained )"

			Retrieves the "count" of the number of unique combos of bit-sequences which
			have mono-polarity bit-sequences embedded within them.

			"fieldLength" is the length of the field, in bits.

			"bitsConstrained" is the number of "constrained" bits in the field.

			Invokes "makeCombos_SomeBitsConstrained()" method in order to generate 
			values to fill "uniqueCombos".


		"getUniqueCombos()"
			
			Retrieves the reference to the collection "uniqueCombos", which contains
			all of the "unique" combinations of bit-sequences which have mono-polarity 
			bit-sequences embedded within them.

			If the method "getCount_SomeBitsConstrained()" has not already been called,
			the reference will be null.


		"getAllCombos()"

			Retrieves the reference to the collection "uniqueCombos", which contains
			all of the "unique" combinations of bit-sequences which have mono-polarity 
			bit-sequences embedded within them.

			If the method "getCount_SomeBitsConstrained()" has not already been called,
			the reference will be null.


		"convertBinaryToInt( String binaryString )"

			Retrieves the integer value of the binary string.

			For instance, if binaryString = "0101", this method returns the value "5".


		"getCombo_AllBitsConstrained( int fieldLength )"


			There are always only 2 combinations for "all bits constrained" ..
			1) field is all 0's, or
			2) field is all 1's ..
		
			i.e.: fieldLength = 3, bitsConstrained = 1 => "1/3" ..
			xxx
			111: 111		000: 000			

		
		"getCount_AllBitsConstrained( int fieldLength )"


			Retrieves the "count" of the number of unique combos of bit-sequences which
			have mono-polarity bit-sequences embedded within them.

			There are always only 2 combinations for "all bits constrained".


5) As-used in "main" method:


		/**
		 * PRINT "COUNTS"
		 */
		

		// print the "counts" of unique mono-polarity bit sequences,
		// in the format: "number of constrained bits" / "field length in bits"
		 
		// i.e.: m bits constrained, 3-bit field length: "m/3" ..
		// count[1/3]: 8
		// count[2/3]: 6
		// count[3/3]: 2
		 
		// i.e.: m bits constrained, 11-bit field length: "m/11" ..
		// NOTE: setting "maxFieldLengths" > 15 causes Java outOfMemory error ..
		 
		int maxFieldLengths = 11;
		mpbs.printAllCounts( maxFieldLengths );
		
		// i.e.: m bits constrained, 29-bit field length: "m/29" ..
		// NOTE: use this method for "fieldLength" > 15 to avoid Java outOfMemory error ..
		 
		int fieldLength = 29;
		mpbs.printCounts( fieldLength );


		/**
		 * PRINT "COMBINATIONS"
		 */
		

		// print the combinations of bit sequences,  
		// which have mono-polarity bit sequences embedded within ..
		// i.e.: "1/3":
		//		 1nn: 100, 101, 110, 111	0nn: 000, 001, 010, 011
		//		 n1n: 010, 011, 110, 111	n0n: 000, 001, 100, 101
		//		 nn1: 001, 011, 101, 111	nn0: 000, 010, 100, 110
		int bitsConstrained = 1;
		int fieldLength = 3;
		
		// get the "count" for the "fieldLength" and number of "bitsConstrained" ..
		// (invokes "makeCombos_SomeBitsConstrained()") ..
		int count = mpbs.getCount_SomeBitsConstrained( fieldLength, bitsConstrained );
		System.out.println( "bitsConstrained: " + bitsConstrained + ", fieldLength: " + fieldLength + ", count: " + count );
		
		// make the combos collection first ..
		// (these print methods need to be passed in "allCombos" collection) ..
		mpbs.makeCombos_SomeBitsConstrained( fieldLength, bitsConstrained );
		
		Vector<String> allCombos = d.getAllCombos();
		
		// print the combos as a table ..
		mpbs.printAllCombosTable( allCombos );
		
		// print the combos as a single row ..
		mpbs.printAllCombosAsOneRow( allCombos );
		
		// print the "unique" combos as a table (non-unique combos replaced with placeholder) ..
		mpbs.printUniqueCombosTable( allCombos );
	

6) Output from the method "printAllCounts()", "fieldSize" = 11

		count[1/1]: 2

		=============

		count[1/2]: 4
		count[2/2]: 2

		=============

		count[1/3]: 8
		count[2/3]: 6
		count[3/3]: 2

		=============

		count[1/4]: 16
		count[2/4]: 14
		count[3/4]: 6
		count[4/4]: 2

		=============

		count[1/5]: 32
		count[2/5]: 30
		count[3/5]: 16
		count[4/5]: 6
		count[5/5]: 2

		=============

		count[1/6]: 64
		count[2/6]: 62
		count[3/6]: 38
		count[4/6]: 16
		count[5/6]: 6
		count[6/6]: 2

		=============

		count[1/7]: 128
		count[2/7]: 126
		count[3/7]: 86
		count[4/7]: 40
		count[5/7]: 16
		count[6/7]: 6
		count[7/7]: 2

		=============

		count[1/8]: 256
		count[2/8]: 254
		count[3/8]: 188
		count[4/8]: 94
		count[5/8]: 40
		count[6/8]: 16
		count[7/8]: 6
		count[8/8]: 2

		=============

		count[1/9]: 512
		count[2/9]: 510
		count[3/9]: 402
		count[4/9]: 214
		count[5/9]: 96
		count[6/9]: 40
		count[7/9]: 16
		count[8/9]: 6
		count[9/9]: 2

		=============

		count[1/10]: 1024
		count[2/10]: 1022
		count[3/10]: 846
		count[4/10]: 476
		count[5/10]: 222
		count[6/10]: 96
		count[7/10]: 40
		count[8/10]: 16
		count[9/10]: 6

		=============

		count[1/11]: 2048
		count[2/11]: 2046
		count[3/11]: 1760
		count[4/11]: 1040
		count[5/11]: 502
		count[6/11]: 224
		count[7/11]: 96
		count[8/11]: 40
		count[9/11]: 16
		count[10/11]: 6
		count[11/11]: 2

7) Running the program
	
(a) Eclipse IDE

	1) Start Eclipse
	
	The "Select a Workspace" window appears.  Select the location 
	of the directory folder "talbste".

	This "Workspace" folder should contain the ".metadata" and 
	the "IRIS" folders.

	Eclipse should show the project, titled "IRIS", in the 
	"Package Explorer" FileChooser in the left hand side view.

	(If this is not the case, try the alternative approach "2)" 
	that follows .. else skip ahead to "3)").

	
	OR


	2) Select a "Workspace" where a new project will be created.

	Create a new "Java Project" in Eclipse via selecting 
	"File->New->Project".  Select "Java Project".  Click "Next".

	Type a project name and select all default values by 
	selecting "Next" 2 times, or just select "Finish".

	Right-click the project, and select "Import" (now that 
	the project is created, we need to fill it with the files 
	of source code).

	"Browse" to the directory where the source code files are 
	located, select "General->File System", click "Next", 
	click "Browse".
	
	Navigate to the folder "..\talbste\IRIS\student\src".  
	In the window that appears, check the box next to the folder 
	"src".  This should include all the ".java" source files 
	appearing in the nested directories.  Click "No" when asked 
	to overwrite files.  Click "Finish".

	Press "Finish" and the files should appear in the 
	"Package Explorer" FileChooser view on the left-hand side 
	under the newly created project folder.
	

	3) Set up the path for the "config.properties" file.

	Select "Run->Run.."  In the window that appears, check to 
	see if there is a sub-entry beneath the entry 
	"Java Application" name "Driver".  If so, select this 
	sub-entry (delete all other sub-entries there).
	
	In the "Main" tab, specify "Main class" as 
	"edu.iit.cs.ir.run.Driver" by clicking "Browse Workspace" next 
	to the "Main class" TextBox, and navigating to 
	"..\edu\iit\cs\ir\run\Driver.java", if it is not already 
	present.
	
	In the "Arguments" tab, specify the Arguments by typing 
	the phrase "-config config.properties". In the 
	"Program arguments" TextBox.
	
	In the "Arguments" tab, specify the "Working directory" by 
	clicking "Other" and then "Browse File System" next to the 
	"Working Directory" TextBoxes.  The path should be  
	"..talbste\IRIS\student\bin".
	
	Check JRE and ClassPath tabs to confirm that proper path is 
	being used.

	Click "Apply".  Click "Close".


	4) Eclipse must be set to recognize Java 6.0 syntax.  
	
	Select "Window->Preferences->Java->Compiler".  Locate 
	"Compiler Compliance Level" drop-down ComboBox.
	
	Select "6.0".  Click "OK", "OK".
	
	
	5) Click on the folder "IRIS" in the "Package Explorer" 
	to display the contents.

	These should include:
	
		a) student\src
		b) Iris.jar
		c) IRE System Library
		d) META-INF
		e) student
		
	Click on the folder "student/src" to see its contents.  
	
	The package "edu.iit.cs.ir.run" contains the class 
	"Driver.java".  This class runs the program.
	
	Right-click "Driver.java", select "Run As -> Java Application" 
	to run the program.
	
	However, make sure to set the properties in the file 
	"..\talbste\IRIS\student\bin\config.properties" prior to 
	running the program,as desired (see "System Properties" below).