[Avida-SVN] r3342 - in branches/interrupt: . Avida.xcodeproj source/actions source/cpu source/drivers source/main source/targets/avida-viewer source/targets/unit-tests source/targets/viewer-text source/tools tests/interruptModel_quorumSensing

beckma24 at myxo.css.msu.edu beckma24 at myxo.css.msu.edu
Thu Jun 25 14:31:09 PDT 2009


Author: beckma24
Date: 2009-06-25 17:31:08 -0400 (Thu, 25 Jun 2009)
New Revision: 3342

Removed:
   branches/interrupt/tests/interruptModel_quorumSensing/expected/
Modified:
   branches/interrupt/Avida.xcodeproj/project.pbxproj
   branches/interrupt/CMakeLists.txt
   branches/interrupt/source/actions/PopulationActions.cc
   branches/interrupt/source/actions/PrintActions.cc
   branches/interrupt/source/cpu/cHardwareBase.cc
   branches/interrupt/source/cpu/cHardwareBase.h
   branches/interrupt/source/cpu/cHardwareCPU.cc
   branches/interrupt/source/cpu/cHardwareCPU.h
   branches/interrupt/source/cpu/cTestCPUInterface.h
   branches/interrupt/source/drivers/cDefaultRunDriver.cc
   branches/interrupt/source/main/cAvidaConfig.h
   branches/interrupt/source/main/cDeme.cc
   branches/interrupt/source/main/cDeme.h
   branches/interrupt/source/main/cDemeNetwork.h
   branches/interrupt/source/main/cDemeTopologyNetwork.h
   branches/interrupt/source/main/cEnvironment.cc
   branches/interrupt/source/main/cEnvironment.h
   branches/interrupt/source/main/cGenomeUtil.cc
   branches/interrupt/source/main/cMutationRates.cc
   branches/interrupt/source/main/cMutationRates.h
   branches/interrupt/source/main/cOrgInterface.h
   branches/interrupt/source/main/cOrganism.cc
   branches/interrupt/source/main/cOrganism.h
   branches/interrupt/source/main/cPhenotype.cc
   branches/interrupt/source/main/cPhenotype.h
   branches/interrupt/source/main/cPopulation.cc
   branches/interrupt/source/main/cPopulation.h
   branches/interrupt/source/main/cPopulationInterface.cc
   branches/interrupt/source/main/cPopulationInterface.h
   branches/interrupt/source/main/cStats.cc
   branches/interrupt/source/main/cStats.h
   branches/interrupt/source/main/cTaskLib.cc
   branches/interrupt/source/main/cTaskLib.h
   branches/interrupt/source/targets/avida-viewer/cTextViewerDriver.cc
   branches/interrupt/source/targets/unit-tests/main.cc
   branches/interrupt/source/targets/viewer-text/cDriver_TextViewer.cc
   branches/interrupt/source/tools/cBitArray.cc
   branches/interrupt/source/tools/cBitArray.h
Log:
merged development r3300:3325 into interrupt branch.  All tests pass.

Modified: branches/interrupt/Avida.xcodeproj/project.pbxproj
===================================================================
--- branches/interrupt/Avida.xcodeproj/project.pbxproj	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/Avida.xcodeproj/project.pbxproj	2009-06-25 21:31:08 UTC (rev 3342)
@@ -224,13 +224,15 @@
 		B516AF840C91E2D400023D53 /* cDemeCellEvent.cc in Sources */ = {isa = PBXBuildFile; fileRef = B516AF790C91E24600023D53 /* cDemeCellEvent.cc */; };
 		BB11B2DB0F1AD35B0056DDB9 /* cGenotypeBatch.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB11B2D90F1AD35B0056DDB9 /* cGenotypeBatch.cc */; };
 		BB11B2DC0F1AD35B0056DDB9 /* cGenotypeData.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB11B2DA0F1AD35B0056DDB9 /* cGenotypeData.cc */; };
-		BB11B2E30F1AD3AC0056DDB9 /* cBitArray.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB11B2E00F1AD3AC0056DDB9 /* cBitArray.cc */; };
 		BB11B2E40F1AD3AC0056DDB9 /* cRCObject.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB11B2E10F1AD3AC0056DDB9 /* cRCObject.cc */; };
 		BB11B2E50F1AD3AC0056DDB9 /* cUnitTestDemo.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB11B2E20F1AD3AC0056DDB9 /* cUnitTestDemo.cc */; };
 		BB11B3150F1AD49D0056DDB9 /* cDriverStatusConduit.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB11B3140F1AD49D0056DDB9 /* cDriverStatusConduit.cc */; };
 		BB4777E70FF4074C00A015E4 /* cResourceHistory.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB4777E60FF4074C00A015E4 /* cResourceHistory.cc */; };
 		BB4777EA0FF4076C00A015E4 /* cOrgMessage.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB4777E90FF4076C00A015E4 /* cOrgMessage.cc */; };
 		BB4777F00FF407AE00A015E4 /* cModularityAnalysis.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB4777EF0FF407AE00A015E4 /* cModularityAnalysis.cc */; };
+		BB4778980FF423C500A015E4 /* cBitArray.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB4778960FF423C500A015E4 /* cBitArray.cc */; };
+		BB4778990FF423C500A015E4 /* cBitArray.h in Headers */ = {isa = PBXBuildFile; fileRef = BB4778970FF423C500A015E4 /* cBitArray.h */; };
+		BB47789A0FF423C500A015E4 /* cBitArray.cc in Sources */ = {isa = PBXBuildFile; fileRef = BB4778960FF423C500A015E4 /* cBitArray.cc */; };
 		BB723EEE0E7B4DE9004461EB /* cOrganismThread.h in Headers */ = {isa = PBXBuildFile; fileRef = BB723EEC0E7B4DE9004461EB /* cOrganismThread.h */; };
 		BB723EEF0E7B4DE9004461EB /* cOrganismThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB723EED0E7B4DE9004461EB /* cOrganismThread.cpp */; };
 /* End PBXBuildFile section */
