Exemplo n.º 1
0
        public void FindMinimum_LogOutputToConsole_OutputNonEmpty()
        {
            const int n = 9;
            var       x = Enumerable.Repeat(0.1, n).ToArray();

            Bobyqa.FindMinimum(Rosen, n, x, null, null, -1, 1.0, 1.0e-8, 1, 2000, Console.Out);
        }
Exemplo n.º 2
0
        public void FindMinimum_HS04_ReturnsValidMinimum()
        {
            var xx = new[] { 1.125, 0.125 };

            Bobyqa.FindMinimum((n, x) => Math.Pow(x[0] + 1.0, 3.0) / 3.0 + x[1], 2, xx, new[] { 1.0, 0.0 }, null, 4);
            Assert.AreEqual(1.0, xx[0], TOL);
            Assert.AreEqual(0.0, xx[1], TOL);
        }
Exemplo n.º 3
0
        public void FindMinimum_IntermedRosenbrock_ReturnsValidMinimum()
        {
            var xx = new[] { 1.0, -1.0 };

            Bobyqa.FindMinimum((n, x) => 10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0), 2, xx);
            Assert.AreEqual(-1.0, xx[0], TOL);
            Assert.AreEqual(1.0, xx[1], TOL);
        }
Exemplo n.º 4
0
        public void FindMinimum_BobyqaTestCase_ReturnStatusNormal(int m, int npt)
        {
            //     Test problem for BOBYQA, the objective function being the sum of
            //     the reciprocals of all pairwise distances between the points P_I,
            //     I=1,2,...,M in two dimensions, where M=N/2 and where the components
            //     of P_I are X(2*I-1) and X(2*I). Thus each vector X of N variables
            //     defines the M points P_I. The initial X gives equally spaced points
            //     on a circle. Four different choices of the pairs (N,NPT) are tried,
            //     namely (10,16), (10,21), (20,26) and (20,41). Convergence to a local
            //     minimum that is not global occurs in both the N=10 cases. The details
            //     of the results are highly sensitive to computer rounding errors. The
            //     choice IPRINT=2 provides the current X and optimal F so far whenever
            //     RHO is reduced. The bound constraints of the problem require every
            //     component of X to be in the interval [-1,1].

            var n  = 2 * m;
            var x0 = new double[n];
            var xl = new double[n];
            var xu = new double[n];

            const double bdl = -1.0;
            const double bdu = 1.0;

            for (var i = 0; i < n; ++i)
            {
                xl[i] = bdl;
                xu[i] = bdu;
            }

            Console.WriteLine("{0}2D output with M ={1,4},  N ={2,4}  and  NPT ={3,4}", Environment.NewLine, m, n, npt);

            for (var j = 1; j <= m; ++j)
            {
                var temp = 2.0 * Math.PI * j / m;
                x0[2 * j - 2] = Math.Cos(temp);
                x0[2 * j - 1] = Math.Sin(temp);
            }

            const int    iprint = 2;
            const int    maxfun = 500000;
            const double rhobeg = 1.0E-1;
            const double rhoend = 1.0E-6;

            var optimizer = new Bobyqa(n, this.BobyqaTestCalfun, xl, xu)
            {
                InterpolationConditions = npt,
                TrustRegionRadiusStart  = rhobeg,
                TrustRegionRadiusEnd    = rhoend,
                PrintLevel           = iprint,
                MaximumFunctionCalls = maxfun
            };

            const OptimizationStatus expected = OptimizationStatus.Normal;
            var actual = optimizer.FindMinimum(x0).Status;

            Assert.AreEqual(expected, actual);
        }
Exemplo n.º 5
0
        public void FindMinimum_HS05_ReturnsValidMinimum()
        {
            var xx = new[] { 0.0, 0.0 };

            Bobyqa.FindMinimum(
                (n, x) => Math.Sin(x[0] + x[1]) + Math.Pow(x[0] - x[1], 2.0) - 1.5 * x[0] + 2.5 * x[1] + 1, 2, xx,
                new[] { -1.5, -3.0 }, new[] { 4.0, 3.0 });
            Assert.AreEqual(0.5 - Math.PI / 3.0, xx[0], TOL);
            Assert.AreEqual(-0.5 - Math.PI / 3.0, xx[1], TOL);
        }
Exemplo n.º 6
0
        public void FindMinimum_LogOutputToConsole_OutputNonEmpty()
        {
            const int n         = 9;
            var       optimizer = new Bobyqa(n, this.Rosen)
            {
                Logger = Console.Out
            };

            optimizer.FindMinimum(Enumerable.Repeat(0.1, n).ToArray());
        }
