コード例 #1
0
        public IndexBoundingBox GetBoundingBox(double[] grid, double min, double max, DoubleEpsComparer dec = null)
        {
            DoubleEpsComparer effDec = (dec == null) ? DoubleEpsComparer.Instance : dec;

            int imin = Array.BinarySearch(grid, min, effDec);

            if (imin < 0)
            {
                imin = (~imin) - 1;
                if (imin == -1)
                {
                    return(new IndexBoundingBox());
                }
            }

            int imax = Array.BinarySearch(grid, max, effDec);

            if (imax < 0)
            {
                imax = ~imax;
                if (imax == grid.Length)
                {
                    return(new IndexBoundingBox());
                }
                imax--;
            }
            else if (imax > imin)
            {
                imax--;
            }
            return(new IndexBoundingBox {
                first = imin, last = imax
            });
        }
コード例 #2
0
        public void GetWeightsTestStepInterpolator()
        {
            double[] axis = Enumerable.Range(0, 24).Select(a => (double)a).ToArray();
            WeightProviders.StepFunctionInterpolation weightsProvider = new WeightProviders.StepFunctionInterpolation();
            DoubleEpsComparer dec = new DoubleEpsComparer(0.1);

            int start, stop;

            double[] weights = weightsProvider.GetWeights(axis, 0.0, 1.0, out start, out stop, dec);
            Assert.AreEqual(1, weights.Length);
            Assert.AreEqual(0, start);
            Assert.AreEqual(0, stop);

            weights = weightsProvider.GetWeights(axis, 0.0, 2.0, out start, out stop, dec);
            Assert.AreEqual(2, weights.Length);
            Assert.AreEqual(weights[0], weights[1]);
            Assert.AreEqual(0, start);
            Assert.AreEqual(1, stop);

            weights = weightsProvider.GetWeights(axis, 3.5, 4.5, out start, out stop, dec);
            Assert.AreEqual(2, weights.Length);
            Assert.AreEqual(weights[0], weights[1]);
            Assert.AreEqual(3, start);
            Assert.AreEqual(4, stop);

            weights = weightsProvider.GetWeights(axis, 3.5, 5.5, out start, out stop, dec);
            Assert.AreEqual(3, weights.Length);
            Assert.AreEqual(weights[0], weights[2]);
            Assert.AreEqual(weights[1], 2.0 * weights[2]);
            Assert.AreEqual(3, start);
            Assert.AreEqual(5, stop);

            weights = weightsProvider.GetWeights(axis, 0.7, 0.75, out start, out stop, dec);
            Assert.AreEqual(1, weights.Length);
            Assert.AreEqual(0, start);
            Assert.AreEqual(0, stop);

            weights = weightsProvider.GetWeights(axis, 5.75, 8.75, out start, out stop, dec);
            Assert.AreEqual(4, weights.Length);
            Assert.AreEqual(weights[1], weights[2]);
            Assert.AreEqual(weights[0], 0.25 * weights[1]);
            Assert.AreEqual(weights[3], 0.75 * weights[2]);
            Assert.AreEqual(5, start);
            Assert.AreEqual(8, stop);


            //out of range
            weights = weightsProvider.GetWeights(axis, 30.0, 31.1, out start, out stop, dec);
            Assert.AreEqual(0, weights.Length);

            weights = weightsProvider.GetWeights(axis, -2.0, -1.0, out start, out stop, dec);
            Assert.AreEqual(0, weights.Length);

            weights = weightsProvider.GetWeights(axis, 10.0, 30.0, out start, out stop, dec);
            Assert.AreEqual(0, weights.Length);
        }
コード例 #3
0
        public void TestGetWeights()
        {
            double[] axis = Enumerable.Range(0, 24).Select(a => (double)a).ToArray();
            StepFunctionWeightsProvider weightsProvider = new StepFunctionWeightsProvider();
            DoubleEpsComparer           dec             = new DoubleEpsComparer(0.1);

            int start, stop;

            double[] weights = weightsProvider.GetWeights(axis, 0.0, 1.0, out start, out stop, dec);
            Assert.AreEqual(1, weights.Length);
            Assert.AreEqual(0, start);
            Assert.AreEqual(0, stop);

            weights = weightsProvider.GetWeights(axis, 0.0, 2.0, out start, out stop, dec);
            Assert.AreEqual(2, weights.Length);
            Assert.AreEqual(weights[0], weights[1]);
            Assert.AreEqual(0, start);
            Assert.AreEqual(1, stop);

            weights = weightsProvider.GetWeights(axis, 3.5, 4.5, out start, out stop, dec);
            Assert.AreEqual(2, weights.Length);
            Assert.AreEqual(weights[0], weights[1]);
            Assert.AreEqual(3, start);
            Assert.AreEqual(4, stop);

            weights = weightsProvider.GetWeights(axis, 3.5, 5.5, out start, out stop, dec);
            Assert.AreEqual(3, weights.Length);
            Assert.AreEqual(weights[0], weights[2]);
            Assert.AreEqual(weights[1], 2.0 * weights[2]);
            Assert.AreEqual(3, start);
            Assert.AreEqual(5, stop);

            weights = weightsProvider.GetWeights(axis, 0.7, 0.75, out start, out stop, dec);
            Assert.AreEqual(1, weights.Length);
            Assert.AreEqual(0, start);
            Assert.AreEqual(0, stop);

            weights = weightsProvider.GetWeights(axis, 5.75, 8.75, out start, out stop, dec);
            Assert.AreEqual(4, weights.Length);
            Assert.AreEqual(weights[1], weights[2]);
            Assert.AreEqual(weights[0], 0.25 * weights[1]);
            Assert.AreEqual(weights[3], 0.75 * weights[2]);
            Assert.AreEqual(5, start);
            Assert.AreEqual(8, stop);

            weights = weightsProvider.GetWeights(axis, 30.0, 30.4, out start, out stop, dec);
            Assert.AreEqual(0, weights.Length);

            weights = weightsProvider.GetWeights(axis, -30.7, -30.4, out start, out stop, dec);
            Assert.AreEqual(0, weights.Length);
        }
コード例 #4
0
        public int[] GetIndices(double[] grid, double min, double max, DoubleEpsComparer dec = null)
        {
            IndexBoundingBox bb = GetBoundingBox(grid, min, max, dec);

            if (bb.IsSingular)
            {
                return(new int[0]);
            }
            else
            {
                int first = bb.first;
                return(Enumerable.Range(first, bb.last - first + 1).ToArray());
            }
        }
コード例 #5
0
        public IndexBoundingBox GetBoundingBox(double[] grid, double min, double max, DoubleEpsComparer dec = null)
        {
            DoubleEpsComparer effDec = (dec == null) ? DoubleEpsComparer.Instance : dec;

            bool isLeftUnexact = false;
            int  imin          = Array.BinarySearch(grid, min, effDec);

            if (imin < 0)
            {
                imin          = (~imin) - 1;
                isLeftUnexact = true;
            }

            bool isRightUnexact = false;
            int  imax           = Array.BinarySearch(grid, max, effDec);

            if (imax < 0)
            {
                imax           = ~imax;
                isRightUnexact = true;
            }

            //if ((imin == -1 && imax == 0 && isLeftUnexact && isRightUnexact) || //interval is lower than the data
            //    (imin == grid.Length - 1 && imax == grid.Length && isLeftUnexact && isRightUnexact))  //is higher than the data
            //    return new IndexBoundingBox();

            if (imin == -1 && isLeftUnexact)
            {
                return(new IndexBoundingBox()); //interval crosses the lower bound of the grid
            }
            if (imax == grid.Length && isRightUnexact)
            {
                return(new IndexBoundingBox());// interval crosses upper bound of the grid
            }
            return(new IndexBoundingBox {
                first = imin, last = imax
            });
        }
コード例 #6
0
        /// <summary>
        /// Automatically selects approppriate linear integrator by axis data
        /// </summary>
        /// <param name="context"></param>
        /// <param name="axisArrayName"></param>
        /// <returns></returns>
        public static async Task <IGridAxisAvgProcessing> SmartConstructAsync(IStorageContext context, string axisArrayName)
        {
            DoubleEpsComparer epsComparer = new DoubleEpsComparer(1e-5);
            var axis = await context.GetDataAsync(axisArrayName);

            double firstElem  = Convert.ToDouble(axis.GetValue(0));
            double secondElem = Convert.ToDouble(axis.GetValue(1));
            double lastElem   = Convert.ToDouble(axis.GetValue(axis.Length - 1));

            if (epsComparer.Compare(firstElem + 360.0, lastElem) == 0)
            {
                //longitudes cycled, last and ferst elemets repeated
                return(new LinearCycledLonsAvgProcessing(axis, true));
            }
            else if (epsComparer.Compare(firstElem + 360.0 - (secondElem - firstElem), lastElem) == 0)
            {
                //longitudes cycled
                return(new LinearCycledLonsAvgProcessing(axis, false));
            }
            else
            {
                return(new LinearGridIntegrator(axis));
            }
        }
