Exemple #1
0
        /// <summary>
        /// проверка на соответствие нормальному закону распределния ряда. озвращая критерий согласия Пирсона для этого ряда
        /// http://www.ekonomstat.ru/kurs-lektsij-po-teorii-statistiki/403-proverka-sootvetstvija-rjada-raspredelenija.html
        /// https://life-prog.ru/2_84515_proverka-po-kriteriyu-hi-kvadrat.html критерий пирсона
        /// https://math.semestr.ru/group/example-normal-distribution.php для нормального распределения
        /// </summary>
        /// <param name="range">ряд</param>
        /// <param name="parameter">проверяемый параметр</param>
        /// <returns></returns>
        private static double checkNormalLaw(RawRange range, MeteorologyParameters parameter)
        {
            GradationInfo <GradationItem> grads;

            switch (parameter)
            {
            case MeteorologyParameters.Speed:
                grads = new GradationInfo <GradationItem>(0, SPEED_GRADATION_STEP, range.Max((item) => { return(item.Speed); }));   //градации скорости
                break;

            case MeteorologyParameters.Direction:
                StatisticalRange <WindDirections16> srwd = StatisticEngine.GetDirectionExpectancy(range, GradationInfo <WindDirections16> .Rhumb16Gradations);

                return(0);

            case MeteorologyParameters.Temperature:
                grads = new GradationInfo <GradationItem>(0, TEMPERATURE_GRADATION_STEP, range.Max((item) => { return(item.Temperature); }));   //градации температуры
                break;

            case MeteorologyParameters.Wetness:
                grads = new GradationInfo <GradationItem>(0, WETNESS_GRADATION_STEP, range.Max((item) => { return(item.Wetness); }));   //градации влажности
                break;

            default: throw new WindEnergyException("Этот параметр не реализован");
            }

            //РАСЧЕТ ДЛЯ ВСЕХ, КРОМЕ НАПРАВЛЕНИЙ
            StatisticalRange <GradationItem> stat_range = StatisticEngine.GetExpectancy(range, grads, parameter); //статистический ряд

            // TODO: расчет критерия пирсона для ряда

            return(0);
        }
Exemple #2
0
        /// <summary>
        /// преобразует ряд наблюдений в статистику
        /// </summary>
        /// <param name="range"></param>
        public Dataset(RawRange range, MeteorologyParameters param, IHoursModel model) : this()
        {
            for (int i = 1; i <= 12; i++) //цикл по месяцам
            {
                switch (param)
                {
                case MeteorologyParameters.AllSkyInsolation:

                    double aver = (from t in range
                                   where t.Date.Month == i
                                   select t.AllSkyInsolation).Average();
                    DataHours <double> hours = model.GetData(aver, param);
                    Months             month = (Months)i;
                    this[month] = hours;
                    break;

                case MeteorologyParameters.ClearSkyInsolation:

                    double aver2 = (from t in range
                                    where t.Date.Month == i
                                    select t.ClearSkyInsolation).Average();
                    DataHours <double> hours2 = model.GetData(aver2, param);
                    Months             month2 = (Months)i;
                    this[month2] = hours2;
                    break;

                default: throw new Exception("Этот параметр не реализован");
                }
            }
        }
Exemple #3
0
        public DataHours <double> GetData(double dailySum, MeteorologyParameters allSkyInsolation)
        {
            DataHours <double> res = new DataHours <double>();

            for (int i = 0; i < 24; i++)
            {
                res.Add(i, dailySum / 24d);
            }
            return(res);
        }
Exemple #4
0
        /// <summary>
        /// возвращает минимальное ограничение для заданого параметра
        /// </summary>
        /// <param name="paramter">тип параметра</param>
        /// <returns></returns>
        internal double GetMinimal(MeteorologyParameters paramter)
        {
            switch (paramter)
            {
            case MeteorologyParameters.Direction:
                double min = directionInclude.Min(new Func <Diapason <double>, double>((diapason) =>
                {
                    return(diapason.From);
                }));
                return(min);

            case MeteorologyParameters.Speed:
                double mins = speedInclude.Min(new Func <Diapason <double>, double>((diapason) =>
                {
                    return(diapason.From);
                }));
                return(mins);

            default: throw new Exception("Этот параметр не реализован");
            }
        }
