private void ProcessFlow(float[] columnTotals) { Parallel.For(0, Productions.GetFlatData().Length, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, () => new float[columnTotals.Length], (int flatOrigin, ParallelLoopState state, float[] localTotals) => { float sumAF = 0; var flatProductions = Productions.GetFlatData(); var flatFriction = Friction.GetFlatData(); var flatAStar = AttractionsStar.GetFlatData(); var flatAttractions = Attractions.GetFlatData(); var length = flatFriction.Length; var flatFrictionRow = flatFriction[flatOrigin]; // check to see if there is no production, if not skip this if (flatProductions[flatOrigin] > 0) { // if there is production continue on for (int i = 0; i < flatFrictionRow.Length; i++) { sumAF += flatFrictionRow[i] * (flatAttractions[i] * flatAStar[i]); } sumAF = (1 / sumAF) * flatProductions[flatOrigin]; if (float.IsInfinity(sumAF) | float.IsNaN(sumAF)) { // this needs to be 0f, otherwise we will be making the attractions have to be balanced higher sumAF = 0f; } var flatFlowsRow = FlowMatrix.GetFlatData()[flatOrigin]; for (int i = 0; i < flatFlowsRow.Length; i++) { var temp = (flatFrictionRow[i] * (sumAF * flatAttractions[i] * flatAStar[i])); temp = float.IsInfinity(temp) | float.IsNaN(temp) ? 0 : temp; localTotals[i] += temp; flatFlowsRow[i] = temp; } } return(localTotals); }, (float[] localTotals) => { lock (columnTotals) { for (int i = 0; i < localTotals.Length; i++) { columnTotals[i] += localTotals[i]; } } }); }
public bool StoreIfValid(int originIndex, int destinationIndex, ITrip currentTrip, float personExpansionFactor) { var startTime = ActivityStartTime ? currentTrip.ActivityStartTime : currentTrip.TripStartTime; if (StartTime <= startTime && startTime < EndTime) { var data = Results.GetFlatData(); lock (this) { data[originIndex][destinationIndex] += personExpansionFactor; } return(true); } return(false); }
private void Apply(SparseTwinIndex <float> ret, float[][] rates) { var zones = Root.ZoneSystem.ZoneArray.GetFlatData(); var data = ret.GetFlatData(); Parallel.For(0, data.Length, i => { var row = data[i]; var rateRow = rates[i]; if (zones[i].RegionNumber == 0) { for (int j = 0; j < row.Length; j++) { row[j] = zones[i].Population * rateRow[j]; } } else { for (int j = 0; j < row.Length; j++) { row[j] = zones[j].Population * rateRow[j]; } } }); }
private static void BuildDistribution(SparseTwinIndex <float> ret, SparseArray <float> O, SparseArray <float> D, int oLength, float[] flows) { var retFlat = ret.GetFlatData(); var ratio = O.GetFlatData().Sum() / flows.Sum(); if (float.IsNaN(ratio) | float.IsInfinity(ratio)) { Parallel.For(0, retFlat.Length, delegate(int i) { var iOffset = i * oLength; var ith = retFlat[i]; for (int j = 0; j < oLength; j++) { ith[j] = (float.IsNaN(ratio) | float.IsInfinity(ratio)) ? 0f : flows[iOffset + j]; } }); return; } Parallel.For(0, retFlat.Length, delegate(int i) { var iOffset = i * oLength; var ith = retFlat[i]; for (int j = 0; j < oLength; j++) { ith[j] = flows[iOffset + j] * ratio; } }); }
public void Add(SparseTwinIndex <float> data) { var flatData = data.GetFlatData(); if (RaiseToE) { foreach (var entry in DataSource.Read()) { var o = data.GetFlatIndex(entry.O); var d = data.GetFlatIndex(entry.D); if (o >= 0 & d >= 0) { flatData[o][d] += (float)Math.Exp(entry.Data); } } } else { foreach (var entry in DataSource.Read()) { var o = data.GetFlatIndex(entry.O); var d = data.GetFlatIndex(entry.D); if (o >= 0 & d >= 0) { flatData[o][d] += entry.Data; } } } }
private void LoadData(IZone[] zones, SparseTwinIndex <float> ret) { for (int i = 0; i < this.SeriesSize; i++) { ReadFile(GetFileName(i), zones, ret.GetFlatData()); } }
private float[] ProcessLoadedData(SparseTwinIndex <float[]> loadedData, int types, int times) { var flatLoadedData = loadedData.GetFlatData(); var dataEntries = DataEntries = times * types; var zoneArray = Root.ZoneSystem.ZoneArray; var zones = zoneArray.GetFlatData(); NumberOfZones = zones.Length; var ret = new float[zones.Length * zones.Length * types * times]; Parallel.For(0, flatLoadedData.Length, i => { var flatI = zoneArray.GetFlatIndex(loadedData.GetSparseIndex(i)); for (int j = 0; j < flatLoadedData[i].Length; j++) { if (flatLoadedData[i][j] == null) { continue; } var flatJ = zoneArray.GetFlatIndex(loadedData.GetSparseIndex(i, j)); for (int k = 0; k < flatLoadedData[i][j].Length; k++) { ret[(flatI * zones.Length + flatJ) * dataEntries + k] = flatLoadedData[i][j][k]; } } }); return(ret); }
private void WriteData(SparseTwinIndex <float> data, int matrixNumber, string fileName) { var zoneNumbers = data.ValidIndexArray(); var flatData = data.GetFlatData(); var numberOfZones = zoneNumbers.Length; using (StreamWriter writer = new StreamWriter(fileName)) { // We need to know what the head should look like. writer.WriteLine("t matrices\r\nd matrix=mf{0}\r\na matrix=mf{0} name=drvtot default=incr descr=generated", matrixNumber); // Now that the header is in place we can start to generate all of the instructions StringBuilder[] builders = new StringBuilder[numberOfZones]; System.Threading.Tasks.Parallel.For(0, numberOfZones, delegate(int o) { var build = builders[o] = new StringBuilder(); var strBuilder = new StringBuilder(10); var convertedO = zoneNumbers[o]; for (int d = 0; d < numberOfZones; d++) { Controller.ToEmmeFloat(flatData[o][d], strBuilder); build.AppendFormat("{0,7:G}{1,7:G} {2}\r\n", convertedO, zoneNumbers[d], strBuilder); } }); for (int i = 0; i < numberOfZones; i++) { writer.Write(builders[i]); } } }
public void SaveMatrix(SparseTwinIndex <float> matrix, string fileName) { var dir = Path.GetDirectoryName(fileName); if (!String.IsNullOrWhiteSpace(dir)) { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } var zones = this.Root.ZoneSystem.ZoneArray.GetFlatData(); using (var writer = new BinaryWriter(File.Open(fileName, FileMode.Create))) { var data = matrix.GetFlatData(); for (int i = 0; i < data.Length; i++) { if (data[i] == null) { for (int j = 0; j < data.Length; j++) { writer.Write((float)0); } } else { SaveLine(data[i], writer); } } writer.Flush(); } }
private void InteractiveModeSplit(List <TreeData <float[][]> > ret, IZone[] zones, int flows, SparseTwinIndex <float> flow) { int soFar = 0; if (SaveUtilities.ContainsFileName()) { var dir = Path.Combine(SaveUtilities.GetFileName(), (ModeUtilitiesProcessed++).ToString()); Directory.CreateDirectory(dir); for (int i = 0; i < InteractiveUtilityTrees.Count; i++) { WriteModeSplit(InteractiveUtilityTrees[i], Root.Modes[i], dir); } } Parallel.For(0, zones.Length, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int o) { var flatFlows = flow.GetFlatData(); var utility = InteractiveUtilityTrees; for (int d = 0; d < zones.Length; d++) { var odFlow = flatFlows[o][d]; if (odFlow > 0) { //utility will have already been calculated ConvertToFlow(utility, zones, o, d, odFlow); SaveResults(utility, ret, o, d, zones.Length); } } Progress = ((Interlocked.Increment(ref soFar) / (float)zones.Length) / NumberOfInteractiveCategories) + (flows / (float)NumberOfInteractiveCategories); }); }
private bool AnyTripIntraDistrict(int districtNumber, IZone[] flatZones, SparseTwinIndex <float> matrix) { var flatData = matrix.GetFlatData(); var length = flatData.Length; for (int i = 0; i < length; i++) { if (flatZones[i].PlanningDistrict != districtNumber) { continue; } for (int j = 0; j < length; j++) { if (i == j) { continue; } if (flatZones[j].PlanningDistrict != districtNumber) { continue; } if (flatData[i][j] > 0) { return(true); } } } return(false); }
private SparseTwinIndex <float> CreateRelativeDifference <T>(SparseTwinIndex <float> runData, SparseTwinIndex <float> baseData, SparseArray <T> refernceArray, Func <IZone, int> getAgg) { var ret = refernceArray.CreateSquareTwinArray <float>(); var truth = refernceArray.CreateSquareTwinArray <float>(); var zones = Root.ZoneSystem.ZoneArray.GetFlatData(); var flatRun = runData.GetFlatData(); var flatBaseData = baseData.GetFlatData(); for (int i = 0; i < flatRun.Length; i++) { var oAgg = getAgg(zones[i]); for (int j = 0; j < flatRun[i].Length; j++) { var jAgg = getAgg(zones[j]); ret[oAgg, jAgg] += flatRun[i][j]; truth[oAgg, jAgg] += flatBaseData[i][j]; } } var factor = Sum(truth) / Sum(ret); var flatRetData = ret.GetFlatData(); var flatTruthData = truth.GetFlatData(); for (int i = 0; i < flatRetData.Length; i++) { for (int j = 0; j < flatRetData[i].Length; j++) { flatRetData[i][j] = (flatRetData[i][j] * factor) / flatTruthData[i][j]; } } return(ret); }
public SparseTwinIndex <float> ProcessFlow(SparseArray <float> O, SparseArray <float> D, int[] validIndexes, SparseArray <float> attractionStar = null) { int length = validIndexes.Length; Productions = O; Attractions = D; if (attractionStar == null) { AttractionsStar = D.CreateSimilarArray <float>(); } else { AttractionsStar = attractionStar; } FlowMatrix = Productions.CreateSquareTwinArray <float>(); if (Friction == null) { InitializeFriction(length); } var flatAttractionStar = AttractionsStar.GetFlatData(); float[] oldTotal = new float[flatAttractionStar.Length]; var flatAttractions = Attractions.GetFlatData(); for (int i = 0; i < length; i++) { flatAttractionStar[i] = 1f; oldTotal[i] = flatAttractions[i]; } int iteration = 0; float[] columnTotals = new float[length]; var balanced = false; do { if (ProgressCallback != null) { // this doesn't go to 100%, but that is alright since when we end, the progress // of the calling model should assume we hit 100% ProgressCallback(iteration / (float)MaxIterations); } Array.Clear(columnTotals, 0, columnTotals.Length); if (Vector.IsHardwareAccelerated) { VectorProcessFlow(columnTotals, FlowMatrix.GetFlatData()); } else { ProcessFlow(columnTotals); } balanced = Balance(columnTotals, oldTotal); } while((++iteration) < MaxIterations && !balanced); if (ProgressCallback != null) { ProgressCallback(1f); } return(FlowMatrix); }
private void AverageIntraDistrictTravelTimes(int districtNumber, IZone[] flatZones, SparseTwinIndex <float> matrix) { var flatData = matrix.GetFlatData(); var length = flatData.Length; var average = GetAverageIntraDistrictNonIntraZonalTravelTime(districtNumber, flatZones, flatData); // after we have the average apply it to the rest of the district's intra zonal trips for (int i = 0; i < length; i++) { if (flatZones[i].PlanningDistrict != districtNumber) { continue; } for (int j = 0; j < length; j++) { if (i == j) { continue; } if (flatZones[j].PlanningDistrict != districtNumber) { continue; } if (flatData[i][j] <= 0) { flatData[i][j] = average; } } } }
private ComputationResult Log(ComputationResult[] values) { if (values[0].IsValue) { return(new ComputationResult((float)Math.Log(values[0].LiteralValue))); } else if (values[0].IsVectorResult) { SparseArray <float> saveTo = values[0].Accumulator ? values[0].VectorData : values[0].VectorData.CreateSimilarArray <float>(); var source = values[0].VectorData.GetFlatData(); var flat = saveTo.GetFlatData(); VectorHelper.Log(flat, 0, source, 0, source.Length); return(new ComputationResult(saveTo, true)); } else { SparseTwinIndex <float> saveTo = values[0].Accumulator ? values[0].OdData : values[0].OdData.CreateSimilarArray <float>(); var source = values[0].OdData.GetFlatData(); var flat = saveTo.GetFlatData(); System.Threading.Tasks.Parallel.For(0, flat.Length, (int i) => { VectorHelper.Log(flat[i], 0, source[i], 0, source[i].Length); }); return(new ComputationResult(saveTo, true)); } }
public void LoadData() { SparseTwinIndex <float> first = GetMatrix(FirstMatrix, FirstDataSource); SparseTwinIndex <float> second = GetMatrix(SecondMatrix, SecondDataSource); SparseTwinIndex <float> ret = GetResultMatrix(first); var data = ret.GetFlatData(); var f = first.GetFlatData(); var s = second.GetFlatData(); if (VectorHelper.IsHardwareAccelerated) { for (int i = 0; i < data.Length; i++) { VectorHelper.Average(data[i], 0, f[i], 0, s[i], 0, data[i].Length); } } else { for (int i = 0; i < data.Length; i++) { for (int j = 0; j < data[i].Length; j++) { data[i][j] = (f[i][j] + s[i][j]) * 0.5f; } } } Data = ret; Loaded = true; }
private void UpdateData(SparseTwinIndex <float> ret, SparseArray <float> productions) { var flatProd = productions.GetFlatData(); var flatRet = ret.GetFlatData(); var numberOfZones = flatProd.Length; try { Parallel.For(0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int i) { var p = flatProd[i]; if (p == 0) { // if there is no production, clear out the data for (int j = 0; j < numberOfZones; j++) { flatRet[i][j] = 0; } return; } var sum = 0f; // Gather the sum of all of the destinations from this origin for (int j = 0; j < numberOfZones; j++) { sum += flatRet[i][j]; } // The rows should already be seeded however, if they are not // just return since all of the values are zero anyway if (sum == 0) { return; } // Calculate the new balance factor var factor = p / sum; // now that we have the new factor we update the demand for (int j = 0; j < numberOfZones; j++) { flatRet[i][j] *= factor; } }); } catch (AggregateException e) { if (e.InnerException is XTMFRuntimeException) { throw new XTMFRuntimeException(e.InnerException.Message); } else { throw new XTMFRuntimeException(e.InnerException.Message + "\r\n" + e.InnerException.StackTrace); } } }
private bool Balance(float[] columnTotals, float[] oldTotal) { bool balanced = true; var flatAttractions = Attractions.GetFlatData(); var flatFlows = FlowMatrix.GetFlatData(); var flatAttractionStar = AttractionsStar.GetFlatData(); int length = flatAttractions.Length; float ep = (float)Epsilon; if (VectorHelper.IsHardwareAccelerated) { VectorHelper.Divide(columnTotals, 0, flatAttractions, 0, columnTotals, 0, columnTotals.Length); VectorHelper.Multiply(flatAttractionStar, 0, flatAttractionStar, 0, columnTotals, 0, flatAttractionStar.Length); VectorHelper.ReplaceIfNotFinite(flatAttractionStar, 0, 1.0f, flatAttractionStar.Length); balanced = VectorHelper.AreBoundedBy(columnTotals, 0, 1.0f, ep, columnTotals.Length); } else { // profiling showed that this is actually faster without running in parallel for (int i = 0; i < flatAttractions.Length; i++) { if (flatAttractions[i] > 0) { var total = 1.0f / columnTotals[i]; if (!float.IsInfinity(total) & !float.IsNaN(total)) { var residual = (float)(flatAttractions[i] * total); if (Math.Abs(1 - residual) > ep) { balanced = false; } flatAttractionStar[i] *= residual; } else { flatAttractionStar[i] = 1.0f; } } } } return(balanced); }
/// <summary> /// Gets the row of data from the probabilities for the given household /// </summary> /// <param name="householdZone">The sparse space to retrieve</param> /// <param name="probabilities">The probability table</param> /// <returns>The row of data, null if it doesn't exist</returns> private float[] GetHouseholdRow(int householdZone, SparseTwinIndex <float> probabilities) { var index = probabilities.GetFlatIndex(householdZone); if (index < 0) { throw new XTMFRuntimeException(this, "In '" + Name + "' we were unable to find any data for a zone numbered '" + householdZone + "'. Please make sure that this zone actually exists."); } return(probabilities.GetFlatData()[index]); }
private double SumFlow(SparseTwinIndex <float> flow) { var flatFlow = flow.GetFlatData(); double localSum = 0f; for (int i = 0; i < flatFlow.Length; i++) { localSum += flatFlow[i].Sum(); } return(localSum); }
private void ApplyAverage(float[] map, float[][] flatRet, SparseTwinIndex <float> original) { var flatOrigin = original.GetFlatData(); Parallel.For(0, flatRet.Length, (int i) => { for (int j = 0; j < flatRet[i].Length; j++) { flatRet[i][j] = ComputeAverage(map, flatOrigin, i, j); } }); }
public void LoadData() { var firstRate = FirstRateToApply.AcquireResource<SparseTwinIndex<float>>(); var secondRate = SecondRateToApply.AcquireResource<SparseTwinIndex<float>>(); SparseTwinIndex<float> data = firstRate.CreateSimilarArray<float>(); var flatFirst = firstRate.GetFlatData(); var flatSecond = secondRate.GetFlatData(); var flat = data.GetFlatData(); for (int i = 0; i < flat.Length; i++) { VectorHelper.Divide(flat[i], 0, flatFirst[i], 0, flatSecond[i], 0, flat[i].Length); } Data = data; }
private void LoadCosts(SparseTwinIndex <float> data, INetworkData network) { var flatData = data.GetFlatData(); var time = TimeToLoad; for (int i = 0; i < flatData.Length; i++) { var row = flatData[i]; for (int j = 0; j < row.Length; j++) { row[j] = network.TravelCost(i, j, time); } } }
private void ProduceZoneData(float[][] diff, SparseTwinIndex <float> runData, SparseTwinIndex <float> baseData) { SparseTwinIndex <float> relativeDiff = CreateRelativeDifference(runData, baseData, Root.ZoneSystem.ZoneArray, (zone => zone.ZoneNumber)); if (ZoneValidationFile.ContainsFileName()) { WriteOut(Root.ZoneSystem.ZoneArray, diff, ZoneValidationFile.GetFileName(), (zone => zone.ZoneNumber)); } if (ZoneRelativeValidationFile.ContainsFileName()) { WriteOut(Root.ZoneSystem.ZoneArray, relativeDiff.GetFlatData(), ZoneRelativeValidationFile.GetFileName(), (zone => zone.ZoneNumber)); } }
private bool Balance(float[] columnTotals, float[] oldTotal) { bool balanced = true; var flatAttractions = Attractions.GetFlatData(); var flatFlows = FlowMatrix.GetFlatData(); var flatAttractionStar = AttractionsStar.GetFlatData(); int length = flatAttractions.Length; float ep = (float)Epsilon; VectorHelper.Divide(columnTotals, 0, flatAttractions, 0, columnTotals, 0, columnTotals.Length); VectorHelper.Multiply(flatAttractionStar, 0, flatAttractionStar, 0, columnTotals, 0, flatAttractionStar.Length); VectorHelper.ReplaceIfNotFinite(flatAttractionStar, 0, 1.0f, flatAttractionStar.Length); return(balanced = VectorHelper.AreBoundedBy(columnTotals, 0, 1.0f, ep, columnTotals.Length)); }
private void LoadInVehicleTimes(SparseTwinIndex <float> data, ITripComponentData network) { var flatData = data.GetFlatData(); var time = TimeToLoad; for (int i = 0; i < flatData.Length; i++) { var row = flatData[i]; for (int j = 0; j < row.Length; j++) { row[j] = network.InVehicleTravelTime(i, j, time).ToMinutes(); } } }
private void AddModeSplit(SparseTwinIndex <float> matrix) { if (Results == null) { InitializeResults(); } if (InterativeMode) { ProduceResultsForInteractive(matrix.GetFlatData()); } else { throw new XTMFRuntimeException(this, "Only Interactive mode is supported!"); } }
private static void TransposeMatrix(SparseTwinIndex <float> ret) { var flatData = ret.GetFlatData(); var length = flatData.Length; for (int i = 0; i < length; i++) { for (int j = 0; j < i; j++) { var temp = flatData[i][j]; flatData[i][j] = flatData[j][i]; flatData[j][i] = temp; } } }
public void LoadData() { SparseTwinIndex <float> first = ModuleHelper.GetDataFromDatasourceOrResource(FirstDataSource, FirstMatrix); SparseTwinIndex <float> second = ModuleHelper.GetDataFromDatasourceOrResource(SecondDataSource, SecondMatrix); SparseTwinIndex <float> ret = GetResultMatrix(first); var data = ret.GetFlatData(); var f = first.GetFlatData(); var s = second.GetFlatData(); for (int i = 0; i < data.Length; i++) { VectorHelper.Average(data[i], 0, f[i], 0, s[i], 0, data[i].Length); } Data = ret; Loaded = true; }
private void FillRatioIntraZonalTravelTime(int districtNumber, IZone[] flatZones, SparseTwinIndex <float> matrix, SparseArray <float> radius) { var validDistricts = radius.ValidIndexArray(); var flatRadius = radius.GetFlatData(); for (int otherDistrict = 0; otherDistrict < validDistricts.Length; otherDistrict++) { var sparseOther = radius.GetSparseIndex(otherDistrict); if (sparseOther == districtNumber) { continue; } if (this.AnyTripIntraDistrict(otherDistrict, flatZones, matrix)) { var distanceRatio = radius[districtNumber] / flatRadius[otherDistrict]; var data = matrix.GetFlatData(); var averageTT = GetAverageIntraDistrictNonIntraZonalTravelTime(sparseOther, flatZones, data); var averageIntraZonealTT = GetAverageIntraZonalTravelTime(sparseOther, flatZones, data); var zoneRatio = GetNumberOfZonesRatio(flatZones, districtNumber, sparseOther); averageTT *= distanceRatio * zoneRatio; averageIntraZonealTT *= distanceRatio * zoneRatio; for (int i = 0; i < flatZones.Length; i++) { if (flatZones[i].PlanningDistrict != districtNumber) { continue; } for (int j = 0; j < flatZones.Length; j++) { if (flatZones[j].PlanningDistrict != districtNumber) { continue; } if (i == j) { data[i][j] = averageIntraZonealTT; } else { data[i][j] = averageTT; } } } break; } } }
private void AverageDiagonals(int districtNumber, IZone[] flatZones, SparseTwinIndex<float> matrix) { var flatData = matrix.GetFlatData(); var length = flatData.Length; var average = GetAverageIntraZonalTravelTime( districtNumber, flatZones, flatData ); if ( average == 0 ) { // if the average is 0 then there were no trips for ( int i = 0; i < length; i++ ) { var otherPD = flatZones[i].PlanningDistrict; if ( otherPD != districtNumber ) { var otherAverage = GetAverageIntraZonalTravelTime( otherPD, flatZones, flatData ); if ( otherAverage != 0 ) { var ratio = this.GetNumberOfZonesRatio( flatZones, otherPD, districtNumber ); var radius = BuildDistrictRadius(); var distanceRatio = radius[districtNumber] / radius[otherPD]; average = otherAverage * distanceRatio * ratio; } } } } // after we have the average apply it to the rest of the district's intra zonal trips for ( int i = 0; i < length; i++ ) { if ( flatZones[i].PlanningDistrict != districtNumber ) continue; if ( flatData[i][i] <= 0 ) { flatData[i][i] = average; } } }
private void AverageIntraDistrictTravelTimes(int districtNumber, IZone[] flatZones, SparseTwinIndex<float> matrix) { var flatData = matrix.GetFlatData(); var length = flatData.Length; var average = GetAverageIntraDistrictNonIntraZonalTravelTime( districtNumber, flatZones, flatData ); // after we have the average apply it to the rest of the district's intra zonal trips for ( int i = 0; i < length; i++ ) { if ( flatZones[i].PlanningDistrict != districtNumber ) continue; for ( int j = 0; j < length; j++ ) { if ( i == j ) continue; if ( flatZones[j].PlanningDistrict != districtNumber ) continue; if ( flatData[i][j] <= 0 ) { flatData[i][j] = average; } } } }
public SparseTwinIndex<float> ProcessFlow(SparseArray<float> O, SparseArray<float> D, int[] validIndexes, SparseArray<float> attractionStar = null) { int length = validIndexes.Length; Productions = O; Attractions = D; if(attractionStar == null) { AttractionsStar = D.CreateSimilarArray<float>(); } else { AttractionsStar = attractionStar; } FlowMatrix = Productions.CreateSquareTwinArray<float>(); if(Friction == null) { InitializeFriction(length); } var flatAttractionStar = AttractionsStar.GetFlatData(); float[] oldTotal = new float[flatAttractionStar.Length]; var flatAttractions = Attractions.GetFlatData(); for(int i = 0; i < length; i++) { flatAttractionStar[i] = 1f; oldTotal[i] = flatAttractions[i]; } int iteration = 0; float[] columnTotals = new float[length]; var balanced = false; do { if(ProgressCallback != null) { // this doesn't go to 100%, but that is alright since when we end, the progress // of the calling model should assume we hit 100% ProgressCallback(iteration / (float)MaxIterations); } Array.Clear(columnTotals, 0, columnTotals.Length); if(Vector.IsHardwareAccelerated) { VectorProcessFlow(columnTotals, FlowMatrix.GetFlatData()); } else { ProcessFlow(columnTotals); } balanced = Balance(columnTotals, oldTotal); } while((++iteration) < MaxIterations && !balanced); if(ProgressCallback != null) { ProgressCallback(1f); } return FlowMatrix; }
private bool AnyTripIntraDistrict(int districtNumber, IZone[] flatZones, SparseTwinIndex<float> matrix) { var flatData = matrix.GetFlatData(); var length = flatData.Length; for ( int i = 0; i < length; i++ ) { if ( flatZones[i].PlanningDistrict != districtNumber ) continue; for ( int j = 0; j < length; j++ ) { if ( i == j ) continue; if ( flatZones[j].PlanningDistrict != districtNumber ) continue; if ( flatData[i][j] > 0 ) { return true; } } } return false; }
public void Add(SparseTwinIndex<float> data) { var flatData = data.GetFlatData(); if ( this.RaiseToE ) { foreach ( var entry in this.DataSource.Read() ) { var o = data.GetFlatIndex( entry.O ); var d = data.GetFlatIndex( entry.D ); if ( o >= 0 & d >= 0 ) { flatData[o][d] += (float)Math.Exp( entry.Data ); } } } else { foreach ( var entry in this.DataSource.Read() ) { var o = data.GetFlatIndex( entry.O ); var d = data.GetFlatIndex( entry.D ); if ( o >= 0 & d >= 0 ) { flatData[o][d] += (float)entry.Data; } } } }
private void InitializeFriction(int length) { Friction = Productions.CreateSquareTwinArray<float>(); var flatFriction = Friction.GetFlatData(); Parallel.For(0, length, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate (int i) { for(int j = 0; j < length; j++) { flatFriction[i][j] = (float)FrictionFunction(Productions.GetSparseIndex(i), Attractions.GetSparseIndex(j)); } }); }
private void Apply(SparseTwinIndex<float> ret, float[][] rates) { var zones = this.Root.ZoneSystem.ZoneArray.GetFlatData(); var data = ret.GetFlatData(); Parallel.For( 0, data.Length, (int i) => { var row = data[i]; var rateRow = rates[i]; if ( zones[i].RegionNumber == 0 ) { for ( int j = 0; j < row.Length; j++ ) { row[j] = zones[i].Population * rateRow[j]; } } else { for ( int j = 0; j < row.Length; j++ ) { row[j] = zones[j].Population * rateRow[j]; } } } ); }
private void Cull(SparseTwinIndex<float> tempValues, float[][] friction, float[] production, float[] attraction) { var flatValues = tempValues.GetFlatData(); var numberOfZones = flatValues.Length; var omax = new float[numberOfZones]; var dmax = new float[numberOfZones]; for ( int i = 0; i < flatValues.Length; i++ ) { for ( int j = 0; j < numberOfZones; j++ ) { if ( flatValues[i][j] >= omax[i] ) { omax[i] = flatValues[i][j]; } } for ( int j = 0; j < numberOfZones; j++ ) { if ( flatValues[j][i] >= dmax[i] ) { dmax[i] = flatValues[j][i]; } } } Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int i) { for ( int j = 0; j < numberOfZones; j++ ) { if ( TestCull( flatValues, i, j, omax, dmax, production, attraction ) ) { friction[i][j] = 0f; } } } ); }
private static void BuildDistribution(SparseTwinIndex<float> ret, SparseArray<float> O, SparseArray<float> D, int oLength, float[] flows) { var retFlat = ret.GetFlatData(); var ratio = O.GetFlatData().Sum() / flows.Sum(); if ( float.IsNaN( ratio ) | float.IsInfinity( ratio ) ) { Parallel.For( 0, retFlat.Length, delegate(int i) { var iOffset = i * oLength; var ith = retFlat[i]; for ( int j = 0; j < oLength; j++ ) { ith[j] = ( float.IsNaN( ratio ) | float.IsInfinity( ratio ) ) ? 0f : flows[iOffset + j]; } } ); return; } Parallel.For( 0, retFlat.Length, delegate(int i) { var iOffset = i * oLength; var ith = retFlat[i]; for ( int j = 0; j < oLength; j++ ) { ith[j] = flows[iOffset + j] * ratio; } } ); }
private void FillRatioIntraZonalTravelTime(int districtNumber, IZone[] flatZones, SparseTwinIndex<float> matrix, SparseArray<float> radius) { var validDistricts = radius.ValidIndexArray(); var flatRadius = radius.GetFlatData(); for ( int otherDistrict = 0; otherDistrict < validDistricts.Length; otherDistrict++ ) { var sparseOther = radius.GetSparseIndex( otherDistrict ); if ( sparseOther == districtNumber ) continue; if ( this.AnyTripIntraDistrict( otherDistrict, flatZones, matrix ) ) { var distanceRatio = radius[districtNumber] / flatRadius[otherDistrict]; var data = matrix.GetFlatData(); var averageTT = GetAverageIntraDistrictNonIntraZonalTravelTime( sparseOther, flatZones, data ); var averageIntraZonealTT = GetAverageIntraZonalTravelTime( sparseOther, flatZones, data ); var zoneRatio = GetNumberOfZonesRatio( flatZones, districtNumber, sparseOther ); averageTT *= distanceRatio * zoneRatio; averageIntraZonealTT *= distanceRatio * zoneRatio; for ( int i = 0; i < flatZones.Length; i++ ) { if ( flatZones[i].PlanningDistrict != districtNumber ) continue; for ( int j = 0; j < flatZones.Length; j++ ) { if ( flatZones[j].PlanningDistrict != districtNumber ) continue; if ( i == j ) { data[i][j] = averageIntraZonealTT; } else { data[i][j] = averageTT; } } } break; } } }
public void BuildMatrix() { //build the region constants var planningDistricts = TMG.Functions.ZoneSystemHelper.CreatePDArray<float>(Root.ZoneSystem.ZoneArray); var pdIndexes = planningDistricts.ValidIndexArray(); PlanningDistrictConstants = planningDistricts.CreateSquareTwinArray<float>(); var data = PlanningDistrictConstants.GetFlatData(); for(int i = 0; i < data.Length; i++) { for(int j = 0; j < data[i].Length; j++) { data[i][j] = GetPDConstant(pdIndexes[i], pdIndexes[j]); } } }
private void AddModeSplit(SparseTwinIndex<float> matrix) { if ( this.Results == null ) { InitializeResults(); } if ( this.InterativeMode ) { ProduceResultsForInteractive( matrix.GetFlatData() ); } else { throw new XTMFRuntimeException( "Only Interactive mode is supported!" ); } }
private float[] ProcessLoadedData(SparseTwinIndex<float[]> loadedData, int types, int times) { var flatLoadedData = loadedData.GetFlatData(); var dataEntries = this.DataEntries = times * types; var zoneArray = this.Root.ZoneSystem.ZoneArray; var zones = zoneArray.GetFlatData(); this.NumberOfZones = zones.Length; var ret = new float[zones.Length * zones.Length * types * times]; Parallel.For( 0, flatLoadedData.Length, (int i) => { var flatI = zoneArray.GetFlatIndex( loadedData.GetSparseIndex( i ) ); for ( int j = 0; j < flatLoadedData[i].Length; j++ ) { if ( flatLoadedData[i][j] == null ) continue; var flatJ = zoneArray.GetFlatIndex( loadedData.GetSparseIndex( i, j ) ); for ( int k = 0; k < flatLoadedData[i][j].Length; k++ ) { ret[( flatI * zones.Length + flatJ ) * dataEntries + k] = flatLoadedData[i][j][k]; } } } ); return ret; }
private double SumFlow(SparseTwinIndex<float> flow) { var flatFlow = flow.GetFlatData(); double localSum = 0f; for ( int i = 0; i < flatFlow.Length; i++ ) { localSum += flatFlow[i].Sum(); } return localSum; }
/// <summary> /// Assign workers to zones /// </summary> /// <param name="workplaceDistribution"></param> /// <param name="occupation"></param> private void AssignToWorkers(SparseTwinIndex<float> workplaceDistribution, IDemographicCategoryGeneration cat) { /* * -> For each zone * 1) Load the population * 2) Count the number of people * 3) Count the number of jobs for the zone * 4) Compute the ratio of people to jobs and Balance it by normalizing @ population level * 5) Shuffle the people to avoid bias * 6) Apply the random split algorithm from the Population Synthesis to finish it off */ var zoneIndexes = this.ZoneArray.ValidIndexies().ToArray(); var flatZones = this.ZoneArray.GetFlatData(); var numberOfZones = zoneIndexes.Length; var flatWorkplaceDistribution = workplaceDistribution.GetFlatData(); var flatPopulation = this.Root.Population.Population.GetFlatData(); try { Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate() { return new Assignment() { dist = this.ZoneArray.CreateSimilarArray<float>(), indexes = null }; }, delegate(int z, ParallelLoopState unused, Assignment assign) { var dist = assign.dist; var indexes = assign.indexes; var flatDist = dist.GetFlatData(); var distributionForZone = flatWorkplaceDistribution[z]; Random rand = new Random( ( this.RandomSeed * z ) * ( this.CurrentOccupationIndex * numberOfZones ) ); IZone zoneI = flatZones[z]; var zonePop = flatPopulation[z]; int popLength = zonePop.Length; if ( indexes == null || indexes.Length < popLength ) { indexes = new int[(int)( popLength * 1.5 )]; assign.indexes = indexes; } int totalPeopleInCat = 0; // 1+2) learn who is qualified for this distribution for ( int i = 0; i < popLength; i++ ) { var person = zonePop[i]; if ( cat.IsContained( person ) ) { indexes[totalPeopleInCat] = i; totalPeopleInCat++; } } // 3) Count how many jobs are expected to come from this zone double totalJobsFromThisOrigin = 0; for ( int i = 0; i < numberOfZones; i++ ) { totalJobsFromThisOrigin += ( flatDist[i] = distributionForZone[i] ); } if ( totalJobsFromThisOrigin == 0 ) { return assign; } // 4) Calculate the ratio of people who work to the number of jobs so we can balance it again float normalizationFactor = 1 / (float)totalJobsFromThisOrigin; for ( int i = 0; i < numberOfZones; i++ ) { flatDist[i] = flatDist[i] * normalizationFactor; } // 5) card sort algo for ( int i = totalPeopleInCat - 1; i > 0; i-- ) { var swapIndex = rand.Next( i ); var temp = indexes[i]; indexes[i] = indexes[swapIndex]; indexes[swapIndex] = temp; } // 6) Apply the random split algorithm from the Population Synthesis to finish it off var flatResult = this.SplitAndClear( totalPeopleInCat, dist, rand ); int offset = 0; for ( int i = 0; i < numberOfZones; i++ ) { var ammount = flatResult[i]; for ( int j = 0; j < ammount; j++ ) { if ( offset + j >= indexes.Length || indexes[offset + j] > zonePop.Length ) { throw new XTMFRuntimeException( "We tried to assign to a person that does not exist!" ); } zonePop[indexes[offset + j]].WorkZone = flatZones[i]; } offset += ammount; } return assign; }, delegate(Assignment unused) { } ); } catch ( AggregateException e ) { throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace ); } }
private void InteractiveModeSplit(int numberOfCategories, List<TreeData<float[][]>> ret, IZone[] zones, int flows, SparseTwinIndex<float> flow) { int soFar = 0; if ( this.SaveUtilities.ContainsFileName() ) { var dir = Path.Combine( this.SaveUtilities.GetFileName(), ( ModeUtilitiesProcessed++ ).ToString() ); Directory.CreateDirectory( dir ); for ( int i = 0; i < this.InteractiveUtilityTrees.Count; i++ ) { WriteModeSplit( this.InteractiveUtilityTrees[i], this.Root.Modes[i], dir ); } } Parallel.For( 0, zones.Length, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int o) { var flatFlows = flow.GetFlatData(); var utility = this.InteractiveUtilityTrees; var numberOfZones = zones.Length; for ( int d = 0; d < zones.Length; d++ ) { var odFlow = flatFlows[o][d]; if ( odFlow > 0 ) { //utility will have already been calculated ConvertToFlow( utility, zones, o, d, odFlow ); SaveResults( utility, ret, o, d, zones.Length ); } } this.Progress = ( ( Interlocked.Increment( ref soFar ) / (float)zones.Length ) / this.NumberOfInteractiveCategories ) + ( flows / (float)this.NumberOfInteractiveCategories ); } ); }
private void SaveDistribution(SparseTwinIndex<float> sparseRet, IZone[] zone, int index) { this.SaveDistributionSeries.SaveMatrix( sparseRet.GetFlatData() ); }
public void IterationStarting(int iterationNumber, int maxIterations) { //build the region constants var regions = TMG.Functions.ZoneSystemHelper.CreateRegionArray<float>(Root.ZoneSystem.ZoneArray); var regionIndexes = regions.ValidIndexArray(); RegionConstants = regions.CreateSquareTwinArray<float>(); var data = RegionConstants.GetFlatData(); for(int i = 0; i < data.Length; i++) { for(int j = 0; j < data[i].Length; j++) { data[i][j] = GetRegionConstant(regionIndexes[i], regionIndexes[j]); } } foreach(var timePeriod in TimePeriodConstants) { timePeriod.BuildMatrix(); } }
private void TraditionalModeSplit(int numberOfCategories, List<TreeData<float[][]>> ret, IZone[] zones, int flows, SparseTwinIndex<float> flow) { try { int soFar = 0; Parallel.For( 0, zones.Length, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate() { return MirrorModeTree.CreateMirroredTree<float>( this.Root.Modes ); }, delegate(int o, ParallelLoopState _unused, List<TreeData<float>> utility) { var flatFlows = flow.GetFlatData(); for ( int d = 0; d < zones.Length; d++ ) { var odFlow = flatFlows[o][d]; if ( odFlow > 0 ) { GatherUtility( utility, o, d, zones ); ConvertToFlow( utility, zones, o, d, odFlow ); SaveResults( utility, ret, o, d, zones.Length ); } } this.Progress = ( ( Interlocked.Increment( ref soFar ) / (float)zones.Length ) / numberOfCategories ) + ( flows / (float)numberOfCategories ); return utility; }, delegate(List<TreeData<float>> _unused) { // do nothing } ); } catch ( AggregateException e ) { throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace ); } }
public static void SaveMatrix(SparseTwinIndex<float> matrix, string fileName) { var zones = matrix.ValidIndexArray(); var data = matrix.GetFlatData(); StringBuilder header = null; StringBuilder[] zoneLines = new StringBuilder[zones.Length]; Parallel.Invoke( () => { var dir = Path.GetDirectoryName(fileName); if (!String.IsNullOrWhiteSpace(dir)) { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } }, () => { header = new StringBuilder(); header.Append("Zones O\\D"); for (int i = 0; i < zones.Length; i++) { header.Append(','); header.Append(zones[i]); } }, () => { Parallel.For(0, zones.Length, (int i) => { zoneLines[i] = new StringBuilder(); zoneLines[i].Append(zones[i]); var row = data[i]; if (row == null) { for (int j = 0; j < zones.Length; j++) { zoneLines[i].Append(','); zoneLines[i].Append('0'); } } else { for (int j = 0; j < zones.Length; j++) { zoneLines[i].Append(','); zoneLines[i].Append(row[j]); } } }); }); using (StreamWriter writer = new StreamWriter(fileName)) { writer.WriteLine(header); for (int i = 0; i < zoneLines.Length; i++) { writer.WriteLine(zoneLines[i]); } } }
/// <summary> /// Take the log of each data point in the matrix. /// </summary> /// <param name="data">The data source to do the log on.</param> private static void LogTheMatrix(SparseTwinIndex<float> data) { var flatData = data.GetFlatData(); Parallel.For( 0, flatData.Length, (int i) => { var row = flatData[i]; if ( row == null ) return; for ( int j = 0; j < row.Length; j++ ) { row[j] = (float)Math.Log( row[j] ); } } ); }
private static void TransposeMatrix(SparseTwinIndex<float> ret) { var flatData = ret.GetFlatData(); var length = flatData.Length; for ( int i = 0; i < length; i++ ) { for ( int j = 0; j < i; j++ ) { var temp = flatData[i][j]; flatData[i][j] = flatData[j][i]; flatData[j][i] = temp; } } }
private void WriteData(SparseTwinIndex<float> data, int matrixNumber, string fileName) { var zoneNumbers = data.ValidIndexArray(); var flatData = data.GetFlatData(); var numberOfZones = zoneNumbers.Length; using ( StreamWriter writer = new StreamWriter( fileName ) ) { // We need to know what the head should look like. writer.WriteLine( "t matrices\r\nd matrix=mf{0}\r\na matrix=mf{0} name=drvtot default=incr descr=generated", matrixNumber ); // Now that the header is in place we can start to generate all of the instructions StringBuilder[] builders = new StringBuilder[numberOfZones]; System.Threading.Tasks.Parallel.For( 0, numberOfZones, delegate(int o) { var build = builders[o] = new StringBuilder(); var strBuilder = new StringBuilder( 10 ); var convertedO = zoneNumbers[o]; for ( int d = 0; d < numberOfZones; d++ ) { this.ToEmmeFloat( flatData[o][d], strBuilder ); build.AppendFormat( "{0,7:G}{1,7:G} {2,9:G}\r\n", convertedO, zoneNumbers[d], strBuilder ); } } ); for ( int i = 0; i < numberOfZones; i++ ) { writer.Write( builders[i] ); } } }