Пример #1
0
 /// <summary>
 /// HELPER: Finds the IDW lambda denominator.
 /// </summary>
 /// <returns></returns>
 private double calcLambdaDenominator(List<Measurement> nearest, Measurement missing)
 {
     double sum = 0;
     foreach (Measurement currNearest in nearest)
     {
         sum += this.calcLambdaNumerator(currNearest, missing);
     }
     return sum;
 }
Пример #2
0
        /// <summary>
        /// HELPER: Finds disatances... used to find di (and dk) values.
        /// 
        /// NOTE: This is currently the least optimized function according to the profiler... I wonder if theres a better 3rd party math library for .NET?
        /// </summary>
        /// <returns></returns>
        private double calcD(Measurement nearest, Measurement missing)
        {
            return Math.Sqrt(
                Math.Pow(nearest.X - missing.X, 2) +
                Math.Pow(nearest.Y - missing.Y, 2) +

                // Notice the TVal is multipled by a scale factor... to allow us control over the range.
                // IE 1-365 or 0.01 - 3.65.
                Math.Pow(this.timeCoefficient * nearest.Time.TVal - this.timeCoefficient * missing.Time.TVal, 2)
            );
        }
Пример #3
0
        private Measurement parseLine(string text)
        {
            // Tokenize the string.
            string[] tokens = text.Split(new string[] {this.delimiter}, StringSplitOptions.RemoveEmptyEntries);

            // Populate the measurement.
            Measurement measurement = new Measurement();
            measurement.Time = (ITimeDomain)Activator.CreateInstance(this.timeDomain.GetType());
            for (int i = 0; i < tokens.Length; i++)
            {
                switch (this.columns[i])
                {
                    case Columns.ID:
                        measurement.ID = long.Parse(tokens[i]);
                        break;
                    case Columns.X:
                        measurement.X = float.Parse(tokens[i]);
                        break;
                    case Columns.Y:
                        measurement.Y = float.Parse(tokens[i]);
                        break;
                    case Columns.Value:
                        measurement.Value = float.Parse(tokens[i]);
                        break;
                    case Columns.Year:
                        measurement.Time.SetProperty("year", int.Parse(tokens[i]));
                        break;
                    case Columns.Quarter:
                        measurement.Time.SetProperty("quarter", int.Parse(tokens[i]));
                        break;
                    case Columns.Month:
                        measurement.Time.SetProperty("month", int.Parse(tokens[i]));
                        break;
                    case Columns.Day:
                        measurement.Time.SetProperty("day", int.Parse(tokens[i]));
                        break;
                }
            }

            return measurement;
        }
Пример #4
0
 /// <summary>
 /// HELPER: Finds the IDW lambda coefficient for element i.
 /// </summary>
 /// <returns></returns>
 private double calcLambdaNumerator(Measurement nearest, Measurement missing)
 {
     double distance = this.calcD(nearest, missing);
     return Math.Pow(1 / distance, this.exponent);
 }
Пример #5
0
        private void InnerLoop(object state)
        {
            // Need to extract state values from the state package object.
            InnerLoopState openState = (InnerLoopState)state;
            Measurement currMissing = openState.currMissing;
            List<Measurement> results = openState.results;

            // This is the time domain of the KNOWN values.
            // We are trying to calculate every unknown element for every value bewteen t=0 and tmax of this time domain.
            ITimeDomain t = (ITimeDomain)Activator.CreateInstance(this.known[0].Time.GetType());
            t.SetProperty("year", this.known[0].Time.DateTime.Year); // Set the year to the year of the first known item.
                                                                     // No example data sets span multiple years. This is kindof undefined behavior.

            // Iterate over all t values in this time domain.
            for (int i = 0; i < t.TMax; i++)
            {
                currMissing.Time = t; // Use the known time domain as the time domain of the missing data set.
                List<Measurement> nearest = this.calcNearest(currMissing); // Get the n nearest known values.

                // Iterate over the nearset known values and sum up their lambdas.
                double sum = 0.0d;
                foreach (Measurement currNearest in nearest)
                {
                    double numerator = this.calcLambdaNumerator(currNearest, currMissing);
                    double denominator = this.calcLambdaDenominator(nearest, currMissing);
                    double lambda = numerator / denominator;
                    double value = lambda * currNearest.Value;
                    sum += value;
                }

                // We can build a single output model now.
                Measurement output = new Measurement();
                output.ID = currMissing.ID;
                output.X = currMissing.X;
                output.Y = currMissing.Y;
                output.Time = (ITimeDomain)Activator.CreateInstance(this.known[0].Time.GetType());
                output.Time.SetT(t.TVal);
                output.Time.SetProperty("year", t.DateTime.Year);
                output.Value = (float)sum;
                results.Add(output); // We now store this model in a new list.

                t.IncrementT(); // Increment the time domain value.
                this.Current++; // Report row increment... this is how the progressbar knows.
            }
        }
Пример #6
0
        /// <summary>
        /// Finds the n known measurements with the smallest euclidian distance to x, y, t in nearly O(n) time.
        /// </summary>
        private List<Measurement> calcNearest(Measurement measure)
        {
            DistanceMeasurement[] results = new DistanceMeasurement[this.nearest];
            foreach (Measurement curr in this.known)
            {
                double distance = this.calcD(curr, measure);

                // Test if this is a new smallest value.
                bool shift = false;
                DistanceMeasurement shifted = null;
                for (int i = 0; i < results.Length; i++)
                {
                    // A smaller value was found continue shifting the array.
                    if (shift)
                    {
                        DistanceMeasurement temp = results[i];
                        results[i] = shifted;
                        shifted = temp;
                    }
                    // Test if this is one of the first n elements.
                    else if (results[i] == null)
                    {
                        // Build a DistanceMeasurement for this value.
                        DistanceMeasurement dm = new DistanceMeasurement();
                        dm.Measurement = curr;
                        dm.Distance = distance;

                        results[i] = dm;
                    }
                    // Test if value smaller than current element.
                    else if (distance < results[i].Distance)
                    {
                        // Build a DistanceMeasurement for this value.
                        DistanceMeasurement dm = new DistanceMeasurement();
                        dm.Measurement = curr;
                        dm.Distance = distance;

                        // Swap in this value.
                        shifted = results[i];
                        results[i] = dm;

                        // Enter shift mode.
                        shift = true;
                    }
                }
            }

            // Convert from DistanceMeasurement to Measurement.
            List<Measurement> nearest = new List<Measurement>();
            foreach (DistanceMeasurement curr in results)
            {
                nearest.Add(curr.Measurement);
            }

            return nearest;
        }