Exemple #1
0
        private static void SetupFrictionData(List <SparseArray <float> > productions, List <SparseArray <float> > attractions,
                                              List <IDemographicCategory> cats, MultiBlendSet multiset, float[][][] productionSet, float[][][] attractionSet,
                                              IDemographicCategory[][] multiCatSet)
        {
            int subsetIndex = -1;

            foreach (var blendSet in multiset.Subsets)
            {
                subsetIndex++;
                var set           = blendSet.Set;
                var length        = set.Count;
                int place         = 0;
                int blendSetCount = 0;
                for (int i = 0; i < length; i++)
                {
                    for (int pos = set[i].Start; pos <= set[i].Stop; pos++)
                    {
                        blendSetCount++;
                    }
                }
                productionSet[subsetIndex] = new float[blendSetCount][];
                attractionSet[subsetIndex] = new float[blendSetCount][];
                multiCatSet[subsetIndex]   = new IDemographicCategory[blendSetCount];
                for (int i = 0; i < length; i++)
                {
                    for (int pos = set[i].Start; pos <= set[i].Stop; pos++)
                    {
                        productionSet[subsetIndex][place] = productions[pos].GetFlatData();
                        attractionSet[subsetIndex][place] = attractions[pos].GetFlatData();
                        multiCatSet[subsetIndex][place]   = cats[pos];
                        place++;
                    }
                }
            }
        }
Exemple #2
0
 public IEnumerable <SparseTwinIndex <float> > Distribute(IEnumerable <SparseArray <float> > production,
                                                          IEnumerable <SparseArray <float> > attraction, IEnumerable <IDemographicCategory> category)
 {
     Progress = 0f;
     using (var ep = production.GetEnumerator())
         using (var ea = attraction.GetEnumerator())
             using (var eCat = category.GetEnumerator())
             {
                 var zones = Root.ZoneSystem.ZoneArray;
                 if (String.IsNullOrWhiteSpace(LoadFrictionFileName))
                 {
                     if (BaseData.Count != MultiBlendSets.Count)
                     {
                         throw new XTMFRuntimeException(this, "In " + Name +
                                                        " the number of BaseData entries is not the same as the number of Blend Sets!");
                     }
                 }
                 var productions = new List <SparseArray <float> >();
                 var attractions = new List <SparseArray <float> >();
                 var cats        = new List <IDemographicCategory>();
                 // We need to pre-load all of our generations in order to handle blending properly
                 while (ep.MoveNext() && ea.MoveNext() && eCat.MoveNext())
                 {
                     productions.Add(ep.Current);
                     attractions.Add(ea.Current);
                     cats.Add(eCat.Current);
                 }
                 int     setNumber = -1;
                 var     ret       = zones.CreateSquareTwinArray <float>();
                 float[] p         = new float[zones.GetFlatData().Length];
                 CountTotalBlendSets();
                 foreach (var multiset in MultiBlendSets)
                 {
                     setNumber++;
                     var numberOfBlendSets = multiset.Subsets.Count;
                     var productionSet     = new float[numberOfBlendSets][][];
                     var attractionSet     = new float[numberOfBlendSets][][];
                     var catSet            = new IDemographicCategory[numberOfBlendSets][];
                     SetupFrictionData(productions, attractions, cats, multiset, productionSet, attractionSet, catSet);
                     for (int subsetIndex = 0; subsetIndex < multiset.Subsets.Count; subsetIndex++)
                     {
                         SumProductionAndAttraction(p, productionSet[subsetIndex]);
                         bool loadedFriction = false;
                         // use the base data if we don't load in the friction base data
                         if (String.IsNullOrWhiteSpace(LoadFrictionFileName))
                         {
                             LoadInBaseData(ret, BaseData[setNumber]);
                         }
                         else
                         {
                             LoadFriction(ret.GetFlatData(), setNumber);
                             loadedFriction = true;
                         }
                         UpdateData(ret.GetFlatData(), p, catSet, productionSet, attractionSet, zones.GetFlatData(),
                                    subsetIndex, loadedFriction);
                         yield return(ret);
                     }
                 }
             }
 }
        private float[][] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[][] friction)
        {
            var numberOfZones = zones.Length;
            var rootModes     = Root.Modes;
            var numberOfModes = rootModes.Count;

            // initialize the category so we can compute the friction
            cat.InitializeDemographicCategory();
            Parallel.For(0, numberOfZones, delegate(int i)
            {
                var origin = zones[i];
                for (int j = 0; j < numberOfZones; j++)
                {
                    double logsum = 0f;
                    for (int mIndex = 0; mIndex < numberOfModes; mIndex++)
                    {
                        var mode = rootModes[mIndex];
                        if (!mode.Feasible(origin, zones[j], SimulationTime))
                        {
                            continue;
                        }
                        var inc = mode.CalculateV(origin, zones[j], SimulationTime);
                        if (float.IsNaN(inc))
                        {
                            continue;
                        }
                        logsum += Math.Exp(inc);
                    }
                    friction[i][j] = (float)Math.Pow(logsum, Beta);
                }
            });
            // Use the Log-Sum from the V's as the impedance function
            return(friction);
        }