@@ -905,10 +907,8 @@
 		BB11B2DA0F1AD35B0056DDB9 /* cGenotypeData.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cGenotypeData.cc; sourceTree = "<group>"; };
 		BB11B2DD0F1AD3690056DDB9 /* cGenotypeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cGenotypeData.h; sourceTree = "<group>"; };
 		BB11B2DE0F1AD3690056DDB9 /* tAnalyzeJobBatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tAnalyzeJobBatch.h; sourceTree = "<group>"; };
-		BB11B2E00F1AD3AC0056DDB9 /* cBitArray.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBitArray.cc; sourceTree = "<group>"; };
 		BB11B2E10F1AD3AC0056DDB9 /* cRCObject.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cRCObject.cc; sourceTree = "<group>"; };
 		BB11B2E20F1AD3AC0056DDB9 /* cUnitTestDemo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cUnitTestDemo.cc; sourceTree = "<group>"; };
-		BB11B2E60F1AD3C90056DDB9 /* cBitArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBitArray.h; sourceTree = "<group>"; };
 		BB11B2E70F1AD3C90056DDB9 /* cRCObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cRCObject.h; sourceTree = "<group>"; };
 		BB11B2E80F1AD3C90056DDB9 /* lightweight_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lightweight_test.h; sourceTree = "<group>"; };
 		BB11B2E90F1AD3C90056DDB9 /* tArrayMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tArrayMap.h; sourceTree = "<group>"; };
@@ -924,6 +924,8 @@
 		BB4777E60FF4074C00A015E4 /* cResourceHistory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cResourceHistory.cc; sourceTree = "<group>"; };
 		BB4777E90FF4076C00A015E4 /* cOrgMessage.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cOrgMessage.cc; sourceTree = "<group>"; };
 		BB4777EF0FF407AE00A015E4 /* cModularityAnalysis.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cModularityAnalysis.cc; sourceTree = "<group>"; };
+		BB4778960FF423C500A015E4 /* cBitArray.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cBitArray.cc; sourceTree = "<group>"; };
+		BB4778970FF423C500A015E4 /* cBitArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cBitArray.h; sourceTree = "<group>"; };
 		BB723EEC0E7B4DE9004461EB /* cOrganismThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cOrganismThread.h; sourceTree = "<group>"; };
 		BB723EED0E7B4DE9004461EB /* cOrganismThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cOrganismThread.cpp; sourceTree = "<group>"; };
 		BBCDD1E50F2A147D005F5AF7 /* cModularityAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cModularityAnalysis.h; sourceTree = "<group>"; };
@@ -1620,7 +1622,8 @@
 		DCC314D8076253A2008F7A48 /* tools */ = {
 			isa = PBXGroup;
 			children = (
-				BB11B2E60F1AD3C90056DDB9 /* cBitArray.h */,
+				BB4778960FF423C500A015E4 /* cBitArray.cc */,
+				BB4778970FF423C500A015E4 /* cBitArray.h */,
 				BB11B2E70F1AD3C90056DDB9 /* cRCObject.h */,
 				BB11B2E80F1AD3C90056DDB9 /* lightweight_test.h */,
 				BB11B2E90F1AD3C90056DDB9 /* tArrayMap.h */,
@@ -1628,7 +1631,6 @@
 				BB11B2EB0F1AD3C90056DDB9 /* tDataCommandManager.h */,
 				BB11B2EC0F1AD3C90056DDB9 /* tKVPair.h */,
 				BB11B2ED0F1AD3C90056DDB9 /* tRCPtr.h */,
-				BB11B2E00F1AD3AC0056DDB9 /* cBitArray.cc */,
 				BB11B2E10F1AD3AC0056DDB9 /* cRCObject.cc */,
 				BB11B2E20F1AD3AC0056DDB9 /* cUnitTestDemo.cc */,
 				2A57A3FD0D6B954D00FC54C7 /* cProbDemeProbSchedule.cc */,
@@ -1815,6 +1817,7 @@
 				70447CA70F83DB5600E1BF72 /* cBirthMateSelectHandler.h in Headers */,
 				70447CAB0F83DBC100E1BF72 /* cBirthDemeHandler.h in Headers */,
 				B462B5C10FA0F47D00F379D1 /* cPhenPlastSummary.h in Headers */,
+				BB4778990FF423C500A015E4 /* cBitArray.h in Headers */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2169,7 +2172,6 @@
 				BB723EEF0E7B4DE9004461EB /* cOrganismThread.cpp in Sources */,
 				BB11B2DB0F1AD35B0056DDB9 /* cGenotypeBatch.cc in Sources */,
 				BB11B2DC0F1AD35B0056DDB9 /* cGenotypeData.cc in Sources */,
-				BB11B2E30F1AD3AC0056DDB9 /* cBitArray.cc in Sources */,
 				BB11B2E40F1AD3AC0056DDB9 /* cRCObject.cc in Sources */,
 				BB11B2E50F1AD3AC0056DDB9 /* cUnitTestDemo.cc in Sources */,
 				BB11B3150F1AD49D0056DDB9 /* cDriverStatusConduit.cc in Sources */,
@@ -2186,6 +2188,7 @@
 				BB4777F00FF407AE00A015E4 /* cModularityAnalysis.cc in Sources */,
 				42C27C840FDC22AC00C45B78 /* cDemeNetwork.cc in Sources */,
 				42C27C870FDC22AC00C45B78 /* cDemeTopologyNetwork.cc in Sources */,
+				BB4778980FF423C500A015E4 /* cBitArray.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2204,6 +2207,7 @@
 			buildActionMask = 2147483647;
 			files = (
 				70B6514F0BEA6FCC002472ED /* main.cc in Sources */,
+				BB47789A0FF423C500A015E4 /* cBitArray.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

Modified: branches/interrupt/CMakeLists.txt
===================================================================
--- branches/interrupt/CMakeLists.txt	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/CMakeLists.txt	2009-06-25 21:31:08 UTC (rev 3342)
@@ -587,6 +587,7 @@
   SET(UNIT_TESTS_DIR source/targets/unit-tests)
   SET(UNIT_TESTS_SOURCES
     ${UNIT_TESTS_DIR}/main.cc
+    ${TOOLS_DIR}/cBitArray.cc
   )
   ADD_EXECUTABLE(unit-tests ${UNIT_TESTS_SOURCES})
   INSTALL_TARGETS(/work unit-tests)

Modified: branches/interrupt/source/actions/PopulationActions.cc
===================================================================
--- branches/interrupt/source/actions/PopulationActions.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/actions/PopulationActions.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -912,6 +912,7 @@
 	double m_exprWeight;
 	double m_exponent;
 	int m_printUpdate;
+	cIntSum m_instCount;
 	cIntSum m_totalkilled;
 	cDoubleSum m_killProd;
 
@@ -923,6 +924,7 @@
 		if (largs.GetSize()) m_exprWeight = largs.PopWord().AsDouble();
 		if (largs.GetSize()) m_exponent = largs.PopWord().AsDouble();
 		if (largs.GetSize()) m_printUpdate = largs.PopWord().AsInt();
+		m_instCount.Clear();
 		m_totalkilled.Clear();
 		m_killProd.Clear();
 	}
@@ -932,7 +934,9 @@
 	void Process(cAvidaContext& ctx)
 	{
 		int totalkilled = 0;
+		cIntSum currentInstCount;
 		cDoubleSum currentKillProb;
+		currentInstCount.Clear();
 		currentKillProb.Clear();
 
 		// for each deme in the population...
@@ -954,9 +958,16 @@
 				
 				// count the number of target instructions in the genome
 				int count = cGenomeUtil::CountInst(cell.GetOrganism()->GetGenome(), m_world->GetHardwareManager().GetInstSet().GetInst(m_inst));
+				currentInstCount.Add(count);
 
-				double killprob = min(pow(m_exprWeight*count,m_exponent), 100.0)/100.0;
+				double killprob;
+				if(m_exponent == -1.0)
+					killprob = min(1.0/(m_exprWeight+ exp(-count)), 100.0)/100.0;  //sigmoid
+				else
+					killprob = min(pow(m_exprWeight*count,m_exponent), 100.0)/100.0;  // linear and exponential
+				
 				// cout << count << " " << killprob << endl;
+				
 				currentKillProb.Add(killprob);
 				// decide if it should be killed or not, based on the kill probability
 				if (ctx.GetRandom().P(killprob)) {
@@ -965,6 +976,7 @@
 				}
 			}
 		}
+		m_instCount.Add(currentInstCount.Average());
 		m_totalkilled.Add(totalkilled);
 		m_killProd.Add(currentKillProb.Average());
 			
@@ -973,9 +985,11 @@
 			cDataFile& df = m_world->GetDataFile("TherapyStructuralNumInst_kill.dat");
 			df.WriteComment("Number of organisms killed by structural therapy NumInst");
 			df.Write(update, "Update");
+			df.Write(m_instCount.Average(), "Mean organisms instruction count update since last print");
 			df.Write(m_totalkilled.Average(), "Mean organisms killed per update since last print");
 			df.Write(m_killProd.Average(), "Mean organism kill probablity");
 			df.Endl();
+			m_instCount.Clear();
 			m_totalkilled.Clear();
 			m_killProd.Clear();
 		}
@@ -998,6 +1012,7 @@
 	double m_exprWeight;
 	double m_exponent;
 	int m_printUpdate;
+	cIntSum m_minDist;
 	cIntSum m_totalkilled;
 	cDoubleSum m_killProd;
 	
@@ -1009,6 +1024,7 @@
 		if (largs.GetSize()) m_exprWeight = largs.PopWord().AsDouble();
 		if (largs.GetSize()) m_exponent = largs.PopWord().AsDouble();
 		if (largs.GetSize()) m_printUpdate = largs.PopWord().AsInt();
+		m_minDist.Clear();
 		m_totalkilled.Clear();
 		m_killProd.Clear();
 	}
@@ -1018,7 +1034,9 @@
 	void Process(cAvidaContext& ctx)
 	{
 		int totalkilled = 0;
+		cIntSum currentMinDist;
 		cDoubleSum currentKillProb;
+		currentMinDist.Clear();
 		currentKillProb.Clear();
 		// for each deme in the population...
 		cPopulation& pop = m_world->GetPopulation();
@@ -1042,6 +1060,7 @@
 				const cGenome& genome = cell.GetOrganism()->GetGenome();
 				const double genomeSize = static_cast<double>(genome.GetSize());
 				int minDist = cGenomeUtil::MinDistBetween(genome, m_world->GetHardwareManager().GetInstSet().GetInst(m_inst));
+				currentMinDist.Add(minDist);
 				
 				int ratioNumerator = min(genomeSize, pow(m_exprWeight*minDist, m_exponent));
 				double killprob = (genomeSize - static_cast<double>(ratioNumerator))/genomeSize;
@@ -1054,6 +1073,7 @@
 				}
 			}
 		}
+		m_minDist.Add(currentMinDist.Average());
 		m_totalkilled.Add(totalkilled);
 		m_killProd.Add(currentKillProb.Average());
 		
@@ -1062,9 +1082,11 @@
 			cDataFile& df = m_world->GetDataFile("TherapyStructuralRatioDistBetweenNearest_kill.dat");
 			df.WriteComment("Number of organisms killed by structural therapy RatioDistBetweenNearest");
 			df.Write(update, "Update");
+			df.Write(m_minDist.Average(), "Mean minimum distance between instructions organism genome per update since last print");
 			df.Write(m_totalkilled.Average(), "Mean organisms killed per update since last print");
 			df.Write(m_killProd.Average(), "Mean organism kill probablity");
 			df.Endl();
+			m_minDist.Clear();
 			m_totalkilled.Clear();
 			m_killProd.Clear();
 		}
@@ -1414,7 +1436,7 @@
 			C_MUT, C_INS, C_DEL, C_UNIFORM, C_SLIP,
 			DS_MUT, DS_INS, DS_DEL, DS_UNIFORM, DS_SLIP,
 			D1_MUT, D1_INS, D1_DEL, D1_UNIFORM, D1_SLIP,
-			PARENT,
+			PARENT, DEATH,
 			I_MUT, I_INS, I_DEL
 		} m_mut_type;
 		
@@ -1456,6 +1478,7 @@
 			else if (mutstr == "DIVIDE_SLIP") m_mut_type = D1_SLIP;
 			
 			else if (mutstr == "PARENT") m_mut_type = PARENT;
+			else if (mutstr == "DEATH") m_mut_type = DEATH;
 			else if (mutstr == "INJECT_MUT") m_mut_type = I_MUT;
 			else if (mutstr == "INJECT_INS") m_mut_type = I_INS;
 			else if (mutstr == "INJECT_DEL") m_mut_type = I_DEL;
@@ -1502,6 +1525,7 @@
 					case D1_SLIP: m_world->GetConfig().DIVIDE_SLIP_PROB.Set(m_prob); break;
 						
 					case PARENT: m_world->GetConfig().PARENT_MUT_PROB.Set(m_prob); break;
+					case DEATH: m_world->GetConfig().DEATH_PROB.Set(m_prob); break;
 					case I_MUT: m_world->GetConfig().INJECT_MUT_PROB.Set(m_prob); break;
 					case I_INS: m_world->GetConfig().INJECT_INS_PROB.Set(m_prob); break;
 					case I_DEL: m_world->GetConfig().INJECT_DEL_PROB.Set(m_prob); break;
@@ -1531,6 +1555,7 @@
 				case D1_SLIP: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDivideSlipProb(m_prob); break;
 					
 				case PARENT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetParentMutProb(m_prob); break;
+				case DEATH: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDeathProb(m_prob); break;
 				case I_MUT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInjectMutProb(m_prob); break;
 				case I_INS: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInjectInsProb(m_prob); break;
 				case I_DEL: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInjectDelProb(m_prob); break;
@@ -1548,7 +1573,7 @@
 			C_MUT, C_INS, C_DEL, C_UNIFORM, C_SLIP,
 			DS_MUT, DS_INS, DS_DEL, DS_UNIFORM, DS_SLIP,
 			D1_MUT, D1_INS, D1_DEL, D1_UNIFORM, D1_SLIP,
-			PARENT,
+			PARENT, DEATH,
 			I_MUT, I_INS, I_DEL
 		} m_mut_type;
 		
@@ -1589,6 +1614,7 @@
       else if (mutstr == "DIVIDE_SLIP") m_mut_type = D1_SLIP;
 			
       else if (mutstr == "PARENT") m_mut_type = PARENT;
+      else if (mutstr == "DEATH") m_mut_type = DEATH;
       else if (mutstr == "INJECT_MUT") m_mut_type = I_MUT;
       else if (mutstr == "INJECT_INS") m_mut_type = I_INS;
       else if (mutstr == "INJECT_DEL") m_mut_type = I_DEL;
@@ -1635,6 +1661,7 @@
 				case D1_SLIP: prob += m_world->GetConfig().DIVIDE_MUT_PROB.Get(); break;
 					
 				case PARENT: prob += m_world->GetConfig().PARENT_MUT_PROB.Get(); break;
+				case DEATH: prob += m_world->GetConfig().DEATH_PROB.Get(); break;
 				case I_MUT: prob += m_world->GetConfig().INJECT_MUT_PROB.Get(); break;
 				case I_INS: prob += m_world->GetConfig().INJECT_INS_PROB.Get(); break;
 				case I_DEL: prob += m_world->GetConfig().INJECT_DEL_PROB.Get(); break;
@@ -1665,6 +1692,7 @@
 					case D1_SLIP: m_world->GetConfig().DIVIDE_SLIP_PROB.Set(prob); break;
 						
 					case PARENT: m_world->GetConfig().PARENT_MUT_PROB.Set(prob); break;
+					case DEATH: m_world->GetConfig().DEATH_PROB.Set(prob); break;
 					case I_MUT: m_world->GetConfig().INJECT_MUT_PROB.Set(prob); break;
 					case I_INS: m_world->GetConfig().INJECT_INS_PROB.Set(prob); break;
 					case I_DEL: m_world->GetConfig().INJECT_DEL_PROB.Set(prob); break;
@@ -1694,6 +1722,7 @@
 					
 					
 				case PARENT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetParentMutProb(prob); break;
+				case DEATH: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDeathProb(prob); break;
 				case I_MUT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInjectMutProb(prob); break;
 				case I_INS: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInjectInsProb(prob); break;
 				case I_DEL: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInjectDelProb(prob); break;

Modified: branches/interrupt/source/actions/PrintActions.cc
===================================================================
--- branches/interrupt/source/actions/PrintActions.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/actions/PrintActions.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -111,6 +111,9 @@
 STATS_OUT_FILE(PrintDemeFoundersData,       deme_founders.dat   );
 STATS_OUT_FILE(PrintPerDemeTasksData,       per_deme_tasks.dat      );
 STATS_OUT_FILE(PrintPerDemeTasksExeData,    per_deme_tasks_exe.dat  );
+STATS_OUT_FILE(PrintAvgDemeTasksExeData,    avg_deme_tasks_exe.dat  );
+STATS_OUT_FILE(PrintAvgTreatableDemeTasksExeData, avg_treatable_deme_tasks_exe.dat  );
+STATS_OUT_FILE(PrintAvgUntreatableDemeTasksExeData, avg_untreatable_deme_tasks_exe.dat  );
 STATS_OUT_FILE(PrintPerDemeReactionData,    per_deme_reactions.dat  );
 STATS_OUT_FILE(PrintDemeTasksData,          deme_tasks.dat      );
 STATS_OUT_FILE(PrintDemeTasksExeData,       deme_tasks_exe.dat  );
@@ -130,6 +133,7 @@
 STATS_OUT_FILE(PrintPredicatedMessages,     messages.dat        );
 STATS_OUT_FILE(PrintCellData,               cell_data.dat       );
 STATS_OUT_FILE(PrintCurrentOpinions,        opinions.dat        );
+STATS_OUT_FILE(PrintOpinionsSetPerDeme,     opinions_set.dat    );
 STATS_OUT_FILE(PrintPerDemeGenPerFounderData,   deme_gen_between_founders.dat );
 STATS_OUT_FILE(PrintSynchronizationData,    sync.dat            );
 STATS_OUT_FILE(PrintDetailedSynchronizationData, sync-detail.dat);
@@ -147,6 +151,7 @@
 
 // group formation 
 STATS_OUT_FILE(PrintGroupsFormedData,         groupformation.dat);
+STATS_OUT_FILE(PrintGroupIds,         groupids.dat);
 
 
 #define POP_OUT_FILE(METHOD, DEFAULT)                                                     /*  1 */ \
@@ -3058,6 +3063,7 @@
 	action_lib->Register<cActionPrintPredicatedMessages>("PrintPredicatedMessages");
 	action_lib->Register<cActionPrintCellData>("PrintCellData");
 	action_lib->Register<cActionPrintCurrentOpinions>("PrintCurrentOpinions");
+	action_lib->Register<cActionPrintOpinionsSetPerDeme>("PrintOpinionsSetPerDeme");
 	action_lib->Register<cActionPrintSynchronizationData>("PrintSynchronizationData");
   action_lib->Register<cActionPrintDetailedSynchronizationData>("PrintDetailedSynchronizationData");
 	
@@ -3083,6 +3089,9 @@
   action_lib->Register<cActionSaveDemeFounders>("SaveDemeFounders");
   action_lib->Register<cActionPrintPerDemeTasksData>("PrintPerDemeTasksData");
   action_lib->Register<cActionPrintPerDemeTasksExeData>("PrintPerDemeTasksExeData");
+  action_lib->Register<cActionPrintAvgDemeTasksExeData>("PrintAvgDemeTasksExeData");
+  action_lib->Register<cActionPrintAvgTreatableDemeTasksExeData>("PrintAvgTreatableDemeTasksExeData");
+  action_lib->Register<cActionPrintAvgUntreatableDemeTasksExeData>("PrintAvgUntreatableDemeTasksExeData");
   action_lib->Register<cActionPrintPerDemeReactionData>("PrintPerDemeReactionData");
   action_lib->Register<cActionPrintDemeTasksData>("PrintDemeTasksData");
   action_lib->Register<cActionPrintDemeTasksExeData>("PrintDemeTasksExeData");
@@ -3215,6 +3224,7 @@
 
 	// Group Formation
 	action_lib->Register<cActionPrintGroupsFormedData>("PrintGroupsFormedData");
+	action_lib->Register<cActionPrintGroupIds>("PrintGroupIds");
 	
   action_lib->Register<cActionSetVerbose>("VERBOSE");
 }

Modified: branches/interrupt/source/cpu/cHardwareBase.cc
===================================================================
--- branches/interrupt/source/cpu/cHardwareBase.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/cpu/cHardwareBase.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -389,7 +389,7 @@
       }
     }
   }
-  
+    
   return totalMutations;
 }
 
@@ -989,10 +989,10 @@
   return true;
 }
 
