Пример #1
0
        /// <summary>
        /// Вычислить результирующее значение функции между 2-мя заданными точками
        /// </summary>
        /// <param name="x">Значение аргумента функции</param>
        /// <param name="fRunk">Ранг (порядок) аргумента</param>
        /// <param name="rangePt">Диапазон известных ближайших точек</param>
        /// <returns>Значение функции в точке</returns>
        private float calc(float x, FRUNK fRunk, RangePOINT rangePt)
        {
            float fRes = -1F;

            fRes = calc(x, rangePt.Left.X(fRunk), rangePt.Left.f, rangePt.Right.X(fRunk), rangePt.Right.f);

            return(fRes);
        }
Пример #2
0
            /// <summary>
            /// Конструктор основной (с параметрами)
            /// </summary>
            /// <param name="id">Идентификатор записи в таблице БД</param>
            /// <param name="a1">1-ый аргумент</param>
            /// <param name="a2">2-ой аргумент</param>
            /// <param name="a3">3-ий аргумент</param>
            /// <param name="f">Значение функции для аргументов</param>
            public POINT(int id, float a1, float a2, float a3, float f)
            {
                m_idRec = id;
                this.a1 = a1;
                this.a2 = a2;
                this.a3 = a3;
                this.f  = f;

                Runk = ((!(a2 == 0F)) || (!(a3 == 0F))) ? (!(a3 == 0F)) ? FRUNK.F3 : (!(a2 == 0F)) ? FRUNK.F2 : FRUNK.F1 : FRUNK.F1;
            }
Пример #3
0
        /// <summary>
        /// Возвратить все аргументы функции для указанного ранга
        /// </summary>
        /// <param name="nameAlg">Наименование функции</param>
        /// <returns>Массив аргументов функции</returns>
        private List <PointPairList> getPointPairListValues(string nameAlg)
        {
            FRUNK fRunk = m_dictValues[nameAlg].Runk;
            List <PointPairList> listRes = new List <PointPairList> ();
            PointPairList        item    = null;
            bool bNewItem = false;

            foreach (POINT pt in m_dictValues[nameAlg])
            {
                bNewItem = true;

                if (listRes.Count == 0)
                {
                    ;
                }
                else
                {
                    foreach (PointPairList ppl in listRes)
                    {
                        if (ppl.ContainsKey(pt) == true)
                        {
                            item     = ppl;
                            bNewItem = false;
                        }
                        else
                        {
                            ;
                        }
                    }
                }

                if (bNewItem == true)
                {
                    item = new PointPairList(pt, fRunk);
                    listRes.Add(item);
                }
                else
                {
                    ;
                }

                if (!(item == null))
                {
                    item.Add(new PointPair(pt.X(FRUNK.F1), pt.f));
                }
                else
                {
                    ;
                }
            }

            return(listRes);
        }
Пример #4
0
        /// <summary>
        /// Найти ближайшие реперные (узловые) точки
        /// </summary>
        /// <param name="nameAlg">Наименование функции</param>
        /// <param name="x">Аргумент функции, относительно которой производится поиск</param>
        /// <param name="fRunk">Ранг аргумента</param>
        /// <returns>Массив точек</returns>
        private RangePOINT getNearby(string nameAlg, float x, FRUNK fRunk, ListLIMIT listLimit)
        {
            RangePOINT rangeRes   = null;
            INDEX_NEAR indxNearby = INDEX_NEAR.UNKNOWN;

            //Получить диапазон аргументов, значений
            rangeRes = getRange(nameAlg, fRunk, listLimit);
            //Определитть порядок назначения ближайших соседних реперных точек
            if ((!(x < rangeRes.Left.X(fRunk))) &&
                (!(x > rangeRes.Right.X(fRunk))))
            {
                // точка внутри диапазона - использовать интерполяцию
                indxNearby = INDEX_NEAR.COUNT;
            }
            else
            // точка вне диапазона
            if (x < rangeRes.Left.X(fRunk))
            {
                // точка "слева" от диапазона - требуется уточнение правой границы
                indxNearby = INDEX_NEAR.LEFT;     // левая - не изменяется
            }
            else
            if (x > rangeRes.Right.X(fRunk))
            {
                // точка "справа" от диапазона - требуется уточнение левой границы
                indxNearby = INDEX_NEAR.RIGHT;         // правая - не изменяется
            }
            else
            {
                ;
            }
            //Назначить ближайшие соседние реперные точки
            if (indxNearby == INDEX_NEAR.COUNT)
            {
                // внутри диапазона
                interpolation(nameAlg, x, fRunk, ref rangeRes, listLimit);
            }
            else
            {
                // вне диапазона
                extrapolation(nameAlg, x, fRunk, ref rangeRes, indxNearby, listLimit);
            }

            return(rangeRes);
        }