Exemple #4
0
        private void ComputeFriction(IZone[] zones, IDemographicCategory cat, float[][] friction)
        {
            var numberOfZones = zones.Length;
            var rootModes     = this.Root.Modes;
            var numberOfModes = rootModes.Count;

            // let it setup the modes so we can compute friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For(0, numberOfZones, new ParallelOptions()
                {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                }, delegate(int i)
                {
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        var destination = zones[j];
                        float utility;
                        if (!this.GatherAllUtility(zones[i], zones[j], out utility))
                        {
                            throw new XTMFRuntimeException("There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber);
                        }
                        else
                        {
                            friction[i][j] = (float)Math.Pow(utility, this.ImpedianceParameter) * (this.KFactor != null ? (float)Math.Exp(this.KFactor[i * this.NumberOfZones + j]) : 1f);
                        }
                    }
                });
            }
            catch (AggregateException e)
            {
                throw e.InnerException;
            }
        }
        private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] friction)
        {
            var numberOfZones = zones.Length;

            float[] ret            = friction == null ? new float[numberOfZones * numberOfZones] : friction;
            var     rootModes      = this.Root.Modes;
            var     numberOfModes  = rootModes.Count;
            var     minFrictionInc = (float)Math.Exp(-10);

            // initialize the category so we can compute the friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For(0, numberOfZones, delegate(int i)
                {
                    int index  = i * numberOfZones;
                    var origin = zones[i];
                    int vIndex = i * numberOfZones * numberOfModes;
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        double logsum     = 0f;
                        var destination   = zones[j];
                        int feasibleModes = 0;
                        for (int mIndex = 0; mIndex < numberOfModes; mIndex++)
                        {
                            var mode = rootModes[mIndex];
                            if (!mode.Feasible(origin, zones[j], this.SimulationTime))
                            {
                                vIndex++;
                                continue;
                            }
                            feasibleModes++;
                            var inc = mode.CalculateV(origin, zones[j], this.SimulationTime);
                            if (float.IsNaN(inc))
                            {
                                continue;
                            }
                            logsum += Math.Exp(inc);
                        }
                        ret[index++] = (float)Math.Pow(logsum, this.Beta);
                    }
                });
            }
            catch (AggregateException e)
            {
                if (e.InnerException is XTMFRuntimeException)
                {
                    throw e.InnerException;
                }
                else
                {
                    throw new XTMFRuntimeException(e.InnerException.Message + "\r\n" + e.InnerException.StackTrace);
                }
            }

            // Use the Log-Sum from the V's as the impedence function
            return(ret);
        }
Exemple #6
0
        private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] friction)
        {
            var numberOfZones = zones.Length;

            float[] ret = friction ?? (new float[numberOfZones * numberOfZones]);
            // let it setup the modes so we can compute friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For(0, numberOfZones, new ParallelOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                }, delegate(int j)
                {
                    var destination = zones[j];
                    if (!InverseLookup(destination.RegionNumber, out int regionIndex))
                    {
                        // make sure to reset the friction to zero
                        for (int i = 0; i < numberOfZones; i++)
                        {
                            ret[i * numberOfZones + j] = float.NegativeInfinity;
                        }
                        return;
                    }
                    // store the log of the population and the employment since we will be using this for each origin
                    var employmentLog = (float)Math.Log((destination.Employment - destination.ManufacturingEmployment) + 1);
                    var populationLog = (float)Math.Log(destination.Population + 1);
                    for (int i = 0; i < numberOfZones; i++)
                    {
                        var origin = zones[i];
                        if (origin.RegionNumber <= 0)
                        {
                            ret[i * numberOfZones + j] = float.NegativeInfinity;
                        }
                        else
                        {
                            var autoTime = RegionEmploymentGeneralParameter[regionIndex] *
                                           NetworkData.TravelTime(origin, destination, SimulationTime).ToMinutes();
                            var destinationUtility = RegionEmploymentParameter[regionIndex] * employmentLog
                                                     + RegionPopulationParameter[regionIndex] * populationLog;
                            // this isn't friction, it is V where friction will be e^V
                            ret[i * numberOfZones + j] = destinationUtility + autoTime;
                        }
                    }
                });
            }
            catch (AggregateException e)
            {
                if (e.InnerException is XTMFRuntimeException)
                {
                    throw new XTMFRuntimeException(this, e.InnerException.Message);
                }
                throw new XTMFRuntimeException(this, e.InnerException?.Message + "\r\n" + e.InnerException?.StackTrace);
            }
            // Use the Log-Sum from the V's as the impedence function
            return(ret);
        }
Exemple #7
0
        private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] production, float[] attraction, float[] friction)
        {
            var numberOfZones = zones.Length;

            float[] ret = friction ?? (new float[numberOfZones * numberOfZones]);
            // let it setup the modes so we can compute friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For(0, numberOfZones, new ParallelOptions {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                }, delegate(int i)
                {
                    int index = i * numberOfZones;
                    if (production[i] == 0)
                    {
                        for (int j = 0; j < numberOfZones; j++)
                        {
                            ret[index++] = 0;
                        }
                        return;
                    }
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        if (attraction != null && attraction[j] == 0)
                        {
                            ret[index++] = 0;
                        }
                        else
                        {
                            if (!GatherAllUtility(zones[i], zones[j], out float utility))
                            {
                                ret[index++] = 0;
                                //throw new XTMFRuntimeException( "There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber );
                            }
                            else
                            {
                                ret[index++] = (float)Math.Pow(utility, ImpedianceParameter) * (KFactor != null ? (float)Math.Exp(KFactor[i * NumberOfZones + j]) : 1f);
                            }
                        }
                    }
                });
            }
            catch (AggregateException e)
            {
                if (e.InnerException is XTMFRuntimeException)
                {
                    throw new XTMFRuntimeException(this, e.InnerException.Message);
                }
                throw new XTMFRuntimeException(this, e.InnerException?.Message + "\r\n" + e.InnerException?.StackTrace);
            }
            // Use the Log-Sum from the V's as the impedence function
            return(ret);
        }
