Click here to Skip to main content
11,640,866 members (62,943 online)
Click here to Skip to main content
Add your own
alternative version

Derivative-free nonlinear optimization for .NET and Java

, 18 Dec 2012 MIT 11.4K 508 19
Announcing standalone implementations of derivative-free nonlinear optimizers for .NET and Java platforms
csbobyqa-master-noexe.zip
csbobyqa-master
.gitignore
.nuget
NuGet.targets
Cureos.Numerics
Properties
Fsharp.Bobyqa
Fsharp.Bobyqa.fsproj
Program.fs
README.rdoc
csbobyqa.Tests
Properties
packages
reference
NA2009_06.pdf
csbobyqa-master.zip
.gitignore
NuGet.exe
NuGet.targets
Fsharp.Bobyqa.fsproj
Program.fs
README.rdoc
NA2009_06.pdf
cscobyla-master-noexe.zip
cscobyla-master
.gitignore
.nuget
NuGet.targets
Cscobyla.Tests
.gitignore
Properties
Tests
Cureos.Numerics
Properties
README.rdoc
cscobyla-master.zip
.gitignore
NuGet.exe
NuGet.targets
.gitignore
README.rdoc
jcobyla-master.zip
jcobyla-master
README.rdoc
nbproject
genfiles.properties
project.properties
src
com
cureos
numerics
test
com
cureos
numerics
using System;
using System.Collections;
using System.IO;
using System.Linq;
using NUnit.Framework;

namespace Cureos.Numerics.Tests
{
    [TestFixture]
    public class BobyqaTests
    {
        #region Fields

        private const double TOL = 1.0e-5;

        #endregion

        #region Unit tests

        [Test]
        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);
        }

        [Test]
        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);
        }

        [Test]
        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);
        }

        [TestCase(5, 16)]
        [TestCase(5, 21)]
        [TestCase(10, 26)]
        [TestCase(10, 41)]
        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 x = 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;
                x[2 * j - 2] = Math.Cos(temp);
                x[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;

            const BobyqaExitStatus expected = BobyqaExitStatus.Normal;
            var actual = Bobyqa.FindMinimum(BobyqaTestCalfun, n, x, xl, xu, npt, rhobeg, rhoend, iprint, maxfun);
            Assert.AreEqual(expected, actual);
        }

        public double BobyqaTestCalfun(int n, double[] x)
        {
            var f = 0.0;
            for (var i = 4; i <= n; i += 2)
            {
                for (var j = 2; j <= i - 2; j += 2)
                {
                    var temp = Math.Max(Math.Pow(x[i - 2] - x[j - 2], 2.0) + Math.Pow(x[i - 1] - x[j - 1], 2.0), 1.0e-6);
                    f += 1.0 / Math.Sqrt(temp);
                }
            }
            return f;
        }

        [TestCase(13, 47)]
        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, 2000, Console.Out);
                CollectionAssert.AreEqual(expected, x, new DoubleComparer(1.0e-6));
            }
        }
        
        [Test]
        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);
            }
        }

        [Test]
        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);
        }

        public double Rosen(int n, double[] x)
        {
            var f = 0.0;
            for (var i = 0; i < n - 1; ++i)
                f += 1e2 * (x[i] * x[i] - x[i + 1]) * (x[i] * x[i] - x[i + 1]) + (x[i] - 1.0) * (x[i] - 1.0);
            return f;
        }

        #endregion
    }

    internal class DoubleComparer : IComparer
    {
        private readonly double _tol;

        internal DoubleComparer(double tol)
        {
            _tol = tol;
        }

        internal int Compare(double x, double y)
        {
            return Math.Abs(x - y) <= _tol ? 0 : x.CompareTo(y);
        }

        int IComparer.Compare(object x, object y)
        {
            return Compare((double)x, (double)y);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

Anders Gustafsson, Cureos
CEO Cureos AB
Sweden Sweden
I am the owner of Cureos AB, a software development and consulting company located in Uppsala, Sweden. The company's main focus is in developing software for dose-response analysis and optimization of large patient treatment materials, primarily using the .NET framework. In my Ph.D. thesis I outlined a general optimization framework for radiation therapy, and I have developed numerous tools for radiotherapy optimization and dose-response modeling that have been integrated into different treatment planning systems.

You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150731.1 | Last Updated 19 Dec 2012
Article Copyright 2012 by Anders Gustafsson, Cureos
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid