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 }); }
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); }
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); }
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()); } }
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 }); }
/// <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)); } }
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 }); } }
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()); }
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 } }; }
//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); }