-bool cHardwareBase::Inst_HalfEnergyUsage(cAvidaContext& ctx)
+bool cHardwareBase::Inst_HalveEnergyUsage(cAvidaContext& ctx)
 {
   cPhenotype& phenotype = m_organism->GetPhenotype();
-  phenotype.HalfEnergyUsage();
+  phenotype.HalveEnergyUsage();
   double newOrgMerit = phenotype.ConvertEnergyToMerit(phenotype.GetStoredEnergy()  * phenotype.GetEnergyUsageRatio());
   m_organism->UpdateMerit(newOrgMerit);
   return true;

Modified: branches/interrupt/source/cpu/cHardwareBase.h
===================================================================
--- branches/interrupt/source/cpu/cHardwareBase.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/cpu/cHardwareBase.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -212,7 +212,7 @@
   
   // --------  Execution Speed Instruction  --------
   bool Inst_DoubleEnergyUsage(cAvidaContext& ctx);
-  bool Inst_HalfEnergyUsage(cAvidaContext& ctx);
+  bool Inst_HalveEnergyUsage(cAvidaContext& ctx);
   bool Inst_DefaultEnergyUsage(cAvidaContext& ctx);
 	
 

Modified: branches/interrupt/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/interrupt/source/cpu/cHardwareCPU.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/cpu/cHardwareCPU.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -679,7 +679,7 @@
 		
     // Energy usage
     tInstLibEntry<tMethod>("double-energy-usage", &cHardwareCPU::Inst_DoubleEnergyUsage, nInstFlag::STALL),
-    tInstLibEntry<tMethod>("half-energy-usage", &cHardwareCPU::Inst_HalfEnergyUsage, nInstFlag::STALL),
+    tInstLibEntry<tMethod>("halve-energy-usage", &cHardwareCPU::Inst_HalveEnergyUsage, nInstFlag::STALL),
     tInstLibEntry<tMethod>("default-energy-usage", &cHardwareCPU::Inst_DefaultEnergyUsage, nInstFlag::STALL),
 		
     // Messaging
@@ -789,6 +789,9 @@
     // These are STALLs because opinions are only relevant with respect to time.
     tInstLibEntry<tMethod>("set-opinion", &cHardwareCPU::Inst_SetOpinion, nInstFlag::STALL),
     tInstLibEntry<tMethod>("get-opinion", &cHardwareCPU::Inst_GetOpinion, nInstFlag::STALL),
+		tInstLibEntry<tMethod>("get-opinionOnly", &cHardwareCPU::Inst_GetOpinionOnly_ZeroIfNone, nInstFlag::STALL),
+		tInstLibEntry<tMethod>("clear-opinion", &cHardwareCPU::Inst_ClearOpinion, nInstFlag::STALL),
+		tInstLibEntry<tMethod>("if-opinion-set", &cHardwareCPU::Inst_IfOpinionSet, nInstFlag::STALL),
 		
 		// Data collection
 		tInstLibEntry<tMethod>("if-cell-data-changed", &cHardwareCPU::Inst_IfCellDataChanged, nInstFlag::STALL),
@@ -836,6 +839,11 @@
 		tInstLibEntry<tMethod>("orgs-in-my-group", &cHardwareCPU::Inst_NumberOrgsInMyGroup, nInstFlag::STALL),
 		tInstLibEntry<tMethod>("orgs-in-group", &cHardwareCPU::Inst_NumberOrgsInGroup, nInstFlag::STALL),
 		
+		// Network creation instructions
+		tInstLibEntry<tMethod>("create-link-facing", &cHardwareCPU::Inst_CreateLinkByFacing, nInstFlag::STALL),
+		tInstLibEntry<tMethod>("create-link-xy", &cHardwareCPU::Inst_CreateLinkByXY, nInstFlag::STALL),
+		tInstLibEntry<tMethod>("create-link-index", &cHardwareCPU::Inst_CreateLinkByIndex, nInstFlag::STALL),
+		
     // Must always be the last instruction in the array
     tInstLibEntry<tMethod>("NULL", &cHardwareCPU::Inst_Nop, 0, "True no-operation instruction: does nothing"),
   };
@@ -4874,7 +4882,7 @@
 		}
 		
 		// stop searching through the neighbors if we already found one
-		if (found == true);{
+		if (found == true) {
     	break;
 		}
 		
@@ -8994,7 +9002,36 @@
   return true;
 }
 
+bool cHardwareCPU::Inst_GetOpinionOnly_ZeroIfNone(cAvidaContext& ctx)
+{
+	assert(m_organism != 0);
+	const int opinion_reg = FindModifiedRegister(REG_BX);
+  if(m_organism->HasOpinion()) {
+    GetRegister(opinion_reg) = m_organism->GetOpinion().first;
+  } else {
+		GetRegister(opinion_reg) = 0;
+	}
+  return true;
+}
 
+
+bool cHardwareCPU::Inst_ClearOpinion(cAvidaContext& ctx) {
+	assert(m_organism != 0);
+	m_organism->ClearOpinion();
+	return true;
+}
+
+/*! If the organism has an opinion then execute the next instruction, else skip.
+ */
+bool cHardwareCPU::Inst_IfOpinionSet(cAvidaContext& ctx)
+{
+	assert(m_organism != 0);
+  if(!m_organism->HasOpinion()) IP().Advance();
+  return true;
+}
+
+
+
 /*! Collect this cell's data, and place it in ?BX?.  Set the flag indicating that
  this organism has collected cell data to true, and set the last collected cell data
  as well.
@@ -9684,13 +9721,22 @@
 	int opinion;
 	// Check if the org is currently part of a group
 	assert(m_organism != 0);
+	
+	// check if this is a valid group
+	if (m_world->GetConfig().USE_FORM_GROUPS.Get() == 2) { 
+		int prop_group_id =   GetRegister(FindModifiedRegister(REG_BX));
+		if (!(m_world->GetEnvironment().IsGroupID(prop_group_id))){
+			return true;
+		}
+	}
+
+	
   if(m_organism->HasOpinion()) {
 		opinion = m_organism->GetOpinion().first;
 		// subtract org from group
 		m_world->GetPopulation().LeaveGroup(opinion);
   }
 	
-	
 	// Call the set opinion instruction, which does all the dirty work.
 	Inst_SetOpinion(ctx);
 	
@@ -9717,7 +9763,6 @@
 	return true;
 }
 
-
 //! Gets the number of organisms in the group of a given id
 //! specified by the ?BX? register and places the value in the ?CX? register
 bool cHardwareCPU::Inst_NumberOrgsInGroup(cAvidaContext& ctx)
@@ -9732,3 +9777,35 @@
 	GetRegister(num_org_reg) = num_orgs;
 	return true;
 }
+
+
+
+
+/*! Create a link to the currently-faced cell.
+ */
+bool cHardwareCPU::Inst_CreateLinkByFacing(cAvidaContext& ctx) {
+	const int wreg = FindModifiedRegister(REG_BX);
+	m_organism->GetOrgInterface().CreateLinkByFacing(GetRegister(wreg));
+	return true;
+}
+
+/*! Create a link to the cell specified by xy-coordinates.
+ */
+bool cHardwareCPU::Inst_CreateLinkByXY(cAvidaContext& ctx) {
+  const int xreg = FindModifiedRegister(REG_BX);
+  const int yreg = FindNextRegister(xreg);
+	const int wreg = FindNextRegister(yreg);
+	m_organism->GetOrgInterface().CreateLinkByXY(GetRegister(xreg), GetRegister(yreg), GetRegister(wreg));
+  return true;
+}
+
+/*! Create a link to the cell specified by index.
+ */
+bool cHardwareCPU::Inst_CreateLinkByIndex(cAvidaContext& ctx) {
+  const int idxreg = FindModifiedRegister(REG_BX);
+	const int wreg = FindNextRegister(idxreg);
+	m_organism->GetOrgInterface().CreateLinkByIndex(GetRegister(idxreg), GetRegister(wreg));
+  return true;
+}
+
+

Modified: branches/interrupt/source/cpu/cHardwareCPU.h
===================================================================
--- branches/interrupt/source/cpu/cHardwareCPU.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/cpu/cHardwareCPU.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -29,6 +29,7 @@
 #include <iomanip>
 #include <vector>
 
+
 #ifndef cCodeLabel_h
 #include "cCodeLabel.h"
 #endif
@@ -211,6 +212,7 @@
   int m_epigenetic_saved_reg[NUM_REGISTERS];
   cCPUStack m_epigenetic_saved_stack;
   // Epigenetic State -->
+	
 
   bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
   
@@ -901,6 +903,12 @@
   bool Inst_SetOpinion(cAvidaContext& ctx);
   //! Retrieve this organism's current opinion.
   bool Inst_GetOpinion(cAvidaContext& ctx);
+	//! Only get opinion.  If none then reg is set to zero
+	bool Inst_GetOpinionOnly_ZeroIfNone(cAvidaContext& ctx);
+	//! Clear this organism's current opinion.
+  bool Inst_ClearOpinion(cAvidaContext& ctx);
+	//! Execute next instruction is org has an opinion, otherwise skip
+	bool Inst_IfOpinionSet(cAvidaContext& ctx);
 
 	// -------- Cell Data Support --------
 public:
@@ -949,7 +957,7 @@
 	bool Inst_IfNeighborhoodChanged(cAvidaContext& ctx);
 
 	
-// -------- Group Formation Support --------
+	// -------- Group Formation Support --------
 public:
 	//! An organism joins a group by setting it opinion to the group id. 
 	bool Inst_JoinGroup(cAvidaContext& ctx);
@@ -957,8 +965,15 @@
 	bool Inst_NumberOrgsInMyGroup(cAvidaContext& ctx);
 	//! Returns the number of organisms in the current organism's group
 	bool Inst_NumberOrgsInGroup(cAvidaContext& ctx);		
-	
-	
+
+	// -------- Network creation support --------
+public:
+	//! Create a link to the currently-faced cell.
+	bool Inst_CreateLinkByFacing(cAvidaContext& ctx);
+	//! Create a link to the cell specified by xy-coordinates.
+	bool Inst_CreateLinkByXY(cAvidaContext& ctx);
+	//! Create a link to the cell specified by index.
+	bool Inst_CreateLinkByIndex(cAvidaContext& ctx);
 };
 
 
@@ -1057,3 +1072,5 @@
 }
 
 #endif
+
+

Modified: branches/interrupt/source/cpu/cTestCPUInterface.h
===================================================================
--- branches/interrupt/source/cpu/cTestCPUInterface.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/cpu/cTestCPUInterface.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -105,6 +105,13 @@
 	void RotateToGreatestReputationWithDifferentLineage(int tag){ }	
   
   int GetStateGridID(cAvidaContext& ctx);
+	
+	//! Link this organism's cell to the cell it is currently facing.
+	void CreateLinkByFacing(double weight=1.0) { }
+	//! Link this organism's cell to the cell with coordinates (x,y).
+	void CreateLinkByXY(int x, int y, double weight=1.0) { }
+	//! Link this organism's cell to the cell with index idx.
+	void CreateLinkByIndex(int idx, double weight=1.0) { }
 };
 
 

Modified: branches/interrupt/source/drivers/cDefaultRunDriver.cc
===================================================================
--- branches/interrupt/source/drivers/cDefaultRunDriver.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/drivers/cDefaultRunDriver.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -121,13 +121,8 @@
     }
     
     // end of update stats...
-    population.CalcUpdateStats();
-    
-    // Process the update for each deme.
-    for(int i=0; i<population.GetNumDemes(); ++i) {
-      population.GetDeme(i).ProcessUpdate();
-    }
-    
+    population.ProcessPostUpdate(ctx);
+        
     // No viewer; print out status for this update....
     if (m_world->GetVerbosity() > VERBOSE_SILENT) {
       cout.setf(ios::left);

Modified: branches/interrupt/source/main/cAvidaConfig.h
===================================================================
--- branches/interrupt/source/main/cAvidaConfig.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cAvidaConfig.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -404,6 +404,8 @@
   CONFIG_ADD_VAR(DIVIDE_POISSON_SLIP_MEAN, double, 0.0, "Slip rate (Poisson distributed, per divide)");
 
   CONFIG_ADD_VAR(DIVIDE_UNIFORM_PROB, double, 0.0, "Uniform mutation probability (per divide)\n- Randomly applies any of the three classes of mutations (ins, del, point).");
+
+  CONFIG_ADD_VAR(DEATH_PROB, double, 0.0, "Death rate (parent organism, per divide)");
   
   CONFIG_ADD_VAR(INJECT_INS_PROB, double, 0.0, "Insertion rate (per site, applied on inject)");
   CONFIG_ADD_VAR(INJECT_DEL_PROB, double, 0.0, "Deletion rate (per site, applied on inject)");
@@ -645,7 +647,7 @@
   CONFIG_ADD_VAR(MATCH_ALREADY_PRODUCED, int, 0, "0=off\n1=on");
 	
 	CONFIG_ADD_GROUP(GROUP_FORMATION_GROUP, "Group Formation Settings");
-  CONFIG_ADD_VAR(USE_FORM_GROUPS, bool, 0, "Enable organisms to form groups. 0/1 (off/on)");
+  CONFIG_ADD_VAR(USE_FORM_GROUPS, int, 0, "Enable organisms to form groups. 0=off,\n 1=on no restrict,\n 2=on restrict to defined");
 	
 	// -------- Deme network config options --------
 	CONFIG_ADD_VAR(DEME_NETWORK_TYPE, int, 0, "0=topology, structure of network determines fitness.");

Modified: branches/interrupt/source/main/cDeme.cc
===================================================================
--- branches/interrupt/source/main/cDeme.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cDeme.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -131,12 +131,28 @@
   return m_world->GetPopulation().GetCell(cell_ids[pos]);
 }
 
+cPopulationCell& cDeme::GetCell(int x, int y) const
+{
+	return m_world->GetPopulation().GetCell(GetCellID(x,y));
+}
 
+
 cOrganism* cDeme::GetOrganism(int pos) const
 {
   return GetCell(pos).GetOrganism();
 }
 
+int cDeme::GetNumOrgsWithOpinion() const {
+	int demeSize = GetSize();
+	int count = 0;
+	
+	for(int pos = 0; pos < demeSize; ++pos) {
+		cPopulationCell& cell = GetCell(pos);
+		if(cell.IsOccupied() and cell.GetOrganism()->HasOpinion())
+			++count;
+	}
+	return count;
+}
 
 void cDeme::ProcessUpdate() {
 	// test deme predicate
@@ -250,6 +266,9 @@
     }
   }
   ++_age;
+	
+	// Let the network process the update too, if we have one.
+	if(IsNetworkInitialized()) { m_network->ProcessUpdate(); }
 }
 
 