Пример #5
0
        /// <summary>
        /// Уточнить диапазон соседних реперных (узловых) точек к указанному значению аргумента
        /// </summary>
        /// <param name="nameAlg">Наименование функции</param>
        /// <param name="xValue">Значение аргумента</param>
        /// <param name="fRunk">Ранг аргумента</param>
        /// <param name="arNearby">Массив с реперными точками, требующий уточнения (приближение к значению)</param>
        private void interpolation(string nameAlg, float xValue, FRUNK fRunk, ref RangePOINT rangeNearby, ListLIMIT listLimit)
        {
            float x = -1F
            , min = rangeNearby.Left.X(fRunk), max = rangeNearby.Right.X(fRunk);

            foreach (POINT pt in m_dictValues[nameAlg])
            {
                if (listLimit.IsAllowedPoint(pt) == true)
                {
                    x = pt.X(fRunk);

                    if (((xValue - x) < (xValue - min)) &&
                        (!((xValue - x) < 0)) &&
                        (!(x == max)))
                    {
                        min = x;
                        rangeNearby.Left = pt;

                        continue;
                    }
                    else
                    {
                        ;
                    }

                    if (((x - xValue) < (max - xValue)) &&
                        (!((x - xValue) < 0)) &&
                        (!(x == min)))
                    {
                        max = x;
                        rangeNearby.Right = pt;
                    }
                    else
                    {
                        ;
                    }
                }
                else
                {
                    ;
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Возвратить диапазон точек по указанному рангу аргумента (кол-во точек должно быть - не меньше 1-ой)
        /// </summary>
        /// <param name="nameAlg">Наименование функции</param>
        /// <param name="fRunk">Ранг аргумента</param>
        /// <returns>Массив точек</returns>
        private RangePOINT getRange(string nameAlg, FRUNK fRunk, ListLIMIT listLimit)
        {
            RangePOINT rangeRes = new RangePOINT(); //Результат
            float      x = -1F                      //Аргумент функции
            , min = float.MaxValue, max = float.MinValue;

            foreach (POINT pt in m_dictValues[nameAlg])
            {
                if (listLimit.IsAllowedPoint(pt) == true)
                {
                    x = pt.X(fRunk);

                    if (x < min)
                    {
                        min           = x;
                        rangeRes.Left = pt;
                    }
                    else
                    {
                        ;
                    }

                    if (x > max)
                    {
                        max            = x;
                        rangeRes.Right = pt;
                    }
                    else
                    {
                        ;
                    }
                }
                else
                {
                    ;
                }
            }

            return(rangeRes);
        }
Пример #7
0
            public float X(FRUNK fRunk)
            {
                float fRes = float.NaN;

                switch (fRunk)
                {
                case FRUNK.F1:
                    fRes = a1;
                    break;

                case FRUNK.F2:
                    fRes = a2;
                    break;

                case FRUNK.F3:
                    fRes = a3;
                    break;

                default:
                    break;
                }

                return(fRes);
            }
Пример #8
0
        /// <summary>
        /// Вычислить значения для функции
        ///  по заданным аргументам
        ///  для одного аргумента все считает
        ///  для двух - ошибка в вычислении
        ///  для трех - алгоритм недописан
        /// </summary>
        /// <param name="args">Аргументы для вычисления функции</param>
        /// <returns>Значение функции по заданным аргументам</returns>
        public float Calculate(string nameALG, FRUNK fRunkVar, params float[] args)
        {
            m_nameAlg = nameALG;
            FRUNK fRunk = _fRunk;
            ////??? для универсализации расчета
            //int iRunk = -1
            //    , iPow = -1
            //    , iRow =-1, iCol = -1;
            List <RangePOINT[, ]> listPointNearby = new List <RangePOINT[, ]>((int)(fRunk + 1));
            List <float [, ]>     listRes         = new List <float[, ]> ();

            if ((fRunkVar > FRUNK.UNKNOWN) && // ранг введенной переменной д.б. известен
                (!((int)fRunkVar > args.Length)) &&  // ранг введенной переменной д.б. не больше кол-ва аргументов
                (m_dictValues[nameALG].Count > 1))    // для вычислений требуется как минимум 2 точки
            {
                ////??? попытка универсализации расчета
                //for (iRunk = (int)FRUNK.F1; iRunk < ((int)fRunk + 1); iRunk++)
                //{
                //    iPow = (int)(fRunk - iRunk);
                //    iRow = (int)(Math.Pow((fRunk == FRUNK.F1 ? 1F : (float)fRunk), iPow) / (iPow == 0 ? 1 : iPow));
                //    iCol = iPow == 0 ? 1 : iPow;
                //    listPointNearby.Insert(iRunk, new RangePOINT[iRow, iCol]);
                //    listRes.Insert(iRunk, new float[iRow, iCol]);
                //}
                //for (iRunk = (int)FRUNK.F1; iRunk < ((int)fRunk + 1); iRunk++)
                //    for (int i = 0; i < listPointNearby[(int)iRunk].GetLength(0); i++)
                //        for (int j = 0; j < listPointNearby[(int)iRunk].GetLength(1); j++)
                //            ;

                switch (fRunk)
                {
                case FRUNK.F1:
                    //??? не универсальное добавление элементов
                    listPointNearby.Insert((int)FRUNK.F1, new RangePOINT[1, 1]);
                    listRes.Insert((int)FRUNK.F1, new float[1, 1]);
                    // получить ближайшие реперные (узловые) точки
                    listPointNearby[(int)FRUNK.F1][0, 0] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT());
                    // вычисление промежуточных значений ... - нет
                    // вычисление рез-та
                    listRes[(int)fRunk][0, 0] = calc(args[(int)FRUNK.F1]
                                                     , FRUNK.F1
                                                     , listPointNearby[(int)FRUNK.F1][(int)FRUNK.F1, (int)FRUNK.F1])
                                                //-1F по умолчанию
                    ;
                    break;

                case FRUNK.F2:
                    //??? не универсальное добавление элементов
                    listPointNearby.Insert((int)FRUNK.F1, new RangePOINT[2, 1]);
                    listRes.Insert((int)FRUNK.F1, new float[2, 1]);
                    listPointNearby.Insert((int)FRUNK.F2, new RangePOINT[1, 1]);
                    listRes.Insert((int)FRUNK.F2, new float[1, 1]);
                    // получить ближайшие реперные (узловые) точки
                    listPointNearby[(int)FRUNK.F2][0, 0] = getNearby(nameALG, args[(int)FRUNK.F2]
                                                                     , FRUNK.F2
                                                                     , new ListLIMIT());
                    listPointNearby[(int)FRUNK.F1][0, 0] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F2, x = listPointNearby[(int)FRUNK.F2][0, 0].Left.a2
                        }
                    }
                                                                     );
                    listPointNearby[(int)FRUNK.F1][1, 0] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F2, x = listPointNearby[(int)FRUNK.F2][0, 0].Right.a2
                        }
                    }
                                                                     );
                    // вычисление промежуточных значений
                    // 1-ый ранг
                    listRes[(int)FRUNK.F1][0, 0] = calc(args[(int)FRUNK.F1]
                                                        , FRUNK.F1
                                                        , listPointNearby[(int)FRUNK.F1][0, 0]);
                    listRes[(int)FRUNK.F1][1, 0] = calc(args[(int)FRUNK.F1]
                                                        , FRUNK.F1
                                                        , listPointNearby[(int)FRUNK.F1][1, 0]);
                    // вычисление рез-та
                    listRes[(int)fRunk][0, 0] = calc(args[(int)FRUNK.F2]
                                                     , listPointNearby[(int)FRUNK.F2][0, 0].Left.X(FRUNK.F2)
                                                     , listRes[(int)FRUNK.F1][0, 0]
                                                     , listPointNearby[(int)FRUNK.F2][0, 0].Right.X(FRUNK.F2)
                                                     , listRes[(int)FRUNK.F1][1, 0])
                                                //-1F по умолчанию
                    ;
                    break;

                case FRUNK.F3:
                    //??? не универсальное добавление элементов
                    listPointNearby.Insert((int)FRUNK.F1, new RangePOINT[2, 2]);
                    listRes.Insert((int)FRUNK.F1, new float[2, 2]);
                    listPointNearby.Insert((int)FRUNK.F2, new RangePOINT[2, 1]);
                    listRes.Insert((int)FRUNK.F2, new float[2, 1]);
                    listPointNearby.Insert((int)FRUNK.F3, new RangePOINT[1, 1]);
                    listRes.Insert((int)FRUNK.F3, new float[1, 1]);
                    // получить ближайшие реперные (узловые) точки
                    listPointNearby[(int)FRUNK.F3][0, 0] = getNearby(nameALG, args[(int)FRUNK.F3]
                                                                     , FRUNK.F3
                                                                     , new ListLIMIT());
                    listPointNearby[(int)FRUNK.F2][0, 0] = getNearby(nameALG, args[(int)FRUNK.F2]
                                                                     , FRUNK.F2
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F3, x = listPointNearby[(int)FRUNK.F3][0, 0].Left.a3
                        }
                    }
                                                                     );
                    listPointNearby[(int)FRUNK.F2][1, 0] = getNearby(nameALG, args[(int)FRUNK.F2]
                                                                     , FRUNK.F2
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F3, x = listPointNearby[(int)FRUNK.F3][0, 0].Right.a3
                        }
                    }
                                                                     );
                    listPointNearby[(int)FRUNK.F1][0, 0] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F3, x = listPointNearby[(int)FRUNK.F3][0, 0].Left.a3
                        }
                        , new LIMIT()
                        {
                            fRunk = FRUNK.F2, x = listPointNearby[(int)FRUNK.F2][0, 0].Left.a2
                        }
                    }
                                                                     );
                    listPointNearby[(int)FRUNK.F1][1, 0] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F3, x = listPointNearby[(int)FRUNK.F3][0, 0].Left.a3
                        }
                        , new LIMIT()
                        {
                            fRunk = FRUNK.F2, x = listPointNearby[(int)FRUNK.F2][0, 0].Right.a2
                        }
                    }
                                                                     );
                    listPointNearby[(int)FRUNK.F1][0, 1] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F3, x = listPointNearby[(int)FRUNK.F3][0, 0].Right.a3
                        }
                        , new LIMIT()
                        {
                            fRunk = FRUNK.F2, x = listPointNearby[(int)FRUNK.F2][1, 0].Left.a2
                        }
                    }
                                                                     );
                    listPointNearby[(int)FRUNK.F1][1, 1] = getNearby(nameALG, args[(int)FRUNK.F1]
                                                                     , FRUNK.F1
                                                                     , new ListLIMIT()
                    {
                        new LIMIT()
                        {
                            fRunk = FRUNK.F3, x = listPointNearby[(int)FRUNK.F3][0, 0].Right.a3
                        }
                        , new LIMIT()
                        {
                            fRunk = FRUNK.F2, x = listPointNearby[(int)FRUNK.F2][1, 0].Right.a2
                        }
                    }
                                                                     );
                    // вычисление промежуточных значений
                    // 1-ый ранг
                    listRes[(int)FRUNK.F1][0, 0] = calc(args[(int)FRUNK.F1]
                                                        , FRUNK.F1
                                                        , listPointNearby[(int)FRUNK.F1][0, 0]);
                    listRes[(int)FRUNK.F1][1, 0] = calc(args[(int)FRUNK.F1]
                                                        , FRUNK.F1
                                                        , listPointNearby[(int)FRUNK.F1][1, 0]);
                    listRes[(int)FRUNK.F1][0, 1] = calc(args[(int)FRUNK.F1]
                                                        , FRUNK.F1
                                                        , listPointNearby[(int)FRUNK.F1][0, 1]);
                    listRes[(int)FRUNK.F1][1, 1] = calc(args[(int)FRUNK.F1]
                                                        , FRUNK.F1
                                                        , listPointNearby[(int)FRUNK.F1][1, 1]);
                    // 2-ой ранг
                    listRes[(int)FRUNK.F2][0, 0] = calc(args[(int)FRUNK.F2]
                                                        , listPointNearby[(int)FRUNK.F2][0, 0].Left.X(FRUNK.F2)
                                                        , listRes[(int)FRUNK.F1][0, 0]
                                                        , listPointNearby[(int)FRUNK.F2][0, 0].Right.X(FRUNK.F2)
                                                        , listRes[(int)FRUNK.F1][1, 0]);
                    listRes[(int)FRUNK.F2][1, 0] = calc(args[(int)FRUNK.F2]
                                                        , listPointNearby[(int)FRUNK.F2][1, 0].Left.X(FRUNK.F2)
                                                        , listRes[(int)FRUNK.F1][0, 1]
                                                        , listPointNearby[(int)FRUNK.F2][1, 0].Right.X(FRUNK.F2)
                                                        , listRes[(int)FRUNK.F1][1, 1]);
                    // вычисление рез-та
                    listRes[(int)fRunk][0, 0] = calc(args[(int)FRUNK.F3]
                                                     , listPointNearby[(int)FRUNK.F3][0, 0].Left.X(FRUNK.F3)
                                                     , listRes[(int)FRUNK.F2][0, 0]
                                                     , listPointNearby[(int)FRUNK.F3][0, 0].Right.X(FRUNK.F3)
                                                     , listRes[(int)FRUNK.F2][1, 0])
                                                //-1F по умолчанию
                    ;
                    break;

                default:
                    break;
                }
            }
            else
            {
                ;
            }

            m_nameAlg = string.Empty;

            return(listRes[(int)fRunk][0, 0]);
        }
