/*
 * jcobyla
 * 
 * The MIT License
 *
 * Copyright (c) 2012 Anders Gustafsson, Cureos AB.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 
 * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 
 * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 
 * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * Remarks:
 * 
 * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk)
 * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998
 */
package com.cureos.numerics;

import static org.junit.Assert.assertArrayEquals;
import org.junit.Test;

/**
 * Test class for COBYLA2 employing tests from Report DAMTP 1992/NA5.
 * 
 * @author Anders Gustafsson, Cureos AB.
 */
public class CobylaTest {
    
    // FIELDS
    
    private double rhobeg = 0.5;
    private double rhoend = 1.0e-6;
    private int iprint = 1;
    private int maxfun = 3500;

    // TESTS
    
    /**
     * Minimization of a simple quadratic function of two variables.
     */
    @Test
    public void test01FindMinimum() {
        System.out.format("%nOutput from test problem 1 (Simple quadratic)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                return 10.0 * Math.pow(x[0] + 1.0, 2.0) + Math.pow(x[1], 2.0);
            }
        };
        double[] x = {1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 0, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { -1.0, 0.0 }, x, 1.0e-5);
    }
    
    /**
     * Easy two dimensional minimization in unit circle.
     */
    @Test
    public void test02FindMinimum() {
        System.out.format("%nOutput from test problem 2 (2D unit circle calculation)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = 1.0 - x[0] * x[0] - x[1] * x[1];
                return x[0] * x[1];
            }
        };
        double[] x = {1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 1, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { Math.sqrt(0.5), -Math.sqrt(0.5) }, x, 1.0e-5);
    }
    
    /**
     * Easy three dimensional minimization in ellipsoid.
     */
    @Test
    public void test03FindMinimum() {
        System.out.format("%nOutput from test problem 3 (3D ellipsoid calculation)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = 1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2];
                return x[0] * x[1] * x[2];
            }
        };
        double[] x = {1.0, 1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 3, 1, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { 1.0 / Math.sqrt(3.0), 1.0 / Math.sqrt(6.0), -1.0 / 3.0 }, x, 1.0e-5);
    }
    
    /**
     * Weak version of Rosenbrock's problem.
     */
    @Test
    public void test04FindMinimum() {
        System.out.format("%nOutput from test problem 4 (Weak Rosenbrock)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                return Math.pow(x[0] * x[0] - x[1], 2.0) + Math.pow(1.0 + x[0], 2.0);
            }
        };
        double[] x = {1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 0, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { -1.0, 1.0 }, x, 1.0e-4);
    }
    
    /**
     * Intermediate version of Rosenbrock's problem.
     */
    @Test
    public void test05FindMinimum() {
        System.out.format("%nOutput from test problem 5 (Intermediate Rosenbrock)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                return 10.0 * Math.pow(x[0] * x[0] - x[1], 2.0) + Math.pow(1.0 + x[0], 2.0);
            }
        };
        double[] x = {1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 0, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { -1.0, 1.0 }, x, 3.0e-4);
    }
    
    /**
     * This problem is taken from Fletcher's book Practical Methods of
     * Optimization and has the equation number (9.1.15).
     */
    @Test
    public void test06FindMinimum() {
        System.out.format("%nOutput from test problem 6 (Equation (9.1.15) in Fletcher's book)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = x[1] - x[0] * x[0];
                con[1] = 1.0 - x[0] * x[0] - x[1] * x[1];
                return -x[0] - x[1];
            }
        };
        double[] x = {1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 2, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { Math.sqrt(0.5), Math.sqrt(0.5) }, x, 1.0e-5);
    }
    
    /**
     * This problem is taken from Fletcher's book Practical Methods of
     * Optimization and has the equation number (14.4.2).
     */
    @Test
    public void test07FindMinimum() {
        System.out.format("%nOutput from test problem 7 (Equation (14.4.2) in Fletcher)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = 5.0 * x[0] - x[1] + x[2];
                con[1] = x[2] - x[0] * x[0] - x[1] * x[1] - 4.0 * x[1];
                con[2] = x[2] - 5.0 * x[0] - x[1];
                return x[2];
            }
        };
        double[] x = {1.0, 1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 3, 3, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { 0.0, -3.0, -3.0 }, x, 1.0e-5);
    }
    
    /**
     * 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.
     */
    @Test
    public void test08FindMinimum() {
        System.out.format("%nOutput from test problem 8 (Rosen-Suzuki)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = 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];
                con[1] = 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];
                con[2] = 5.0 - 2.0 * x[0] * x[0] - x[1] * x[1] - x[2] * x[2] - 2.0 * x[0] + x[1] + x[3];
                return 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];
            }
        };
        double[] x = {1.0, 1.0, 1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 4, 3, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, new double[] { 0.0, 1.0, 2.0, -1.0 }, x, 1.0e-5);
    }
    
    /**
     * 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.
     */
    @Test
    public void test09FindMinimum() {
        System.out.format("%nOutput from test problem 9 (Hock and Schittkowski 100)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = 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];
                con[1] = 282.0 - 7.0 * x[0] - 3.0 * x[1] - 10.0 * x[2] * x[2] - x[3] + x[4];
                con[2] = 196.0 - 23.0 * x[0] - x[1] * x[1] - 6.0 * x[5] * x[5] + 8.0 * x[6];
                con[3] = -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];
                return 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];
            }
        };
        double[] x = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 7, 4, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, 
                new double[] { 2.330499, 1.951372, -0.4775414, 4.365726, -0.624487, 1.038131, 1.594227 }, x, 1.0e-5);
    }
    
    /**
     * 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.
     */
    @Test
    public void test10FindMinimum() {
        System.out.format("%nOutput from test problem 10 (Hexagon area)%n");
        Calcfc calcfc = new Calcfc() {
            @Override
            public double Compute(int n, int m, double[] x, double[] con) {
                con[0] = 1.0 - x[2] * x[2] - x[3] * x[3];
                con[1] = 1.0 - x[8] * x[8];
                con[2] = 1.0 - x[4] * x[4] - x[5] * x[5];
                con[3] = 1.0 - x[0] * x[0] - Math.pow(x[1] - x[8], 2.0);
                con[4] = 1.0 - Math.pow(x[0] - x[4], 2.0) - Math.pow(x[1] - x[5], 2.0);
                con[5] = 1.0 - Math.pow(x[0] - x[6], 2.0) - Math.pow(x[1] - x[7], 2.0);
                con[6] = 1.0 - Math.pow(x[2] - x[4], 2.0) - Math.pow(x[3] - x[5], 2.0);
                con[7] = 1.0 - Math.pow(x[2] - x[6], 2.0) - Math.pow(x[3] - x[7], 2.0);
                con[8] = 1.0 - x[6] * x[6] - Math.pow(x[7] - x[8], 2.0);
                con[9] = x[0] * x[3] - x[1] * x[2];
                con[10] = x[2] * x[8];
                con[11] = -x[4] * x[8];
                con[12] = x[4] * x[7] - x[5] * x[6];
                con[13] = x[8];
                return -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]);
            }
        };
        double[] x = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 };
        CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 9, 14, x, rhobeg, rhoend, iprint, maxfun);
        assertArrayEquals(null, 
                new double[] { x[0], x[1], x[2], x[3], x[0], x[1], x[2], x[3], 0.0 }, x, 1.0e-4);
    }
}

 

Ads help maintain this website.