Exemplo n.º 7
0
        public void FindMinimum_IntermedRosenbrock_ReturnsValidMinimum()
        {
            var optimizer = new Bobyqa(
                2,
                (n, x) => 10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));
            var summary = optimizer.FindMinimum(new[] { 1.0, -1.0 });

            Assert.AreEqual(-1.0, summary.X[0], TOL);
            Assert.AreEqual(1.0, summary.X[1], TOL);
        }
Exemplo n.º 8
0
        public void FindMinimum_HS04_ReturnsValidMinimum()
        {
            var optimizer = new Bobyqa(2, (n, x) => Math.Pow(x[0] + 1.0, 3.0) / 3.0 + x[1], new[] { 1.0, 0.0 }, null)
            {
                InterpolationConditions = 4
            };
            var result = optimizer.FindMinimum(new[] { 1.125, 0.125 });

            Assert.AreEqual(1.0, result.X[0], TOL);
            Assert.AreEqual(0.0, result.X[1], TOL);
        }
Exemplo n.º 9
0
        public void FindMinimum_LogOutput_OutputNonEmpty()
        {
            const int n = 9;
            var       x = Enumerable.Repeat(0.1, n).ToArray();

            using (var logger = new StringWriter())
            {
                Bobyqa.FindMinimum(Rosen, n, x, null, null, -1, 1.0, 1.0e-8, 1, 2000, logger);
                Assert.Greater(logger.ToString().Length, 0);
            }
        }
Exemplo n.º 10
0
        public void FindMinimum_HS05_ReturnsValidMinimum()
        {
            var optimizer = new Bobyqa(
                2,
                (n, x) => Math.Sin(x[0] + x[1]) + Math.Pow(x[0] - x[1], 2.0) - 1.5 * x[0] + 2.5 * x[1] + 1,
                new[] { -1.5, -3.0 },
                new[] { 4.0, 3.0 });
            var result = optimizer.FindMinimum(new[] { 0.0, 0.0 });

            Assert.AreEqual(0.5 - Math.PI / 3.0, result.X[0], TOL);
            Assert.AreEqual(-0.5 - Math.PI / 3.0, result.X[1], TOL);
        }
Exemplo n.º 11
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh          mesh          = new Mesh();
            List <double> initialValues = new List <double>();
            double        desiredWidth  = 0.0;
            double        lambda        = 0.0;
            double        nu            = 0.0;

            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetDataList(1, initialValues))
            {
                return;
            }
            if (!DA.GetData(2, ref desiredWidth))
            {
                return;
            }
            if (!DA.GetData(3, ref lambda))
            {
                return;
            }
            if (!DA.GetData(4, ref nu))
            {
                return;
            }


            mesh.FaceNormals.ComputeFaceNormals();

            GeodesicsFromLevelSets levelSets = new GeodesicsFromLevelSets(mesh, initialValues, desiredWidth, lambda, nu);

            var optimizer = new Bobyqa(mesh.Vertices.Count, levelSets.Compute);

            optimizer.MaximumFunctionCalls = 200;

            double[]      x           = initialValues.ToArray();
            var           result      = optimizer.FindMinimum(x);
            List <double> finalValues = new List <double>(result.X);

            List <double> divergence = levelSets.ComputeDivergence(false);

            DA.SetDataList(1, levelSets.Gradient);
            DA.SetDataList(2, divergence);
            DA.SetDataList(3, levelSets.VertexVoronoiArea);
            DA.SetData(4, result.F);
            DA.SetDataList(5, finalValues);
        }
Exemplo n.º 12
0
        public List <Curve> GenerateSubCurves(double[] _startData, double[] _xl, double[] _xu)
        {
            // Generate Initial values and variable Bounds for the optimization problem.
            // Only using first variable for now, the extra variable is just to make it work.
            double[] startData = _startData;
            double[] xl        = _xl;
            double[] xu        = _xu;

            List <Curve> pieceWiseList = new List <Curve>();

            pieceWiseList.Add(selectedGeodesic);

            if (bestFitInterval.Length != 0)
            {
                pieceWiseList[0] = CutCurveBetweenPerpIndexes(pieceWiseList[0], perpGeodesics, bestFitInterval[0], bestFitInterval[1]);

                if (bestFitInterval[1] < (perpGeodesics.Count - 1))
                {
                    List <Curve>  tempGeodesics  = perpGeodesics.GetRange(bestFitInterval[1], (perpGeodesics.Count - bestFitInterval[1]));
                    List <double> tempParameters = perpParameters.GetRange(bestFitInterval[1], (perpGeodesics.Count - bestFitInterval[1]));
                    Vector3d      tangent        = pieceWiseList[0].TangentAtEnd;
                    double        t;
                    tempGeodesics[0].ClosestPoint(pieceWiseList[0].PointAtEnd, out t);
                    tempParameters[0] = t;
                    BestFitPieceWiseGeodesic tempBestFit = new BestFitPieceWiseGeodesic(mesh, tempGeodesics, tempParameters, maxIter / 2, false, 0, threshold, tangent);
                    var tempOptimizer = new Bobyqa(2, tempBestFit.ComputeError, xl, xu);
                    var tempResult    = tempOptimizer.FindMinimum(startData);

                    pieceWiseList.AddRange(tempBestFit.GenerateSubCurves(startData, xl, xu));
                }

                if (bestFitInterval[0] > 0)
                {
                    List <Curve>  tempGeodesics  = perpGeodesics.GetRange(0, bestFitInterval[0] + 1);
                    List <double> tempParameters = perpParameters.GetRange(0, bestFitInterval[0] + 1);

                    double   t;
                    Vector3d tangent = pieceWiseList[0].TangentAtStart;

                    tempGeodesics[tempGeodesics.Count - 1].ClosestPoint(pieceWiseList[0].PointAtStart, out t);
                    tempParameters[tempGeodesics.Count - 1] = t;
                    BestFitPieceWiseGeodesic tempBestFit = new BestFitPieceWiseGeodesic(mesh, tempGeodesics, tempParameters, maxIter / 2, false, tempGeodesics.Count - 1, threshold, -tangent);
                    var tempOptimizer = new Bobyqa(2, tempBestFit.ComputeError, xl, xu);
                    var tempResult    = tempOptimizer.FindMinimum(startData);
                    pieceWiseList.AddRange(tempBestFit.GenerateSubCurves(startData, xl, xu));
                }
            }
            return(pieceWiseList);
        }