Exemple #8
0
        private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] friction)
        {
            var numberOfZones = zones.Length;

            float[] ret           = friction == null ? new float[numberOfZones * numberOfZones] : friction;
            var     rootModes     = this.Root.Modes;
            var     numberOfModes = rootModes.Count;

            // let it setup the modes so we can compute friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For(0, numberOfZones, new ParallelOptions()
                {
                    MaxDegreeOfParallelism = Environment.ProcessorCount
                }, delegate(int i)
                {
                    int index  = i * numberOfZones;
                    var origin = zones[i];
                    int vIndex = i * numberOfZones * numberOfModes;
                    int regionIndex;
                    if (!InverseLookup(zones[i].RegionNumber, out regionIndex))
                    {
                        for (int j = 0; j < numberOfZones; j++)
                        {
                            ret[index++] = 0;
                        }
                        return;
                    }
                    for (int j = 0; j < numberOfZones; j++)
                    {
                        var destination = zones[j];
                        var autoTime    = this.NetworkData.TravelTime(origin, destination, this.SimulationTime);
                        var population  = destination.Population;
                        ret[index++]    = (float)(this.RegionAutoParameter[regionIndex] * autoTime.ToMinutes()
                                                  // population
                                                  + this.RegionPopulationParameter[regionIndex] * Math.Log(population + 1)
                                                  // employment
                                                  + this.RegionEmploymentProfessionalParameter[regionIndex] * Math.Log(destination.ProfessionalEmployment + 1)
                                                  + this.RegionEmploymentGeneralParameter[regionIndex] * Math.Log(destination.GeneralEmployment + 1)
                                                  + this.RegionEmploymentSalesParameter[regionIndex] * Math.Log(destination.RetailEmployment + 1)
                                                  + this.RegionEmploymentManufacturingParameter[regionIndex] * Math.Log(destination.ManufacturingEmployment + 1));
                    }
                });
            }
            catch (AggregateException e)
            {
                throw e.InnerException;
            }
            // Use the Log-Sum from the V's as the impedence function
            return(ret);
        }
        private IEnumerable <SparseTwinIndex <float> > CPUDoublyConstrained(IZone[] zones, IEnumerator <SparseArray <float> > ep, IEnumerator <SparseArray <float> > ea, IEnumerator <IDemographicCategory> ec)
        {
            float completed      = 0f;
            var   frictionSparse = this.Root.ZoneSystem.ZoneArray.CreateSquareTwinArray <float>();
            var   productions    = new List <SparseArray <float> >();
            var   attractions    = new List <SparseArray <float> >();
            var   cats           = new List <IDemographicCategory>();

            // We need to pre load all of our generations in order to handle blending properly
            while (ep.MoveNext() & ea.MoveNext() & ec.MoveNext())
            {
                productions.Add(ep.Current);
                attractions.Add(ea.Current);
                cats.Add(ec.Current);
            }
            var ret = this.Root.ZoneSystem.ZoneArray.CreateSquareTwinArray <float>();
            SparseArray <float> production = this.Root.ZoneSystem.ZoneArray.CreateSimilarArray <float>();
            SparseArray <float> attraction = this.Root.ZoneSystem.ZoneArray.CreateSimilarArray <float>();

            this.CurrentMultiSetIndex = -1;
            foreach (var multiset in this.MultiBlendSets)
            {
                this.CurrentMultiSetIndex++;
                var numberOfSubsets = multiset.Subsets.Count;
                var productionSet   = new float[numberOfSubsets][][];
                var attractionSet   = new float[numberOfSubsets][][];
                var multiCatSet     = new IDemographicCategory[numberOfSubsets][];
                SetupFrictionData(productions, attractions, cats, multiset, productionSet, attractionSet, multiCatSet);
                this.ComputeFriction(zones, multiCatSet, productionSet, attractionSet,
                                     frictionSparse.GetFlatData(), production.GetFlatData(), attraction.GetFlatData());
                string balanceFileName;
                SparseArray <float> balanceFactors = GetWarmBalancingFactors(attraction, out balanceFileName);
                if (this.CullSmallValues)
                {
                    var tempValues = new GravityModel(frictionSparse, null, this.Epsilon, this.MaxIterations)
                                     .ProcessFlow(production, attraction, production.ValidIndexArray(), balanceFactors);
                    this.Cull(tempValues, frictionSparse.GetFlatData(), production.GetFlatData(), attraction.GetFlatData());
                    if (!String.IsNullOrWhiteSpace(this.SaveFrictionFileName))
                    {
                        this.SaveFriction(frictionSparse.GetFlatData());
                    }
                }
                yield return(new GravityModel(frictionSparse, (p => this.Progress = (p * (1f / (this.MultiBlendSets.Count)) + (completed / (this.MultiBlendSets.Count)))), this.Epsilon, this.MaxIterations)
                             .ProcessFlow(production, attraction, production.ValidIndexArray(), balanceFactors));

                if (balanceFileName != null)
                {
                    SaveBalanceFactors(balanceFileName, balanceFactors);
                }
                completed += 1f;
            }
        }
