Example #1
0
        /// <summary>
        /// Returns a computational context which is a set of nodes and a set "weights" to apply to the nodes to form a linear combination to get the mean value of the cells
        /// </summary>
        public async Task <LinearCombinationContext> CreateAsync(IEnumerable <ICellRequest> cells)
        {
            Stopwatch sw             = Stopwatch.StartNew();
            var       tsAveragerTask = timeSeriesAveragerFactory.CreateAsync();
            var       liTask         = linearInterpolatorFactory.CreateAsync();

            var tsAverager         = await tsAveragerTask;
            var linearInterpolator = await liTask;

            sw.Stop();

            traceSource.TraceEvent(TraceEventType.Verbose, 1, "Time series averager and lenear interpolator constructed in {0}", sw.Elapsed);

            sw = Stopwatch.StartNew();
            var resultTasks = cells.Select <ICellRequest, Task <Tuple <ICellRequest, RealValueNodes, IEnumerable <LinearWeight> > > >(async c =>
            {
                var tsa = (RealValueNodes)(await tsAverager.GetAsync(c));
                var w   = (IEnumerable <LinearWeight>)(await linearInterpolator.GetLinearWeigthsAsync(tsa, c));

                return(Tuple.Create(c, tsa, w));
            }).ToArray();

            var result = await Task.WhenAll(resultTasks);

            sw.Stop();
            traceSource.TraceEvent(TraceEventType.Verbose, 2, "Linear weights for {0} cells prepared in {1}", resultTasks.Length, sw.Elapsed);
            LinearCombinationContext lcc = new LinearCombinationContext(result);

            return(lcc);
        }
        public async Task LinearCombinationAggregatorTest()
        {
            LinearCombinationAggregator lca = new LinearCombinationAggregator();

            var nodes   = new RealValueNodes(new double[3], new double[3], new double[] { 2.0, 3.0, 5.0 });
            var weights = new LinearWeight[] { new LinearWeight(1, 7.0), new LinearWeight(0, 11.0), new LinearWeight(2, 13.0) };
            LinearCombinationContext lcc = new LinearCombinationContext(new Tuple <ICellRequest, RealValueNodes, IEnumerable <LinearWeight> >[] { new Tuple <ICellRequest, RealValueNodes, IEnumerable <LinearWeight> >(new RequestStubs(), nodes, (IEnumerable <LinearWeight>)weights) });

            double[] result = await lca.AggregateCellsBatchAsync(lcc, new ICellRequest[] { new RequestStubs() });

            Assert.AreEqual(1, result.Length);
            Assert.AreEqual(108, result[0]);
        }
        public async Task <double[]> EvaluateCellsBatchAsync(LinearCombinationContext computationalContext, IEnumerable <ICellRequest> cells)
        {
            var variogramProvider = await variogramProviderFactory.ConstructAsync();

            var combinationsIterator = computationalContext.Combinations.GetEnumerator();


            traceSource.TraceEvent(TraceEventType.Start, 1, "Filtering out cells that are not requested");

            var filtered = cells.Select(cell =>
            {
                Tuple <ICellRequest, RealValueNodes, IEnumerable <LinearWeight> > currentElement;
                ICellRequest contextCell;
                do
                {
                    var nextExists = combinationsIterator.MoveNext();
                    if (!nextExists)
                    {
                        throw new InvalidOperationException("Received linear combination does not containg information about requested cell. Context is not synchronize with requested cells sequenece.");
                    }
                    currentElement = combinationsIterator.Current;
                    contextCell    = currentElement.Item1;
                } while (!contextCell.Equals(cell));

                return(currentElement);
            }).ToArray();

            traceSource.TraceEvent(TraceEventType.Stop, 1, "Filtered out cells that are not requested");
            traceSource.TraceEvent(TraceEventType.Start, 2, "Evaluating uncertatinty for sequence of cells using precomputed linear combinations");

            var resultsTasks = filtered.AsParallel().AsOrdered().Select(async tuple =>
            {
                if (tuple.Item2.Lats.Length == 0)
                {
                    return(Double.NaN); //there are no nodes. Out of data request? can't produce uncertainty
                }
                var variogram = await variogramProvider.GetSpatialVariogramAsync(tuple.Item2);
                var cell      = tuple.Item1;
                var weights   = tuple.Item3.ToArray();
                var nodes     = tuple.Item2;

                Debug.Assert(Math.Abs(weights.Sum(w => w.Weight) - 1.0) < 1e-10);

                double sill = variogram.Sill;

                double cellLat = (cell.LatMax + cell.LatMin) * 0.5;
                double cellLon = (cell.LonMax + cell.LonMin) * 0.5;
                //var = cov(0)+ sum sum (w[i]*w[j]*cov(i,j))-2.0*sum(w[i]*cov(x,i))
                double cov_at_0 = sill;

                double acc = cov_at_0; //cov(0)
                for (int i = 0; i < weights.Length; i++)
                {
                    double w    = weights[i].Weight;
                    int idx1    = weights[i].DataIndex;
                    double lat1 = nodes.Lats[idx1];
                    double lon1 = nodes.Lons[idx1];
                    for (int j = 0; j < i; j++)
                    {
                        int idx2    = weights[j].DataIndex;
                        double lat2 = nodes.Lats[idx2];
                        double lon2 = nodes.Lons[idx2];
                        double dist = SphereMath.GetDistance(lat1, lon1, lat2, lon2);
                        double cov  = sill - variogram.GetGamma(dist);
                        acc        += 2.0 * w * weights[j].Weight * cov;
                    }
                    acc         += w * w * cov_at_0; //diagonal elements
                    double dist2 = SphereMath.GetDistance(lat1, lon1, cellLat, cellLon);
                    double cov2  = sill - variogram.GetGamma(dist2);
                    acc         -= 2.0 * w * cov2;
                }
                return(acc * 0.5); //as dealing with full variogram instead of semivariogram
            }).ToArray();
            var results = await Task.WhenAll(resultsTasks);

            traceSource.TraceEvent(TraceEventType.Stop, 2, "Evaluated uncertatinty for sequence of cells using precomputed linear combinations");
            return(results);
        }