Exemplo n.º 13
0
        public void FindMinimum_ConstrainedRosenWithAdditionalInterpolationPoints_ReturnsValidMinimum(int n, int maxAdditionalPoints)
        {
            var xl       = Enumerable.Repeat(-1.0, n).ToArray();
            var xu       = Enumerable.Repeat(2.0, n).ToArray();
            var expected = Enumerable.Repeat(1.0, n).ToArray();

            for (var num = 1; num <= maxAdditionalPoints; ++num)
            {
                Console.WriteLine("\nNumber of additional points = {0}", num);
                var npt = 2 * n + 1 + num;
                var x   = Enumerable.Repeat(0.1, n).ToArray();
                Bobyqa.FindMinimum(Rosen, n, x, xl, xu, npt, -1, 1.0e-8, 1, 3000, Console.Out);
                CollectionAssert.AreEqual(expected, x, new DoubleComparer(1.0e-6));
            }
        }
Exemplo n.º 14
0
        public void FindMinimum_LogOutput_OutputNonEmpty()
        {
            const int n         = 9;
            var       optimizer = new Bobyqa(n, this.Rosen)
            {
                Logger = Console.Out
            };

            using (var logger = new StringWriter())
            {
                optimizer.Logger = logger;
                optimizer.FindMinimum(Enumerable.Repeat(0.1, n).ToArray());
                Assert.Greater(logger.ToString().Length, 0);
            }
        }
Exemplo n.º 15
0
        /// <summary>
        ///     Finds central point of all lines with BOBYQA 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 bobyqaCentralPointWithWeight(Ray3D[] lines)
        {
            gLines = lines;

            var xyz     = new[] { 0.0, 0.0, 0.0 };
            var lBounds = new[] { -30.0, -30.0, -30.0 };
            var uBounds = new[] { 30.0, 30.0, 30.0 };

            var status = Bobyqa.FindMinimum(calfunBobyqaWeight, 3, xyz, lBounds, uBounds, -1, -1, -1, 1, 10000, Console.Out);

            if (status == BobyqaExitStatus.Normal)
            {
                return(new Point3D(xyz[0], xyz[1], xyz[2]));
            }
            else
            {
                return(new Point3D(Double.NaN, Double.NaN, Double.NaN));
            }
        }
