public void ConstructorTest2()
        {
            Func <double[], double> function =            // min f(x) = 10 * (x+1)^2 + y^2
                                               x => 10.0 * Math.Pow(x[0] + 1.0, 2.0) + Math.Pow(x[1], 2.0);

            Func <double[], double[]> gradient = x => new[] { 20 * (x[0] + 1), 2 * x[1] };


            double[] start = new double[2];

            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2,
                                                                                     function.Invoke, gradient.Invoke);

            Assert.IsTrue(target.Minimize());
            double minimum = target.Value;

            double[] solution = target.Solution;

            Assert.AreEqual(0, minimum, 1e-10);
            Assert.AreEqual(-1, solution[0], 1e-5);
            Assert.AreEqual(0, solution[1], 1e-5);

            double expectedMinimum = function(target.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Beispiel #2
0
        public Optimizer(MainViewModel viewModel)
        {
            this.viewModel = viewModel;

            bfgs           = new BroydenFletcherGoldfarbShanno(2, Function, Gradient);
            bfgs.Progress += Bfgs_Progress;
        }
        public void lbfgsTest3()
        {
            Accord.Math.Tools.SetupGenerator(0);

            Func <double[], double>   f;
            Func <double[], double[]> g;

            createExpDiff(out f, out g);

            int errors = 0;

            for (int i = 0; i < 10000; i++)
            {
                double[] start = Accord.Math.Matrix.Random(2, -1.0, 1.0);

                var lbfgs = new BroydenFletcherGoldfarbShanno(numberOfVariables: 2, function: f, gradient: g);

                lbfgs.Minimize(start);
                double   minValue = lbfgs.Value;
                double[] solution = lbfgs.Solution;

                double expected = -2;

                if (Math.Abs(expected - minValue) > 1e-3)
                {
                    errors++;
                }
            }

            Assert.IsTrue(errors < 800);
        }
Beispiel #4
0
        public OptimizationProgressEventArgs[] Actual(Specification problem)
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(problem.Variables)
            {
                Corrections        = m,
                Epsilon            = epsilon,
                Past               = past,
                Delta              = delta,
                MaxIterations      = max_iterations,
                LineSearch         = (LineSearch)linesearch,
                MaxLineSearch      = max_linesearch,
                MinStep            = min_step,
                MaxStep            = max_step,
                ParameterTolerance = ftol,
                Wolfe              = wolfe,
                GradientTolerance  = gtol,
                FunctionTolerance  = xtol,
                OrthantwiseC       = orthantwise_c,
                OrthantwiseStart   = orthantwise_start,
                OrthantwiseEnd     = orthantwise_end
            };

            target.Function = problem.Function;
            target.Gradient = problem.Gradient;

            actual.Clear();
            target.Progress += new EventHandler <OptimizationProgressEventArgs>(target_Progress);

            target.Minimize((double[])problem.Start.Clone());

            ActualMessage = target.Status.GetDescription();


            return(actual.ToArray());
        }
        public void lbfgsTest()
        {
            Func <double[], double>   f = rosenbrockFunction;
            Func <double[], double[]> g = rosenbrockGradient;

            Assert.AreEqual(104, f(new[] { -1.0, 2.0 }));


            int n = 2; // number of variables

            double[] initial = { -1.2, 1 };

            BroydenFletcherGoldfarbShanno lbfgs = new BroydenFletcherGoldfarbShanno(n, f, g);

            double actual   = lbfgs.Minimize(initial);
            double expected = 0;

            Assert.AreEqual(expected, actual, 1e-10);

            double[] result = lbfgs.Solution;

            Assert.AreEqual(49, lbfgs.Evaluations);
            Assert.AreEqual(40, lbfgs.Iterations);
            Assert.AreEqual(0.99999999999963229, result[0]);
            Assert.AreEqual(0.99999999999924027, result[1]);

            double y = f(result);

            double[] d = g(result);

            Assert.AreEqual(1.9432410039142452E-25, y);
            Assert.AreEqual(0.0000000000089901419642010907, d[0]);
            Assert.AreEqual(-0.0000000000048627768478581856, d[1]);
        }
Beispiel #6
0
 /// <summary>
 ///   Constructs a new L-BFGS learning algorithm.
 /// </summary>
 ///
 public QuasiNewtonHiddenLearning(HiddenConditionalRandomField <T> model)
     : base(model)
 {
     lbfgs           = new BroydenFletcherGoldfarbShanno(model.Function.Weights.Length);
     lbfgs.Tolerance = 1e-3;
     lbfgs.Function  = base.Objective;
     lbfgs.Gradient  = base.Gradient;
 }