Exemple #10
0
        private void ComputeFriction(IZone[] zones, IDemographicCategory cat, float[][] friction)
        {
            var numberOfZones = zones.Length;

            // let it setup the modes so we can compute friction
            cat.InitializeDemographicCategory();
            Parallel.For(0, numberOfZones, new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            }, delegate(int i)
            {
                for (int j = 0; j < numberOfZones; j++)
                {
                    if (!GatherAllUtility(zones[i], zones[j], out float utility))
                    {
                        throw new XTMFRuntimeException(this, "There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber);
                    }
                    friction[i][j] = (float)Math.Pow(utility, ImpedianceParameter) * (KFactor != null ? (float)Math.Exp(KFactor[i * NumberOfZones + j]) : 1f);
                }
            });
        }
        public IEnumerable <SparseTwinIndex <float> > Distribute(IEnumerable <SparseArray <float> > eps, IEnumerable <SparseArray <float> > eas, IEnumerable <IDemographicCategory> ecs)
        {
            float[] friction    = null;
            var     zones       = Root.ZoneSystem.ZoneArray.GetFlatData();
            var     productions = new List <SparseArray <float> >();
            var     cats        = new List <IDemographicCategory>();

            using (var ep = eps.GetEnumerator())
                using (var ec = ecs.GetEnumerator())
                {
                    while (ep.MoveNext() && ec.MoveNext())
                    {
                        productions.Add(ep.Current);
                        cats.Add(ec.Current);
                    }
                }
            SparseArray <float> production = Root.ZoneSystem.ZoneArray.CreateSimilarArray <float>();

            TotalBlendSets = 0;
            for (int i = 0; i < BlendSets.Count; i++)
            {
                TotalBlendSets += BlendSets[i].Subsets.Count;
            }
            foreach (var multiset in BlendSets)
            {
                var setLength     = multiset.Subsets.Count;
                var productionSet = new float[setLength][][];
                var catSet        = new IDemographicCategory[setLength][];
                SetupFrictionData(productions, cats, multiset, productionSet, catSet);
                for (int subIndex = 0; subIndex < multiset.Subsets.Count; subIndex++)
                {
                    friction = ComputeFriction(zones, catSet, productionSet, friction, production.GetFlatData(), subIndex);
                    var ret = SinglyConstrainedGravityModel.Process(production, friction);
                    if (Transpose)
                    {
                        TransposeMatrix(ret);
                    }
                    yield return(ret);
                }
            }
        }
 public IEnumerable<SparseTwinIndex<float>> Distribute(IEnumerable<SparseArray<float>> production, IEnumerable<SparseArray<float>> attraction, IEnumerable<IDemographicCategory> category)
 {
     this.Progress = 0f;
     var ep = production.GetEnumerator();
     var ea = attraction.GetEnumerator();
     var eBaseData = this.BaseData.GetEnumerator();
     var eCat = category.GetEnumerator();
     var zones = this.Root.ZoneSystem.ZoneArray;
     if ( String.IsNullOrWhiteSpace( this.LoadFrictionFileName ) )
     {
         if ( BaseData.Count != this.MultiBlendSets.Count )
         {
             throw new XTMFRuntimeException( "In " + this.Name + " the number of BaseData entries is not the same as the number of Blend Sets!" );
         }
     }
     var productions = new List<SparseArray<float>>();
     var attractions = new List<SparseArray<float>>();
     var cats = new List<IDemographicCategory>();
     // We need to pre-load all of our generations in order to handle blending properly
     while ( ep.MoveNext() && ea.MoveNext() && eCat.MoveNext() )
     {
         productions.Add( ep.Current );
         attractions.Add( ea.Current );
         cats.Add( eCat.Current );
     }
     int setNumber = -1;
     var ret = zones.CreateSquareTwinArray<float>();
     float[] p = new float[zones.GetFlatData().Length];
     CountTotalBlendSets();
     foreach ( var multiset in this.MultiBlendSets )
     {
         setNumber++;
         var numberOfBlendSets = multiset.Subsets.Count;
         var productionSet = new float[numberOfBlendSets][][];
         var attractionSet = new float[numberOfBlendSets][][];
         var catSet = new IDemographicCategory[numberOfBlendSets][];
         SetupFrictionData( productions, attractions, cats, multiset, productionSet, attractionSet, catSet );
         for ( int subsetIndex = 0; subsetIndex < multiset.Subsets.Count; subsetIndex++ )
         {
             SumProductionAndAttraction( p, productionSet[subsetIndex] );
             bool loadedFriction = false;
             // use the base data if we don't load in the friction base data
             if ( String.IsNullOrWhiteSpace( this.LoadFrictionFileName ) )
             {
                 LoadInBaseData( ret, this.BaseData[setNumber] );
             }
             else
             {
                 LoadFriction( ret.GetFlatData(), setNumber );
                 loadedFriction = true;
             }
             UpdateData( ret.GetFlatData(), p, catSet, productionSet, attractionSet, zones.GetFlatData(), subsetIndex, loadedFriction );
             if ( this.Transpose )
             {
                 TransposeMatrix( ret );
                 if ( !String.IsNullOrWhiteSpace( this.SaveFrictionFileName ) )
                 {
                     this.SaveFriction( ret.GetFlatData() );
                 }
             }
             yield return ret;
         }
     }
 }
 private void UpdateData(float[][] flatRet, float[] flatProd, IDemographicCategory[][] cats, float[][][] productions, float[][][] attractions, IZone[] zones, int subset, bool loadedFriction)
 {
     var numberOfZones = flatProd.Length;
     this.InteractiveModeSplit.StartNewInteractiveModeSplit( this.TotalBlendSets );
     var mpd = this.Root.ModeParameterDatabase;
     float[] subsetRatios = new float[productions.Length];
     float[] ratio = new float[cats[subset].Length];
     for ( int i = 0; i < numberOfZones; i++ )
     {
         var p = flatProd[i];
         var factor = 0f;
         if ( p == 0 )
         {
             // if there is no production, clear out everything
             for ( int j = 0; j < numberOfZones; j++ )
             {
                 flatRet[i][j] = 0f;
             }
             continue;
         }
         if ( this.UseProductionPercentages )
         {
             var totalProduction = 0f;
             factor = 0f;
             for ( int j = 0; j < attractions[subset].Length; j++ )
             {
                 totalProduction += productions[subset][j][i];
             }
             if ( totalProduction <= 0 )
             {
                 for ( int j = 0; j < numberOfZones; j++ )
                 {
                     flatRet[i][j] = 0f;
                 }
                 continue;
             }
             // compute how much each one contributes to the total
             // then sum it all up into our final factor
             for ( int j = 0; j < productions[subset].Length; j++ )
             {
                 ratio[j] = productions[subset][j][i] / totalProduction;
                 factor += productions[subset][j][i];
             }
             float retTotal = 0;
             for ( int j = 0; j < flatRet[i].Length; j++ )
             {
                 retTotal += flatRet[i][j];
             }
             factor = factor / retTotal;
             // in this case we use the attraction since that is where the people
             // are actually stored in this case
             ComputeSubsetRatios( i, subsetRatios, attractions );
             if ( factor <= 0f )
             {
                 for ( int j = 0; j < numberOfZones; j++ )
                 {
                     flatRet[i][j] = 0f;
                 }
                 continue;
             }
             // we actually still need to operate on the friction since it will be in totals
             loadedFriction = false;
         }
         else
         {
             var sum = 0f;
             var retRow = flatRet[i];
             // Gather the sum of all of the destinations from this origin
             for ( int j = 0; j < numberOfZones; j++ )
             {
                 sum += retRow[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 )
             {
                 throw new XTMFRuntimeException( "In '" + this.Name + "' there was no attraction for zone " + zones[i].ZoneNumber );
             }
             ProcessRatio( i, ratio, flatProd, productions[subset] );
             ComputeSubsetRatios( i, subsetRatios, productions );
             // p is already the production of this subset
             factor = p / sum;
         }
         SetupModeSplit( cats, subset, mpd, ratio );
         // make sure to only include the total factor of people that belong to this subset
         // now that we have the new factor we update the demand
         UpdateDemand( flatRet, zones, numberOfZones, loadedFriction, i, factor );
     }
     this.CheckSaveFriction( flatRet );
 }
 private static void SetupModeSplit(IDemographicCategory[][] cats, int subset, IModeParameterDatabase mpd, float[] ratio)
 {
     mpd.InitializeBlend();
     for ( int j = 0; j < cats[subset].Length; j++ )
     {
         mpd.SetBlendWeight( ratio[j] );
         cats[subset][j].InitializeDemographicCategory();
     }
     mpd.CompleteBlend();
 }
 private static void SetupFrictionData(List<SparseArray<float>> productions, List<SparseArray<float>> attractions,
     List<IDemographicCategory> cats, MultiBlendSet multiset, float[][][] productionSet, float[][][] attractionSet,
     IDemographicCategory[][] multiCatSet)
 {
     int subsetIndex = -1;
     foreach ( var blendSet in multiset.Subsets )
     {
         subsetIndex++;
         var set = blendSet.Set;
         var length = set.Count;
         int place = 0;
         int blendSetCount = 0;
         for ( int i = 0; i < length; i++ )
         {
             for ( int pos = set[i].Start; pos <= set[i].Stop; pos++ )
             {
                 blendSetCount++;
             }
         }
         productionSet[subsetIndex] = new float[blendSetCount][];
         attractionSet[subsetIndex] = new float[blendSetCount][];
         multiCatSet[subsetIndex] = new IDemographicCategory[blendSetCount];
         for ( int i = 0; i < length; i++ )
         {
             for ( int pos = set[i].Start; pos <= set[i].Stop; pos++ )
             {
                 productionSet[subsetIndex][place] = productions[pos].GetFlatData();
                 attractionSet[subsetIndex][place] = attractions[pos].GetFlatData();
                 multiCatSet[subsetIndex][place] = cats[pos];
                 place++;
             }
         }
     }
 }
        private void ComputeFriction(IZone[] zones, IDemographicCategory[][] cats, float[][][] productions, float[][][] attractions, float[][] friction, float[] production, float[] attraction)
        {
            var numberOfZones = zones.Length;
            bool loadedFriction = false;
            if ( !String.IsNullOrWhiteSpace( this.LoadFrictionFileName ) )
            {
                LoadFriction( friction, -1 );
                loadedFriction = true;
            }
            else
            {
                ClearFriction( friction, numberOfZones );
            }

            var mpd = this.Root.ModeParameterDatabase;
            float[] subsetRatios = new float[productions.Length];
            SumProductionAndAttraction( production, attraction, productions, attractions );
            for ( int subset = 0; subset < cats.Length; subset++ )
            {
                this.InteractiveModeSplit.StartNewInteractiveModeSplit( this.MultiBlendSets.Count );
                float[] ratio = new float[cats[subset].Length];
                for ( int i = 0; i < numberOfZones; i++ )
                {
                    ComputeSubsetRatios( i, subsetRatios, productions );
                    ProcessBlendsetRatio( i, ratio, productions[subset] );
                    // if there is no production for this origin we can just skip ahead for the next zone
                    if ( production[i] == 0 )
                    {
                        continue;
                    }
                    // if there is something here to process
                    SetupModeChoice( cats, ratio, mpd, subset );
                    GatherUtilities( zones, friction, attraction, numberOfZones, loadedFriction, subsetRatios, subset, i );
                }
                this.InteractiveModeSplit.EndInterativeModeSplit();
            }
            ConvertToFriction( friction, zones );
            CheckSaveFriction( friction );
        }
 private IEnumerable<SparseTwinIndex<float>> CPUDoublyConstrained(IZone[] zones, IEnumerator<SparseArray<float>> ep, IEnumerator<SparseArray<float>> ea, IEnumerator<IDemographicCategory> ec)
 {
     float completed = 0f;
     var frictionSparse = this.Root.ZoneSystem.ZoneArray.CreateSquareTwinArray<float>();
     var productions = new List<SparseArray<float>>();
     var attractions = new List<SparseArray<float>>();
     var cats = new List<IDemographicCategory>();
     // We need to pre load all of our generations in order to handle blending properly
     while ( ep.MoveNext() & ea.MoveNext() & ec.MoveNext() )
     {
         productions.Add( ep.Current );
         attractions.Add( ea.Current );
         cats.Add( ec.Current );
     }
     var ret = this.Root.ZoneSystem.ZoneArray.CreateSquareTwinArray<float>();
     SparseArray<float> production = this.Root.ZoneSystem.ZoneArray.CreateSimilarArray<float>();
     SparseArray<float> attraction = this.Root.ZoneSystem.ZoneArray.CreateSimilarArray<float>();
     this.CurrentMultiSetIndex = -1;
     foreach ( var multiset in this.MultiBlendSets )
     {
         this.CurrentMultiSetIndex++;
         var numberOfSubsets = multiset.Subsets.Count;
         var productionSet = new float[numberOfSubsets][][];
         var attractionSet = new float[numberOfSubsets][][];
         var multiCatSet = new IDemographicCategory[numberOfSubsets][];
         SetupFrictionData( productions, attractions, cats, multiset, productionSet, attractionSet, multiCatSet );
         this.ComputeFriction( zones, multiCatSet, productionSet, attractionSet,
             frictionSparse.GetFlatData(), production.GetFlatData(), attraction.GetFlatData() );
         string balanceFileName;
         SparseArray<float> balanceFactors = GetWarmBalancingFactors( attraction, out balanceFileName );
         if ( this.CullSmallValues )
         {
             var tempValues = new GravityModel( frictionSparse, null, this.Epsilon, this.MaxIterations )
             .ProcessFlow( production, attraction, production.ValidIndexArray(), balanceFactors );
             this.Cull( tempValues, frictionSparse.GetFlatData(), production.GetFlatData(), attraction.GetFlatData() );
             if ( !String.IsNullOrWhiteSpace( this.SaveFrictionFileName ) )
             {
                 this.SaveFriction( frictionSparse.GetFlatData() );
             }
         }
         yield return new GravityModel( frictionSparse, ( p => this.Progress = ( p * ( 1f / ( this.MultiBlendSets.Count ) ) + ( completed / ( this.MultiBlendSets.Count ) ) ) ), this.Epsilon, this.MaxIterations )
             .ProcessFlow( production, attraction, production.ValidIndexArray(), balanceFactors );
         if ( balanceFileName != null )
         {
             SaveBalanceFactors( balanceFileName, balanceFactors );
         }
         completed += 1f;
     }
 }
 private static void SetupModeChoiceParameters(IDemographicCategory[] cats, float[] ratio, IModeParameterDatabase mpd)
 {
     mpd.InitializeBlend();
     for ( int c = 0; c < cats.Length; c++ )
     {
         mpd.SetBlendWeight( ratio[c] );
         cats[c].InitializeDemographicCategory();
     }
     mpd.CompleteBlend();
 }
Exemple #19
0
 private void ComputeFriction(IZone[] zones, IDemographicCategory cat, float[][] friction)
 {
     var numberOfZones = zones.Length;
     var rootModes = this.Root.Modes;
     var numberOfModes = rootModes.Count;
     // let it setup the modes so we can compute friction
     cat.InitializeDemographicCategory();
     try
     {
         Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int i)
         {
             for ( int j = 0; j < numberOfZones; j++ )
             {
                 var destination = zones[j];
                 float utility;
                 if ( !this.GatherAllUtility( zones[i], zones[j], out utility ) )
                 {
                     throw new XTMFRuntimeException( "There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber );
                 }
                 else
                 {
                     friction[i][j] = (float)Math.Pow( utility, this.ImpedianceParameter ) * ( this.KFactor != null ? (float)Math.Exp( this.KFactor[i * this.NumberOfZones + j] ) : 1f );
                 }
             }
         } );
     }
     catch ( AggregateException e )
     {
         throw e.InnerException;
     }
 }
Exemple #20
0
 private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] production, float[] attraction, float[] friction)
 {
     var numberOfZones = zones.Length;
     float[] ret = friction == null ? new float[numberOfZones * numberOfZones] : friction;
     var rootModes = this.Root.Modes;
     var numberOfModes = rootModes.Count;
     // let it setup the modes so we can compute friction
     cat.InitializeDemographicCategory();
     try
     {
         Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int i)
         {
             int index = i * numberOfZones;
             if ( production[i] == 0 )
             {
                 for ( int j = 0; j < numberOfZones; j++ )
                 {
                     ret[index++] = 0;
                 }
                 return;
             }
             for ( int j = 0; j < numberOfZones; j++ )
             {
                 if ( attraction != null && attraction[j] == 0 )
                 {
                     ret[index++] = 0;
                 }
                 else
                 {
                     var utility = 0f;
                     if ( !this.GatherAllUtility( zones[i], zones[j], out utility ) )
                     {
                         ret[index++] = 0;
                         //throw new XTMFRuntimeException( "There was no valid mode to travel between " + zones[i].ZoneNumber + " and " + zones[j].ZoneNumber );
                     }
                     else
                     {
                         ret[index++] = (float)Math.Pow( utility, this.ImpedianceParameter ) * ( this.KFactor != null ? (float)Math.Exp( this.KFactor[i * this.NumberOfZones + j] ) : 1f );
                     }
                 }
             }
         } );
     }
     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 );
         }
     }
     // Use the Log-Sum from the V's as the impedence function
     return ret;
 }
        private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] friction)
        {
            var numberOfZones = zones.Length;
            float[] ret = friction == null ? new float[numberOfZones * numberOfZones] : friction;
            var rootModes = this.Root.Modes;
            var numberOfModes = rootModes.Count;
            var minFrictionInc = (float)Math.Exp( -10 );
            // initialize the category so we can compute the friction
            cat.InitializeDemographicCategory();
            try
            {
                Parallel.For( 0, numberOfZones, delegate(int i)
                {
                    int index = i * numberOfZones;
                    var origin = zones[i];
                    int vIndex = i * numberOfZones * numberOfModes;
                    for ( int j = 0; j < numberOfZones; j++ )
                    {
                        double logsum = 0f;
                        var destination = zones[j];
                        int feasibleModes = 0;
                        for ( int mIndex = 0; mIndex < numberOfModes; mIndex++ )
                        {
                            var mode = rootModes[mIndex];
                            if ( !mode.Feasible( origin, zones[j], this.SimulationTime ) )
                            {
                                vIndex++;
                                continue;
                            }
                            feasibleModes++;
                            var inc = mode.CalculateV( origin, zones[j], this.SimulationTime );
                            if ( float.IsNaN( inc ) )
                            {
                                continue;
                            }
                            logsum += Math.Exp( inc );
                        }
                        ret[index++] = (float)Math.Pow( logsum, this.Beta );
                    }
                } );
            }
            catch ( AggregateException e )
            {
                if ( e.InnerException is XTMFRuntimeException )
                {
                    throw e.InnerException;
                }
                else
                {
                    throw new XTMFRuntimeException( e.InnerException.Message + "\r\n" + e.InnerException.StackTrace );
                }
            }

            // Use the Log-Sum from the V's as the impedence function
            return ret;
        }