Exemple #5
0
        /// <summary>
        /// создание нового интерполятора с заданными значениями на основе существующего базового ряда наблюдения
        /// </summary>
        /// <param name="func">известные значения функции в заданной точке</param>
        /// <param name="baseRange">базовый ряд (с ближайшей МС), на основе которого будет происходить восстановление</param>
        /// <param name="parameterType">тип мтеорологического параметра</param>
        /// <param name="replaceExistMeasurements">Заменять существующие измерения в исходном ряде на расчетные</param>
        public NearestMSInterpolateMethod(Dictionary <double, double> func, RawRange baseRange, MeteorologyParameters parameterType, bool replaceExistMeasurements)
        {
            if (func.Keys.Count == 0)
            {
                Empty = true; return;
            }
            Empty = false;

            this.parameterType            = parameterType;
            this.func                     = func;
            this.replaceExistMeasurements = replaceExistMeasurements;
            this.nearestRange             = baseRange;

            //расчет диапазона сделанных измерений
            baseRange = new RawRange(baseRange.OrderBy(x => x.Date).ToList());
            interpolationDiapason.From = Math.Max(baseRange[0].DateArgument, func.Keys.Min());                   //максимальную дату из начал каждой функции
            interpolationDiapason.To   = Math.Min(baseRange[baseRange.Count - 1].DateArgument, func.Keys.Max()); //минимальную дату из концов каждой функции

            double a = 0, b = 0, r = 0;                                                                          //коэффициенты прямой  и коэффициент корреляции

            Dictionary <double, double> baseFunc = baseRange.GetFunction(parameterType);                         //функция базового ряда

            List <double>[] tableCoeff = calcTableCoeff(func, baseFunc);                                         //таблица для расчёта коэффициентов a, b, r

            a = getParameterA(tableCoeff);                                                                       //коэффициенты прямой
            b = getParameterB(tableCoeff, a);
            r = getParameterR(tableCoeff);                                                                       //коэффициент корреляции

            //проверка попадания коэфф корреляции в допустимый диапазон (если для этого параметра надо проверять диапазон)
            if (r < Vars.Options.MinimalCorrelationCoeff && Vars.Options.MinimalCorrelationControlParametres.Contains(parameterType))
            {
                throw new Exception("Недостаточное коррелирование функций");
            }

            //ФУНКЦИЯ ПОЛУЧЕНИЯ ЗНАЧЕНИЯ
            getRes = new Func <double, double>((x) =>
            {
                //если в исходном ряде есть это значение и не надо заменять исходное, то его и возвращаем
                if (func.ContainsKey(x) && !replaceExistMeasurements)
                {
                    return(func[x]);
                }

                //Если в базовой функции нет измерения за этой время, то возвращаем NaN
                //иначе расчитываем скорость по полученной зависимости.
                if (!baseFunc.ContainsKey(x))
                {
                    return(double.NaN);
                }
                else
                {
                    if (baseFunc[x] == 0) //если в базовой функции это значение равно нулю, то возвращаем NaN, чтоб не завышать результат прибавлением b
                    {
                        return(double.NaN);
                    }
                    else
                    {
                        return(a * baseFunc[x] + b);
                    }
                }
            });
        }
Exemple #6
0
 /// <summary>
 /// создание нового интерполятора с заданными значениями на основе существующего интерполятора (в том случае, если для этой точки уже был создан интерполятор)
 /// </summary>
 /// <param name="func">известные значения функции</param>
 /// <param name="baseInterpolator">интерполятор, откуда взять ряд наблюдения для этого экземпляра</param>
 /// <param name="parameterType">тип параметра для восстановления</param>
 /// <param name="replaceExistMeasurements">Заменять существующие измерения в исходном ряде на расчетные</param>
 public NearestMSInterpolateMethod(Dictionary <double, double> func, NearestMSInterpolateMethod baseInterpolator, MeteorologyParameters parameterType, bool replaceExistMeasurements)
     : this(func, baseInterpolator.nearestRange, parameterType, replaceExistMeasurements)
 {
 }
Exemple #7
0
 /// <summary>
 /// создаёт новый интерполятор для заданной точки с заданной функций и типом расчетного параметра
 /// </summary>
 /// <param name="func">известные значения функции в заданной точке</param>
 /// <param name="coordinates">координаты точки, для которой известны значения func</param>
 /// <param name="parameterType">тип мтеорологического параметра</param>
 /// <param name="replaceExistMeasurements">Заменять существующие измерения в исходном ряде на расчетные</param>
 public NearestMSInterpolateMethod(Dictionary <double, double> func, PointLatLng coordinates, MeteorologyParameters parameterType, bool replaceExistMeasurements)
     : this(func, getNearestRange(func, coordinates), parameterType, replaceExistMeasurements)
 {
 }