Exemplo n.º 16
0
        public void FindMinimum_ConstrainedRosenWithAdditionalInterpolationPoints_ReturnsValidMinimum(int n, int maxAdditionalPoints)
        {
            var xl       = Enumerable.Repeat(-1.0, n).ToArray();
            var xu       = Enumerable.Repeat(2.0, n).ToArray();
            var expected = Enumerable.Repeat(1.0, n).ToArray();

            var optimizer = new Bobyqa(n, this.Rosen, xl, xu)
            {
                TrustRegionRadiusEnd = 1.0e-8,
                MaximumFunctionCalls = 3000,
                Logger = Console.Out
            };

            for (var num = 1; num <= maxAdditionalPoints; ++num)
            {
                Console.WriteLine("\nNumber of additional points = {0}", num);
                optimizer.InterpolationConditions = 2 * n + 1 + num;
                var result = optimizer.FindMinimum(Enumerable.Repeat(0.1, n).ToArray());

                CollectionAssert.AreEqual(expected, result.X, new DoubleComparer(1.0e-6));
            }
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh          mesh          = new Mesh();
            List <double> initialValues = new List <double>();
            double        desiredWidth  = 0.0;
            double        lambda        = 0.0;
            double        nu            = 0.0;
            int           maxCalls      = 0;
            int           optim         = 0;
            double        objective     = 10;

            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetDataList(1, initialValues))
            {
                return;
            }
            if (!DA.GetData(2, ref desiredWidth))
            {
                return;
            }
            if (!DA.GetData(3, ref lambda))
            {
                return;
            }
            if (!DA.GetData(4, ref nu))
            {
                return;
            }
            if (!DA.GetData(5, ref maxCalls))
            {
                return;
            }
            if (!DA.GetData(6, ref optim))
            {
                return;
            }
            if (!DA.GetData(7, ref objective))
            {
                return;
            }

            mesh.FaceNormals.ComputeFaceNormals();

            GeodesicsFromLevelSets levelSets = new GeodesicsFromLevelSets(mesh, initialValues, desiredWidth, lambda, nu);

            var optimizer = new Bobyqa(mesh.Vertices.Count, levelSets.Compute);

            optimizer.MaximumFunctionCalls = maxCalls;
            double[] x = initialValues.ToArray();


            var func = new LevelSetOpt(levelSets);

            var opt = new clsOptNelderMead(func);

            //if (optim == 1) opt = new clsOptNelderMead(func);
            //if (optim == 2) opt = new clsOptSimulatedAnnealing(func);
            //if (optim == 3) opt = new clsFireFly(func);
            opt.IsUseCriterion  = false;
            opt.InitialPosition = initialValues.ToArray();
            opt.Iteration       = maxCalls;
            double finalError = 0;
            bool   retry      = false;

            do
            {
                double[] resultX = { };
                if (optim == 0)
                {
                    var result = optimizer.FindMinimum(x);
                    finalError = result.F;
                    resultX    = result.X;
                }
                else if (optim > 0)
                { // Nelder mead & simulated annealing
                    opt.Init();

                    while (opt.DoIteration(100) == false)
                    {
                        var eval = opt.Result.Eval;

                        //my criterion
                        if (eval < 10)
                        {
                            break;
                        }
                        Console.WriteLine("Iter: {0} Eval: {1}", opt.IterationCount, opt.Result.Eval);
                    }
                    finalError = opt.Result.Eval;
                    clsUtil.DebugValue(opt);
                }

                //if (optim == 0) {
                //    String str = "Optimization ended with an error of" + finalError + "\nDo you wish to run again using this results as input?";
                //    if (MessageBox.Show(str, "Optimization Ended", MessageBoxButtons.YesNo, MessageBoxIcon.Stop, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                //    {
                //        x = resultX;
                //        retry = true;
                //    }
                //    else
                //    {
                //        retry = false;
                //    }
                //}
            } while (retry == true);

            //levelSets = func.levelSets;

            List <double> desiredLevels = new List <double>();
            double        max           = 0.0;
            double        min           = 0.0;

            for (int i = 0; i < levelSets.VertexValues.Count; i++)
            {
                double value = levelSets.VertexValues[i];
                if (i == 0)
                {
                    max = value; min = value;
                }

                if (value < min)
                {
                    min = value;
                }
                if (value > max)
                {
                    max = value;
                }
            }

            double diff       = max - min;
            int    levelCount = (int)(diff / desiredWidth);

            for (int j = 0; j <= levelCount; j++)
            {
                desiredLevels.Add(min + (j * desiredWidth));
            }

            DataTree <Line> pattern        = levelSets.DrawLevelSetCurves(desiredLevels);
            List <double>   divergence     = levelSets.ComputeDivergence(false);
            List <double>   divergenceNorm = levelSets.ComputeDivergence(true);

            DA.SetDataTree(0, pattern);
            DA.SetDataList(1, levelSets.Gradient);
            DA.SetDataList(2, divergence);
            DA.SetDataList(3, levelSets.VertexVoronoiArea);
            DA.SetData(4, finalError);
            DA.SetDataList(5, levelSets.VertexValues);
            DA.SetDataList(6, divergenceNorm);
        }
