コード例 #1
0
        public void ConstructorTest6_3()
        {
            bool thrown = false;

            try
            {
                var function = new NonlinearObjectiveFunction(2, x => - x[0] - x[1]);

                NonlinearConstraint[] constraints =
                {
                    new NonlinearConstraint(2, x => x[1] - x[0] * x[0]),
                    new NonlinearConstraint(4, x => 1.0 - x[0] * x[0] - x[1] * x[1]),
                };

                Cobyla cobyla = new Cobyla(function, constraints);

                Assert.IsTrue(cobyla.Minimize());
                double minimum = cobyla.Value;
            }
            catch (Exception)
            {
                thrown = true;
            }

            Assert.IsTrue(thrown);
        }
コード例 #2
0
        public void ConstructorTest2_2()
        {
            var function = new NonlinearObjectiveFunction(2, x => x[0] * x[1]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(2, x => x[0] * x[0] + x[1] * x[1] <= 1.0)
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

            bool   success = cobyla.Minimize();
            double minimum = cobyla.Value;

            Assert.IsTrue(success);

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

            Assert.AreEqual(-0.5, minimum, 1e-10);
            Assert.AreEqual(sqrthalf, solution[0], 1e-5);
            Assert.AreEqual(-sqrthalf, solution[1], 1e-5);
        }
コード例 #3
0
        public void ConstructorTest6_2()
        {
            /// This problem is taken from Fletcher's book Practical Methods of
            /// Optimization and has the equation number (9.1.15).
            var function = new NonlinearObjectiveFunction(2, x => - x[0] - x[1]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(2, x => - (x[1] - x[0] * x[0]) <= 0),
                new NonlinearConstraint(2, x => - (-x[0] * x[0] - x[1] * x[1]) <= 1.0),
            };

            Cobyla cobyla = new Cobyla(function, constraints);

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

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

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

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #4
0
        public void ConstructorTest7()
        {
            /// This problem is taken from Fletcher's book Practical Methods of
            /// Optimization and has the equation number (14.4.2).
            var function = new NonlinearObjectiveFunction(3, x => x[2]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(3, x => 5.0 * x[0] - x[1] + x[2]),
                new NonlinearConstraint(3, x => x[2] - x[0] * x[0] - x[1] * x[1] - 4.0 * x[1]),
                new NonlinearConstraint(3, x => x[2] - 5.0 * x[0] - x[1]),
            };

            Cobyla cobyla = new Cobyla(function, constraints);

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

            double[] solution = cobyla.Solution;

            Assert.AreEqual(-3, minimum, 1e-5);
            Assert.AreEqual(0.0, solution[0], 1e-5);
            Assert.AreEqual(-3.0, solution[1], 1e-5);
            Assert.AreEqual(-3.0, solution[2], 1e-5);

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #5
0
        public void ConstructorTest2_1()
        {
            var function = new NonlinearObjectiveFunction(2, x => x[0] * x[1]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(function,                           x => x[0] * x[0] + x[1] * x[1],
                                        ConstraintType.LesserThanOrEqualTo, 1.0)
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

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

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

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

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #6
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest2()
        {
            var function = new NonlinearObjectiveFunction(2, x => x[0] * x[1]);

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(function, x => 1.0 - x[0] * x[0] - x[1] * x[1])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
                cobyla.Solution[i] = 1;

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

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

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

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #7
0
        public void FindMinimum_LogOutputToConsole_VisualInspection()
        {
            var optimizer = new Cobyla(9, 14, calcfc10)
            {
                PrintLevel = 2, Logger = Console.Out
            };

            optimizer.FindMinimum(Enumerable.Repeat(1.0, 9).ToArray());
        }
コード例 #8
0
ファイル: CobylaTest.cs プロジェクト: zhenyao2008/ai4unity
        public void ConstructorTest10()
        {
            /// This problem is taken from page 415 of Luenberger's book Applied
            /// Nonlinear Programming. It is to maximize the area of a hexagon of
            /// unit diameter.
            ///
            var function = new NonlinearObjectiveFunction(9, x =>
                                                          - 0.5 * (x[0] * x[3] - x[1] * x[2] + x[2] * x[8]
                                                                   - x[4] * x[8] + x[4] * x[7] - x[5] * x[6]));

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(9, x => 1.0 - x[2] * x[2] - x[3] * x[3]),
                new NonlinearConstraint(9, x => 1.0 - x[8] * x[8]),
                new NonlinearConstraint(9, x => 1.0 - x[4] * x[4] - x[5] * x[5]),
                new NonlinearConstraint(9, x => 1.0 - x[0] * x[0] - Math.Pow(x[1] - x[8],                       2.0)),
                new NonlinearConstraint(9, x => 1.0 - Math.Pow(x[0] - x[4],               2.0) - Math.Pow(x[1] - x[5], 2.0)),
                new NonlinearConstraint(9, x => 1.0 - Math.Pow(x[0] - x[6],               2.0) - Math.Pow(x[1] - x[7], 2.0)),
                new NonlinearConstraint(9, x => 1.0 - Math.Pow(x[2] - x[4],               2.0) - Math.Pow(x[3] - x[5], 2.0)),
                new NonlinearConstraint(9, x => 1.0 - Math.Pow(x[2] - x[6],               2.0) - Math.Pow(x[3] - x[7], 2.0)),
                new NonlinearConstraint(9, x => 1.0 - x[6] * x[6] - Math.Pow(x[7] - x[8],                       2.0)),
                new NonlinearConstraint(9, x => x[0] * x[3] - x[1] * x[2]),
                new NonlinearConstraint(9, x => x[2] * x[8]),
                new NonlinearConstraint(9, x => - x[4] * x[8]),
                new NonlinearConstraint(9, x => x[4] * x[7] - x[5] * x[6]),
                new NonlinearConstraint(9, x => x[8]),
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

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

            double[] solution = cobyla.Solution;

            double[] expected =
            {
                0.688341, 0.725387, -0.284033, 0.958814, 0.688341, 0.725387, -0.284033, 0.958814, 0.0
            };

            for (int i = 0; i < expected.Length; i++)
            {
                Assert.AreEqual(expected[i], cobyla.Solution[i], 1e-2);
            }
            Assert.AreEqual(-0.86602540378486847, minimum, 1e-10);

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #9
0
        private static void optimization(double[][] inputs, double[] outputs)
        {
            // Non-linear regression can also be solved using arbitrary models
            // that can be defined by the user. For example, let's say we know
            // the overall model for the outputs but we do not know the value
            // of its parameters: log(w0  * x) / sqrt(w1 * y + w2)

            Func <double[], double[], double> model = (double[] x, double[] w)
                                                      => Math.Log(w[0] * x[0]) / Math.Sqrt(w[1] * x[1] + w[2]);

            // Now that we have the model, we want to find which values we
            // can plug in its parameters such that the error when evaluating
            // in our data is as close to zero as possible. Mathematically, we
            // would like to find the best parameters w that minimizes:

            Func <double[], double> objective = (double[] w) =>
            {
                double sumOfSquares = 0.0;
                for (int i = 0; i < inputs.Length; i++)
                {
                    double expected = outputs[i];
                    double actual   = model(inputs[i], w);
                    sumOfSquares += Math.Pow(expected - actual, 2);
                }
                return(sumOfSquares);
            };

            // Now, let's use a gradient-free optimization algorithm to
            // find the best parameters for our model's equations:
            var cobyla = new Cobyla(numberOfVariables: 3) // we have 3 parameters: w0, w1, and w2
            {
                Function      = objective,
                MaxIterations = 100,
                Solution      = new double[] { 1.0, 6.4, 100 } // start with some random values
            };

            bool success = cobyla.Minimize(); // should be true

            double[] solution = cobyla.Solution;

            // Get machine's predictions for inputs
            double[] prediction = inputs.Apply(x => model(x, solution));

            // Compute the error in the prediction (should be 0.0)
            double error = new SquareLoss(outputs).Loss(prediction);

            Console.WriteLine(error); // should be 0.000
        }
コード例 #10
0
ファイル: GH1.cs プロジェクト: jeancroy/csnumerics
        public void Cobyla_FindMinimum_ConstraintsShouldBeSatisfied()
        {
            var x0 = new[] { 0.705, 0.0075, 0.075, 0, 0.0375, 0, 0.05, 0.125 };
            var cobyla = new Cobyla(x0.Length, 3 + x0.Length, Calcfc)
                             {
                                 MaximumFunctionCalls = 100000,
                                 TrustRegionRadiusStart = 1.0,
                                 TrustRegionRadiusEnd = 1.0e-6,
                                 PrintLevel = 1,
                                 Logger = Console.Out
                             };

            var summary = cobyla.FindMinimum(x0);
            Assert.AreEqual(OptimizationStatus.Normal, summary.Status);
            Assert.IsTrue(summary.G.All(c => c >= -1.0e-6));
        }
コード例 #11
0
        public void Cobyla_FindMinimum_ConstraintsShouldBeSatisfied()
        {
            var x0     = new[] { 0.705, 0.0075, 0.075, 0, 0.0375, 0, 0.05, 0.125 };
            var cobyla = new Cobyla(x0.Length, 3 + x0.Length, Calcfc)
            {
                MaximumFunctionCalls   = 100000,
                TrustRegionRadiusStart = 1.0,
                TrustRegionRadiusEnd   = 1.0e-6,
                PrintLevel             = 1,
                Logger = Console.Out
            };

            var summary = cobyla.FindMinimum(x0);

            Assert.AreEqual(OptimizationStatus.Normal, summary.Status);
            Assert.IsTrue(summary.G.All(c => c >= -1.0e-6));
        }
コード例 #12
0
ファイル: Cobyla2Tests.cs プロジェクト: lovejike/cscobyla
        public double RunTestProblem(CalcfcDelegate calcfc, int n, int m, double rhoend, double[] xopt)
        {
            var x = Enumerable.Repeat(1.0, n).ToArray();

            var timer = new Stopwatch();

            timer.Restart();
            Assert.That(Cobyla.FindMinimum(calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun),
                        Is.EqualTo(CobylaExitStatus.Normal).Or.EqualTo(CobylaExitStatus.MaxIterationsReached));
            timer.Stop();

            var error = xopt.Select((xo, i) => Math.Pow(xo - x[i], 2.0)).Sum();

            Console.WriteLine("{0}Least squares error in variables = {1,16:E6}", Environment.NewLine, error);
            Console.WriteLine("Elapsed time for optimization = {0} ms", timer.ElapsedMilliseconds);

            return(error);
        }
コード例 #13
0
        /// # Summary
        /// Uses a classical optimizer to change beta and gamma parameters so that the objective function is minimized. The optimization is performed some number of times to decrease the chance of getting stuck in a local minimum.
        ///
        /// # Output
        /// Optimal solution to the optimization problem input by the user.
        ///
        /// # Remarks
        /// Currently used optimizer is Cobyla which is a gradient-free optimization technique.
        /// The objective function Hamiltonian is based on Z operators, the range of values in the gamma vector is 0 <= beta_i <= 2PI.
        public OptimalSolution RunOptimization()
        {
            Func <Double[], Double> objectiveFunction = CalculateObjectiveFunction;

            var optimizerObjectiveFunction = new NonlinearObjectiveFunction(2 * p, objectiveFunction);

            NonlinearConstraint[] constraints = GenerateConstraints();

            for (int i = 0; i < numberOfRandomStartingPoints; i++)
            {
                var      cobyla         = new Cobyla(optimizerObjectiveFunction, constraints);
                double[] freeParameters = SetUpFreeParameters();
                bool     success        = cobyla.Minimize(freeParameters);
                Utils.PrintSuccess(success);
            }

            return(new OptimalSolution(this.bestVector, this.bestHamiltonianValue, this.bestBeta, this.bestGamma));
        }
コード例 #14
0
ファイル: CobylaTest.cs プロジェクト: zhenyao2008/ai4unity
        public void ConstructorTest8()
        {
            /// This problem is taken from page 66 of Hock and Schittkowski's book Test
            /// Examples for Nonlinear Programming Codes. It is their test problem Number
            /// 43, and has the name Rosen-Suzuki.
            var function = new NonlinearObjectiveFunction(4, x => x[0] * x[0]
                                                          + x[1] * x[1] + 2.0 * x[2] * x[2]
                                                          + x[3] * x[3] - 5.0 * x[0] - 5.0 * x[1]
                                                          - 21.0 * x[2] + 7.0 * x[3]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(4, x => 8.0 - x[0] * x[0]
                                        - x[1] * x[1] - x[2] * x[2] - x[3] * x[3] - x[0] + x[1] - x[2] + x[3]),

                new NonlinearConstraint(4, x => 10.0 - x[0] * x[0]
                                        - 2.0 * x[1] * x[1] - x[2] * x[2] - 2.0 * x[3] * x[3] + x[0] + x[3]),

                new NonlinearConstraint(4, x => 5.0 - 2.0 * x[0] * x[0]
                                        - x[1] * x[1] - x[2] * x[2] - 2.0 * x[0] + x[1] + x[3])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

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

            double[] solution = cobyla.Solution;

            double[] expected =
            {
                0.0, 1.0, 2.0, -1.0
            };

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

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #15
0
ファイル: CobylaTest.cs プロジェクト: zhenyao2008/ai4unity
        public void ConstructorTest9()
        {
            /// This problem is taken from page 111 of Hock and Schittkowski's
            /// book Test Examples for Nonlinear Programming Codes. It is their
            /// test problem Number 100.
            ///
            var function = new NonlinearObjectiveFunction(7, x =>
                                                          Math.Pow(x[0] - 10.0, 2.0) + 5.0 * Math.Pow(x[1] - 12.0, 2.0) + Math.Pow(x[2], 4.0) +
                                                          3.0 * Math.Pow(x[3] - 11.0, 2.0) + 10.0 * Math.Pow(x[4], 6.0) + 7.0 * x[5] * x[5] + Math.Pow(x[6], 4.0) -
                                                          4.0 * x[5] * x[6] - 10.0 * x[5] - 8.0 * x[6]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(7,                                        x => 127.0 - 2.0 * x[0] * x[0] - 3.0 * Math.Pow(x[1], 4.0)
                                        - x[2] - 4.0 * x[3] * x[3] - 5.0 * x[4]),
                new NonlinearConstraint(7,                                        x => 282.0 - 7.0 * x[0] - 3.0 * x[1] - 10.0 * x[2] * x[2] - x[3] + x[4]),
                new NonlinearConstraint(7,                                        x => 196.0 - 23.0 * x[0] - x[1] * x[1] - 6.0 * x[5] * x[5] + 8.0 * x[6]),
                new NonlinearConstraint(7,                                        x => - 4.0 * x[0] * x[0] - x[1] * x[1] + 3.0 * x[0] * x[1]
                                        - 2.0 * x[2] * x[2] - 5.0 * x[5] + 11.0 * x[6])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

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

            double[] solution = cobyla.Solution;

            double[] expected =
            {
                2.330499, 1.951372, -0.4775414, 4.365726, -0.624487, 1.038131, 1.594227
            };

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

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #16
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest1()
        {
            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);

            Cobyla cobyla = new Cobyla(2, function);

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

            double[] solution = cobyla.Solution;

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

            double expectedMinimum = function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #17
0
ファイル: CobylaTest.cs プロジェクト: zhenyao2008/ai4unity
        public void ConstructorTest1()
        {
            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);

            Cobyla cobyla = new Cobyla(2, function);

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

            double[] solution = cobyla.Solution;

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

            double expectedMinimum = function(cobyla.Solution);

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #18
0
ファイル: CobylaTest.cs プロジェクト: zhenyao2008/ai4unity
        public void ConstructorTest5()
        {
            // Intermediate version of Rosenbrock's problem.
            var function = new NonlinearObjectiveFunction(2, x =>
                                                          10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            Cobyla cobyla = new Cobyla(function);

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

            double[] solution = cobyla.Solution;

            Assert.AreEqual(-0, minimum, 1e-6);
            Assert.AreEqual(-1, solution[0], 1e-3);
            Assert.AreEqual(+1, solution[1], 1e-3);

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #19
0
ファイル: CobylaTest.cs プロジェクト: zhenyao2008/ai4unity
        public void ConstructorTest3()
        {
            // Easy three dimensional minimization in ellipsoid.
            var function = new NonlinearObjectiveFunction(3, x => x[0] * x[1] * x[2]);

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

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

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

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

            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], cobyla.Solution[i], 1e-4);
            }
            Assert.AreEqual(-0.078567420132031968, minimum, 1e-10);

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #20
0
ファイル: Locator.cs プロジェクト: zhoukaii/PointAndControl
        /// <summary>
        ///     Finds central point of all lines with COBYLA using weight
        ///     <param name="list">Array of lines</param>
        ///     <returns>Returns central Point or Vector3D(NaN,NaN,NaN) on error</returns>
        /// </summary>
        private static Point3D cobylaCentralPointWithWeight(Ray3D[] lines)
        {
            gLines = lines;

            var xyz = new[] { 0.0, 0.0, 0.0 };

            var status = Cobyla.FindMinimum(calfunCobylaWeight, 3, 3, xyz, 0.5, 1.0e-6, 0, 3500, Console.Out);

            if (status == CobylaExitStatus.MaxIterationsReached)
            {
                status = Cobyla.FindMinimum(calfunCobylaWeight, 3, 3, xyz, 0.5, 1.0e-6, 1, 10000, Console.Out);
            }

            if (status == CobylaExitStatus.Normal)
            {
                return(new Point3D(xyz[0], xyz[1], xyz[2]));
            }
            else
            {
                return(new Point3D(Double.NaN, Double.NaN, Double.NaN));
            }
        }
コード例 #21
0
        private static void test_body(NonlinearObjectiveFunction function, NonlinearConstraint[] constraints)
        {
            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

            bool   success = cobyla.Minimize();
            double minimum = cobyla.Value;

            Assert.IsTrue(success);

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

            Assert.AreEqual(-0.5, minimum, 1e-10);
            Assert.AreEqual(sqrthalf, solution[0], 1e-5);
            Assert.AreEqual(-sqrthalf, solution[1], 1e-5);
        }
コード例 #22
0
        public void ConstructorTest2()
        {
            var function = new NonlinearObjectiveFunction(2, x => x[0] * x[1]);

            NonlinearConstraint[] constraints =
            {
                new NonlinearConstraint(function, x => 1.0 - x[0] * x[0] - x[1] * x[1])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
            {
                cobyla.Solution[i] = 1;
            }

            bool success = cobyla.Minimize();

            double violation = constraints[0].GetViolation(cobyla.Solution);

            var status = cobyla.Status;


            Assert.IsTrue(success);
            double minimum = cobyla.Value;

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

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

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

            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #23
0
    private void init_func()
    {
        model = (double[] x, double[] w) => Math.Log(w[0] * x[0]) / Math.Sqrt(w[1] * x[1] + w[2]);

        objective = (double[] w) =>
        {
            double sumOfSquares = 0.0;
            for (int i = 0; i < inputs.Length; i++)
            {
                double expected = outputs[i];
                double actual   = model(inputs[i], w);
                sumOfSquares += Math.Pow(expected - actual, 2);
            }
            return(sumOfSquares);
        };

        cobyla = new Cobyla(numberOfVariables: 3) // we have 3 parameters: w0, w1, and w2
        {
            Function      = objective,
            MaxIterations = 100,
            Solution      = new double[] { 1.0, 6.4, 100 } // start with some random values
        };
    }
コード例 #24
0
ファイル: LogiCurveTest2.cs プロジェクト: honglux/UnityTests
    private void init_func()
    {
        model = (double x, double[] w) => (w[0] / (1.0 + Math.Pow(Math.E, (-w[1] * (x - w[2])))) + 0.125);

        objective = (double[] w) =>
        {
            double sumOfSquares = 0.0;
            for (int i = 0; i < inputs.Length; i++)
            {
                double expected = outputs[i];
                double actual   = model(inputs[i], w);
                sumOfSquares += Math.Pow(expected - actual, 2);
            }
            return(sumOfSquares);
        };

        cobyla = new Cobyla(numberOfVariables: 3)
        {
            Function      = objective,
            MaxIterations = 100,
            Solution      = new double[] { 0.5, 0.1, 0.9 } // start with some random values
        };
    }
コード例 #25
0
        private void MatchPosition()
        {
            if (LockTarget == null || !IsLocked || !IsLockedPosition)
            {
                TurnUpsideUp();
                SurfaceMesh.UpdateBuffers();
                Viewport.Redraw();
                return;
            }

            Vector3[] IdealPositions = new Vector3[VertexLocks.Count];
            Vector4[] StartPositions = new Vector4[VertexLocks.Count];
            {
                int i = 0;
                foreach (var pair in VertexLocks)
                {
                    Vector3 OwnPosition = pair.Key.VolumePosition;
                    Vector3 Mean        = new Vector3(0);
                    foreach (var target in pair.Value)
                    {
                        Vector3 Relative           = OwnPosition - target.GetVolumeCenter();
                        Matrix4 Volume2Transformed = target.GetPlaneMatrix() * Matrix4.Transpose(target.GetVolumePlaneMatrix());
                        Relative  = Vector3.Transform(Relative, Matrix4.Transpose(Volume2Transformed));
                        Relative += target.GetCenter();
                        Mean     += Relative;
                    }

                    Mean *= 1f / pair.Value.Length;
                    IdealPositions[i] = Mean;
                    StartPositions[i] = new Vector4(pair.Key.Position, 1);
                    i++;
                }
            }

            Vector3 BestRotation = new Vector3(), BestTranslation = new Vector3();
            float   BestScore = float.MaxValue;

            Vector3 Extent            = SurfaceMesh.GetMax() - SurfaceMesh.GetMin();
            float   MaxExtent         = Math.Max(Math.Max(Extent.X, Extent.Y), Extent.Z) / 2f;
            float   AngleConditioning = (float)Math.Asin(Math.Min(1f / MaxExtent, Math.Sin(30 * Helper.ToRad)));

            AngleConditioning = Math.Max(1, Helper.ToDeg * AngleConditioning);

            List <Vector3> AnglesToTry = new List <Vector3> {
                new Vector3(5, 3, -4), new Vector3(5, 3, 184), new Vector3(185, 3, -4), new Vector3(5, 182, -4)
            };
            Random Rand = new Random(123);

            for (int i = 0; i < 5; i++)
            {
                AnglesToTry.Add(new Vector3(Rand.Next(360), Rand.Next(360), Rand.Next(360)));
            }
            for (int i = 0; i < AnglesToTry.Count; i++)
            {
                AnglesToTry[i] /= AngleConditioning;
            }

            Func <double[], double> F = vars =>
            {
                Vector3 Angles = new Vector3(Helper.ToRad * (float)vars[0], Helper.ToRad * (float)vars[1], Helper.ToRad * (float)vars[2]) * AngleConditioning;
                Vector3 Shifts = new Vector3((float)vars[3], (float)vars[4], (float)vars[5]);

                Matrix4 Transform = Matrix4.CreateTranslation(Shifts) *
                                    Matrix4.CreateRotationX(Angles.X) *
                                    Matrix4.CreateRotationY(Angles.Y) *
                                    Matrix4.CreateRotationZ(Angles.Z);

                float MeanDistance = 0;
                for (int i = 0; i < StartPositions.Length; i++)
                {
                    MeanDistance += (Vector4.Transform(StartPositions[i], Transform).Xyz - IdealPositions[i]).LengthSquared;
                }
                MeanDistance /= StartPositions.Length;

                return(Math.Sqrt(MeanDistance));
            };

            Func <double[], double[]> G = vars =>
            {
                double[] Gradients = new double[vars.Length];

                for (int i = 0; i < vars.Length; i++)
                {
                    double[] Plus = new double[vars.Length];
                    vars.CopyTo(Plus, 0);
                    Plus[i] += 0.1;

                    double[] Minus = new double[vars.Length];
                    vars.CopyTo(Minus, 0);
                    Minus[i] -= 0.1;

                    Gradients[i] = (F(Plus) - F(Minus)) / 0.2;
                }

                return(Gradients);
            };

            foreach (var startAngle in AnglesToTry)
            {
                double[] Start = { startAngle.X, startAngle.Y, startAngle.Z, 0, 0, 0 };

                Cobyla Optimizer = new Cobyla(6, F);
                Optimizer.Minimize(Start);

                if (Optimizer.Value < BestScore)
                {
                    BestScore       = (float)Optimizer.Value;
                    BestRotation    = new Vector3((float)Optimizer.Solution[0], (float)Optimizer.Solution[1], (float)Optimizer.Solution[2]) * AngleConditioning;
                    BestTranslation = new Vector3((float)Optimizer.Solution[3], (float)Optimizer.Solution[4], (float)Optimizer.Solution[5]);
                }
            }

            Matrix4 ToTarget = Matrix4.CreateTranslation(BestTranslation) *
                               Matrix4.CreateRotationX(Helper.ToRad * BestRotation.X) *
                               Matrix4.CreateRotationY(Helper.ToRad * BestRotation.Y) *
                               Matrix4.CreateRotationZ(Helper.ToRad * BestRotation.Z);

            foreach (var v in SurfaceMesh.Vertices)
            {
                v.Position = Vector4.Transform(new Vector4(v.Position, 1), ToTarget).Xyz;
            }
            foreach (var t in SurfaceMesh.Triangles)
            {
                t.UpdateNormal();
            }

            SurfaceMesh.UpdateBuffers();
            Viewport.Redraw();
        }
コード例 #26
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest6_2()
        {
            /// This problem is taken from Fletcher's book Practical Methods of
            /// Optimization and has the equation number (9.1.15).
            var function = new NonlinearObjectiveFunction(2, x => -x[0] - x[1]);

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(2, x =>  -(x[1] - x[0] * x[0]) <= 0),
                new NonlinearConstraint(2, x =>  -(-x[0] * x[0] - x[1] * x[1]) <= 1.0),
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);
            Assert.AreEqual(-sqrthalf * 2, minimum, 1e-10);
            Assert.AreEqual(sqrthalf, solution[0], 1e-5);
            Assert.AreEqual(sqrthalf, solution[1], 1e-5);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #27
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest2_2()
        {
            var function = new NonlinearObjectiveFunction(2, x => x[0] * x[1]);

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(2, x =>  x[0] * x[0] + x[1] * x[1] <= 1.0)
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
                cobyla.Solution[i] = 1;

            bool success = cobyla.Minimize();
            double minimum = cobyla.Value;
            Assert.IsTrue(success);

            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

            Assert.AreEqual(-0.5, minimum, 1e-10);
            Assert.AreEqual(sqrthalf, solution[0], 1e-5);
            Assert.AreEqual(-sqrthalf, solution[1], 1e-5);
        }
コード例 #28
0
ファイル: Cobyla2Tests.cs プロジェクト: lovejike/cscobyla
 public void FindMinimum_LogOutputToConsole_VisualInspection()
 {
     var x      = Enumerable.Repeat(1.0, 9).ToArray();
     var actual = Cobyla.FindMinimum(calcfc10, 9, 14, x, rhobeg, rhoend1, 2, maxfun, Console.Out);
 }
コード例 #29
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest5()
        {
            // Intermediate version of Rosenbrock's problem.
            var function = new NonlinearObjectiveFunction(2, x =>
                10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));

            Cobyla cobyla = new Cobyla(function);

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            Assert.AreEqual(-0, minimum, 1e-6);
            Assert.AreEqual(-1, solution[0], 1e-3);
            Assert.AreEqual(+1, solution[1], 1e-3);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #30
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest3()
        {
            // Easy three dimensional minimization in ellipsoid.
            var function = new NonlinearObjectiveFunction(3, x => x[0] * x[1] * x[2]);

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

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
                cobyla.Solution[i] = 1;

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            double sqrthalf = Math.Sqrt(0.5);

            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], cobyla.Solution[i], 1e-4);
            Assert.AreEqual(-0.078567420132031968, minimum, 1e-10);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #31
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest7()
        {
            /// This problem is taken from Fletcher's book Practical Methods of
            /// Optimization and has the equation number (14.4.2).
            var function = new NonlinearObjectiveFunction(3, x => x[2]);

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(3, x=> 5.0 * x[0] - x[1] + x[2]),
                new NonlinearConstraint(3, x =>  x[2] - x[0] * x[0] - x[1] * x[1] - 4.0 * x[1]),
                new NonlinearConstraint(3, x =>  x[2] - 5.0 * x[0] - x[1]),
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            Assert.AreEqual(-3, minimum, 1e-5);
            Assert.AreEqual(0.0, solution[0], 1e-5);
            Assert.AreEqual(-3.0, solution[1], 1e-5);
            Assert.AreEqual(-3.0, solution[2], 1e-5);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #32
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest8()
        {
            /// This problem is taken from page 66 of Hock and Schittkowski's book Test
            /// Examples for Nonlinear Programming Codes. It is their test problem Number
            /// 43, and has the name Rosen-Suzuki.
            var function = new NonlinearObjectiveFunction(4, x => x[0] * x[0]
                + x[1] * x[1] + 2.0 * x[2] * x[2]
                + x[3] * x[3] - 5.0 * x[0] - 5.0 * x[1]
                - 21.0 * x[2] + 7.0 * x[3]);

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(4, x=> 8.0 - x[0] * x[0] 
                    - x[1] * x[1] - x[2] * x[2] - x[3] * x[3] - x[0] + x[1] - x[2] + x[3]),

                new NonlinearConstraint(4, x => 10.0 - x[0] * x[0] 
                    - 2.0 * x[1] * x[1] - x[2] * x[2] - 2.0 * x[3] * x[3] + x[0] + x[3]),

                new NonlinearConstraint(4, x => 5.0 - 2.0 * x[0] * x[0] 
                    - x[1] * x[1] - x[2] * x[2] - 2.0 * x[0] + x[1] + x[3])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            double[] expected = 
            {
                0.0, 1.0, 2.0, -1.0
            };

            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], cobyla.Solution[i], 1e-4);
            Assert.AreEqual(-44, minimum, 1e-10);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #33
0
        public static double[] OptimiseWeights(double[,] allHistoryBars, double [] retNorm)
        {
            var covMatrix = allHistoryBars.Transpose().Covariance();

            var maxRet = 0.9 * retNorm.Max();


            Func <double[], double> retNormFunc = (x) => x.Dot(retNorm) - maxRet;

            // The scoring function
            var f = new NonlinearObjectiveFunction(covMatrix.GetLength(0), x => x.DotAndDot(covMatrix, x));
            // Under the following constraints
            var constraints = new[]
            {
                //the sum of all weights is equal to 1 (ish)
                //using Enumerable sum because of Accord.Math extension redefinition
                //https://stackoverflow.com/questions/32380592/why-am-i-required-to-reference-system-numerics-with-this-simple-linq-expression
                new NonlinearConstraint(covMatrix.GetLength(0), x => - Math.Pow(Enumerable.Sum(x) - 1, 2) >= -1e-6),
                new NonlinearConstraint(covMatrix.GetLength(0), x => retNormFunc(x) >= 0),
                //the values are bounded between 0 and 1
                new NonlinearConstraint(covMatrix.GetLength(0), x => x.Min() >= -1),
                new NonlinearConstraint(covMatrix.GetLength(0), x => - x.Max() >= -1),
            };


            //var nbVar =3;

            //NelderMead algo = new NelderMead(f);



            //         var function  = new NonlinearObjectiveFunction(covMatrix.GetLength(0),
            //             function: (x) => x.DotAndDot(covMatrix, x)//,
            //             //gradient: (x) => x.DotProduct(covMatrix, x)
            //         );

            // var inner = new BroydenFletcherGoldfarbShanno(4);
            //         inner.LineSearch = LineSearch.BacktrackingArmijo;
            //         inner.Corrections = 10;

            //         var algo = new AugmentedLagrangian(inner, function, constraints);


            //         bool s = algo.Minimize();

            //var g =  new FiniteDifferences(nbVar, f);
            //
            //var algo = new NonlinearConjugateGradient (f, constraints);
            //var algo = new BroydenFletcherGoldfarbShanno(numberOfVariables: nbVar, function: f, gradient: g);
            //var algo = new AugmentedLagrangian(f, constraints);
            // Optimize it
            //TODO handle !success



            var  algo    = new Cobyla(f, constraints);
            bool success = algo.Minimize();

            if (!success)
            {
                return(null);
            }
            double minimum = algo.Value;

            double[] weights = algo.Solution;


            return(weights);
        }
コード例 #34
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest9()
        {
            /// This problem is taken from page 111 of Hock and Schittkowski's
            /// book Test Examples for Nonlinear Programming Codes. It is their
            /// test problem Number 100.
            /// 
            var function = new NonlinearObjectiveFunction(7, x =>
                Math.Pow(x[0] - 10.0, 2.0) + 5.0 * Math.Pow(x[1] - 12.0, 2.0) + Math.Pow(x[2], 4.0) +
                3.0 * Math.Pow(x[3] - 11.0, 2.0) + 10.0 * Math.Pow(x[4], 6.0) + 7.0 * x[5] * x[5] + Math.Pow(x[6], 4.0) -
                4.0 * x[5] * x[6] - 10.0 * x[5] - 8.0 * x[6]);

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(7, x => 127.0 - 2.0 * x[0] * x[0] - 3.0 * Math.Pow(x[1], 4.0)
                    - x[2] - 4.0 * x[3] * x[3] - 5.0 * x[4]),
                new NonlinearConstraint(7, x => 282.0 - 7.0 * x[0] - 3.0 * x[1] - 10.0 * x[2] * x[2] - x[3] + x[4]),
                new NonlinearConstraint(7, x => 196.0 - 23.0 * x[0] - x[1] * x[1] - 6.0 * x[5] * x[5] + 8.0 * x[6]),
                new NonlinearConstraint(7, x => -4.0 * x[0] * x[0] - x[1] * x[1] + 3.0 * x[0] * x[1] 
                    - 2.0 * x[2] * x[2] - 5.0 * x[5] + 11.0 * x[6])
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            double[] expected = 
            {
                2.330499, 1.951372, -0.4775414, 4.365726, -0.624487, 1.038131, 1.594227
            };

            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], cobyla.Solution[i], 1e-4);
            Assert.AreEqual(680.63005737443393, minimum, 1e-6);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #35
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest10()
        {
            /// This problem is taken from page 415 of Luenberger's book Applied
            /// Nonlinear Programming. It is to maximize the area of a hexagon of
            /// unit diameter.
            /// 
            var function = new NonlinearObjectiveFunction(9, x =>
                -0.5 * (x[0] * x[3] - x[1] * x[2] + x[2] * x[8]
                - x[4] * x[8] + x[4] * x[7] - x[5] * x[6]));

            NonlinearConstraint[] constraints = 
            {
                new NonlinearConstraint(9, x => 1.0 - x[2] * x[2] - x[3] * x[3]),
                new NonlinearConstraint(9, x =>  1.0 - x[8] * x[8]),
                new NonlinearConstraint(9, x =>  1.0 - x[4] * x[4] - x[5] * x[5]),
                new NonlinearConstraint(9, x =>  1.0 - x[0] * x[0] - Math.Pow(x[1] - x[8], 2.0)),
                new NonlinearConstraint(9, x =>  1.0 - Math.Pow(x[0] - x[4], 2.0) - Math.Pow(x[1] - x[5], 2.0)),
                new NonlinearConstraint(9, x =>  1.0 - Math.Pow(x[0] - x[6], 2.0) - Math.Pow(x[1] - x[7], 2.0)),
                new NonlinearConstraint(9, x =>  1.0 - Math.Pow(x[2] - x[4], 2.0) - Math.Pow(x[3] - x[5], 2.0)),
                new NonlinearConstraint(9, x =>  1.0 - Math.Pow(x[2] - x[6], 2.0) - Math.Pow(x[3] - x[7], 2.0)),
                new NonlinearConstraint(9, x =>  1.0 - x[6] * x[6] - Math.Pow(x[7] - x[8], 2.0)),
                new NonlinearConstraint(9, x =>  x[0] * x[3] - x[1] * x[2]),
                new NonlinearConstraint(9, x =>  x[2] * x[8]),
                new NonlinearConstraint(9, x =>  -x[4] * x[8]),
                new NonlinearConstraint(9, x =>  x[4] * x[7] - x[5] * x[6]),
                new NonlinearConstraint(9, x =>  x[8]),
            };

            Cobyla cobyla = new Cobyla(function, constraints);

            for (int i = 0; i < cobyla.Solution.Length; i++)
                cobyla.Solution[i] = 1;

            Assert.IsTrue(cobyla.Minimize());
            double minimum = cobyla.Value;
            double[] solution = cobyla.Solution;

            double[] expected = 
            {
                0.688341, 0.725387, -0.284033, 0.958814, 0.688341, 0.725387, -0.284033, 0.958814, 0.0
            };

            for (int i = 0; i < expected.Length; i++)
                Assert.AreEqual(expected[i], cobyla.Solution[i], 1e-2);
            Assert.AreEqual(-0.86602540378486847, minimum, 1e-10);

            double expectedMinimum = function.Function(cobyla.Solution);
            Assert.AreEqual(expectedMinimum, minimum);
        }
コード例 #36
0
ファイル: CobylaTest.cs プロジェクト: RLaumeyer/framework
        public void ConstructorTest6_3()
        {
            bool thrown = false;

            try
            {
                var function = new NonlinearObjectiveFunction(2, x => -x[0] - x[1]);

                NonlinearConstraint[] constraints = 
                {
                    new NonlinearConstraint(2, x =>  x[1] - x[0] * x[0]),
                    new NonlinearConstraint(4, x =>  1.0 - x[0] * x[0] - x[1] * x[1]),
                };

                Cobyla cobyla = new Cobyla(function, constraints);

                Assert.IsTrue(cobyla.Minimize());
                double minimum = cobyla.Value;
            }
            catch (Exception)
            {
                thrown = true;
            }

            Assert.IsTrue(thrown);
        }
コード例 #37
0
ファイル: SurfacePatch.cs プロジェクト: dtegunov/membranorama
        private void MatchPosition()
        {
            if (LockTarget == null || !IsLocked || !IsLockedPosition)
            {
                TurnUpsideUp();
                SurfaceMesh.UpdateBuffers();
                Viewport.Redraw();
                return;
            }

            Vector3[] IdealPositions = new Vector3[VertexLocks.Count];
            Vector4[] StartPositions = new Vector4[VertexLocks.Count];
            {
                int i = 0;
                foreach (var pair in VertexLocks)
                {
                    Vector3 OwnPosition = pair.Key.VolumePosition;
                    Vector3 Mean = new Vector3(0);
                    foreach (var target in pair.Value)
                    {
                        Vector3 Relative = OwnPosition - target.GetVolumeCenter();
                        Matrix4 Volume2Transformed = target.GetPlaneMatrix() * Matrix4.Transpose(target.GetVolumePlaneMatrix());
                        Relative = Vector3.Transform(Relative, Matrix4.Transpose(Volume2Transformed));
                        Relative += target.GetCenter();
                        Mean += Relative;
                    }

                    Mean *= 1f / pair.Value.Length;
                    IdealPositions[i] = Mean;
                    StartPositions[i] = new Vector4(pair.Key.Position, 1);
                    i++;
                }
            }

            Vector3 BestRotation = new Vector3(), BestTranslation = new Vector3();
            float BestScore = float.MaxValue;

            Vector3 Extent = SurfaceMesh.GetMax() - SurfaceMesh.GetMin();
            float MaxExtent = Math.Max(Math.Max(Extent.X, Extent.Y), Extent.Z) / 2f;
            float AngleConditioning = (float) Math.Asin(Math.Min(1f / MaxExtent, Math.Sin(30 * Helper.ToRad)));
            AngleConditioning = Math.Max(1, Helper.ToDeg * AngleConditioning);

            List<Vector3> AnglesToTry = new List<Vector3> { new Vector3(5, 3, -4), new Vector3(5, 3, 184), new Vector3(185, 3, -4), new Vector3(5, 182, -4) };
            Random Rand = new Random(123);
            for (int i = 0; i < 5; i++)
                AnglesToTry.Add(new Vector3(Rand.Next(360), Rand.Next(360), Rand.Next(360)));
            for (int i = 0; i < AnglesToTry.Count; i++)
                AnglesToTry[i] /= AngleConditioning;

            Func<double[], double> F = vars =>
            {
                Vector3 Angles = new Vector3(Helper.ToRad * (float)vars[0], Helper.ToRad * (float)vars[1], Helper.ToRad * (float)vars[2]) * AngleConditioning;
                Vector3 Shifts = new Vector3((float)vars[3], (float)vars[4], (float)vars[5]);

                Matrix4 Transform = Matrix4.CreateTranslation(Shifts) *
                                    Matrix4.CreateRotationX(Angles.X) *
                                    Matrix4.CreateRotationY(Angles.Y) *
                                    Matrix4.CreateRotationZ(Angles.Z);

                float MeanDistance = 0;
                for (int i = 0; i < StartPositions.Length; i++)
                    MeanDistance += (Vector4.Transform(StartPositions[i], Transform).Xyz - IdealPositions[i]).LengthSquared;
                MeanDistance /= StartPositions.Length;

                return Math.Sqrt(MeanDistance);
            };

            Func<double[], double[]> G = vars =>
            {
                double[] Gradients = new double[vars.Length];

                for (int i = 0; i < vars.Length; i++)
                {
                    double[] Plus = new double[vars.Length];
                    vars.CopyTo(Plus, 0);
                    Plus[i] += 0.1;

                    double[] Minus = new double[vars.Length];
                    vars.CopyTo(Minus, 0);
                    Minus[i] -= 0.1;

                    Gradients[i] = (F(Plus) - F(Minus)) / 0.2;
                }

                return Gradients;
            };

            foreach (var startAngle in AnglesToTry)
            {
                double[] Start = { startAngle.X, startAngle.Y, startAngle.Z, 0, 0, 0 };

                Cobyla Optimizer = new Cobyla(6, F);
                Optimizer.Minimize(Start);

                if (Optimizer.Value < BestScore)
                {
                    BestScore = (float)Optimizer.Value;
                    BestRotation = new Vector3((float)Optimizer.Solution[0], (float)Optimizer.Solution[1], (float)Optimizer.Solution[2]) * AngleConditioning;
                    BestTranslation = new Vector3((float)Optimizer.Solution[3], (float)Optimizer.Solution[4], (float)Optimizer.Solution[5]);
                }
            }

            Matrix4 ToTarget = Matrix4.CreateTranslation(BestTranslation) *
                                    Matrix4.CreateRotationX(Helper.ToRad * BestRotation.X) *
                                    Matrix4.CreateRotationY(Helper.ToRad * BestRotation.Y) *
                                    Matrix4.CreateRotationZ(Helper.ToRad * BestRotation.Z);

            foreach (var v in SurfaceMesh.Vertices)
                v.Position = Vector4.Transform(new Vector4(v.Position, 1), ToTarget).Xyz;
            foreach (var t in SurfaceMesh.Triangles)
                t.UpdateNormal();

            SurfaceMesh.UpdateBuffers();
            Viewport.Redraw();
        }