Exemple #8
0
        /// <summary>
        /// ищет наиболее подходящую к заданной точке МС и получает её ряд. Если ряд не найден, то возвращает null
        /// </summary>
        /// <param name="coordinates"></param>
        /// <param name="r"></param>
        /// <param name="actionPercent"></param>
        /// <param name="Range">ряд, для которого подбирается функция</param>
        /// <exception cref="GetBaseRangeException">Возвращает иснформацию о параметрах, мешающих получить ближайшую МС</exception>
        /// <returns></returns>
        internal static RawRange TryGetBaseRange(RawRange Range, PointLatLng coordinates, out double r, Action <int, string> actionPercent)
        {
            bool nlaw = CheckNormalLaw(Range, Vars.Options.NormalLawPirsonCoefficientDiapason);

            if (!nlaw)
            {
                throw new WindEnergyException("Исходный ряд не подчиняется нормальному закону распределения");
            }

            DateTime from = Range.Min((ri) => ri.Date).Date, to = Range.Max((ri) => ri.Date).Date;

            List <RP5MeteostationInfo>  mts = Vars.RP5Meteostations.GetNearestMS(coordinates, Vars.Options.NearestMSRadius, false);
            Dictionary <double, double> funcSpeed = Range.GetFunction(MeteorologyParameters.Speed); //функция скорости на заданном ряде
            RawRange res = null;
            double   rmax = double.MinValue, total_rmax = double.MinValue;
            RP5ru    provider = new RP5ru(Vars.Options.CacheFolder + "\\rp5.ru");

            for (int i = 0; i < mts.Count; i++)
            {
                if (actionPercent != null)
                {
                    actionPercent.Invoke((int)((i * 1d / mts.Count) * 100d), "Поиск подходящей МС...");
                }

                RP5MeteostationInfo m = mts[i];

                //если нет диапазона измерений в БД, то загружаем с сайта
                if (m.MonitoringFrom == DateTime.MinValue)
                {
                    provider.GetMeteostationExtInfo(ref m);
                }

                //если для этой МС нет наблюдений в этом периоде, то переходим на другую
                if (m.MonitoringFrom > from)
                {
                    continue;
                }

                //загрузка ряда с очередной МС
                RawRange curRange = null;
                try
                { curRange = provider.GetRange(from, to, m); }
                catch (WindEnergyException wex) // если не удалось получить ряд этой МС, то переходим к следующей
                { continue; }


                curRange = new Checker().ProcessRange(curRange, new CheckerParameters(LimitsProviders.StaticLimits, curRange.Position), out CheckerInfo info, null); //исправляем ошибки


                //СКОРОСТЬ
                MeteorologyParameters parameter = MeteorologyParameters.Speed;

                Dictionary <double, double> funcSpeedCurrentNearest = curRange.GetFunction(parameter); //функция скорости на текущей МС

                //проверка на нормальный закон распределения
                bool normal = CheckNormalLaw(curRange, Vars.Options.NormalLawPirsonCoefficientDiapason);
                if (!normal)
                {
                    continue;
                }

                //расчёт и проверка коэфф корреляции
                List <double>[] table     = calcTableCoeff(funcSpeed, funcSpeedCurrentNearest); //таблица для расчет коэффициентов
                double          current_r = getParameterR(table);                               //коэффициент корреляции

                //общий максимальный коэфф корреляции
                if (current_r > total_rmax)
                {
                    total_rmax = current_r;
                }

                //проверяем, можно ли взять эту МС
                if (current_r > rmax)
                {
                    //истина, если надо проверять этот параметр на допустимый диапазон корреляции
                    bool needCheck = Vars.Options.MinimalCorrelationControlParametres.Contains(parameter);
                    if ((needCheck && current_r >= Vars.Options.MinimalCorrelationCoeff) || !needCheck)
                    {
                        rmax = current_r;
                        res  = curRange;
                    }
                }
            }
            r = rmax;
            if (res == null)
            {
                RP5MeteostationInfo mi = Vars.RP5Meteostations.GetNearestMS(coordinates);
                double l = EarthModel.CalculateDistance(mi.Position, coordinates);
                throw new GetBaseRangeException(total_rmax, Vars.Options.MinimalCorrelationCoeff, l, mts.Count, Vars.Options.NearestMSRadius, coordinates);
            }
            return(res);
        }
Exemple #9
0
        /// <summary>
        /// получить статистический ряд по заданным значениям и заданным градациям
        /// </summary>
        /// <param name="range"></param>
        /// <param name="gradations"></param>
        /// <param name="parameter"></param>
        /// <returns></returns>
        public static StatisticalRange <GradationItem> GetExpectancy(IList <RawItem> range, GradationInfo <GradationItem> gradations, MeteorologyParameters parameter = MeteorologyParameters.Speed)
        {
            List <double> rang;

            switch (parameter)
            {
            case MeteorologyParameters.Speed:
                rang = new List <double>(from t in range select t.Speed);
                break;

            case MeteorologyParameters.Direction:
                rang = new List <double>(from t in range select t.Direction);
                break;

            case MeteorologyParameters.Temperature:
                rang = new List <double>(from t in range select t.Temperature);
                break;

            case MeteorologyParameters.Wetness:
                rang = new List <double>(from t in range select t.Wetness);
                break;

            default: throw new WindEnergyException("Этот параметр не реализован");
            }
            StatisticalRange <GradationItem> r = new StatisticalRange <GradationItem>(rang, gradations);

            return(r);
        }