Exemplo n.º 18
0
        public List <Curve> GeneratePiecewiseGeodesicCurve(Mesh mesh, List <double> perpParameters, List <Curve> perpGeodesics, int maxIter, bool bothDir, int startIndex, double threshold, Vector3d dir)
        {
            // Generate Initial values and variable Bounds for the optimization problem.
            // Only using first variable for now, the extra variable is just to make it work.
            Random rnd   = new Random();
            double limit = 0.35;
            double start = (rnd.NextDouble() * limit) - (limit / 2);

            double[] startData = { start, 0 };
            double[] xl        = new double[] { -limit * Math.PI, -1 };
            double[] xu        = new double[] { limit *Math.PI, 1 };

            // Generate bestfit G
            BestFitPieceWiseGeodesic bestFitG = new BestFitPieceWiseGeodesic(mesh, perpGeodesics, perpParameters, maxIter, bothDir, startIndex, threshold, dir);

            // Run optimization
            var optimizer = new Bobyqa(2, bestFitG.ComputeError, xl, xu);
            var result    = optimizer.FindMinimum(startData);

            // If no best fit is found, gradually increase angle
            if (bestFitG.bestFitInterval.Length == 0 || result.F > 0.1)
            {
                do
                {
                    limit += 0.05;
                    Debug.WriteLine("Limit increased :" + limit);
                    start        = (rnd.NextDouble() * limit) - (limit / 2);
                    startData[0] = start;
                    xl           = new double[] { -limit * Math.PI, -1 };
                    xu           = new double[] { limit *Math.PI, 1 };
                    optimizer    = new Bobyqa(2, bestFitG.ComputeError, xl, xu);
                    result       = optimizer.FindMinimum(startData);
                    //Debug.WriteLine("Result: " + result.F + " Interval: " + bestFitG.bestFitInterval[0] + "-" + bestFitG.bestFitInterval[1]);
                } while (limit < 0.35);

                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "No best interval found?!");
                if (bestFitG.bestFitInterval.Length == 0)
                {
                    return new List <Curve>()
                           {
                               bestFitG.selectedGeodesic
                           }
                }
                ;
            }
            //Debug.WriteLine("Result: " + result.F + " Interval: " + bestFitG.bestFitInterval[0] + "-" + bestFitG.bestFitInterval[1]);

            // Split the curve
            double domainLength = bestFitG.bestFitInterval[1] - bestFitG.bestFitInterval[0];
            Curve  splitC       = bestFitG.selectedGeodesic;

            splitC.Domain = new Interval(0, 1);
            List <Curve> pieceWiseList = new List <Curve>();

            if (domainLength < perpGeodesics.Count - 4)
            {
                // Generate piecewise at end
                if (bestFitG.bestFitInterval[1] < perpGeodesics.Count - 3)
                {
                    // Get reference point for splitting
                    //var refInt = Intersection.CurveCurve(splitC, perpGeodesics[(bestFitG.bestFitInterval[1] - 1)], 0.0, 0.0);
                    //double refT = refInt[0].ParameterA;

                    // Get intersection with end point
                    var endInt = Intersection.CurveCurve(splitC, perpGeodesics[(bestFitG.bestFitInterval[1])], 0.0, 0.0);

                    var endParam = endInt[0].ParameterA;

                    Point3d refPoint = splitC.PointAt(endParam / 2);

                    // Split the curve
                    Curve[] splitGs = splitC.Split(endParam);
                    // Select the correct curve
                    foreach (Curve g in splitGs)
                    {
                        double t;
                        g.ClosestPoint(refPoint, out t);
                        double distance = refPoint.DistanceTo(g.PointAt(t));
                        if (distance < 0.01)
                        {
                            splitC = g;
                            break;
                        }
                    }

                    List <double> paramsAtEnd = new List <double>(perpParameters);
                    paramsAtEnd.RemoveRange(0, bestFitG.bestFitInterval[1]);
                    List <Curve> geodsAtEnd = new List <Curve>(perpGeodesics);
                    geodsAtEnd.RemoveRange(0, bestFitG.bestFitInterval[1]);
                    // Replace first parameter with the parameter of the piecewise curve endpoint at the perpGeod.
                    var events = Intersection.CurveCurve(geodsAtEnd[0], bestFitG.selectedGeodesic, 0.0, 0.0);
                    paramsAtEnd[0] = events[0].ParameterA;
                    // Get the best next best fit geodesic at end
                    pieceWiseList.AddRange(GeneratePiecewiseAtEnd(mesh, paramsAtEnd, geodsAtEnd, maxIter, 0, threshold));
                }

                //// Generate piecewise at start
                //if (bestFitG.bestFitInterval[0] > 3)
                //{
                //    var refInt = Intersection.CurveCurve(splitC, perpGeodesics[(bestFitG.bestFitInterval[0] + 2)], 0.0, 0.0);
                //    Point3d refPoint = refInt[0].PointB;
                //    // Get intersection with end point
                //    var startInt = Intersection.CurveCurve(splitC, perpGeodesics[(bestFitG.bestFitInterval[0])], 0.0, 0.0);
                //    var startParam = startInt[0].ParameterA;
                //    // Split the curve
                //    Curve[] splitGs = splitC.Split(startParam);
                //    // Select the correct curve
                //    foreach (Curve g in splitGs)
                //    {
                //        double t;
                //        g.ClosestPoint(refPoint, out t);
                //        double distance = refPoint.DistanceTo(g.PointAt(t));
                //        if (distance < 0.01)
                //        {
                //            splitC = g;
                //            break;
                //        }
                //    }

                //    List<double> paramsAtStart = new List<double>(perpParameters);
                //    paramsAtStart.RemoveRange(bestFitG.bestFitInterval[0], (perpParameters.Count - 1) - bestFitG.bestFitInterval[0] - 1);
                //    List<Curve> geodsAtStart = new List<Curve>(perpGeodesics);
                //    geodsAtStart.RemoveRange(bestFitG.bestFitInterval[0], (perpGeodesics.Count - 1) - bestFitG.bestFitInterval[0] - 1);

                //    // Replace first parameter with the parameter of the piecewise curve endpoint at the perpGeod.
                //    paramsAtStart.Reverse();
                //    geodsAtStart.Reverse();
                //    var events = Intersection.CurveCurve(geodsAtStart[0], bestFitG.selectedGeodesic, 0.0, 0.0);
                //    paramsAtStart[0] = events[0].ParameterA;
                //    Vector3d vector = -splitC.TangentAtStart;
                //    // This would be the same as at end, but with a first step flipping the direction of the perpGeodesics list.
                //    /pieceWiseList.AddRange(GeneratePiecewiseAtStart(mesh, paramsAtStart, geodsAtStart, maxIter, 0, threshold, vector));
                //}

                pieceWiseList.Add(splitC);
            }
            else
            {
                pieceWiseList.Add(bestFitG.selectedGeodesic);
            }

            //pieceWiseList = bestFitG.GenerateSubCurves(startData, xl, xu, 0);
            return(pieceWiseList);
        }