Пример #9
0
        /// <summary>
        /// Уточнить диапазон соседних реперных (узловых) точек к указанному значению аргумента
        /// </summary>
        /// <param name="nameAlg">Наименование функции</param>
        /// <param name="xValue">Значение аргумента</param>
        /// <param name="fRunk">Ранг аргумента</param>
        /// <param name="arNearby">Массив с реперными точками, требующий уточнения (приближение к значению)</param>
        /// <param name="indxConstNearby">Граница диапазона, остающейся постоянной</param>
        private void extrapolation(string nameAlg, float xValue, FRUNK fRunk, ref RangePOINT rangeNearby, INDEX_NEAR indxConstNearby, ListLIMIT listLimit)
        {
            float min = -1F, max = -1F
            , x = -1F;

            min = float.MaxValue; //rangeNearby.Left.X(fRunk);
            max = float.MinValue; //rangeNearby.Right.X(fRunk);

            foreach (POINT pt in m_dictValues[nameAlg])
            {
                if (listLimit.IsAllowedPoint(pt) == true)
                {
                    x = pt.X(fRunk);

                    if (min == float.MaxValue)
                    {
                        min = x;
                        rangeNearby.Left = pt;

                        continue;
                    }
                    else
                    {
                        ;
                    }

                    if ((max == float.MinValue) &&
                        (!(min == x)))
                    {
                        max = x;
                        rangeNearby.Right = pt;

                        continue;
                    }
                    else
                    {
                        ;
                    }

                    if ((!(min == float.MaxValue)) &&
                        (!(max == float.MinValue)))
                    {
                        if ((Math.Abs(xValue - x) < Math.Abs(xValue - min)) &&
                            (!(x == max)))
                        {
                            if ((xValue - min) < (xValue - max))
                            {
                                max = min;
                                rangeNearby.Right = rangeNearby.Left;
                            }
                            else
                            {
                                ;
                            }

                            min = x;
                            rangeNearby.Left = pt;
                        }
                        else
                        {
                            ;
                        }
                    }
                    else
                    if ((Math.Abs(xValue - x) < Math.Abs(xValue - max)) &&
                        (!(x == min)))
                    {
                        max = x;
                        rangeNearby.Right = pt;
                    }
                    else
                    {
                        ;
                    }
                }
                else
                {
                    ;
                }
            }
        }
Пример #10
0
 /// <summary>
 /// Конструктор - основной
 /// </summary>
 /// <param name="key">Ключ для линии</param>
 /// <param name="fRunk">Ранг (порядок) линии</param>
 public PointPairList(POINT key, FRUNK fRunk)
 {
     this.key   = key;
     this.fRunk = fRunk;
 }