Modified: branches/interrupt/source/main/cDeme.h
===================================================================
--- branches/interrupt/source/main/cDeme.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cDeme.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -160,6 +160,7 @@
   //! Returns an (x,y) pair for the position of the passed-in cell ID.
   std::pair<int, int> GetCellPosition(int cellid) const;
   cPopulationCell& GetCell(int pos) const;
+	cPopulationCell& GetCell(int x, int y) const;
   cOrganism* GetOrganism(int pos) const;
 
   int GetWidth() const { return width; }
@@ -179,8 +180,10 @@
 
   int GetOrgCount() const { return cur_org_count; }
   int GetLastOrgCount() const { return last_org_count; }
+
 	double GetDensity() const { return static_cast<double>(cur_org_count) / static_cast<double>(GetSize()); }
-
+	int GetNumOrgsWithOpinion() const;
+	
   void IncOrgCount() { cur_org_count++; }
   void DecOrgCount() { cur_org_count--; }
 

Modified: branches/interrupt/source/main/cDemeNetwork.h
===================================================================
--- branches/interrupt/source/main/cDemeNetwork.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cDemeNetwork.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -54,7 +54,7 @@
 	 neighboring cells.  The network's performance is based on its structure (evaluated as a graph).
 	 */
 	enum NetworkType { TOPOLOGY };
-
+	
 	//! Factory method, the only way to create a deme network (pointer is owned by the caller).
 	static cDemeNetwork* DemeNetworkFactory(cWorld* world, cDeme& deme);
 	
@@ -65,7 +65,7 @@
 	virtual void ProcessUpdate() = 0;
 
 	//! Connect u->v with weight w.
-	virtual void Connect(cPopulationCell& u, cPopulationCell& v, double w=0.0) = 0;
+	virtual void Connect(cPopulationCell& u, cPopulationCell& v, double w=1.0) = 0;
 	
 	//! Called when the organism living in cell u dies.
 	virtual void OrganismDeath(cPopulationCell& u) = 0;

Modified: branches/interrupt/source/main/cDemeTopologyNetwork.h
===================================================================
--- branches/interrupt/source/main/cDemeTopologyNetwork.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cDemeTopologyNetwork.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -78,7 +78,7 @@
 	virtual void ProcessUpdate() { }
 	
 	//! Connect u->v with weight w.
-	virtual void Connect(cPopulationCell& u, cPopulationCell& v, double w=0.0);
+	virtual void Connect(cPopulationCell& u, cPopulationCell& v, double w=1.0);
 	
 	//! Called when the organism living in cell u dies.
 	virtual void OrganismDeath(cPopulationCell& u) { }

Modified: branches/interrupt/source/main/cEnvironment.cc
===================================================================
--- branches/interrupt/source/main/cEnvironment.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cEnvironment.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -1270,7 +1270,7 @@
     result.MarkReaction(reaction_id);
     
     double bonus = consumed * cur_process->GetValue();
-    
+
     if (!cur_process->GetIsGermline())
     {
       // normal bonus
@@ -1524,3 +1524,15 @@
   return true;
 }
 
+/* 
+ helper function that checks if this is a valid group id. The ids are specified 
+ in the environment file as tasks.
+ */
+bool cEnvironment::IsGroupID(int test_id) 
+{
+	bool val = false;
+	if (possible_group_ids.find(test_id) != possible_group_ids.end())
+		val = true;
+	return val;
+	
+}

Modified: branches/interrupt/source/main/cEnvironment.h
===================================================================
--- branches/interrupt/source/main/cEnvironment.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cEnvironment.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -61,7 +61,10 @@
 # endif
 #endif
 
+#include <set>
 
+
+
 class cAvidaContext;
 class cReaction;
 class cReactionRequisite;
@@ -187,6 +190,14 @@
   bool SetReactionTask(const cString& name, const cString& task);
   bool SetResourceInflow(const cString& name, double _inflow );
   bool SetResourceOutflow(const cString& name, double _outflow );
+	
+//--------------- used for spatial group formation
+public: 
+	void AddGroupID(int new_id) { possible_group_ids.insert(new_id); }
+	bool IsGroupID(int test_id);
+	
+protected:
+	std::set<int> possible_group_ids;
   
 };
 

Modified: branches/interrupt/source/main/cGenomeUtil.cc
===================================================================
--- branches/interrupt/source/main/cGenomeUtil.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cGenomeUtil.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -51,47 +51,51 @@
 int cGenomeUtil::CountInst(const cGenome & gen, const cInstruction & inst)
 {
   int count = 0;
-  for(int i = 0; i < gen.GetSize(); i++) {
-    if (gen[i] == inst) count++;
+  for(int i = 0; i < gen.GetSize(); ++i) {
+    if (gen[i] == inst) ++count;
   }
 	
   return count;
 }
 
 // Returns minimum distance between two instance of inst respecting genome circularity.
-// If only one instance is found then lenght of genome is returned.
+// If zero or one instance is found then 0 is returned.
 int cGenomeUtil::MinDistBetween(const cGenome& genome, const cInstruction& inst) {
 	const int genomeSize = genome.GetSize();
 	int firstInstance(-1);
 	int secondInstance(-1);
 	int startIndex(0);
 	int minDist(genomeSize);
-
+	assert(startIndex < genomeSize);
+	
 	while(startIndex < genomeSize) {
 		firstInstance = FindInst(genome, inst, startIndex);
-		startIndex = firstInstance + 1;
-		
-		if(startIndex >= genomeSize)
+		if(firstInstance == -1 && startIndex == 0) {
+			// no instance of inst
+			return 0;
+		} else if(firstInstance == -1) {
+			// no more instances
 			return minDist;
+		}
 		
+		startIndex = firstInstance + 1;
 		secondInstance = FindInst(genome, inst, startIndex);
+		
+		if(secondInstance == -1) {
+			// no instance between startIndex and end
+			// search from begining
+			secondInstance = FindInst(genome, inst, 0);
+			// worst-case this finds same instance of inst as firstInstance
+		}			
 	
-		if(firstInstance != -1 and secondInstance != -1) {
-			minDist = min(min(secondInstance-firstInstance, firstInstance+genomeSize-secondInstance), minDist);
-		} else if(secondInstance != -1) {
-			secondInstance = FindInst(genome, inst, 0);
-			if(firstInstance == secondInstance)
-				return minDist;
-			else {
-				assert(secondInstance < firstInstance);
-				minDist = min(secondInstance+genomeSize-firstInstance, minDist);
-			}
-		} else {
-			return minDist;
-		}
-	}
-	assert(false);
-	return -1;
+		if(firstInstance != secondInstance) {
+			minDist = min(min(abs(firstInstance-secondInstance), secondInstance+genomeSize-firstInstance), minDist);
+			assert(minDist > 0);
+		} else { // they are equal, so there is only one instance of inst
+			return 0;
+		} 
+	}	
+	return minDist;
 }
 
 

Modified: branches/interrupt/source/main/cMutationRates.cc
===================================================================
--- branches/interrupt/source/main/cMutationRates.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cMutationRates.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -56,6 +56,7 @@
   divide.divide_slip_prob = world->GetConfig().DIVIDE_SLIP_PROB.Get();
   
   divide.parent_mut_prob = world->GetConfig().PARENT_MUT_PROB.Get();  
+  divide.death_prob = world->GetConfig().DEATH_PROB.Get();  
   
   inject.ins_prob = world->GetConfig().INJECT_INS_PROB.Get();
   inject.del_prob = world->GetConfig().INJECT_DEL_PROB.Get();
@@ -92,6 +93,8 @@
   divide.divide_slip_prob = 0.0;
   
   divide.parent_mut_prob = 0.0;
+
+  divide.death_prob = 0.0;
   
   inject.ins_prob = 0.0;
   inject.del_prob = 0.0;
@@ -128,6 +131,7 @@
   divide.divide_slip_prob = in_muts.divide.divide_slip_prob;
   
   divide.parent_mut_prob = in_muts.divide.parent_mut_prob;
+  divide.death_prob = in_muts.divide.death_prob;
   
   inject.ins_prob = in_muts.inject.ins_prob;
   inject.del_prob = in_muts.inject.del_prob;

Modified: branches/interrupt/source/main/cMutationRates.h
===================================================================
--- branches/interrupt/source/main/cMutationRates.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cMutationRates.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -67,6 +67,7 @@
     double divide_slip_prob;     // Max one per divide
     double divide_uniform_prob;
     double parent_mut_prob;
+    double death_prob;
   };
   sDivideMuts divide;
   
@@ -126,7 +127,8 @@
   }
 
   
-  bool TestParentMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.parent_mut_prob); }
+  bool TestParentMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.parent_mut_prob); }  
+  bool TestDeath(cAvidaContext& ctx) const { return (divide.death_prob == 0.0) ? false : ctx.GetRandom().P(divide.death_prob); }
   
   double DoMetaCopyMut(cAvidaContext& ctx) {
     if (meta.copy_mut_prob == 0.0 || !ctx.GetRandom().P(meta.copy_mut_prob)) return 1.0;
@@ -156,6 +158,7 @@
   double GetDivideSlipProb() const    { return divide.divide_slip_prob; }
   
   double GetParentMutProb() const     { return divide.parent_mut_prob; }
+  double GetDeathProb() const   { return divide.death_prob; }
   
   double GetInjectInsProb() const     { return inject.ins_prob; }
   double GetInjectDelProb() const     { return inject.del_prob; }
@@ -184,6 +187,7 @@
   void SetDivideSlipProb(double in_prob)    { divide.divide_del_prob = in_prob; }
   
   void SetParentMutProb(double in_prob)     { divide.parent_mut_prob = in_prob; }
+  void SetDeathProb(double in_prob)   { divide.death_prob      = in_prob; }
   
   void SetInjectInsProb(double in_prob)     { inject.ins_prob        = in_prob; }
   void SetInjectDelProb(double in_prob)     { inject.del_prob        = in_prob; }

Modified: branches/interrupt/source/main/cOrgInterface.h
===================================================================
--- branches/interrupt/source/main/cOrgInterface.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cOrgInterface.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -113,7 +113,10 @@
 	virtual void RotateToGreatestReputation() =0;
 	virtual void RotateToGreatestReputationWithDifferentTag(int tag) =0;
 	virtual void RotateToGreatestReputationWithDifferentLineage(int line) =0;	
-	
+
+	virtual void CreateLinkByFacing(double weight=1.0) = 0;
+	virtual void CreateLinkByXY(int x, int y, double weight=1.0) = 0;
+	virtual void CreateLinkByIndex(int idx, double weight=1.0) = 0;
 };
 
 #endif

Modified: branches/interrupt/source/main/cOrganism.cc
===================================================================
--- branches/interrupt/source/main/cOrganism.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cOrganism.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -430,9 +430,10 @@
     m_phenotype.RefreshEnergy();
     m_phenotype.ApplyToEnergyStore();
     double newMerit = m_phenotype.ConvertEnergyToMerit(m_phenotype.GetStoredEnergy() * m_phenotype.GetEnergyUsageRatio());
-    if(newMerit != -1) {
-      m_interface->UpdateMerit(newMerit);
-    }
+		m_interface->UpdateMerit(newMerit);
+		if(GetPhenotype().GetMerit().GetDouble() == 0.0) {
+			GetPhenotype().SetToDie();
+		}
   }
   m_interface->UpdateResources(global_res_change);
 

Modified: branches/interrupt/source/main/cOrganism.h
===================================================================
--- branches/interrupt/source/main/cOrganism.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cOrganism.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -347,6 +347,7 @@
   bool TestDivideSlip(cAvidaContext& ctx) const { return m_mut_rates.TestDivideSlip(ctx); } 
   
   bool TestParentMut(cAvidaContext& ctx) const { return m_mut_rates.TestParentMut(ctx); }
+  bool TestDeath(cAvidaContext& ctx) const { return m_mut_rates.TestDeath(ctx); }
   
   double GetCopyMutProb() const { return m_mut_rates.GetCopyMutProb(); }
   double GetCopyInsProb() const { return m_mut_rates.GetCopyInsProb(); }
@@ -364,6 +365,7 @@
   double GetDivSlipProb() const { return m_mut_rates.GetDivSlipProb(); }
 
   double GetParentMutProb() const { return m_mut_rates.GetParentMutProb();}
+  double GetDeathProb() const { return m_mut_rates.GetDeathProb();}
 
   double GetInjectInsProb() const { return m_mut_rates.GetInjectInsProb(); }
   double GetInjectDelProb() const { return m_mut_rates.GetInjectDelProb(); }
@@ -490,6 +492,8 @@
   const DatedOpinionList& GetOpinions() { InitOpinions(); return m_opinion->opinion_list; }
   //! Return whether this organism has an opinion.
   bool HasOpinion() { InitOpinions(); return m_opinion->opinion_list.size(); }
+	//! remove all opinions
+	void ClearOpinion() { InitOpinions(); m_opinion->opinion_list.clear(); }
   
 private:
   //! Initialize opinion support.

Modified: branches/interrupt/source/main/cPhenotype.cc
===================================================================
--- branches/interrupt/source/main/cPhenotype.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cPhenotype.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -1409,7 +1409,7 @@
   executionRatio *= 2.0;
 }
 
-void cPhenotype::HalfEnergyUsage() {
+void cPhenotype::HalveEnergyUsage() {
   executionRatio *= 0.5;
 }
 
@@ -1499,15 +1499,18 @@
   ReduceEnergy(GetStoredEnergy() * frac_energy_decay_at_birth);
   
   // calculate energy to be given to child
-  double child_energy = min(GetStoredEnergy() * frac_parent_energy_given_at_birth + energy_given_at_birth, energy_cap);
-  
+  double child_energy = max(0.0, min(GetStoredEnergy() * frac_parent_energy_given_at_birth + energy_given_at_birth, energy_cap));
+  assert(GetStoredEnergy()>0.0);
   // adjust energy in parent
   ReduceEnergy(child_energy - 2*energy_given_at_birth); // 2*energy_given_at_birth: 1 in child_energy & 1 for parent
     
   //TODO: add energy_given_at_birth to Stored_energy
   cMerit parentMerit(ConvertEnergyToMerit(GetStoredEnergy() * GetEnergyUsageRatio()));
-  SetMerit(parentMerit);
-  
+	if(parentMerit.GetDouble() > 0.0)
+		SetMerit(parentMerit);
+  else
+		SetToDie();
+	
   return child_energy;
 }
 