Exemple #22
0
 private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] friction)
 {
     var numberOfZones = zones.Length;
     float[] ret = friction == null ? new float[numberOfZones * numberOfZones] : friction;
     // let it setup the modes so we can compute friction
     cat.InitializeDemographicCategory();
     try
     {
         Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int j)
         {
             var destination = zones[j];
             int regionIndex;
             if ( !InverseLookup( destination.RegionNumber, out regionIndex ) )
             {
                 // make sure to reset the friction to zero
                 for ( int i = 0; i < numberOfZones; i++ )
                 {
                     ret[i * numberOfZones + j] = float.NegativeInfinity;
                 }
                 return;
             }
             // store the log of the population and the employment since we will be using this for each origin
             var employmentLog = (float)Math.Log( ( destination.Employment - destination.ManufacturingEmployment ) + 1 );
             var populationLog = (float)Math.Log( destination.Population + 1 );
             for ( int i = 0; i < numberOfZones; i++ )
             {
                 var origin = zones[i];
                 if ( origin.RegionNumber <= 0 )
                 {
                     ret[i * numberOfZones + j] = float.NegativeInfinity;
                 }
                 else
                 {
                     var autoTime = this.RegionEmploymentGeneralParameter[regionIndex] *
                         this.NetworkData.TravelTime( origin, destination, this.SimulationTime ).ToMinutes();
                     var destinationUtility = this.RegionEmploymentParameter[regionIndex] * employmentLog
                     + this.RegionPopulationParameter[regionIndex] * populationLog;
                     // this isn't friction, it is V where friction will be e^V
                     ret[i * numberOfZones + j] = destinationUtility + autoTime;
                 }
             }
         } );
     }
     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 );
         }
     }
     // Use the Log-Sum from the V's as the impedence function
     return ret;
 }