Beispiel #7
0
        public void lbfgsTest2()
        {
            #region doc_minimize
            // Ensure that results are reproducible
            Accord.Math.Random.Generator.Seed = 0;

            // Suppose we would like to find the minimum of the function
            //
            //   f(x,y)  =  -exp{-(x-1)²} - exp{-(y-2)²/2}
            //

            // First we need write down the function either as a named
            // method, an anonymous method or as a lambda function:

            Func <double[], double> f = (x) =>
                                        - Math.Exp(-Math.Pow(x[0] - 1, 2)) - Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2));

            // Now, we need to write its gradient, which is just the
            // vector of first partial derivatives del_f / del_x, as:
            //
            //   g(x,y)  =  { del f / del x, del f / del y }
            //

            Func <double[], double[]> g = (x) => new double[]
            {
                // df/dx = {-2 e^(-    (x-1)^2) (x-1)}
                2 * Math.Exp(-Math.Pow(x[0] - 1, 2)) * (x[0] - 1),

                // df/dy = {-  e^(-1/2 (y-2)^2) (y-2)}
                Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2)) * (x[1] - 2)
            };

            // Finally, we create a L-BFGS solver for the two variable problem:
            var lbfgs = new BroydenFletcherGoldfarbShanno(numberOfVariables: 2)
            {
                Function = f,
                Gradient = g
            };

            // And then minimize the function:
            bool     success  = lbfgs.Minimize(); // should be true
            double   minValue = lbfgs.Value;      // should be -2
            double[] solution = lbfgs.Solution;   // should be (1, 2)

            // The resultant minimum value should be -2, and the solution
            // vector should be { 1.0, 2.0 }. The answer can be checked on
            // Wolfram Alpha by clicking the following the link:

            // http://www.wolframalpha.com/input/?i=maximize+%28exp%28-%28x-1%29%C2%B2%29+%2B+exp%28-%28y-2%29%C2%B2%2F2%29%29
            #endregion

            Assert.IsTrue(success);
            double expected = -2;
            Assert.AreEqual(expected, minValue, 1e-10);

            Assert.AreEqual(1, solution[0], 1e-3);
            Assert.AreEqual(2, solution[1], 1e-3);
        }
        public void NoGradientTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0
            };

            target.Minimize();
        }
        public void WrongGradientSizeTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0,
                Gradient = (x) => new double[1]
            };

            target.Minimize();
        }
        public void MutableGradientSizeTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0,
                Gradient = (x) => x
            };

            target.Minimize();
        }
Beispiel #11
0
        public void MutableGradientSizeTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0,
                Gradient = (x) => x
            };

            Assert.Throws <InvalidOperationException>(() => target.Minimize(), "");
        }
Beispiel #12
0
        /// <summary>
        ///   Constructs a new L-BFGS learning algorithm.
        /// </summary>
        ///
        public HiddenQuasiNewtonLearning(HiddenConditionalRandomField <T> model)
        {
            Model = model;

            calculator = new ForwardBackwardGradient <T>(model);

            lbfgs           = new BroydenFletcherGoldfarbShanno(model.Function.Weights.Length);
            lbfgs.Tolerance = 1e-3;
            lbfgs.Function  = calculator.Objective;
            lbfgs.Gradient  = calculator.Gradient;
        }
Beispiel #13
0
        public void NoGradientTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2)
            {
                Function = (x) => 0.0
            };

            Assert.IsTrue(target.Minimize());

            // The optimizer should use finite differences as the gradient
        }
        public static double[] InverseKinematics(List <MDHParameters> dht, double[] target, ref bool success)
        {
            Func <double[], double> f   = x => Distance(dht, target, x);
            var calculator              = new FiniteDifferences(dht.Count, f);
            Func <double[], double[]> g = calculator.Gradient;

            var optimizer = new BroydenFletcherGoldfarbShanno(numberOfVariables: dht.Count, function: f, gradient: g);

            optimizer.Minimize();
            success = !(optimizer.Value >= 0.01);

            return(optimizer.Solution);
        }
Beispiel #15
0
        public void lbfgsTest2()
        {
            Accord.Math.Tools.SetupGenerator(0);

            // Suppose we would like to find the minimum of the function
            //
            //   f(x,y)  =  -exp{-(x-1)²} - exp{-(y-2)²/2}
            //

            // First we need write down the function either as a named
            // method, an anonymous method or as a lambda function:

            Func <double[], double> f = (x) =>
                                        - Math.Exp(-Math.Pow(x[0] - 1, 2)) - Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2));

            // Now, we need to write its gradient, which is just the
            // vector of first partial derivatives del_f / del_x, as:
            //
            //   g(x,y)  =  { del f / del x, del f / del y }
            //

            Func <double[], double[]> g = (x) => new double[]
            {
                // df/dx = {-2 e^(-    (x-1)^2) (x-1)}
                2 * Math.Exp(-Math.Pow(x[0] - 1, 2)) * (x[0] - 1),

                // df/dy = {-  e^(-1/2 (y-2)^2) (y-2)}
                Math.Exp(-0.5 * Math.Pow(x[1] - 2, 2)) * (x[1] - 2)
            };

            // Finally, we can create the L-BFGS solver, passing the functions as arguments
            var lbfgs = new BroydenFletcherGoldfarbShanno(numberOfVariables: 2, function: f, gradient: g);

            // And then minimize the function:
            double minValue = lbfgs.Minimize();

            double[] solution = lbfgs.Solution;

            // The resultant minimum value should be -2, and the solution
            // vector should be { 1.0, 2.0 }. The answer can be checked on
            // Wolfram Alpha by clicking the following the link:

            // http://www.wolframalpha.com/input/?i=maximize+%28exp%28-%28x-1%29%C2%B2%29+%2B+exp%28-%28y-2%29%C2%B2%2F2%29%29

            double expected = -2;

            Assert.AreEqual(expected, minValue, 1e-10);

            Assert.AreEqual(1, solution[0], 1e-6);
            Assert.AreEqual(2, solution[1], 1e-6);
        }
