public void TestSimpleGravityModelSolution() { var data = CreateData(); var gm = new GravityModel( data, null, 0.0f, 300 ); var o = SparseArray<float>.CreateSparseArray( new int[] { 1, 2 }, new float[] { 2, 2 } ); var d = SparseArray<float>.CreateSparseArray( new int[] { 1, 2 }, new float[] { 1.5f, 2.5f } ); var ret = gm.ProcessFlow( o, d, new int[] { 1, 2 } ); var result = ret.GetFlatData(); Assert.AreEqual( 0.5f, result[0][0], 0.0001f ); Assert.AreEqual( 1.5f, result[0][1], 0.0001f); Assert.AreEqual( 1f, result[1][0], 0.0001f); Assert.AreEqual( 1f, result[1][1], 0.0001f); }
private void InitializeFlows() { this.Progress = 0; // we are going to need to split based on this information this.ZoneArray = this.Root.ZoneSystem.ZoneArray; var occupations = this.Root.Demographics.OccupationCategories; var validZones = this.ZoneArray.ValidIndexies().ToArray(); var numberOfZones = validZones.Length; //[Occupation][O , D] var distribution = occupations.CreateSimilarArray<SparseTwinIndex<float>>(); //Generate the place of work place of residence OD's SparseArray<float> O = this.ZoneArray.CreateSimilarArray<float>(); SparseArray<float> D = this.ZoneArray.CreateSimilarArray<float>(); var occupationIndexes = occupations.ValidIndexies().ToArray(); var numCat = Categories.Count; // Start burning that CPU Thread.CurrentThread.Priority = ThreadPriority.Highest; SparseTwinIndex<float> workplaceDistribution = null; SparseTwinIndex<float> prevWorkplaceDistribution = null; float[] friction = null; float[] nextFriction = null; MultiRunGPUGravityModel multiRunGPU = null; for ( int i = 0; i < numCat; i++ ) { this.CurrentOccupationIndex = i; Task assignToPopulation = null; if ( i > 0 ) { assignToPopulation = new Task( delegate() { if ( prevWorkplaceDistribution != null ) { // We actually are assigning to the previous category with this data so we need i - 1 AssignToWorkers( prevWorkplaceDistribution, this.Categories[i - 1] ); prevWorkplaceDistribution = null; } } ); assignToPopulation.Start(); } Task computeNextFriction = null; if ( i + 1 < numCat ) { computeNextFriction = new Task( delegate() { nextFriction = this.ComputeFriction( ZoneArray.GetFlatData(), this.Categories[i + 1], nextFriction ); } ); computeNextFriction.Start(); } this.Categories[i].Generate( O, D ); if ( this.UseGPU ) { if ( i == 0 ) { try { Parallel.Invoke( () => friction = this.ComputeFriction( ZoneArray.GetFlatData(), this.Categories[i], friction ), () => multiRunGPU = new MultiRunGPUGravityModel( O.GetFlatData().Length, ( progress => this.Progress = ( progress / numCat ) + ( (float)i / numCat ) ), this.Epsilon, this.MaxIterations ) ); } catch ( AggregateException e ) { throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace ); } } workplaceDistribution = multiRunGPU.ProcessFlow( friction, O, D ); } else { GravityModel gravityModel = new GravityModel( ImpedenceFunction, ( progress => this.Progress = ( progress / numCat ) + ( (float)i / numCat ) ), this.Epsilon, this.MaxIterations ); workplaceDistribution = gravityModel.ProcessFlow( O, D, validZones ); } this.Progress = ( (float)( i + 1 ) / numCat ); if ( assignToPopulation != null ) { try { assignToPopulation.Wait(); assignToPopulation.Dispose(); assignToPopulation = null; } catch ( AggregateException e ) { throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace ); } } if ( computeNextFriction != null ) { try { computeNextFriction.Wait(); computeNextFriction.Dispose(); computeNextFriction = null; } catch ( AggregateException e ) { throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace ); } } prevWorkplaceDistribution = workplaceDistribution; var frictionTemp = friction; friction = nextFriction; nextFriction = friction; } friction = null; nextFriction = null; prevWorkplaceDistribution = null; if ( multiRunGPU != null ) { multiRunGPU.Dispose(); multiRunGPU = null; } AssignToWorkers( workplaceDistribution, this.Categories[numCat - 1] ); workplaceDistribution = null; // ok now we can relax Thread.CurrentThread.Priority = ThreadPriority.Normal; GC.Collect(); }