Exemple #23
0
        public IEnumerable <SparseTwinIndex <float> > Distribute(IEnumerable <SparseArray <float> > productions, IEnumerable <SparseArray <float> > attractions, IEnumerable <IDemographicCategory> category)
        {
            if (this.SaveDistributionSeries != null)
            {
                this.SaveDistributionSeries.Reset();
            }
            IDemographicCategory cat = null;
            var ret            = this.Root.ZoneSystem.ZoneArray.CreateSquareTwinArray <float>();
            var linkages       = this.Root.ZoneSystem.ZoneArray.CreateSquareTwinArray <float>();
            var catEnum        = category.GetEnumerator();
            var productionEnum = productions.GetEnumerator();
            int catIndex       = 0;
            var rangeSet       = new RangeSet(new int[] { 0 });

            // just multiply by the number of occupations in v2 since this is a throw away module
            this.NumberOfGenerations = NumberOfCategoriesPerOccupation * 4;
            while (catEnum.MoveNext() & productionEnum.MoveNext())
            {
                cat = catEnum.Current;
                var ageRate = productionEnum.Current;
                Parallel.Invoke(
                    () => SetupMobilityInformation(catIndex),
                    () => LoadLinkages(catIndex, linkages.GetFlatData())
                    );
                foreach (var mobilitySet in this.MobilityRanges)
                {
                    for (int mobility = mobilitySet.Start; mobility <= mobilitySet.Stop; mobility++)
                    {
                        var realCat = cat as DemographicCategoryGeneration;
                        if (realCat == null)
                        {
                            throw new XTMFRuntimeException("In '" + this.Name + "' it is required that all generates be of the type DemographicCategoryGeneration!");
                        }
                        rangeSet[0] = new Range()
                        {
                            Start = mobility, Stop = mobility
                        };
                        realCat.Mobility = rangeSet;
                        DistributePopulation(realCat, ageRate.GetFlatData(), linkages.GetFlatData(), catIndex, ret.GetFlatData());
                        Task save = null;
                        if (this.SaveDistributionSeries != null)
                        {
                            save = Task.Factory.StartNew(() =>
                            {
                                SaveDistribution(ret, this.Root.ZoneSystem.ZoneArray.GetFlatData(), catIndex);
                            });
                        }
                        yield return(ret);

                        if (save != null)
                        {
                            save.Wait();
                        }
                        catIndex++;
                    }
                }
            }
            // Free up our memory
            this.MobilityCache = null;
            this.UnloadRates();
        }
 private float[] ComputeFriction(IZone[] zones, IDemographicCategory[][] cats, float[][][] productionSet, float[] friction, float[] production, int subsetIndex)
 {
     var numberOfZones = zones.Length;
     float[] ret = friction == null ? new float[numberOfZones * numberOfZones] : friction;
     var rootModes = this.Root.Modes;
     var numberOfModes = rootModes.Count;
     if ( !String.IsNullOrWhiteSpace( this.LoadFrictionFileName ) )
     {
         LoadFriction( ret );
     }
     else
     {
         ComputeFriction( zones, numberOfZones, ret );
     }
     this.InteractiveModeSplit.StartNewInteractiveModeSplit( this.TotalBlendSets );
     SumProduction( production, productionSet, subsetIndex );
     try
     {
         float[] ratio = new float[cats[subsetIndex].Length];
         var mpd = this.Root.ModeParameterDatabase;
         for ( int i = 0; i < numberOfZones; i++ )
         {
             // let it setup the modes so we can compute friction
             ProcessRatio( i, ratio, production, productionSet[subsetIndex] );
             SetupModeChoiceParameters( cats[subsetIndex], ratio, mpd );
             SaveModeChoice( zones, numberOfZones, i );
         }
     }
     catch ( AggregateException e )
     {
         throw e.InnerException;
     }
     // Use the Log-Sum from the V's as the impedence function
     if ( !String.IsNullOrWhiteSpace( this.SaveFrictionFileName ) )
     {
         SaveFriction( ret );
     }
     return ret;
 }