コード例 #7
0
        public IndexBoundingBox GetBoundingBox(double[] grid, double min, double max, DoubleEpsComparer dec = null)
        {
            if (grid.Length < 2)
            {
                throw new ArgumentException("Supplied grid to small. Less 2 elements");
            }
            if (grid[0] > grid[grid.Length - 1])
            {
                throw new ArgumentException("Grid is not ascending. StepFunctionWeightsProvider can't be used");
            }
            if (min > max)
            {
                throw new ArgumentException("Min should be less or equal to max");
            }

            int  leftBound = Array.BinarySearch(grid, min);
            int  rightBound = Array.BinarySearch(grid, max);
            int  leftIdx, rightIdx;
            bool exactLeftBound = leftBound >= 0;

            if (exactLeftBound)
            {
                leftIdx = leftBound;
            }
            else
            {
                leftIdx = ~leftBound - 1;
            }
            if (rightBound >= 0)
            {
                rightIdx = rightBound - 1;
            }
            else
            {
                rightIdx = ~rightBound - 1;
            }
            if (
                rightIdx < leftIdx ||
                rightIdx == -1 ||                                //entirly to the left of data
                (leftIdx == grid.Length - 1 && !exactLeftBound)) //entirly to the right of data
            {
                return(IndexBoundingBox.Singular);
            }
            else
            {
                leftIdx = Math.Max(0, leftIdx); //in case of request coveres additional interval not covered by data. it is stell valid
                return(new IndexBoundingBox()
                {
                    first = leftIdx, last = rightIdx
                });
            }
        }
コード例 #8
0
        public double[] GetWeights(double[] grid, double min, double max, out int start, out int stop, DoubleEpsComparer dec = null)
        {
            if (grid.Length < 2)
            {
                throw new ArgumentException("Supplied grid to small. Less 2 elements");
            }
            if (grid[0] > grid[grid.Length - 1])
            {
                throw new ArgumentException("Grid is not ascending. StepFunctionWeightsProvider can't be used");
            }
            if (min > max)
            {
                throw new ArgumentException("Min should be less or equal to max");
            }

            if (max > grid[grid.Length - 1] || min < grid[0])
            {
                start = stop = 0;
                return(new double[0]);
            }

            bool requestGreaterThanGrid = (min > grid[grid.Length - 1]);
            bool requestLowerThanGrid   = (max < grid[0]);

            if (requestGreaterThanGrid || requestLowerThanGrid) //out of the grid
            {
                if (requestGreaterThanGrid)
                {
                    start = stop = grid.Length - 1;
                }
                else
                {
                    start = stop = 0;
                }
                return(new double[0]);
            }

            DoubleEpsComparer effDec = (dec == null) ? DoubleEpsComparer.Instance : dec;

            int  imin              = Array.BinarySearch(grid, min, effDec);
            bool leftBoundUnexact  = false;
            bool rightBoundUnexact = false;

            if (imin < 0)
            {
                leftBoundUnexact = true;
                imin             = ~imin;
            }

            int imax = Array.BinarySearch(grid, max, effDec);

            if (imax < 0)
            {
                rightBoundUnexact = true;
                imax = ~imax;
                imax--;
            }
            imax--;
            List <double> weightsList = new List <double>(16);

            start = imin;
            stop  = imax;
            if (imin - imax > 1)
            {
                weightsList.Add(1.0);
                start = stop = imin - 1;
            }
            else
            {
                if (leftBoundUnexact)
                {
                    weightsList.Add(grid[imin] - min);
                    start--;
                }
                for (int i = imin; i <= imax; i++)
                {
                    weightsList.Add(grid[i + 1] - grid[i]);
                }
                if (rightBoundUnexact)
                {
                    weightsList.Add(max - grid[imax + 1]);
                    stop++;
                }
            }
            return(weightsList.ToArray());
        }
コード例 #9
0
        public IndexBoundingBox GetBoundingBox(double[] grid, double min, double max, DoubleEpsComparer dec = null)
        {
            int leftBound, rightBound;
            int leftIdx  = Array.BinarySearch(grid, min);
            int rightIdx = Array.BinarySearch(grid, max);

            if (leftIdx >= 0)
            {
                leftBound = leftIdx;
            }
            else
            {
                leftBound = ~leftIdx;
            }
            if (rightIdx >= 0)
            {
                rightBound = rightIdx;
            }
            else
            {
                rightBound = ~rightIdx - 1;
            }
            if (rightBound < leftBound)
            {
                return(IndexBoundingBox.Singular);
            }
            else
            {
                return new IndexBoundingBox()
                       {
                           first = leftBound, last = rightBound
                       }
            };
        }