Modified: branches/interrupt/source/main/cPhenotype.h
===================================================================
--- branches/interrupt/source/main/cPhenotype.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cPhenotype.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -367,7 +367,7 @@
   const tArray<int>& GetCurSenseCount() const { assert(initialized == true); return cur_sense_count; }
   double GetSensedResource(int _in) { assert(initialized == true); return sensed_resources[_in]; }
   const tArray<int>& GetCurCollectSpecCounts() const { assert(initialized == true); return cur_collect_spec_counts; }
-  const int GetCurCollectSpecCount(int spec_id) const { assert(initialized == true); return cur_collect_spec_counts[spec_id]; }
+  int GetCurCollectSpecCount(int spec_id) const { assert(initialized == true); return cur_collect_spec_counts[spec_id]; }
 	const tArray<int>& GetTestCPUInstCount() const { assert(initialized == true); return testCPU_inst_count; }
 
   void  NewTrial(); //Save the current fitness, and reset the bonus. @JEB
@@ -396,7 +396,7 @@
   double GetLastFitness() const { assert(initialized == true); return last_fitness; }
   double GetPermanentGermlinePropensity() const { assert(initialized == true); return permanent_germline_propensity; }
   const tArray<int>& GetLastCollectSpecCounts() const { assert(initialized == true); return last_collect_spec_counts; }
-  const int GetLastCollectSpecCount(int spec_id) const { assert(initialized == true); return last_collect_spec_counts[spec_id]; }
+  int GetLastCollectSpecCount(int spec_id) const { assert(initialized == true); return last_collect_spec_counts[spec_id]; }
 
   int GetNumDivides() const { assert(initialized == true); return num_divides;}
   int GetGeneration() const { assert(initialized == true); return generation; }
@@ -576,7 +576,7 @@
   bool& IsMultiThread() { assert(initialized == true); return is_multi_thread; }
   
   void DoubleEnergyUsage();
-  void HalfEnergyUsage();
+  void HalveEnergyUsage();
   void DefaultEnergyUsage();
   
   void RefreshEnergy();

Modified: branches/interrupt/source/main/cPopulation.cc
===================================================================
--- branches/interrupt/source/main/cPopulation.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cPopulation.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -424,6 +424,17 @@
 			child_array[i]->SetReputation(parent_organism->GetReputation()); 
 		}
 		
+		
+		// If spatial groups are used, put the offspring in the 
+		// parents' group
+		if (m_world->GetConfig().USE_FORM_GROUPS.Get()){
+			assert(parent_organism->HasOpinion());
+			int group = parent_organism->GetOpinion().first;
+			child_array[i]->SetOpinion(group); 
+			JoinGroup(group);
+
+		}
+		
 	
 	}
 	
@@ -4385,8 +4396,10 @@
   stats.SetDomInjSequence(dom_inj_genotype->GetGenome().AsString());
 }
 
-void cPopulation::CalcUpdateStats()
+void cPopulation::ProcessPostUpdate(cAvidaContext& ctx)
 {
+  //ProcessUpdateCellActions(ctx);
+  
   cStats& stats = m_world->GetStats();
   // Reset the Genebank to prepare it for stat collection.
   m_world->GetClassificationManager().UpdateReset();
@@ -4406,9 +4419,18 @@
   // Have stats calculate anything it now can...
   stats.CalcEnergy();
   stats.CalcFidelity();
+  
+  for (int i = 0; i < deme_array.GetSize(); i++) deme_array[i].ProcessUpdate();
 }
 
+void cPopulation::ProcessUpdateCellActions(cAvidaContext& ctx)
+{
+  for (int i = 0; i < cell_array.GetSize(); i++) {
+    if (cell_array[i].MutationRates().TestDeath(ctx)) KillOrganism(cell_array[i]);
+  }
+}
 
+
 bool cPopulation::SaveClone(ofstream& fp)
 {
   if (fp.good() == false) return false;
@@ -5418,7 +5440,7 @@
   //is processed, they accurately reflect this trial only...
   cStats& stats = m_world->GetStats();
   stats.ProcessUpdate();
-  CalcUpdateStats();
+  ProcessPostUpdate(ctx);
 }
 
 /*

Modified: branches/interrupt/source/main/cPopulation.h
===================================================================
--- branches/interrupt/source/main/cPopulation.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cPopulation.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -271,7 +271,8 @@
   void ProcessStepSpeculative(cAvidaContext& ctx, double step_size, int cell_id);
 
   // Calculate the statistics from the most recent update.
-  void CalcUpdateStats();
+  void ProcessPostUpdate(cAvidaContext& ctx);
+  void ProcessUpdateCellActions(cAvidaContext& ctx);
 
   // Clear all but a subset of cells...
   void SerialTransfer(int transfer_size, bool ignore_deads);

Modified: branches/interrupt/source/main/cPopulationInterface.cc
===================================================================
--- branches/interrupt/source/main/cPopulationInterface.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cPopulationInterface.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -25,6 +25,7 @@
 
 #include "cPopulationInterface.h"
 
+#include "cDeme.h"
 #include "cEnvironment.h"
 #include "cGenotype.h"
 #include "cHardwareManager.h"
@@ -42,8 +43,16 @@
 #define NULL 0
 #endif
 
-cDeme* cPopulationInterface::GetDeme()
-{
+
+cPopulationCell* cPopulationInterface::GetCell() { 
+	return &m_world->GetPopulation().GetCell(m_cell_id);
+}
+
+cPopulationCell* cPopulationInterface::GetCellFaced() {
+	return &GetCell()->GetCellFaced();
+}
+
+cDeme* cPopulationInterface::GetDeme() {
   return &m_world->GetPopulation().GetDeme(m_deme_id);
 }
 
@@ -583,9 +592,32 @@
 			cell.ConnectionList().CircNext();
 			
 		}
-		
-		
-		
-	}
-	
+	}	
 }
+
+/*! Link this organism's cell to the cell it is currently facing.
+ */
+void cPopulationInterface::CreateLinkByFacing(double weight) {
+	cDeme* deme = GetDeme(); assert(deme);
+	cPopulationCell* this_cell = GetCell(); assert(this_cell);
+	cPopulationCell* that_cell = GetCellFaced(); assert(that_cell);
+	deme->GetNetwork().Connect(*this_cell, *that_cell, weight);
+}
+
+/*! Link this organism's cell to the cell with coordinates (x,y).
+ */
+void cPopulationInterface::CreateLinkByXY(int x, int y, double weight) {
+	cDeme* deme = GetDeme(); assert(deme);
+	cPopulationCell* this_cell = GetCell(); assert(this_cell);
+	cPopulationCell& that_cell = deme->GetCell(x % deme->GetWidth(), y % deme->GetHeight());
+	deme->GetNetwork().Connect(*this_cell, that_cell, weight);
+}
+
+/*! Link this organism's cell to the cell with index idx.
+ */
+void cPopulationInterface::CreateLinkByIndex(int idx, double weight) {
+	cDeme* deme = GetDeme(); assert(deme);
+	cPopulationCell* this_cell = GetCell(); assert(this_cell);
+	cPopulationCell& that_cell = deme->GetCell(idx % deme->GetSize());
+	deme->GetNetwork().Connect(*this_cell, that_cell, weight);
+}

Modified: branches/interrupt/source/main/cPopulationInterface.h
===================================================================
--- branches/interrupt/source/main/cPopulationInterface.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cPopulationInterface.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -35,9 +35,10 @@
 #ifndef cWorldDriver_h
 #include "cWorldDriver.h"
 #endif
-#include "cDeme.h"
 
+class cDeme;
 class cPopulation;
+class cPopulationCell;
 class cOrgMessage;
 
 
@@ -61,7 +62,12 @@
   virtual ~cPopulationInterface() { ; }
 
   int GetCellID() { return m_cell_id; }
+	//! Retrieve the cell in which this organism lives.
+	cPopulationCell* GetCell();
+	//! Retrieve the cell currently faced by this organism.
+	cPopulationCell* GetCellFaced();
   int GetDemeID() { return m_deme_id; }
+	//! Retrieve the deme in which this organism lives.
   cDeme* GetDeme();
   void SetCellID(int in_id) { m_cell_id = in_id; }
   void SetDemeID(int in_id) { m_deme_id = in_id; }
@@ -119,7 +125,15 @@
 	// Reputation
 	void RotateToGreatestReputation();
 	void RotateToGreatestReputationWithDifferentTag(int tag);
-	void RotateToGreatestReputationWithDifferentLineage(int line);	
+	void RotateToGreatestReputationWithDifferentLineage(int line);
+	
+	// -------- Network creation support --------
+	//! Link this organism's cell to the cell it is currently facing.
+	void CreateLinkByFacing(double weight=1.0);
+	//! Link this organism's cell to the cell with coordinates (x,y).
+	void CreateLinkByXY(int x, int y, double weight=1.0);
+	//! Link this organism's cell to the cell with index idx.
+	void CreateLinkByIndex(int idx, double weight=1.0);	
 };
 
 

Modified: branches/interrupt/source/main/cStats.cc
===================================================================
--- branches/interrupt/source/main/cStats.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cStats.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -1468,6 +1468,7 @@
 		for(map<cString, int>::iterator iter = demeResourceThresholdPredicateMap.begin(); iter != demeResourceThresholdPredicateMap.end(); ++iter) {
 			df.Write(iter->second, iter->first);
 			iter->second = 0;
+			assert(iter->second == 0 && demeResourceThresholdPredicateMap[iter->first] == 0);
 		}
 		df.Endl();
 	}	
@@ -1731,6 +1732,7 @@
   m_deme_founders.clear();
 }
 
