コード例 #1
0
        /// <summary>
        /// Find the nearest point.
        /// </summary>
        public Arguments Interpolate(Arguments start, Arguments finish, int axissIndex, double?isolevel = null)
        {
            var    startValue  = start[axissIndex].Value > finish[axissIndex].Value ? finish[axissIndex].Value : start[axissIndex].Value;
            var    finishValue = start[axissIndex].Value > finish[axissIndex].Value ? start[axissIndex].Value : finish[axissIndex].Value;
            var    curA        = startValue;
            var    curB        = finishValue;
            double funcA       = 0;
            double funcB       = 0;
            double calcA       = 0;
            double calcB       = 0;

            var point = start.CloneArguments();
            // Some constants
            var c          = (3 - Math.Sqrt(5)) / 2;
            var fi         = (Math.Sqrt(5) + 1) / 2;
            var calculated = Calculated.FirstIteration;

            for (; ;)
            {
                if ((curB - curA < accuracyEpsilon) && calculated != Calculated.FirstIteration)
                {
                    var pointToReturn = point.CloneArguments();
                    if (GetNearestOrMin(funcA, funcB, isolevel))
                    {
                        pointToReturn[axissIndex] = curA;
                    }
                    else
                    {
                        pointToReturn[axissIndex] = curB;
                    }

                    return(pointToReturn);
                }

                calcA             = curA + c * (curB - curA);
                point[axissIndex] = calcA;
                funcA             = function.Calculate(point);

                calcB             = curA + (1 - c) * (curB - curA);
                point[axissIndex] = calcB;
                funcB             = function.Calculate(point);

                var result = GetNearestOrMin(funcA, funcB, isolevel);

                if (result)
                {
                    curB       = calcB;
                    calculated = Calculated.B;
                }
                else
                {
                    curA       = calcA;
                    calculated = Calculated.A;
                }
            }
        }
コード例 #2
0
        public double GetDerivate(Arguments inArgs, int special)
        {
            if (function == null)
            {
                throw new ArgumentException("function is not set to object");
            }

            if (special > inArgs.Count)
            {
                throw new ArgumentException(String.Format("Function cannot find argument number {0}", special));
            }

            if (inArgs.Count != function.Dimension)
            {
                throw new ArgumentException(String.Format("Arguments count does not match function dimension"));
            }

            Arguments args = inArgs.CloneArguments();

            if (special != -1)
            {
                int index = 1;
                foreach (Variable item in args)
                {
                    if (index != special)
                    {
                        item.IsConstant = true;
                        item.Value      = 0;
                    }
                    index++;
                }
            }
            if (accurracy == DerivationAccuracy.Normal)
            {
                return((function.Calculate(args + h) - function.Calculate(args - h)) / (2 * h));
            }
            else if (accurracy == DerivationAccuracy.High)
            {
                return((-function.Calculate(args + h * 2) + 8 * function.Calculate(args + h) -
                        8 * function.Calculate(args - h) + function.Calculate(args - h * 2)) / (12 * h));
            }
            else
            {
                return(0);
            }
        }
コード例 #3
0
        public Trajectory GradientDescent()
        {
            var parameters = this.Parameters;

            if (function == null || derivation == null || parameters == null)
            {
                throw new OperationCanceledException("Неможливо розпочати роботу. Не всі параметри вказано");
            }

            var    curPoint     = parameters.StartPoint;
            var    curBeta      = parameters.Beta;
            var    staticBeta   = curBeta;
            double curAlpha     = 0;
            bool   pointChanged = false;

            Arguments antiGrad           = derivation.GetAntiGradient(curPoint);
            double    functionInCurPoint = function.Calculate(curPoint);
            double    antiGradModule     = antiGrad.Pow(2).GetSumm();
            var       allPoints          = new Trajectory();

            allPoints.Add(curPoint);
            for (; ;)
            {
                if (pointChanged)
                {
                    antiGrad           = derivation.GetAntiGradient(curPoint);
                    functionInCurPoint = function.Calculate(curPoint);
                    antiGradModule     = antiGrad.Pow(2).GetSumm();
                }
                Arguments nextPoint = curPoint + (antiGrad * curBeta);

                double functionInNextPoint = function.Calculate(nextPoint);

                if (!IsValidValue(antiGradModule))
                {
                    return(allPoints);
                }

                //F(Xk)-F(xk=B*antigrad(xk))>=epsilon|antigrad(xk)|^2
                double toTest     = antiGradModule * (curBeta * parameters.Epsilon);
                double toTestLeft = functionInCurPoint - functionInNextPoint;
                if (toTestLeft >= toTest)
                {
                    //add point it is normal
                    allPoints.Add(nextPoint);
                    double exitValue = (nextPoint - curPoint).GetModule();
                    if (exitValue < parameters.AccuracyEpsilon)
                    {
                        return(allPoints); //exit
                    }
                    else
                    {
                        curPoint = nextPoint;
                        // Increase step
                        Arguments antiGradNew = derivation.GetAntiGradient(curPoint);
                        antiGrad = antiGradNew;
                        bool      calculated    = false;
                        Arguments newValue      = null;
                        double    funcResultNew = 0;
                        Arguments oldValue      = null;
                        double    funcResultOld = 0;
                        for (; ;)
                        {
                            if (calculated)
                            {
                                oldValue      = newValue;
                                funcResultOld = funcResultNew;
                            }
                            else
                            {
                                oldValue      = curPoint + (antiGradNew * curBeta);
                                funcResultOld = function.Calculate(oldValue);
                            }

                            var nextInfinity = Double.IsInfinity(curBeta * parameters.M);
                            if (!nextInfinity)
                            {
                                curBeta = curBeta * parameters.M;
                                // Step is too big.
                                newValue      = curPoint + (antiGradNew * curBeta);
                                funcResultNew = function.Calculate(newValue);
                            }
                            calculated = true;

                            if (nextInfinity || funcResultOld <= funcResultNew)
                            {
                                curBeta      = curBeta / parameters.M;
                                staticBeta   = curBeta;
                                pointChanged = true;
                                curPoint     = curPoint + (antiGrad * curBeta);
                                curAlpha     = 0;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    pointChanged = false;

                    if (curAlpha == 0)
                    {
                        curAlpha = parameters.Alpha;
                    }
                    else
                    {
                        curAlpha = curAlpha * curAlpha;
                    }

                    curBeta = staticBeta * curAlpha;
                }
            }
        }