Exemplo n.º 19
0
        public void FindMinimum_BobyqaTestCase_ReturnStatusNormal(int m, int npt)
        {
            //     Test problem for BOBYQA, the objective function being the sum of
            //     the reciprocals of all pairwise distances between the points P_I,
            //     I=1,2,...,M in two dimensions, where M=N/2 and where the components
            //     of P_I are X(2*I-1) and X(2*I). Thus each vector X of N variables
            //     defines the M points P_I. The initial X gives equally spaced points
            //     on a circle. Four different choices of the pairs (N,NPT) are tried,
            //     namely (10,16), (10,21), (20,26) and (20,41). Convergence to a local
            //     minimum that is not global occurs in both the N=10 cases. The details
            //     of the results are highly sensitive to computer rounding errors. The
            //     choice IPRINT=2 provides the current X and optimal F so far whenever
            //     RHO is reduced. The bound constraints of the problem require every
            //     component of X to be in the interval [-1,1].

            var n = 2 * m;
            var x0 = new double[n];
            var xl = new double[n];
            var xu = new double[n];

            const double bdl = -1.0;
            const double bdu = 1.0;
            for (var i = 0; i < n; ++i)
            {
                xl[i] = bdl;
                xu[i] = bdu;
            }

            Console.WriteLine("{0}2D output with M ={1,4},  N ={2,4}  and  NPT ={3,4}", Environment.NewLine, m, n, npt);

            for (var j = 1; j <= m; ++j)
            {
                var temp = 2.0 * Math.PI * j / m;
                x0[2 * j - 2] = Math.Cos(temp);
                x0[2 * j - 1] = Math.Sin(temp);
            }

            const int iprint = 2;
            const int maxfun = 500000;
            const double rhobeg = 1.0E-1;
            const double rhoend = 1.0E-6;

            var optimizer = new Bobyqa(n, this.BobyqaTestCalfun, xl, xu)
                                {
                                    InterpolationConditions = npt,
                                    TrustRegionRadiusStart = rhobeg,
                                    TrustRegionRadiusEnd = rhoend,
                                    PrintLevel = iprint,
                                    MaximumFunctionCalls = maxfun
                                };

            const OptimizationStatus expected = OptimizationStatus.Normal;
            var actual = optimizer.FindMinimum(x0).Status;
            Assert.AreEqual(expected, actual);
        }
Exemplo n.º 20
0
 public void FindMinimum_LogOutput_OutputNonEmpty()
 {
     const int n = 9;
     var optimizer = new Bobyqa(n, this.Rosen) { Logger = Console.Out };
     using (var logger = new StringWriter())
     {
         optimizer.Logger = logger;
         optimizer.FindMinimum(Enumerable.Repeat(0.1, n).ToArray());
         Assert.Greater(logger.ToString().Length, 0);
     }
 }
Exemplo n.º 21
0
 public void FindMinimum_LogOutputToConsole_OutputNonEmpty()
 {
     const int n = 9;
     var optimizer = new Bobyqa(n, this.Rosen) { Logger = Console.Out };
     optimizer.FindMinimum(Enumerable.Repeat(0.1, n).ToArray());
 }
