예제 #1
0
        /* TODO delete
                private static List<GridPolygon> getSourcePoligon(GridInfo gridInfo) {
                    var width = gridInfo.Width;
                    var height = gridInfo.Height;

                    var poligon = new GridPolygon();
                    var points = new List<GridPoint>();

                    for (double i = gridInfo.MinY; i < gridInfo.MaxY; i += gridInfo.Step) {
                        points.Add(new GridPoint(gridInfo.MinX, i));
                    }

                    for (double i = gridInfo.MinX; i < gridInfo.MaxX; i += gridInfo.Step) {
                        points.Add(new GridPoint(i, gridInfo.MaxY));
                    }

                    for (double i = gridInfo.MaxY; i > gridInfo.MinY; i -= gridInfo.Step) {
                        points.Add(new GridPoint(gridInfo.MaxX, i));
                    }

                    for (double i = gridInfo.MaxX; i > gridInfo.MinX; i -= gridInfo.Step) {
                        points.Add(new GridPoint(i, gridInfo.MinY));
                    }

                    poligon.Points = points.ToArray();
                    return new List<GridPolygon> { poligon };
                }
         */

        /// <summary>
        /// Восстановление значений в ячейках грида с помощью бикубической интерполяции, вызывается в параллельных потоках
        /// </summary>
        /// <param name="grid">Грид</param>
        /// <param name="interpolant">Функция для восстановления значений</param>
        /// <param name="workerId">идентификатор рабочего процесса</param>
        private static void restoreGridCells(GridField grid, alglib.spline2dinterpolant interpolant, int workerId)
        {
            int procCount = Environment.ProcessorCount;
            int countX = grid.GridInfo.NumberColumns;
            int countY = grid.GridInfo.NumberRows;
            var max = countX * (workerId + 1) / procCount;
            for (var column = countX * workerId / procCount; column < max; ++column)
            {
                for (var row = 0; row < countY; ++row)
                {
                    double? v = grid.GridData[column, row];
                    if (v == null || !double.IsNegativeInfinity(v.Value))
                    {
                        var point = grid.createPoint(column, row);
                        grid.GridData[column, row] = alglib.spline2dcalc(interpolant, point.X, point.Y);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Расчет ячеек грида кригингом, вызывается в параллельных потоках
        /// </summary>
        /// <param name="config">Настройки для расчёта</param>
        /// <param name="grid">Рассчитываемый грид</param>
        /// <param name="semivarianseDelegate">Вариограмма</param>
        /// <param name="workerId">идентификатор рабочего процесса</param>
        /// <param name="points">точки из которых набираем значения для расчёта</param>
        /// <param name="xvals">
        /// Хранилище куда складываем насчитанные значения по X<br/>
        /// В дальнейшем используется для кубического сплайна
        /// </param>
        /// <param name="yvals">
        /// Хранилище куда складываем насчитанные значения по Y<br/>
        /// В дальнейшем используется для кубического сплайна
        /// </param>
        /// <param name="step">
        /// Шаг по которому будем вычислять в каких ячейках насчитать значения<br/>
        /// Если передано значение &lt;= 0, тогда возьмем 5
        /// </param>
        private static void calculate(KrigingConfig config, GridField grid, Func<double, double> semivarianseDelegate, int workerId, GridPoint[] points,
            ConcurrentBag<KeyValuePair<double, int>> xvals, ConcurrentBag<KeyValuePair<double, int>> yvals, int step)
        {
            if (grid == null || grid.GridData == null)
            {
                return;
            }

            if (step <= 0)
            {
                step = 10;
            }
            int countX = grid.GridInfo.NumberColumns;
            int countY = grid.GridInfo.NumberRows;
            var degreeOfParallelism = Environment.ProcessorCount;
            var max = countX * (workerId + 1) / degreeOfParallelism;
            //нужно ли заполнять множество Y значениями
            bool needFillYValues = workerId == 0;

            for (int column = countX * workerId / degreeOfParallelism; column < max; column += step)
            {
                for (var row = 0; row < countY; row += step)
                {
                    var point = grid.createPoint(column, row);
                    double? v = grid.GridData[column, row];
                    if (v == null || !double.IsNegativeInfinity(v.Value))
                    {
                        var nearestPoints = getNearestPoints(point, points, config.SearchRadius, config.SectorsCount, config.MaxPointsInSector);
                        grid.GridData[column, row] = (nearestPoints.Length != 0)
                                                         ? interpolatePoint(point, nearestPoints, semivarianseDelegate)
                                                         : config.NotDefinedValue;
                    }
                    if (needFillYValues)
                    {
                        yvals.Add(new KeyValuePair<double, int>(point.Y, row));
                    }
                }
                needFillYValues = false;
                xvals.Add(new KeyValuePair<double, int>(grid.getXCoord(column), column));
            }
        }