Exemple #25
0
 private float[] ComputeFriction(IZone[] zones, IDemographicCategory cat, float[] friction)
 {
     var numberOfZones = zones.Length;
     float[] ret = friction == null ? new float[numberOfZones * numberOfZones] : friction;
     var rootModes = this.Root.Modes;
     var numberOfModes = rootModes.Count;
     // let it setup the modes so we can compute friction
     cat.InitializeDemographicCategory();
     try
     {
         Parallel.For( 0, numberOfZones, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(int i)
         {
             int index = i * numberOfZones;
             var origin = zones[i];
             int vIndex = i * numberOfZones * numberOfModes;
             int regionIndex;
             if ( !InverseLookup( zones[i].RegionNumber, out regionIndex ) )
             {
                 for ( int j = 0; j < numberOfZones; j++ )
                 {
                     ret[index++] = 0;
                 }
                 return;
             }
             for ( int j = 0; j < numberOfZones; j++ )
             {
                 var destination = zones[j];
                 var autoTime = this.NetworkData.TravelTime( origin, destination, this.SimulationTime );
                 var population = destination.Population;
                 ret[index++] = (float)( this.RegionAutoParameter[regionIndex] * autoTime.ToMinutes()
                     // population
                     + this.RegionPopulationParameter[regionIndex] * Math.Log( population + 1 )
                     // employment
                     + this.RegionEmploymentProfessionalParameter[regionIndex] * Math.Log( destination.ProfessionalEmployment + 1 )
                     + this.RegionEmploymentGeneralParameter[regionIndex] * Math.Log( destination.GeneralEmployment + 1 )
                     + this.RegionEmploymentSalesParameter[regionIndex] * Math.Log( destination.RetailEmployment + 1 )
                     + this.RegionEmploymentManufacturingParameter[regionIndex] * Math.Log( destination.ManufacturingEmployment + 1 ) );
             }
         } );
     }
     catch ( AggregateException e )
     {
         throw e.InnerException;
     }
     // Use the Log-Sum from the V's as the impedence function
     return ret;
 }
 public IEnumerable<SparseTwinIndex<float>> Distribute(IEnumerable<SparseArray<float>> eps, IEnumerable<SparseArray<float>> eas, IEnumerable<IDemographicCategory> ecs)
 {
     float[] friction = null;
     var zones = this.Root.ZoneSystem.ZoneArray.GetFlatData();
     var productions = new List<SparseArray<float>>();
     var cats = new List<IDemographicCategory>();
     var ep = eps.GetEnumerator();
     var ec = ecs.GetEnumerator();
     while ( ep.MoveNext() && ec.MoveNext() )
     {
         productions.Add( ep.Current );
         cats.Add( ec.Current );
     }
     SparseArray<float> production = this.Root.ZoneSystem.ZoneArray.CreateSimilarArray<float>();
     this.TotalBlendSets = 0;
     for ( int i = 0; i < this.BlendSets.Count; i++ )
     {
         this.TotalBlendSets += this.BlendSets[i].Subsets.Count;
     }
     foreach ( var multiset in this.BlendSets )
     {
         var setLength = multiset.Subsets.Count;
         var productionSet = new float[setLength][][];
         var catSet = new IDemographicCategory[setLength][];
         SetupFrictionData( productions, cats, multiset, productionSet, catSet );
         for ( int subIndex = 0; subIndex < multiset.Subsets.Count; subIndex++ )
         {
             friction = this.ComputeFriction( zones, catSet, productionSet, friction, production.GetFlatData(), subIndex );
             var ret = SinglyConstrainedGravityModel.Process( production, friction );
             if ( this.Transpose )
             {
                 TransposeMatrix( ret );
             }
             yield return ret;
         }
     }
 }