+
 void cStats::PrintPerDemeTasksData(const cString& filename){
   cDataFile& df = m_world->GetDataFile(filename);
 	df.WriteComment("Avida deme tasks data");
@@ -1741,7 +1743,7 @@
 
   const int num_tasks = m_world->GetEnvironment().GetNumTasks();
 
-	df.Write(m_update,   "Update");
+	df.Write(m_update, "Update");
   for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
     cDeme& deme = m_world->GetPopulation().GetDeme(i);
     for(int j = 0; j < num_tasks; j++) {
@@ -1751,6 +1753,7 @@
   df.Endl();
 }
 
+
 void cStats::PrintPerDemeTasksExeData(const cString& filename){
   cDataFile& df = m_world->GetDataFile(filename);
 	df.WriteComment("Avida deme tasks exe data");
@@ -1761,7 +1764,7 @@
 
   const int num_tasks = m_world->GetEnvironment().GetNumTasks();
 
-	df.Write(m_update,   "Update");
+	df.Write(m_update, "Update");
   for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
     cDeme& deme = m_world->GetPopulation().GetDeme(i);
     for(int j = 0; j < num_tasks; j++) {
@@ -1771,6 +1774,92 @@
   df.Endl();
 }
 
+
+void cStats::PrintAvgDemeTasksExeData(const cString& filename) {
+  cDataFile& df = m_world->GetDataFile(filename);
+  const int num_demes = m_world->GetPopulation().GetNumDemes();
+  const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+  cIntSum tasksum;
+  
+	df.WriteComment("Avida average deme tasks data");
+	df.WriteTimeStamp();
+  df.WriteComment("First column is the update, remaining columns are the average number of times");
+  df.WriteComment("each task has been executed by the demes");
+  df.WriteComment(cStringUtil::Stringf("Data based on %i demes and %i tasks", num_demes, num_tasks));
+  
+  df.Write(m_update, "Update");
+  
+  for(int t = 0; t < num_tasks; t++) {
+    tasksum.Clear();
+    
+    for(int d = 0; d < num_demes; d++) {
+      cDeme& deme = m_world->GetPopulation().GetDeme(d);
+      tasksum.Add(deme.GetLastTaskExeCount()[t]);
+    }
+    df.Write(tasksum.Average(), task_names[t]);
+  }
+  df.Endl();  
+}
+
+
+void cStats::PrintAvgTreatableDemeTasksExeData(const cString& filename) {
+  cDataFile& df = m_world->GetDataFile(filename);
+  const int num_demes = m_world->GetPopulation().GetNumDemes();
+  const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+  cIntSum tasksum;
+  
+	df.WriteComment("Avida average tasks data for treatable demes");
+	df.WriteTimeStamp();
+  df.WriteComment("First column is the update, remaining columns are the average number of times");
+  df.WriteComment("each task has been executed by treatable demes");
+  df.WriteComment(cStringUtil::Stringf("Data based on %i demes and %i tasks", num_demes, num_tasks));
+  
+  df.Write(m_update, "Update");
+  
+  for(int t = 0; t < num_tasks; t++) {
+    tasksum.Clear();
+    
+    for(int d = 0; d < num_demes; d++) {
+      cDeme& deme = m_world->GetPopulation().GetDeme(d);
+      if(deme.isTreatable()) {
+        tasksum.Add(deme.GetLastTaskExeCount()[t]);
+      }
+    }
+    df.Write(tasksum.Average(), task_names[t]);
+  }
+  df.Endl();  
+}
+
+
+void cStats::PrintAvgUntreatableDemeTasksExeData(const cString& filename) {
+  cDataFile& df = m_world->GetDataFile(filename);
+  const int num_demes = m_world->GetPopulation().GetNumDemes();
+  const int num_tasks = m_world->GetEnvironment().GetNumTasks();
+  cIntSum tasksum;
+  
+	df.WriteComment("Avida average tasks data for untreatable demes");
+	df.WriteTimeStamp();
+  df.WriteComment("First column is the update, remaining columns are the average number of times");
+  df.WriteComment("each task has been executed by untreatable demes");
+  df.WriteComment(cStringUtil::Stringf("Data based on %i demes and %i tasks", num_demes, num_tasks));
+  
+  df.Write(m_update, "Update");
+  
+  for(int t = 0; t < num_tasks; t++) {
+    tasksum.Clear();
+    
+    for(int d = 0; d < num_demes; d++) {
+      cDeme& deme = m_world->GetPopulation().GetDeme(d);
+      if(!deme.isTreatable()) {
+        tasksum.Add(deme.GetLastTaskExeCount()[t]);
+      }
+    }
+    df.Write(tasksum.Average(), task_names[t]);
+  }
+  df.Endl();  
+}
+
+
 void cStats::PrintPerDemeReactionData(const cString& filename){
   cDataFile& df = m_world->GetDataFile(filename);
 	df.WriteComment("Avida deme reactions data");
@@ -2188,6 +2277,51 @@
 	}	
 }
 
+void cStats::PrintOpinionsSetPerDeme(const cString& filename) {
+	cDataFile& df = m_world->GetDataFile(filename);
+	df.WriteComment("Current fractions of opinions set in deme.");
+	df.WriteComment("This files shows data for both treatable and untreatable demes.");
+	df.WriteTimeStamp();
+	
+	cIntSum    treatableOpinionCounts, untreatableOpinionCounts;
+	cDoubleSum treatableDensityCounts, untreatableDensityCounts;
+	treatableOpinionCounts.Clear();
+	untreatableOpinionCounts.Clear();
+	treatableDensityCounts.Clear();
+	untreatableDensityCounts.Clear();
+	
+	for(int i=0; i<m_world->GetPopulation().GetNumDemes(); ++i) {
+    cDeme& deme = m_world->GetPopulation().GetDeme(i);
+		int demeSize = deme.GetSize();
+		if(deme.isTreatable()) {
+			// accumultate counts for treatable demes 
+			for(int orgID = 0; orgID < demeSize; ++orgID) {
+				treatableOpinionCounts.Add(deme.GetNumOrgsWithOpinion());
+				treatableDensityCounts.Add(deme.GetDensity());
+			}
+		} else {
+			// accumultate counts for untreatable demes 
+			for(int orgID = 0; orgID < demeSize; ++orgID) {
+				untreatableOpinionCounts.Add(deme.GetNumOrgsWithOpinion());
+				untreatableDensityCounts.Add(deme.GetDensity());
+			}
+		}
+	}
+	
+	df.Write(GetUpdate(), "Update [update]");
+	
+	if(treatableOpinionCounts.N() > 0 and untreatableOpinionCounts.N() > 0) {
+		df.Write(treatableOpinionCounts.Average(), "Average number of opinions set in Treatable demes");
+		df.Write(untreatableOpinionCounts.Average(), "Average number of opinions set in Unreatable demes");
+		df.Write(treatableDensityCounts.Average(), "Average density of Treatable demes");
+		df.Write(untreatableDensityCounts.Average(), "Average density of Unreatable demes");
+	} else {
+		df.Write(untreatableOpinionCounts.Average(), "Average number of opinions set in demes");
+		df.Write(untreatableDensityCounts.Average(), "Average density of demes");
+	}
+	df.Endl();
+}
+
 /*! Called when an organism issues a flash instruction.
  
  We do some pretty detailed tracking here in order to support the use of flash
@@ -2608,7 +2742,7 @@
 {
 
 	cDataFile& df = m_world->GetDataFile(filename);
-	df.WriteComment("The number of groups, average, max, and min number of orgs in groups");
+	df.WriteComment("Information about the groups joined and used by the organisms");
 	
 	map<int,int> groups = m_world->GetPopulation().GetFormedGroups();
 	
@@ -2618,6 +2752,7 @@
 	double max_size = 0.0;
 	double min_size = 100000000000.0;
 	double active_groups = 0.0;
+	double groups_per_org = 0.0;
 	
 	for(itr = groups.begin();itr!=groups.end();itr++) {
 		double cur_size = itr->second;
@@ -2630,8 +2765,20 @@
 		}
 	}
 	
+	cOrganism* org; 
+	for(int i=0; i<m_world->GetPopulation().GetSize(); ++i) {
+    cPopulationCell& cell = m_world->GetPopulation().GetCell(i);
+		org = cell.GetOrganism();
+		
+    if(cell.IsOccupied()) {
+			org = cell.GetOrganism();
+			groups_per_org += org->HasOpinion();
+		}	
+	}
+	
 	avg_size = avg_size / groups.size();
 	avg_size_wout_empty = avg_size_wout_empty / active_groups;
+	groups_per_org = groups_per_org / m_world->GetPopulation().GetSize();
 	df.WriteTimeStamp();
 	df.Write(m_update,   "Update [update]");
 	df.Write((double)groups.size(), "number of groups [num]");
@@ -2640,12 +2787,43 @@
 	df.Write(max_size, "max size of groups [maxsize]");
 	df.Write(min_size, "min size of groups [minsize]");
 	df.Write(active_groups, "active groups [actgroup]");
+	df.Write(groups_per_org, "groups per org life [groupsperorg]");
 	
 	
 	df.Endl();
 	
 }
 
+/* 	
+ Print data regarding the ids of used groups.
+ */
+void cStats::PrintGroupIds(const cString& filename)
+{
+	
+	cDataFile& df = m_world->GetDataFile(filename);
+	df.WriteComment("The ids of groups used.");
+	
+	map<int,int> groups = m_world->GetPopulation().GetFormedGroups();
+	
+	map <int,int>::iterator itr;
+
+	df.WriteTimeStamp();
+	
+	for(itr = groups.begin();itr!=groups.end();itr++) {
+		double cur_size = itr->second;
+		if (cur_size > 0) {
+			df.Write(m_update,   "Update [update]");
+			df.Write(itr->first, "group id [groupid]");
+			df.Write(cur_size, "size of groups [grsize]");
+			df.Endl();
+		}
+	}
+	
+	
+	df.Endl();
+	
+}
+
 /*! Print and reset network statistics.
  */
 void cStats::PrintDemeNetworkData(const cString& filename) {

Modified: branches/interrupt/source/main/cStats.h
===================================================================
--- branches/interrupt/source/main/cStats.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cStats.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -777,6 +777,7 @@
   void PrintExtendedTimeData(const cString& filename);
   void PrintNumOrgsKilledData(const cString& filename);
   void PrintGroupsFormedData(const cString& filename);
+	void PrintGroupIds(const cString& filename);
   
   // deme predicate stats
   void IncEventCount(int x, int y);
@@ -850,6 +851,9 @@
 
   void PrintPerDemeTasksData(const cString& filename);
   void PrintPerDemeTasksExeData(const cString& filename);
+  void PrintAvgDemeTasksExeData(const cString& filename);
+  void PrintAvgTreatableDemeTasksExeData(const cString& filename);
+  void PrintAvgUntreatableDemeTasksExeData(const cString& filename);
   void PrintPerDemeReactionData(const cString& filename);
   void PrintDemeTasksData(const cString& filename);
   void PrintDemeTasksExeData(const cString& filename);
@@ -915,6 +919,8 @@
 public:
 	//! Prints the current opinions of all organisms in the population.
 	void PrintCurrentOpinions(const cString& filename);
+	//! Prints the average number of organism with set opinions
+	void PrintOpinionsSetPerDeme(const cString& filename);
 	
 	// -------- Synchronization support --------
 public:

Modified: branches/interrupt/source/main/cTaskLib.cc
===================================================================
--- branches/interrupt/source/main/cTaskLib.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cTaskLib.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -37,6 +37,7 @@
 #include "cStateGrid.h"
 #include "tArrayUtils.h"
 #include "tHashTable.h"
+#include "cEnvironment.h"
 
 #include "platform.h"
 
@@ -440,6 +441,9 @@
   
 	if (name == "form-group")
     Load_FormSpatialGroup(name, info, envreqs, errors);
+	
+	if (name == "form-group-id")
+    Load_FormSpatialGroupWithID(name, info, envreqs, errors);
   
   // Make sure we have actually found a task  
   if (task_array.GetSize() == start_size) {
@@ -3400,20 +3404,82 @@
 
 double cTaskLib::Task_FormSpatialGroup(cTaskContext& ctx) const
 {
-	int ideal_group_size = ctx.GetTaskEntry()->GetArguments().GetInt(0);
+	double t = (double) ctx.GetTaskEntry()->GetArguments().GetInt(0);
 	double reward = 0.0;
 	int group_id = 0; 
 	if (ctx.GetOrganism()->HasOpinion()) {
 		group_id = ctx.GetOrganism()->GetOpinion().first;
 	}
-	int orgs_in_group = m_world->GetPopulation().NumberOfOrganismsInGroup(group_id);
+	double g = (double) m_world->GetPopulation().NumberOfOrganismsInGroup(group_id);
+	double num = (t-g) * (t-g);
+	double denom = (t*t);
 	
-	if (orgs_in_group < ideal_group_size) {
+	reward = 1 - (num/denom);
+	if (reward < 0) reward = 0;
+	/*if (orgs_in_group < ideal_group_size) {
 		reward = orgs_in_group*orgs_in_group;
 	} else {
 		reward = ideal_group_size*ideal_group_size;
 	}
-	reward = reward / ideal_group_size;
+	reward = reward / ideal_group_size;*/
 	return reward;
 }
 
+
+/* Reward organisms for having a given group-id, provided the group is under the 
+ max number of members.*/
+void cTaskLib::Load_FormSpatialGroupWithID(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors)
+{
+	cArgSchema schema;
+  
+  // Integer Arguments
+  schema.AddEntry("group_size", 0, 1);
+  schema.AddEntry("group_id", 1, 1);
+	
+
+  
+  cArgContainer* args = cArgContainer::Load(argstr, schema, errors);
+  if (args) NewTask(name, "FormSpatialGroupWithID", &cTaskLib::Task_FormSpatialGroupWithID, 0, args);
+	
+	// Add this group id to the list in the instructions file. 
+	m_world->GetEnvironment().AddGroupID(args->GetInt(1));
+	
+}
+
+double cTaskLib::Task_FormSpatialGroupWithID(cTaskContext& ctx) const
+{
+	double t = (double) ctx.GetTaskEntry()->GetArguments().GetInt(0);
+	int des_group_id = ctx.GetTaskEntry()->GetArguments().GetInt(1);
+
+	double reward = 0.0;
+	int group_id = -1; 
+	if (ctx.GetOrganism()->HasOpinion()) {
+		group_id = ctx.GetOrganism()->GetOpinion().first;
+	}
+	
+	// If the organism is in the group...
+	if (group_id == des_group_id) {
+		double g = (double) m_world->GetPopulation().NumberOfOrganismsInGroup(group_id);
+		// If the population size is less than the max size
+		if (g < t) {
+			reward = 1;
+		} else {
+			
+			double num = (t-g) * (t-g);
+			double denom = (t*t);
+			
+			if (denom > 0) {
+				reward = 1 - (num/denom);
+				if (reward < 0) reward = 0;
+			} else {
+				reward = 0;
+			}
+			
+		}
+		
+	}
+	
+
+	return reward;
+}
+

Modified: branches/interrupt/source/main/cTaskLib.h
===================================================================
--- branches/interrupt/source/main/cTaskLib.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/main/cTaskLib.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -43,6 +43,7 @@
 #endif
 
 
+
 class cEnvReqs;
 class cString;
 class cWorld;
@@ -321,6 +322,8 @@
 	// group formation 
 	void Load_FormSpatialGroup(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
 	double Task_FormSpatialGroup(cTaskContext& ctx) const; 
+	void Load_FormSpatialGroupWithID(const cString& name, const cString& argstr, cEnvReqs& envreqs, tList<cString>* errors);
+	double Task_FormSpatialGroupWithID(cTaskContext& ctx) const; 
 };
 
 

Modified: branches/interrupt/source/targets/avida-viewer/cTextViewerDriver.cc
===================================================================
--- branches/interrupt/source/targets/avida-viewer/cTextViewerDriver.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/targets/avida-viewer/cTextViewerDriver.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -135,7 +135,7 @@
     
     
     // end of update stats...
-    population.CalcUpdateStats();
+    population.ProcessPostUpdate(ctx);
     
     // Setup the viewer for the new update.
     if (m_view->GetStepOrganism() == -1) {

Modified: branches/interrupt/source/targets/unit-tests/main.cc
===================================================================
--- branches/interrupt/source/targets/unit-tests/main.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/targets/unit-tests/main.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -99,6 +99,251 @@
 
 
 
+#include "cBitArray.h"
+class cRawBitArrayTests : public cUnitTest
+{
+public:
+  const char* GetUnitName() { return "cRawBitArray"; }
+protected:
+  void RunTests()
+  {
+    int result = true;
+    
+    cRawBitArray bit_array1;
+    bit_array1.ResizeClear(10);
+    for (int i = 0; i < 10; i++) {
+      if (bit_array1.GetBit(i) != false) {
+        result = false;
+        break;
+      }
+    }
+    ReportTestResult("Default Constructor - ResizeClear", result);
+    
+
+    result = true;
+    
+    bit_array1.SetBit(1, true);
+    bit_array1.SetBit(3, true);
+    bit_array1.SetBit(5, true);
+    bit_array1.SetBit(7, true);
+    bit_array1.SetBit(9, true);
+    
+    for (int i = 0; i < 10; i++) {
+      bool bit_value = !(2*(i/2) == i);
+      if (bit_array1.GetBit(i) != bit_value) {
+        result = false;
+        break;
+      }
+    }
+    ReportTestResult("SetBit (round 1)", result);
+
+    
+    result = true;
+    
+    bit_array1.SetBit(0, true);
+    bit_array1.SetBit(1, false);
+    bit_array1.SetBit(5, false);
+    bit_array1.SetBit(6, true);
+    bit_array1.SetBit(7, false);
+    
+    for (int i = 0; i < 10; i++) {
+      bool bit_value = (3*(i/3) == i);
+      if (bit_array1.GetBit(i) != bit_value) {
+        result = false;
+        break;
+      }
+    }
+    ReportTestResult("SetBit (round 2)", result);
+    
+    // Test constructor with initial size < 32.
+    cRawBitArray bit_array2(26);
+    for (int i = 0; i < 26; i++) {
+      if (bit_array2.GetBit(i) != false) {
+        result = false;
+        break;
+      }
+    }
+    ReportTestResult("Constructor (size < 32)", result);
+    
+    
+    result = true;
+    
+    bit_array2.SetBit(8, true);
+    bit_array2.Copy(bit_array1, 10);
+    
+    for (int i = 0; i < 10; i++) {
+      bool bit_value = (3*(i/3) == i);
+      if (bit_array2.GetBit(i) != bit_value) {
+        result = false;
+        break;
+      }
+    }
+    ReportTestResult("Copy", result);
+    
+    
+    result = true;
+    
+    // Test constructor with initial size > 32.
+    const int high_bit_count = 1000;
+    cRawBitArray bit_array3(high_bit_count);
+    int bit_pos = 2;
+    while (bit_pos < high_bit_count) {
+      bit_array3.SetBit(bit_pos, true);
+      bit_pos = bit_pos * 3 / 2;
+    }
+    
+    
+    // Test faux copy constructor.
+    cRawBitArray bit_array4(bit_array3, high_bit_count);
+    bit_array4.SetBit(22, true);
+    bit_array4.SetBit(24, true);
+    int count1 =  bit_array3.CountBits(high_bit_count);
+    int count2 =  bit_array3.CountBits2(high_bit_count);
+    int count3 =  bit_array4.CountBits(high_bit_count);
+    int count4 =  bit_array4.CountBits2(high_bit_count);
+    ReportTestResult("CountBits vs. CountBits2", (count1 == count2 && count3 == count4));
+    ReportTestResult("CountBits - Post Copy", (count1 == (count3 - 2)));
+    
+    
+    int diff_count = 0;
+    for (int i = 0; i < high_bit_count; i++) {
+      if (bit_array3.GetBit(i) != bit_array4.GetBit(i)) diff_count++;
+    }
+    ReportTestResult("Copy Constructor", (diff_count == 2));
+    
+    
+    // LOGICAL OPERATORS
+    
+    bit_array4.Resize(1000, 70);
+    int count5 = bit_array4.CountBits(70);
+    bit_array4.NOT(70);
+    int count6 = bit_array4.CountBits(70);
+    bit_array4.NOT(70);
+    ReportTestResult("NOT Operation", (count5 + count6 == 70));
+    
+    
+    cRawBitArray bit_array5(70);
+    int pos = 1;
+    int step = 1;
+    while (pos <= 70) {
+      bit_array5.SetBit(70 - pos, true);
+      pos += step++;
+    }
+    
+    cRawBitArray bit_array6(70);
+    bit_array6.AND(bit_array4, bit_array5, 70);
+    int count_and = bit_array6.CountBits(70);
+    ReportTestResult("AND Operation", (count_and == 3));
+    
+    
+    bit_array6.OR(bit_array4, bit_array5, 70);
+    int count_or = bit_array6.CountBits(70);
+    ReportTestResult("OR Operation", (count_or == 21));
+    
+    
+    bit_array6.NAND(bit_array4, bit_array5, 70);
+    int count_nand = bit_array6.CountBits(70);
+    ReportTestResult("NAND Operation", (count_nand == 67));
+    
+    
+    bit_array6.NOR(bit_array4, bit_array5, 70);
+    int count_nor = bit_array6.CountBits(70);
+    ReportTestResult("NOR Operation", (count_nor == 49));
+    
+    
+    bit_array6.XOR(bit_array4, bit_array5, 70);
+    int count_xor = bit_array6.CountBits(70);
+    ReportTestResult("XOR Operation", (count_xor == 18));
+    
+    
+    bit_array6.EQU(bit_array4, bit_array5, 70);
+    int count_equ = bit_array6.CountBits(70);
+    ReportTestResult("EQU Operation", (count_equ == 52));
+    
+    
+    // LEFT AND RIGHT SHIFT
+    
+    cRawBitArray bit_array7(32);
+    bit_array7.SetBit(0, true);
+    
+    bit_array7.SHIFT(32, 0);
+    ReportTestResult("Shift 0", (bit_array7.GetBit(0) && bit_array7.CountBits(32) == 1));
+    
+    
+    bit_array7.SHIFT(32, 31);
+    ReportTestResult("Shift Left", (bit_array7.GetBit(31) && bit_array7.CountBits(32) == 1));
+    
+    
+    bit_array7.SHIFT(32, -31);
+    ReportTestResult("Shift Right (sign bit)", (bit_array7.GetBit(0) || bit_array7.CountBits(32) == 1));
+    
+    
+    bit_array7.SHIFT(32, 30);
+    bit_array7.SHIFT(32, -30);
+    ReportTestResult("Shift Right (no sign bit)", (bit_array7.GetBit(0) && bit_array7.CountBits(32) == 1));
+    
+    
+    bit_array7.SHIFT(32, 32);
+    ReportTestResult("Shift Left Overflow", (bit_array7.CountBits(32) == 0));
+    
+    
+    bit_array7.SetBit(31, true);
+    bit_array7.SHIFT(32, -32);
+    ReportTestResult("Shift Right Overflow", (bit_array7.CountBits(32) == 0));
+    
+    
+    cRawBitArray bit_array8(34);
+    bit_array8.SetBit(0, true);
+    
+    bit_array8.SHIFT(34, 33);
+    ReportTestResult("Shift Left (across bit fields)", (bit_array8.GetBit(33) && bit_array8.CountBits(34) == 1));
+    
+    
+    bit_array8.SHIFT(34, -33);
+    ReportTestResult("Shift Right (across bit fields)", (bit_array8.GetBit(0) && bit_array8.CountBits(34) == 1));
+    
+    
+    cRawBitArray bit_array9(66);
+    bit_array9.SetBit(0, true);
+    bit_array9.SetBit(32, true);
+    
+    bit_array9.SHIFT(66, 65);
+    ReportTestResult("Shift Left (multiple bit fields)", (bit_array9.GetBit(65) && bit_array9.CountBits(66) == 1));
+    
+    
+    bit_array9.SHIFT(66, -65);
+    ReportTestResult("Shift Right (multiple bit fields)", (bit_array9.GetBit(0) && bit_array9.CountBits(66) == 1));
+  }
+};
+
+class cBitArrayTests : public cUnitTest
+{
+public:
+  const char* GetUnitName() { return "cBitArray"; }
+protected:
+  void RunTests()
+  {
+    cBitArray ba(74);
+    for (int i = 0; i < 74; i++) if (i % 5 == 3) ba[i] = true;
+    
+    cBitArray ba2(74);
+    for (int i = 0; i < 74; i++) {
+      if ((i % 2 == 0 || i % 3 == 0) && i % 6 != 0) ba2[i] = true;
+    }
+    
+    ReportTestResult("operator&", ((ba & ba2).CountBits() == 8));
+    ReportTestResult("operator|", ((ba | ba2).CountBits() == 43));
+    ReportTestResult("operator^", ((ba ^ ba2).CountBits() == 35));
+    ReportTestResult("operator~", ((~ba).CountBits() == 59));
+    ReportTestResult("operator<<", ((ba << 65).CountBits() == 2));
+    ReportTestResult("operator>>", ((ba >> 65).CountBits() == 2));
+    ReportTestResult("Chained Bitwise Operations", ((~ba & ~ba2).CountBits() == 31));
+  }
+};
+
+
+
+
 #define TEST(CLASS) \
 tester = new CLASS ## Tests(); \
 tester->Execute(); \
@@ -117,6 +362,8 @@
   cout << endl;
   
   TEST(tArray);
+  TEST(cRawBitArray);
+  TEST(cBitArray);
   
   if (failed == 0)
     cout << "All unit tests passed." << endl;
@@ -147,7 +394,7 @@
   
   size_t l = strlen(test_name);
   char* str = new char[l + 3];
-  str = strncpy(str, test_name, l);
+  str = strncpy(str, test_name, l + 1);
   str = strncat(str, ": ", 2);
   
   cout << setw(74) << left << str;
@@ -157,5 +404,7 @@
     cout << "failed";
     m_failed++;
   }
-  cout << endl;  
+  cout << endl;
+  
+  delete str;
 }

Modified: branches/interrupt/source/targets/viewer-text/cDriver_TextViewer.cc
===================================================================
--- branches/interrupt/source/targets/viewer-text/cDriver_TextViewer.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/targets/viewer-text/cDriver_TextViewer.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -170,7 +170,7 @@
     
     
     // end of update stats...
-    population.CalcUpdateStats();
+    population.ProcessPostUpdate(ctx);
     
     
     // Setup the viewer for the new update.

Modified: branches/interrupt/source/tools/cBitArray.cc
===================================================================
--- branches/interrupt/source/tools/cBitArray.cc	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/tools/cBitArray.cc	2009-06-25 21:31:08 UTC (rev 3342)
@@ -6,7 +6,7 @@
   if (bit_fields != NULL) {
     delete [] bit_fields;
   }
-  bit_fields = new int[num_fields];
+  bit_fields = new unsigned int[num_fields];
   for (int i = 0; i < num_fields; i++) {
     bit_fields[i] = in_array.bit_fields[i];
   }
@@ -29,9 +29,9 @@
   const int num_new_fields = GetNumFields(new_bits);
   if (num_old_fields == num_new_fields) {
     // Clear all bits past the new end and stop.
-    int & last_field = bit_fields[num_new_fields - 1];
+    unsigned int & last_field = bit_fields[num_new_fields - 1];
     for (int i = new_bits; i < old_bits; i++) {
-      const int clear_bit = i & 31;
+      const unsigned int clear_bit = i & 31;
       last_field &= ~(1 << clear_bit);
     }
     return;
@@ -39,7 +39,7 @@
 
   // If we made it this far, we have to change the number of fields.
   // Create the new bit array and copy the old one into it.
-  int * new_bit_fields = new int[ num_new_fields ];
+  unsigned int * new_bit_fields = new unsigned int[ num_new_fields ];
   for (int i = 0; i < num_new_fields && i < num_old_fields; i++) {
     new_bit_fields[i] = bit_fields[i];
   }
@@ -47,7 +47,7 @@
   // If the old bits are longer, we need to clear the end of the last
   // bit field.
   if (num_old_fields > num_new_fields) {
-    int & last_field = new_bit_fields[num_new_fields - 1];
+    unsigned int & last_field = new_bit_fields[num_new_fields - 1];
     for (int clear_bit=GetFieldPos(new_bits); clear_bit < 32; clear_bit++) {
       last_field &= ~(1 << clear_bit);
     }
@@ -72,7 +72,7 @@
   if (bit_fields != NULL) {
     delete [] bit_fields;
   }
-  bit_fields = new int[ new_fields ];
+  bit_fields = new unsigned int[ new_fields ];
 }
 
 void cRawBitArray::ResizeClear(const int new_bits)
@@ -137,7 +137,66 @@
   return out_array;
 }
 
+void cRawBitArray::ShiftLeft(const int num_bits, const int shift_size)
+{
+  assert(shift_size > 0);
+  int num_fields = GetNumFields(num_bits);
+  int field_shift = shift_size / 32;
+  int bit_shift = shift_size % 32;
+      
+  // acount for field_shift
+  if(field_shift) {
+    for (int i = num_fields - 1; i >= field_shift; i--) {
+      bit_fields[i] = bit_fields[i - field_shift];
+    }
+    for (int i = field_shift - 1; i >= 0; i--) {
+      bit_fields[i] = 0;
+    }
+  }
+  
+  // account for bit_shift
+  int temp = 0;
+  for (int i = 0; i < num_fields; i++) {
+    temp = bit_fields[i] >> (32 - bit_shift);
+    bit_fields[i] <<= bit_shift;
+    bit_fields[i - 1] |= temp;  // same as += in this case since lower bit_shift bits of bit_fields[i - 1] are all 0 at this point -- any advantage?  
+    //could also check for temp != 0 here before assignment -- would that save any time for sparse arrays, or is it always going to be useless?
+  }
+  
+  // mask out any bits that have left-shifted away, allowing CountBits and CountBits2 to work
+  // blw: if CountBits/CountBits2 are fixed, this code should be removed as it will be redundant
+  unsigned int shift_mask = 0xffffffff >> 32 - (num_bits % 32);
+  bit_fields[num_fields - 1] &= shift_mask;
+}
 
+// ALWAYS shifts in zeroes, irrespective of sign bit (since fields are unsigned)
+void cRawBitArray::ShiftRight(const int num_bits, const int shift_size)
+{
+  assert(shift_size > 0);
+  int num_fields = GetNumFields(num_bits);
+  int field_shift = shift_size / 32;
+  int bit_shift = shift_size % 32;
+  
+  // account for field_shift
+  if (field_shift) {
+    for (int i = 0; i < num_fields - field_shift; i++) {
+      bit_fields[i] = bit_fields[i + field_shift];
+    }
+    for(int i = num_fields - field_shift; i < num_fields; i++) {
+      bit_fields[i] = 0;
+    }
+  }
+  
+  // account for bit_shift
+  bit_fields[num_fields - 1] >>= bit_shift;  // drops off right end, may shift in ones if sign bit was set
+  int temp = 0;
+  for (int i = num_fields - 2; i >= 0; i--) {
+    temp = bit_fields[i] << (32 - bit_shift);
+    bit_fields[i] >>= bit_shift;
+    bit_fields[i + 1] |= temp;
+  }
+}
+
 void cRawBitArray::NOT(const int num_bits)
 {
   const int num_fields = GetNumFields(num_bits);
@@ -215,10 +274,34 @@
   }
 }
 
+void cRawBitArray::SHIFT(const int num_bits, const int shift_size)
+{
+  if (shift_size == 0) return;
+  if (shift_size > 0) { ShiftLeft(num_bits, shift_size); return; }
+  if (shift_size < 0) { ShiftRight(num_bits, -shift_size); return; }
+  assert(false); // Should never get here.
+}
 
+void cRawBitArray::INCREMENT(const int num_bits)
+{
+  const int num_fields = GetNumFields(num_bits);
+  int i = 0;
+  for (i = 0; i < num_fields; i++) {
+    bit_fields[i]++;
+    if (bit_fields[i] != 0) { break; }  // no overflow, do not need to increment higher fields
+  }
+  
+  // if highest bit field was incremented, mask out any unused portions of the field so as not to confuse CountBits
+  if (i == num_fields - 1) {
+    unsigned int shift_mask = 0xffffffff >> 32 - (num_bits % 32);
+    bit_fields[num_fields - 1] &= shift_mask;
+  }
+}
 
 
 
+
+
 void cRawBitArray::NOT(const cRawBitArray & array1, const int num_bits)
 {
   ResizeSloppy(num_bits);
@@ -315,7 +398,24 @@
   }
 }
 
+void cRawBitArray::SHIFT(const cRawBitArray & array1, const int num_bits, const int shift_size)
+{
+  if (shift_size == 0) return;
+  
+  Copy(array1, num_bits);
+  
+  SHIFT(num_bits, shift_size);
+}
 
+void cRawBitArray::INCREMENT(const cRawBitArray & array1, const int num_bits)
+{
+  Copy(array1, num_bits);
+  INCREMENT(num_bits);
+}
+
+
+
+
 std::ostream & operator << (std::ostream & out, const cBitArray & bit_array)
 {
   bit_array.Print(out);
@@ -499,7 +599,106 @@
     passed = false;
     cerr << "ERROR in EQU operation!" << endl;
   }
+  
+  // LEFT AND RIGHT SHIFT
+  
+  cRawBitArray bit_array7(32);
+  bit_array7.SetBit(0, true);
+  
+  bit_array7.SHIFT(32, 0);
+  if (bit_array7.GetBit(0) != true || bit_array7.CountBits(32) != 1) {
+    passed = false;
+    cerr << "ERROR when Shifting by zero bits!" << endl;
+  }
+  
+  bit_array7.SHIFT(32, 31);
+  if (bit_array7.GetBit(31) != true || bit_array7.CountBits(32) != 1) {
+    passed = false;
+    cerr << "ERROR in ShiftLeft!" << endl;
+  }
+  
+  bit_array7.SHIFT(32, -31);
+  if (bit_array7.GetBit(0) != true || bit_array7.CountBits(32) != 1)  {
+    passed = false;
+    cerr << "ERROR in ShiftRight with sign bit!" << endl;
+  }
+  
+  bit_array7.SHIFT(32, 30);
+  bit_array7.SHIFT(32, -30);
+  if (bit_array7.GetBit(0) != true || bit_array7.CountBits(32) != 1) {
+    passed = false;
+    cerr << "ERROR in ShiftRight without sign bit!" << endl;
+  }
 
+  bit_array7.SHIFT(32, 32);
+  if (bit_array7.CountBits(32) != 0) {
+    passed = false;
+    cerr << "ERROR in ShiftLeft dropping!" << endl;
+  }
+  
+  bit_array7.SetBit(31, true);
+  bit_array7.SHIFT(32, -32);
+  if(bit_array7.CountBits(32) != 0) {
+    passed = false;
+    cerr << "ERROR in ShiftRight dropping!" << endl;
+  }
+  
+  cRawBitArray bit_array8(34);
+  bit_array8.SetBit(0, true);
+
+  bit_array8.SHIFT(34, 33);
+  if (bit_array8.GetBit(33) != true || bit_array8.CountBits(34) != 1) {
+    passed = false;
+    cerr << "ERROR in ShiftLeft across bit fields!" << endl;
+  }
+  
+  bit_array8.SHIFT(34, -33);
+  if (bit_array8.GetBit(0) != true || bit_array8.CountBits(34) != 1) {
+    passed = false;
+    cerr << "ERROR in ShiftRight accross bit fields!" << endl;
+  }
+  
+  cRawBitArray bit_array9(66);
+  bit_array9.SetBit(0, true);
+  bit_array9.SetBit(32, true);
+  
+  bit_array9.SHIFT(66, 65);
+  if(bit_array9.GetBit(65) != true || bit_array9.CountBits(66) != 1) {
+    passed = false;
+    cerr << "ERROR in ShiftLeft across multiple fields!" << endl;
+  }
+  
+  bit_array9.SHIFT(66, -65);
+  if(bit_array9.GetBit(0) != true || bit_array9.CountBits(66) != 1) {
+    passed = false;
+    cerr << "ERROR in ShiftRight across multiple fields!" << endl;
+  }
+  
+  // INCREMENT
+  
+  cRawBitArray bit_array10(1);
+  
+  bit_array10.INCREMENT(1);
+  if (bit_array10.GetBit(0) != true || bit_array10.CountBits(1) != 1) {
+    passed = false;
+    cerr << "ERROR in INCREMENT operation!" << endl;
+  }
+  
+  bit_array10.INCREMENT(1);
+  if (bit_array10.GetBit(0) != false || bit_array10.CountBits(1) != 0) {
+    passed = false;
+    cerr << "ERROR in INCREMENT overflowing last bit field!" << endl;
+  }
+  
+  cRawBitArray bit_array11(33);
+  for (int i = 0; i < 32; i++) { bit_array11.SetBit(i, true); }
+  
+  bit_array11.INCREMENT(33);
+  if (bit_array11.GetBit(32) != 1 || bit_array11.CountBits(33) != 1) {
+    passed = false;
+    cerr << "ERROR in INCREMENT across fields!" << endl;
+  }
+
 //   bit_array4.Print(70);
 //   bit_array5.Print(70);
 //   bit_array6.Print(70);
@@ -532,12 +731,32 @@
     passed = false;
     cerr << "ERROR: operator~ failed for cBitArray" << endl;
   }