Exemplo n.º 22
0
        public void FindMinimum_IntermedRosenbrock_ReturnsValidMinimum()
        {
            var optimizer = new Bobyqa(
                2,
                (n, x) => 10.0 * Math.Pow(x[0] * x[0] - x[1], 2.0) + Math.Pow(1.0 + x[0], 2.0));
            var summary = optimizer.FindMinimum(new[] { 1.0, -1.0 });

            Assert.AreEqual(-1.0, summary.X[0], TOL);
            Assert.AreEqual(1.0, summary.X[1], TOL);
        }
Exemplo n.º 23
0
        public void FindMinimum_HS05_ReturnsValidMinimum()
        {
            var optimizer = new Bobyqa(
                2,
                (n, x) => Math.Sin(x[0] + x[1]) + Math.Pow(x[0] - x[1], 2.0) - 1.5 * x[0] + 2.5 * x[1] + 1,
                new[] { -1.5, -3.0 },
                new[] { 4.0, 3.0 });
            var result = optimizer.FindMinimum(new[] { 0.0, 0.0 });

            Assert.AreEqual(0.5 - Math.PI / 3.0, result.X[0], TOL);
            Assert.AreEqual(-0.5 - Math.PI / 3.0, result.X[1], TOL);
        }
Exemplo n.º 24
0
        public void FindMinimum_HS04_ReturnsValidMinimum()
        {
            var optimizer = new Bobyqa(2, (n, x) => Math.Pow(x[0] + 1.0, 3.0) / 3.0 + x[1], new[] { 1.0, 0.0 }, null)
                                {
                                    InterpolationConditions = 4
                                };
            var result = optimizer.FindMinimum(new[] { 1.125, 0.125 });

            Assert.AreEqual(1.0, result.X[0], TOL);
            Assert.AreEqual(0.0, result.X[1], TOL);
        }