Beispiel #16
0
        public static double[] Learn(double[][] X, double[] Y, double[] weights, double lambda = 0)
        {
            var    optimizationAlgorithm = new BroydenFletcherGoldfarbShanno(weights.Length);
            double m = Y.Length;

            optimizationAlgorithm.Function = (double[] t) =>
                                             (1.0 / 2.0 * m) * (X.Dot(t).Subtract(Y).Pow(2).Sum()) + (lambda / 2.0 * m) * (t.Pow(2).Sum());

            optimizationAlgorithm.Gradient = (double[] t) =>
                                             X.TransposeAndDot(X.Dot(t).Subtract(Y)).Divide(m).Add(t.Multiply(lambda / m));

            optimizationAlgorithm.Minimize(weights);
            return(optimizationAlgorithm.Solution
                   .To <double[]>());
        }
        public void InvalidLineSearchTest2()
        {
            int n = 10;

            Func <double[], double> function = (parameters) =>
            {
                return(-(n * Math.Log(0) - n * Math.Log(Math.PI)));
            };

            Func <double[], double[]> gradient = (parameters) =>
            {
                return(new[] { 2.0, Double.NegativeInfinity });
            };

            double[] start = { 0, 0 };

            var lbfgs = new BroydenFletcherGoldfarbShanno(2, function, gradient);

            bool success = lbfgs.Minimize(start);

            Assert.IsFalse(success);
        }
        public void lbfgsTest()
        {
            Func <double[], double>   f = rosenbrockFunction;
            Func <double[], double[]> g = rosenbrockGradient;

            Assert.AreEqual(104, f(new[] { -1.0, 2.0 }));


            int n = 2; // number of variables

            double[] initial = { -1.2, 1 };

            var lbfgs = new BroydenFletcherGoldfarbShanno(n, f, g);

            double expected = 0;

            Assert.IsTrue(lbfgs.Minimize(initial));

            bool   success = lbfgs.Minimize();
            double actual  = lbfgs.Value;

            Assert.IsTrue(success);

            Assert.AreEqual(expected, actual, 1e-10);

            double[] result = lbfgs.Solution;

            Assert.AreEqual(1.0, result[0], 1e-5);
            Assert.AreEqual(1.0, result[1], 1e-5);

            double y = f(result);

            double[] d = g(result);

            Assert.AreEqual(0, y, 1e-10);
            Assert.AreEqual(0, d[0], 1e-6);
            Assert.AreEqual(0, d[1], 1e-6);
        }
        public void ConstructorTest3()
        {
            // minimize f(x) = x*y*z,
            // s.t.
            //
            //    1 - x² - 2y² - 3z² > 0
            //    x > 0,
            //    y > 0
            //

            // Easy three dimensional minimization in ellipsoid.
            var function = new NonlinearObjectiveFunction(3,
                                                          function: x => x[0] * x[1] * x[2],
                                                          gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] });

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(3,
                                        function: x => 1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2],
                                        gradient: x => new[] { -2.0 * x[0],                               -4.0 * x[1], -6.0 * x[2] }),
                new NonlinearConstraint(3,
                                        function: x => x[0],
                                        gradient: x => new[] { 1.0,                                                 0,           0 }),
                new NonlinearConstraint(3,
                                        function: x => x[1],
                                        gradient: x => new[] { 0,                                                 1.0,           0 }),
                new NonlinearConstraint(3,
                                        function: x => - x[2],
                                        gradient: x => new[] { 0,                                                   0,        -1.0 }),
            };

            for (int i = 0; i < constraints.Length; i++)
            {
                Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe);
                Assert.AreEqual(0, constraints[i].Value);
            }

            var inner = new BroydenFletcherGoldfarbShanno(3);

            inner.LineSearch  = LineSearch.BacktrackingArmijo;
            inner.Corrections = 10;

            var solver = new AugmentedLagrangian(inner, function, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;

            double[] solution = solver.Solution;

            double[] expected =
            {
                1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0
            };


            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], solver.Solution[i], 1e-3);
            }
            Assert.AreEqual(-0.078567420132031968, minimum, 1e-4);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Beispiel #20