+  
+  if ((ba << 65).CountBits() != 2) { 
+    passed = false;
+    cerr << "ERROR: operator<< (leftshift) failed for cBitArray" << endl;
+  }
+  
+  if ((ba >> 65).CountBits() != 2) {
+    passed = false;
+    cerr << "ERROR: operator>> (rightshift) failed for cBitArray" << endl;
+  }
 
   if ((~ba & ~ba2).CountBits() != 31) {
     passed = false;
     cerr << "ERROR: Chained bitwise operators failed for cBitArray" << endl;
   }
   
+  if ((++(~ba & ~ba2)).CountBits() != 30) {
+    passed = false;
+    cerr << "ERROR: prefix ++ failed for cBitArray" << endl;
+  }
+
+  if (((~ba & ~ba2)++).CountBits() != 31) {
+    passed = false;
+    cerr << "ERROR: postfix ++ failed for cBitArray" << endl;
+  }
+  
   cout << ba << "  " << ba.CountBits() << endl;
   cout << ba2 << "  " << ba2.CountBits() << endl;
   cout << (~ba & ~ba2) << "  " << (~ba & ~ba2).CountBits() << endl;

Modified: branches/interrupt/source/tools/cBitArray.h
===================================================================
--- branches/interrupt/source/tools/cBitArray.h	2009-06-25 21:18:09 UTC (rev 3341)
+++ branches/interrupt/source/tools/cBitArray.h	2009-06-25 21:31:08 UTC (rev 3342)
@@ -53,6 +53,7 @@
 //  cBitArray NOR(const cBitArray & array2) const
 //  cBitArray XOR(const cBitArray & array2) const
 //  cBitArray EQU(const cBitArray & array2) const