Exemplo n.º 25
0
        public void FindMinimum_ConstrainedRosenWithAdditionalInterpolationPoints_ReturnsValidMinimum(int n, int maxAdditionalPoints)
        {
            var xl = Enumerable.Repeat(-1.0, n).ToArray();
            var xu = Enumerable.Repeat(2.0, n).ToArray();
            var expected = Enumerable.Repeat(1.0, n).ToArray();

            var optimizer = new Bobyqa(n, this.Rosen, xl, xu)
                                {
                                    TrustRegionRadiusEnd = 1.0e-8,
                                    MaximumFunctionCalls = 3000,
                                    Logger = Console.Out
                                };
            for (var num = 1; num <= maxAdditionalPoints; ++num)
            {
                Console.WriteLine("\nNumber of additional points = {0}", num);
                optimizer.InterpolationConditions = 2 * n + 1 + num;
                var result = optimizer.FindMinimum(Enumerable.Repeat(0.1, n).ToArray());

                CollectionAssert.AreEqual(expected, result.X, new DoubleComparer(1.0e-6));
            }
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // Properties
            Mesh          mesh           = null;
            List <Curve>  perpGeodesics  = new List <Curve>();
            List <double> perpParameters = new List <double>();
            int           maxIter        = 0;
            bool          bothDir        = false;
            int           startIndex     = 0;

            mesh           = null;
            perpGeodesics  = new List <Curve>();
            perpParameters = new List <double>();
            double threshold = 0.0;

            // Set the input data
            if (!DA.GetData(0, ref mesh))
            {
                return;
            }
            if (!DA.GetDataList(1, perpGeodesics))
            {
                return;
            }
            if (!DA.GetDataList(2, perpParameters))
            {
                return;
            }
            if (!DA.GetData(3, ref maxIter))
            {
                return;
            }
            if (!DA.GetData(4, ref bothDir))
            {
                return;
            }
            if (!DA.GetData(5, ref startIndex))
            {
                return;
            }
            if (!DA.GetData(6, ref threshold))
            {
                return;
            }

            // Data validation
            if (maxIter == 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "MaxIter cannot be 0");
            }
            if (!mesh.IsValid)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh is invalid");
            }
            if (perpGeodesics.Count < 2)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "There must be at least 2 perpendicular geodesics");
            }
            if (perpParameters.Count != perpGeodesics.Count)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Curves and Params list must have the same number of items");
            }

            // Generate Initial values and variable Bounds for the optimization problem.
            // Only using first variable for now, the extra variable is just to make it work.
            double[] startData = { 0.010, 0 };
            double[] xl        = new double[] { -0.15, -1 };
            double[] xu        = new double[] { 0.15, 1 };


            BestFitPieceWiseGeodesic bestFitG = new BestFitPieceWiseGeodesic(mesh, perpGeodesics, perpParameters, maxIter, bothDir, startIndex, threshold, Vector3d.Unset);

            var optimizer = new Bobyqa(2, bestFitG.ComputeError, xl, xu);
            var result    = optimizer.FindMinimum(startData);

            if (bestFitG.bestFitInterval.Length == 0)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "No best interval found?!");
                return;
            }

            // Sub curves methods go here
            List <Curve> pieceWiseList = new List <Curve>();

            pieceWiseList = bestFitG.GenerateSubCurves(startData, xl, xu);


            DA.SetDataList(0, pieceWiseList);
            DA.SetDataList(1, result.X);
        }
        /// <summary>
        /// Generates the sub curves.
        /// </summary>
        /// <returns>The sub curves.</returns>
        /// <param name="_startData">Start data.</param>
        /// <param name="_xl">Xl.</param>
        /// <param name="_xu">Xu.</param>
        /// <param name="type">Generation type: 0 for doubleside, 1 for end side, -1 for start side of curve</param>
        public List <Curve> GenerateSubCurves(double[] _startData, double[] _xl, double[] _xu, int type)
        {
            // Generate Initial values and variable Bounds for the optimization problem.
            // Only using first variable for now, the extra variable is just to make it work.
            double[] startData = _startData;
            double[] xl        = _xl;
            double[] xu        = _xu;

            List <Curve> pieceWiseList = new List <Curve>();

            pieceWiseList.Add(selectedGeodesic);

            if (bestFitInterval.Length != 0)
            {
                switch (type)
                {
                // End point
                case 1:
                    pieceWiseList[0] = CutCurveBetweenPerpIndexes(pieceWiseList[0], perpGeodesics, 0, bestFitInterval[1]);
                    break;

                // Start point
                case -1:
                    pieceWiseList[0] = CutCurveBetweenPerpIndexes(pieceWiseList[0], perpGeodesics, bestFitInterval[0], perpGeodesics.Count - 1);
                    break;

                default:
                    pieceWiseList[0] = CutCurveBetweenPerpIndexes(pieceWiseList[0], perpGeodesics, bestFitInterval[0], bestFitInterval[1]);
                    break;
                }

                if ((bestFitInterval[1] < (perpGeodesics.Count - 1)) && (type == 0 || type == 1))
                {
                    List <Curve>  tempGeodesics  = perpGeodesics.GetRange(bestFitInterval[1], (perpGeodesics.Count - bestFitInterval[1]));
                    List <double> tempParameters = perpParameters.GetRange(bestFitInterval[1], (perpGeodesics.Count - bestFitInterval[1]));
                    Vector3d      tangent        = pieceWiseList[0].TangentAtEnd;
                    double        t;
                    tempGeodesics[0].ClosestPoint(pieceWiseList[0].PointAtEnd, out t);
                    tempParameters[0] = t;
                    BestFitPieceWiseGeodesic tempBestFit = new BestFitPieceWiseGeodesic(mesh, tempGeodesics, tempParameters, maxIter, false, 0, threshold, tangent);
                    var tempOptimizer = new Bobyqa(2, tempBestFit.ComputeError, xl, xu);
                    var tempResult    = tempOptimizer.FindMinimum(startData);

                    if (tempBestFit.bestFitInterval.Length == 0)
                    {
                        pieceWiseList[0] = selectedGeodesic; //No best fit found
                    }
                    else
                    {
                        pieceWiseList.AddRange(tempBestFit.GenerateSubCurves(startData, xl, xu, 1));
                    }
                }

                //if (bestFitInterval[0] > 0 && (type == 0 || type == -1))
                //{

                //    List<Curve> tempGeodesics = perpGeodesics.GetRange(0, bestFitInterval[0] + 1);
                //    List<double> tempParameters = perpParameters.GetRange(0, bestFitInterval[0] + 1);

                //    double t;
                //    Vector3d tangent = pieceWiseList[0].TangentAtStart;
                //    //tangent.Rotate(Math.PI, mesh.NormalAt(mesh.ClosestMeshPoint(pieceWiseList[0].PointAtStart, 0.0)));

                //    tempGeodesics[tempGeodesics.Count - 1].ClosestPoint(pieceWiseList[0].PointAtStart, out t);
                //    tempParameters[tempGeodesics.Count - 1] = t;
                //    BestFitPieceWiseGeodesic tempBestFit = new BestFitPieceWiseGeodesic(mesh, tempGeodesics, tempParameters, maxIter, false, tempGeodesics.Count - 1, threshold, -tangent);
                //    var tempOptimizer = new Bobyqa(2, tempBestFit.ComputeError, xl, xu);
                //    var tempResult = tempOptimizer.FindMinimum(startData);

                //    if (tempBestFit.bestFitInterval.Length == 0)
                //    {
                //        pieceWiseList.Add(tempBestFit.selectedGeodesic); // No best fit found;
                //    }
                //    else
                //    {
                //        tempBestFit.selectedGeodesic.Reverse();
                //        pieceWiseList.AddRange(tempBestFit.GenerateSubCurves(startData, xl, xu, -1));
                //    }
                //}
            }

            return(pieceWiseList);
        }