コード例 #10
0
        //the method is not static as the class is used in typed parmeters
        public double[] GetWeights(double[] grid, double min, double max, out int start, out int stop, DoubleEpsComparer dec = null)
        {
            if (DoubleEpsComparer.Instance.Compare(min, max) > 0)
            {
                throw new ArgumentException("Min should be less or equal to max");
            }

            if (grid[0] > grid[grid.Length - 1])
            {
                throw new ArgumentException("Grid is not ascending. LinearWeightsProvider can't be used");
            }

            if (grid.Length < 2)
            {
                if (grid.Length == 1 && (Math.Abs(max - min) < 0.0000000000001) && (Math.Abs(grid[0] - min) < 0.00001))
                {
                    start = 0;
                    stop  = 0;
                    return(new double[] { 1.0 });
                }
                else
                {
                    throw new ArgumentException("Grid length must be at least 2");
                }
            }

            DoubleEpsComparer effDec = (dec == null) ? DoubleEpsComparer.Instance : dec;

            if (effDec.Compare(min, grid[0]) < 0)
            {
                start = stop = 0;
                return(new double[0]);
            }
            if (effDec.Compare(max, grid[grid.Length - 1]) > 0)
            //    max = grid[grid.Length - 1];
            {
                start = stop = 0;
                return(new double[0]);
            }

            bool leftBoundUnexact = false, rightBoundUnexact = false;

            int imin = Array.BinarySearch <double>(grid, (double)min, effDec);

            if (imin < 0)
            {
                imin             = ~imin - 1;
                leftBoundUnexact = true;
            }

            int imax = Array.BinarySearch <double>(grid, imin, grid.Length - imin, (double)max, effDec);

            if (imax < 0)
            {
                imax = ~imax;
                rightBoundUnexact = true;
            }
            System.Diagnostics.Debug.Assert(imax < grid.Length);


            double[] w = new double[imax - imin + 1];
            w.Initialize();

            if (imax == imin)
            {
                w[0]  = 1.0;
                start = stop = imin;
            }
            else if (imax == imin + 1) //inside single grid interval
            {
                double x_k = grid[imin];
                double x_m = grid[imax];

                double k;

                double x_m_k = x_m - x_k;

                k    = 0.5 * (min + max - 2.0 * x_k) / x_m_k; //both for min=max and non-zero length intervals
                w[1] = k;
                w[0] = 1 - k;
            }
            else
            {
                double divider    = (max - min) * 2.0;
                double multiplier = 1.0 / divider;

                int solidIntervals_imin   = leftBoundUnexact ? imin + 1 : imin;
                int solidIntervals_imax   = rightBoundUnexact ? imax - 1 : imax;
                int solid_imin_output_idx = leftBoundUnexact ? 1 : 0;
                int solid_imax_output_idx = rightBoundUnexact ? w.Length - 2 : w.Length - 1;
                if (solidIntervals_imax > solidIntervals_imin) //full covered intervals
                {
                    w[solid_imin_output_idx] = (grid[solidIntervals_imin + 1] - grid[solidIntervals_imin]) * multiplier;

                    for (int i = 1; i < solidIntervals_imax - solidIntervals_imin; i++)
                    {
                        w[solid_imin_output_idx + i] = (grid[solidIntervals_imin + i + 1] - grid[solidIntervals_imin + i - 1]) * multiplier;
                    }

                    w[solid_imax_output_idx] = (grid[solidIntervals_imax] - grid[solidIntervals_imax - 1]) * multiplier;
                }
                if (leftBoundUnexact) //partially covered intervals, if present
                {
                    double x_0 = grid[imin + 1];
                    double x_a = grid[imin];
                    double x_l = min;

                    double k = (x_l + x_0 - 2.0 * x_a) / (x_0 - x_a);

                    double width = x_0 - x_l;

                    w[0]  = (2.0 - k) * width * multiplier;
                    w[1] += k * width * multiplier;
                }
                if (rightBoundUnexact)
                {
                    double x_r = max;
                    double x_z = grid[imax];
                    double x_n = grid[imax - 1];

                    double k = (x_n + x_r - 2.0 * x_n) / (x_z - x_n);

                    double width = x_r - x_n;

                    w[solid_imax_output_idx]    += (2.0 - k) * width * multiplier;
                    w[solid_imax_output_idx + 1] = k * width * multiplier;
                }
            }

            System.Diagnostics.Debug.Assert(Math.Abs(w.Sum() - 1.0) < 1e-3); // test for unbiasness

            start = imin;
            stop  = imax;
            return(w);
        }