+//  cBitArray SHIFT(const int shift_size) const   -- positive for left shift, negative for right shift
 
 //  const cBitArray & NOTSELF()
 //  const cBitArray & ANDSELF(const cBitArray & array2)
@@ -61,15 +62,25 @@
 //  const cBitArray & NORSELF(const cBitArray & array2)
 //  const cBitArray & XORSELF(const cBitArray & array2)
 //  const cBitArray & EQUSELF(const cBitArray & array2)
+//  const cBitArray & SHIFTSELF(const int shift_size) const
 
+// Arithmetic:
+//  cBitArray INCREMENTSELF()
+
 // Operator overloads:
 //  cBitArray operator~() const
 //  cBitArray operator&(const cBitArray & ar2) const
 //  cBitArray operator|(const cBitArray & ar2) const
 //  cBitArray operator^(const cBitArray & ar2) const
+//  cBitArray operator>>(const int) const
+//  cBitArray operator<<(const int) const
 //  const cBitArray & operator&=(const cBitArray & ar2)
 //  const cBitArray & operator|=(const cBitArray & ar2)
 //  const cBitArray & operator^=(const cBitArray & ar2)
+//  const cBitArray & operator>>=(const int)
+//  const cBitArray & operator<<=(const int)
+//  cBitArray & operator++()     // prefix ++
+//  cBitArray & operator++(int)  // postfix ++
 
 
 
@@ -80,7 +91,7 @@
 
 class cRawBitArray {
 private:
-  int * bit_fields;
+  unsigned int * bit_fields;
   
   // Disallow default copy constructor and operator=
   // (we need to know the number of bits we're working with!)
@@ -120,7 +131,7 @@
 
   cRawBitArray(const int num_bits) {
     const int num_fields = GetNumFields(num_bits);
-    bit_fields = new int[ num_fields ];
+    bit_fields = new unsigned int[ num_fields ];
     Zero(num_bits);
   }
 
@@ -168,12 +179,21 @@
   // Other bit-play
   int FindBit1(const int num_bits, const int start_pos) const;
   tArray<int> GetOnes(const int num_bits) const;
+  void ShiftLeft(const int num_bits, const int shift_size); // Helper: call SHIFT with positive number instead
+  void ShiftRight(const int num_bits, const int shift_size); // Helper: call SHIFT with negative number instead
 
   void Print(const int num_bits, ostream & out=cout) const {
     for (int i = 0; i < num_bits; i++) {
       out << GetBit(i);
     }
   }
+  
+  // prints in the accepted human readable low-to-hight = right-to-left format, taking bit 0 as low bit
+  void PrintRightToLeft(const int num_bits, ostream & out=cout) const {
+    for (int i = num_bits - 1; i >= 0; i--) {
+      out << GetBit(i);
+    }
+  }
 
   void PrintOneIDs(const int num_bits, ostream & out=cout) const {
     for (int i = 0; i < num_bits; i++) {
@@ -192,6 +212,8 @@
   void NOR(const cRawBitArray & array2, const int num_bits);
   void XOR(const cRawBitArray & array2, const int num_bits);
   void EQU(const cRawBitArray & array2, const int num_bits);
+  void SHIFT(const int num_bits, const int shift_size);  // positive numbers for left and negative for right (0 does nothing)
+  void INCREMENT(const int num_bits);
 
   // Fast bool operators where we load all of the inputs and store the
   // results here.
@@ -208,6 +230,8 @@
 	   const int num_bits);
   void EQU(const cRawBitArray & array1, const cRawBitArray & array2,
 	   const int num_bits);
+  void SHIFT(const cRawBitArray & array1, const int num_bits, const int shift_size);
+  void INCREMENT(const cRawBitArray & array1, const int num_bits);  // implemented for completeness, but unused by cBitArray
 };
 
 class cBitArray {
@@ -268,6 +292,7 @@
   
 
   void Print(ostream & out=cout) const { bit_array.Print(array_size, out); }
+  void PrintRightToLeft(ostream & out=cout) const { bit_array.PrintRightToLeft(array_size, out); }
   void PrintOneIDs(ostream & out=cout) const
     { bit_array.PrintOneIDs(array_size, out); }
   void Resize(const int new_size) {
@@ -340,6 +365,13 @@
     out_array.array_size = array_size;
     return out_array;
   }
+  
+  cBitArray SHIFT(const int shift_size) const {
+    cBitArray out_array;
+    out_array.bit_array.SHIFT(bit_array, array_size, shift_size);
+    out_array.array_size = array_size;
+    return out_array;
+  }
 
   const cBitArray & NOTSELF() {
     bit_array.NOT(array_size);
@@ -381,15 +413,32 @@
     bit_array.EQU(array2.bit_array, array_size);
     return *this;
   }
+  
+  const cBitArray & SHIFTSELF(const int shift_size) {
+    bit_array.SHIFT(array_size, shift_size);
+    return *this;
+  }
+  
+  cBitArray & INCREMENTSELF() {
+    bit_array.INCREMENT(array_size);
+    return *this;
+  }
+  
 
   // Operator overloads...
   cBitArray operator~() const { return NOT(); }
   cBitArray operator&(const cBitArray & ar2) const { return AND(ar2); }
   cBitArray operator|(const cBitArray & ar2) const { return OR(ar2); }
   cBitArray operator^(const cBitArray & ar2) const { return XOR(ar2); }
+  cBitArray operator<<(const int shift_size) const { return SHIFT(shift_size); }
+  cBitArray operator>>(const int shift_size) const { return SHIFT(-shift_size); }
   const cBitArray & operator&=(const cBitArray & ar2) { return ANDSELF(ar2); }
   const cBitArray & operator|=(const cBitArray & ar2) { return ORSELF(ar2); }
   const cBitArray & operator^=(const cBitArray & ar2) { return XORSELF(ar2); }
+  const cBitArray & operator<<=(const int shift_size) { return SHIFTSELF(shift_size); }
+  const cBitArray & operator>>=(const int shift_size) { return SHIFTSELF(-shift_size); }
+  cBitArray & operator++() { return INCREMENTSELF(); }  // prefix ++
+  cBitArray operator++(int) { cBitArray ans = *this; operator++(); return ans;}  // postfix ++
 
 };
 




More information about the Avida-cvs mailing list