0
        public static void FitCTF(float2[] data, Func <float[], float[]> approximation, float[] zeros, float[] peaks, out Cubic1D background, out Cubic1D scale)
        {
            float MinX = MathHelper.Min(data.Select(p => p.X)), MaxX = MathHelper.Max(data.Select(p => p.X)), ScaleX = 1f / (MaxX - MinX);
            float MinY = MathHelper.Min(data.Select(p => p.Y)), MaxY = MathHelper.Max(data.Select(p => p.Y)), ScaleY = 1f / (MaxY - MinY);

            if (float.IsNaN(ScaleY))
            {
                ScaleY = 1f;
            }

            peaks = peaks.Where(v => v >= MinX && v <= MaxX).Where((v, i) => i % 1 == 0).ToArray();
            zeros = zeros.Where(v => v >= MinX && v <= MaxX).Where((v, i) => i % 1 == 0).ToArray();

            float2[] ScaledData = data.Select(p => new float2((p.X - MinX) * ScaleX, (p.Y - MinY) * ScaleY)).ToArray();
            float    StdY       = MathHelper.StdDev(data.Select(p => p.Y).ToArray());

            double[] Start      = new double[zeros.Length + peaks.Length];
            double[] NodeX      = new double[zeros.Length + peaks.Length];
            Cubic1D  DataSpline = new Cubic1D(data);

            for (int i = 0; i < zeros.Length; i++)
            {
                NodeX[i] = (zeros[i] - MinX) * ScaleX;
                Start[i] = DataSpline.Interp(zeros[i]) - MinY;
            }
            {
                Cubic1D PreliminaryBackground = new Cubic1D(Helper.Zip(NodeX.Take(zeros.Length).Select(v => (float)v).ToArray(),
                                                                       Start.Take(zeros.Length).Select(v => (float)v).ToArray()));
                float[]  PreliminaryInterpolated = PreliminaryBackground.Interp(data.Select(v => (v.X - MinX) * ScaleX).ToArray());
                float2[] BackgroundSubtracted    = data.Select((v, i) => new float2(v.X, v.Y - MinY - PreliminaryInterpolated[i])).ToArray();
                Cubic1D  BackgroundSpline        = new Cubic1D(BackgroundSubtracted);

                for (int i = 0; i < peaks.Length; i++)
                {
                    NodeX[i + zeros.Length] = (peaks[i] - MinX) * ScaleX;
                    float PeakValue = BackgroundSpline.Interp(peaks[i]);
                    Start[i + zeros.Length] = Math.Max(0.0001f, PeakValue);
                }
            }

            float[] DataX         = ScaledData.Select(p => p.X).ToArray();
            float[] OriginalDataX = data.Select(p => p.X).ToArray();
            float[] SimulatedCTF  = approximation(OriginalDataX);

            float2[] NodesBackground = new float2[zeros.Length];
            for (int i = 0; i < NodesBackground.Length; i++)
            {
                NodesBackground[i] = new float2((float)NodeX[i], 0f);
            }
            float2[] NodesScale = new float2[peaks.Length];
            for (int i = 0; i < NodesScale.Length; i++)
            {
                NodesScale[i] = new float2((float)NodeX[i + zeros.Length], 0f);
            }

            Func <double[], double> Eval = input =>
            {
                float2[] NodesBackgroundCopy = new float2[NodesBackground.Length];
                for (int i = 0; i < zeros.Length; i++)
                {
                    NodesBackgroundCopy[i] = new float2(NodesBackground[i].X, (float)input[i]);
                }

                float2[] NodesScaleCopy = new float2[NodesScale.Length];
                for (int i = 0; i < peaks.Length; i++)
                {
                    NodesScaleCopy[i] = new float2(NodesScale[i].X, (float)input[i + zeros.Length]);
                }

                float[] InterpolatedBackground = new Cubic1D(NodesBackgroundCopy).Interp(DataX);
                float[] InterpolatedScale      = new Cubic1D(NodesScaleCopy).Interp(DataX);

                double Sum = 0f;
                for (int i = 0; i < ScaledData.Length; i++)
                {
                    double Diff = ScaledData[i].Y - (InterpolatedBackground[i] + SimulatedCTF[i] * (double)InterpolatedScale[i]) * ScaleY;
                    Sum += Diff * Diff;
                    if (InterpolatedScale[i] < 0.0005f)
                    {
                        Sum += (0.0005 - InterpolatedScale[i]) * 10;
                    }
                }

                //return Math.Sqrt(Sum / data.Length) * 10;
                return(0);
            };

            Func <double[], double[]> Gradient = input =>
            {
                double[] Result = new double[input.Length];

                //Parallel.For(0, input.Length, i =>
                for (int i = 0; i < input.Length; i++)
                {
                    double[] UpperInput = new double[input.Length];
                    input.CopyTo(UpperInput, 0);
                    UpperInput[i] += 0.0001;
                    double UpperValue = Eval(UpperInput);

                    double[] LowerInput = new double[input.Length];
                    input.CopyTo(LowerInput, 0);
                    LowerInput[i] -= 0.0001;
                    double LowerValue = Eval(LowerInput);

                    Result[i] = (UpperValue - LowerValue) / 0.0002;
                }//);

                return(Result);
            };

            BroydenFletcherGoldfarbShanno Optimizer = new BroydenFletcherGoldfarbShanno(Start.Length, Eval, Gradient);

            Optimizer.Minimize(Start);

            {
                for (int i = 0; i < zeros.Length; i++)
                {
                    NodesBackground[i] = new float2((float)NodeX[i] / ScaleX + MinX, (float)Optimizer.Solution[i] + MinY);
                }
                for (int i = 0; i < peaks.Length; i++)
                {
                    NodesScale[i] = new float2((float)NodeX[i + zeros.Length] / ScaleX + MinX, Math.Max(0.001f, (float)Optimizer.Solution[i + zeros.Length]));
                }

                background = new Cubic1D(NodesBackground);
                scale      = new Cubic1D(NodesScale);
            }
        }
