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); }
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); }
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); }
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); }
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); }
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); }
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()); }
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); }
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 }
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)); }
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)); }
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); }
/// # 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)); }
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); }
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); }
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); }
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); }
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); }
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); }
/// <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)); } }
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); }
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); }
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 }; }
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 }; }
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(); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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(); }