コード例 #1
0
        /// <summary>
        /// Find value x that minimizes the scalar function f(x), constrained within bounds, using the Golden Section algorithm.
        /// For more options and diagnostics consider to use <see cref="GoldenSectionMinimizer"/> directly.
        /// </summary>
        public static double OfScalarFunctionConstrained(Func <double, double> function, double lowerBound, double upperBound, double tolerance = 1e-5, int maxIterations = 1000)
        {
            var objective = ObjectiveFunction.ScalarValue(function);
            var result    = GoldenSectionMinimizer.Minimum(objective, lowerBound, upperBound, tolerance, maxIterations);

            return(result.MinimizingPoint);
        }
コード例 #2
0
        public void Test_Works()
        {
            var algorithm = new GoldenSectionMinimizer(1e-5, 1000);
            var f1        = new Func <double, double>(x => (x - 3) * (x - 3));
            var obj       = ObjectiveFunction.ScalarValue(f1);
            var r1        = GoldenSectionMinimizer.Minimum(obj, -100, 100);

            Assert.That(Math.Abs(r1.MinimizingPoint - 3.0), Is.LessThan(1e-4));
        }
コード例 #3
0
        // try this for multiparameter optimization: https://numerics.mathdotnet.com/api/MathNet.Numerics.Optimization.TrustRegion/index.htm

        // Golden Section Minimizer
        public static Value Argmin(Value function, Value lowerBound, Value upperBound, Value tolerance, Netlist netlist, Style style, int s)
        {
            if (!(lowerBound is NumberValue) || !(upperBound is NumberValue))
            {
                throw new Error("argmin: expecting numbers for lower and upper bounds");
            }
            double lower = (lowerBound as NumberValue).value;
            double upper = (upperBound as NumberValue).value;

            if (lower > upper)
            {
                throw new Error("argmin: lower bound greater than upper bound");
            }
            if (!(function is FunctionValue))
            {
                throw new Error("argmin: expecting a function as first argument");
            }
            FunctionValue closure = function as FunctionValue;

            if (closure.parameters.parameters.Count != 1)
            {
                throw new Error("argmin: initial values and function parameters have different lengths");
            }

            IScalarObjectiveFunction objectiveFunction = ObjectiveFunction.ScalarValue(
                (double parameter) => {
                List <Value> arguments = new List <Value>(); arguments.Add(new NumberValue(parameter));
                bool autoContinue      = netlist.autoContinue; netlist.autoContinue = true;
                Value result           = closure.ApplyReject(arguments, netlist, style, s);
                if (result == null)
                {
                    throw new Error("Objective function returned null");
                }
                netlist.autoContinue = autoContinue;
                if (!(result is NumberValue))
                {
                    throw new Error("Objective function must return a number, not: " + result.Format(style));
                }
                KGui.gui.GuiOutputAppendText("argmin: parameter=" + Style.FormatSequence(arguments, ", ", x => x.Format(style)) + " => cost=" + result.Format(style) + Environment.NewLine);
                return((result as NumberValue).value);
            });

            try {
                ScalarMinimizationResult result = GoldenSectionMinimizer.Minimum(objectiveFunction, lower, upper);
                if (result.ReasonForExit == ExitCondition.Converged || result.ReasonForExit == ExitCondition.BoundTolerance)
                {
                    KGui.gui.GuiOutputAppendText("argmin: converged with parameter=" + result.MinimizingPoint + " and reason '" + result.ReasonForExit + "'" + Environment.NewLine);
                    return(new NumberValue(result.MinimizingPoint));
                }
                else
                {
                    throw new Error("reason '" + result.ReasonForExit.ToString() + "'");
                }
            } catch (Exception e) { throw new Error("argmin ended: " + ((e.InnerException == null) ? e.Message : e.InnerException.Message)); } // somehow we need to recatch the inner exception coming from CostAndGradient
        }
コード例 #4
0
        /// <summary>
        /// 只有一个参数时的拟合方法
        /// </summary>
        public double[] ScalarHuberLossSolver()
        {
            var f1     = new Func <double, double>(ScalarHuberLoss);
            var obj    = ObjectiveFunction.ScalarValue(f1);
            var r1     = GoldenSectionMinimizer.Minimum(obj, -10, 10);
            var theta1 = r1.MinimizingPoint;

            Console.WriteLine("theta1 = " + theta1);//最小时的 x 值 -> theta1
            Console.WriteLine("Minimum Loss = " + ScalarHuberLoss(theta1));
            scalarPred = new double[_xArr.Length];
            for (var i = 0; i < _xArr.Length; i++)
            {
                //输出预测的y值
                scalarPred[i] = theta1 * _xArr[i];
            }

            return(scalarPred);
        }