Beispiel #21
0
        public void constructorTest5()
        {
            // AugmentedLagrangian with NonlinearConstraints
            // have a Gradient NullReferenceException issue
            // https://github.com/accord-net/framework/issues/177

            // Easy three dimensional minimization in ellipsoid.
            var function = new NonlinearObjectiveFunction(3,
                                                          function: x => x[0] * x[1] * x[2],
                                                          gradient: x => new[] { x[1] * x[2], x[0] * x[2], x[0] * x[1] });

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(function,
                                        constraint: x => (1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2]) >= 0,
                                        gradient: x => new[] { -2.0 * x[0],                                        -4.0 * x[1], -6.0 * x[2] }),
                new NonlinearConstraint(function,
                                        constraint: x => x[0] >= 0,
                                        gradient: x => new[] { 1.0,                                                          0,           0 }),
                new NonlinearConstraint(function,
                                        constraint: x => x[1] >= 0,
                                        gradient: x => new[] { 0,                                                          1.0,           0 }),
                new NonlinearConstraint(function,
                                        constraint: x => - x[2] >= 0,
                                        gradient: x => new[] { 0,                                                            0,        -1.0 }),
            };

            for (int i = 0; i < constraints.Length; i++)
            {
                Assert.AreEqual(ConstraintType.GreaterThanOrEqualTo, constraints[i].ShouldBe);
                Assert.AreEqual(0, constraints[i].Value);
            }

            var inner = new BroydenFletcherGoldfarbShanno(3);

            inner.LineSearch  = LineSearch.BacktrackingArmijo;
            inner.Corrections = 10;

            var solver = new AugmentedLagrangian(inner, function, constraints);

            Assert.AreEqual(inner, solver.Optimizer);

            Assert.IsTrue(solver.Minimize());
            double minimum = solver.Value;

            double[] solution = solver.Solution;

            double[] expected =
            {
                1.0 / Math.Sqrt(3.0), 1.0 / Math.Sqrt(6.0), -1.0 / 3.0
            };


            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], solver.Solution[i], 1e-3);
            }
            Assert.AreEqual(-0.078567420132031968, minimum, 1e-4);

            double expectedMinimum = function.Function(solver.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
Beispiel #22
0
        private void init(NonlinearObjectiveFunction function,
                          IEnumerable <IConstraint> constraints, IGradientOptimizationMethod innerSolver)
        {
            if (function is not null)
            {
                if (function.NumberOfVariables != NumberOfVariables)
                {
                    throw new ArgumentOutOfRangeException("function",
                                                          "Incorrect number of variables in the objective function. " +
                                                          "The number of variables must match the number of variables set in the solver.");
                }

                Function = function.Function;
                Gradient = function.Gradient;
            }

            if (innerSolver is null)
            {
                innerSolver = new BroydenFletcherGoldfarbShanno(NumberOfVariables)
                {
                    LineSearch    = LineSearch.BacktrackingArmijo,
                    Corrections   = 10,
                    Epsilon       = 1e-10,
                    MaxIterations = 100000
                };
            }

            var equality    = new List <IConstraint>();
            var lesserThan  = new List <IConstraint>();
            var greaterThan = new List <IConstraint>();

            foreach (var c in constraints)
            {
                switch (c.ShouldBe)
                {
                case ConstraintType.EqualTo:
                    equality.Add(c); break;

                case ConstraintType.GreaterThanOrEqualTo:
                    greaterThan.Add(c); break;

                case ConstraintType.LesserThanOrEqualTo:
                    lesserThan.Add(c); break;

                default:
                    throw new ArgumentException("Unknown constraint type.", "constraints");
                }
            }

            lesserThanConstraints  = lesserThan.ToArray();
            greaterThanConstraints = greaterThan.ToArray();
            equalityConstraints    = equality.ToArray();

            lambda = new double[equalityConstraints.Length];
            mu     = new double[lesserThanConstraints.Length];
            nu     = new double[greaterThanConstraints.Length];

            g = new double[NumberOfVariables];

            dualSolver          = innerSolver;
            dualSolver.Function = objectiveFunction;
            dualSolver.Gradient = objectiveGradient;
        }
Beispiel #23
0
        public static Image AlignLocallyToTarget(Image map, Image target, int alignmentSize, int oversampling, out float3 shift, out float3 rotation)
        {
            float ScaleFactor = (float)alignmentSize / map.Dims.X;
            int3  DimsScaled  = new int3(alignmentSize, alignmentSize, alignmentSize);

            #region Prepare Scaled & FFTed maps

            Image MapScaled = map.AsScaled(DimsScaled);
            map.FreeDevice();

            Image TargetScaled = target.AsScaled(DimsScaled);
            target.FreeDevice();
            TargetScaled.RemapToFT(true);
            TargetScaled.WriteMRC("d_targetscaled.mrc", true);
            Image TargetScaledFT = TargetScaled.AsFFT(true);
            TargetScaled.Dispose();

            Projector ProjMapScaled = new Projector(MapScaled, oversampling);
            Image     TestFT        = ProjMapScaled.Project(DimsScaled, new float3[1]);
            Image     Test          = TestFT.AsIFFT(true);
            Test.RemapFromFT(true);
            Test.WriteMRC("d_projected.mrc", true);

            #endregion

            float3 CurShift = new float3(), CurRotation = new float3();

            Func <double[], double> GetDiff         = input =>
            {
                CurShift    = new float3((float)input[0], (float)input[1], (float)input[2]);
                CurRotation = new float3((float)input[3], (float)input[4], (float)input[5]) * Helper.ToRad;
                CurRotation = Matrix3.EulerFromMatrix(Matrix3.RotateX(CurRotation.X) * Matrix3.RotateY(CurRotation.Y) * Matrix3.RotateZ(CurRotation.Z)) * Helper.ToDeg;

                Image TargetFTShifted = TargetScaledFT.AsShiftedVolume(-CurShift * ScaleFactor);
                Image MapRotatedFT    = ProjMapScaled.Project(DimsScaled, new[] { CurRotation *Helper.ToRad });

                GPU.MultiplySlices(TargetFTShifted.GetDevice(Intent.Read),
                                   MapRotatedFT.GetDevice(Intent.Read),
                                   TargetFTShifted.GetDevice(Intent.Write),
                                   TargetFTShifted.ElementsReal,
                                   1);
                MapRotatedFT.Dispose();

                IntPtr d_Sum = GPU.MallocDevice(1);
                GPU.Sum(TargetFTShifted.GetDevice(Intent.Read), d_Sum, (uint)TargetFTShifted.ElementsReal, 1);
                TargetFTShifted.Dispose();

                float[] h_Sum = new float[1];
                GPU.CopyDeviceToHost(d_Sum, h_Sum, 1);

                GPU.FreeDevice(d_Sum);

                return(h_Sum[0]);
            };

            Func <double[], double[]> GetGradient   = input =>
            {
                float    Delta  = 0.05f;
                double[] Result = new double[input.Length];

                Console.WriteLine(GetDiff(input));

                for (int i = 0; i < input.Length; i++)
                {
                    double[] InputPlus = input.ToList().ToArray();
                    InputPlus[i] += Delta;
                    double ScorePlus = GetDiff(InputPlus);

                    double[] InputMinus = input.ToList().ToArray();
                    InputMinus[i] -= Delta;
                    double ScoreMinus = GetDiff(InputMinus);

                    Result[i] = (ScorePlus - ScoreMinus) / (Delta * 2);
                }

                return(Result);
            };

            double[] StartParams                    = new double[6];
            BroydenFletcherGoldfarbShanno Optimizer = new BroydenFletcherGoldfarbShanno(StartParams.Length, GetDiff, GetGradient);
            Optimizer.MaxIterations = 20;
            Optimizer.Maximize(StartParams);

            GetDiff(StartParams);
            shift    = CurShift;
            rotation = CurRotation;

            #region Shift and rotate input map by determined values for final output

            ProjMapScaled.Dispose();
            Image MapResult = map.AsShiftedVolume(shift);
            map.FreeDevice();

            Projector ProjMapResult = new Projector(MapResult, oversampling);
            MapResult.Dispose();

            Image MapResultFT = ProjMapResult.Project(map.Dims, new[] { rotation *Helper.ToRad });
            ProjMapResult.Dispose();

            MapResult = MapResultFT.AsIFFT(true);
            MapResultFT.Dispose();
            MapResult.RemapFromFT(true);

            #endregion

            return(MapResult);
        }
        /// <summary>
        ///   Fits the underlying distribution to a given set of observations.
        /// </summary>
        ///
        /// <param name="observations">The array of observations to fit the model against. The array
        ///   elements can be either of type double (for univariate data) or
        ///   type double[] (for multivariate data).</param>
        /// <param name="weights">The weight vector containing the weight for each of the samples.</param>
        /// <param name="options">Optional arguments which may be used during fitting, such
        ///   as regularization constants and additional parameters.</param>
        ///
        /// <remarks>
        ///   Although both double[] and double[][] arrays are supported,
        ///   providing a double[] for a multivariate distribution or a
        ///   double[][] for a univariate distribution may have a negative
        ///   impact in performance.
        /// </remarks>
        ///
        public void Fit(double[] observations, double[] weights, CauchyOptions options)
        {
            if (immutable)
            {
                throw new InvalidOperationException("This object can not be modified.");
            }

            if (weights != null)
            {
                throw new ArgumentException("This distribution does not support weighted samples.");
            }

            bool useMLE    = true;
            bool estimateT = true;
            bool estimateS = true;

            if (options != null)
            {
                useMLE    = options.MaximumLikelihood;
                estimateT = options.EstimateLocation;
                estimateS = options.EstimateScale;
            }


            double t = location;
            double s = scale;

            int n = observations.Length;


            DoubleRange range;
            double      median = Accord.Statistics.Tools.Quartiles(observations, out range, alreadySorted: false);

            if (estimateT)
            {
                t = median;
            }

            if (estimateS)
            {
                s = range.Length;
            }


            if (useMLE)
            {
                // Minimize the log-likelihood through numerical optimization
                BroydenFletcherGoldfarbShanno lbfgs = new BroydenFletcherGoldfarbShanno(2);


                // Define the negative log-likelihood function,
                // which is the objective we want to minimize:
                lbfgs.Function = (parameters) =>
                {
                    // Assume location is the first
                    // parameter, shape is the second
                    if (estimateT)
                    {
                        t = parameters[0];
                    }
                    if (estimateS)
                    {
                        s = parameters[1];
                    }

                    if (s < 0)
                    {
                        s = -s;
                    }

                    double sum = 0;
                    for (int i = 0; i < observations.Length; i++)
                    {
                        double y = (observations[i] - t);
                        sum += Math.Log(s * s + y * y);
                    }

                    return(-(n * Math.Log(s) - sum - n * Math.Log(Math.PI)));
                };


                lbfgs.Gradient = (parameters) =>
                {
                    // Assume location is the first
                    // parameter, shape is the second
                    if (estimateT)
                    {
                        t = parameters[0];
                    }
                    if (estimateS)
                    {
                        s = parameters[1];
                    }

                    double sum1 = 0, sum2 = 0;
                    for (int i = 0; i < observations.Length; i++)
                    {
                        double y = (observations[i] - t);
                        sum1 += y / (s * s + y * y);
                        sum2 += s / (s * s + y * y);
                    }

                    double dt = -2.0 * sum1;
                    double ds = +2.0 * sum2 - n / s;

                    double[] g = new double[2];
                    g[0] = estimateT ? dt : 0;
                    g[1] = estimateS ? ds : 0;

                    return(g);
                };


                // Initialize using the sample median as starting
                // value for location, and half interquartile range
                // for shape.

                double[] values = { t, s };

                // Minimize
                double error = lbfgs.Minimize(values);

                // Check solution
                t = lbfgs.Solution[0];
                s = lbfgs.Solution[1];
            }


            init(t, s); // Become the new distribution
        }
Beispiel #25
0
        public void NoFunctionTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2);

            Assert.Throws <InvalidOperationException>(() => target.Minimize(), "");
        }
Beispiel #26
0
 /// <summary>
 ///   Constructs a new L-BFGS learning algorithm.
 /// </summary>
 ///
 public QuasiNewtonLearning(ConditionalRandomField <T> model)
 {
     this.model           = model;
     this.lbfgs           = new BroydenFletcherGoldfarbShanno(model.Function.Weights.Length);
     this.lbfgs.Tolerance = 1e-3;
 }
Beispiel #27
0
        public static void FitCTF(float2[] data, float[] simulation, float[] zeros, float[] peaks, out Cubic1D background, out Cubic1D scale)
        {
            if (zeros.Length < 2 || peaks.Length < 1)
            {
                background = new Cubic1D(new[] { new float2(0, 0), new float2(1, 0) });
                scale      = new Cubic1D(new[] { new float2(0, 1), new float2(1, 1) });

                return;
            }

            float MinX = MathHelper.Min(data.Select(p => p.X)), MaxX = MathHelper.Max(data.Select(p => p.X)), ScaleX = 1f / (MaxX - MinX);

            peaks = peaks.Where(v => v >= MinX && v <= MaxX).Where((v, i) => i % 1 == 0).ToArray();
            zeros = zeros.Where(v => v >= MinX && v <= MaxX).Where((v, i) => i % 1 == 0).ToArray();

            List <float2> Peaks = new List <float2>(), Zeros = new List <float2>();

            foreach (var zero in zeros)
            {
                int   Pos    = (int)((zero - MinX) * ScaleX * data.Length);
                int   First  = Math.Max(0, Pos - 1);
                int   Last   = Math.Min(data.Length - 1, Pos + 1);
                float MinVal = data[First].Y;
                for (int i = First; i < Last; i++)
                {
                    MinVal = Math.Min(MinVal, data[i].Y);
                }
                Zeros.Add(new float2(zero, MinVal));
            }
            float[]  Background     = (new Cubic1D(Zeros.ToArray())).Interp(data.Select(v => v.X).ToArray());
            float2[] DataSubtracted = Helper.ArrayOfFunction(i => new float2(data[i].X, data[i].Y - Background[i]), Background.Length);

            for (int z = 0; z < Zeros.Count; z++)
            {
                float2 Zero = Zeros[z];

                int   Pos    = (int)((Zero.X - MinX) * ScaleX * DataSubtracted.Length);
                int   First  = Math.Max(0, Pos - 1);
                int   Last   = Math.Min(DataSubtracted.Length, Pos + 1);
                float MinVal = DataSubtracted[First].Y;
                for (int i = First; i < Last; i++)
                {
                    MinVal = Math.Min(MinVal, DataSubtracted[i].Y);
                }

                Zeros[z] = new float2(Zero.X, Zero.Y + MinVal);
            }
            Background     = (new Cubic1D(Zeros.ToArray())).Interp(data.Select(v => v.X).ToArray());
            DataSubtracted = Helper.ArrayOfFunction(i => new float2(data[i].X, data[i].Y - Background[i]), Background.Length);

            float GlobalMax = 0;

            foreach (var peak in peaks)
            {
                int   Pos    = (int)((peak - MinX) * ScaleX * DataSubtracted.Length);
                int   First  = Math.Max(0, Pos - 1);
                int   Last   = Math.Min(DataSubtracted.Length, Pos + 1);
                float MaxVal = GlobalMax * 0.05f;// DataSubtracted[First].Y;
                for (int i = First; i < Last; i++)
                {
                    MaxVal = Math.Max(MaxVal, DataSubtracted[i].Y);
                }
                Peaks.Add(new float2(peak, MaxVal));
                GlobalMax = Math.Max(MaxVal, GlobalMax);
            }

            background = Zeros.Count > 1 ? new Cubic1D(Zeros.ToArray()) : new Cubic1D(new[] { new float2(0, 0), new float2(1, 0) });
            scale      = Peaks.Count > 1 ? new Cubic1D(Peaks.ToArray()) : new Cubic1D(new[] { new float2(0, 1), new float2(1, 1) });

            return;

            int EveryNth = 1;

            float[] ZerosX = new float[Zeros.Count / EveryNth];
            for (int i = 0; i < ZerosX.Length; i++)
            {
                ZerosX[i] = Zeros[i * EveryNth].X;
            }

            float[] PeaksX = new float[Peaks.Count / EveryNth];
            for (int i = 0; i < PeaksX.Length; i++)
            {
                PeaksX[i] = Peaks[i * EveryNth].X;
            }

            float[] DataX = data.Select(v => v.X).ToArray();
            float[] DataY = data.Select(v => v.Y).ToArray();

            Func <double[], double> Eval = (input) =>
            {
                Cubic1D SplineBackground = new Cubic1D(Helper.ArrayOfFunction(i => new float2(ZerosX[i], (float)Math.Exp(input[i])), ZerosX.Length));
                Cubic1D SplineScale      = new Cubic1D(Helper.ArrayOfFunction(i => new float2(PeaksX[i], (float)Math.Exp(input[i + ZerosX.Length])), PeaksX.Length));

                float[] ContinuumBackground = SplineBackground.Interp(DataX);
                float[] ContinuumScale      = SplineScale.Interp(DataX);

                float[] Diff   = Helper.ArrayOfFunction(i => ContinuumBackground[i] + ContinuumScale[i] * simulation[i] - DataY[i], ContinuumBackground.Length);
                float   DiffSq = 0;
                for (int i = 0; i < Diff.Length; i++)
                {
                    DiffSq += Diff[i] * Diff[i];
                }

                return(DiffSq);
            };

            Func <double[], double[]> Grad = (input) =>
            {
                double   CurrentValue = Eval(input);
                double[] Result       = new double[input.Length];

                Parallel.For(0, input.Length, i =>
                {
                    double Delta       = 1e-5;
                    double[] InputPlus = input.ToArray();
                    InputPlus[i]      += Delta;

                    Result[i] = (Eval(InputPlus) - CurrentValue) / Delta;
                });

                return(Result);
            };

            double[] ResampledBackground = background.Interp(ZerosX).Select(v => Math.Log(Math.Max(v, 1e-5))).ToArray();
            double[] ResampledScale      = scale.Interp(PeaksX).Select(v => Math.Log(Math.Max(v, 1e-5))).ToArray();
            double[] StartParams         = Helper.Combine(ResampledBackground, ResampledScale);

            BroydenFletcherGoldfarbShanno Optimizer = new BroydenFletcherGoldfarbShanno(StartParams.Length, Eval, Grad);

            Optimizer.MaxIterations = 10;

            Optimizer.Minimize(StartParams);

            background = new Cubic1D(Helper.ArrayOfFunction(i => new float2(ZerosX[i], (float)Math.Exp(StartParams[i])), ZerosX.Length));
            scale      = new Cubic1D(Helper.ArrayOfFunction(i => new float2(PeaksX[i], (float)Math.Exp(StartParams[i + ZerosX.Length])), PeaksX.Length));
        }
        public void NoFunctionTest()
        {
            BroydenFletcherGoldfarbShanno target = new BroydenFletcherGoldfarbShanno(2);

            target.Minimize();
        }