1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.math.optimization;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertTrue;
22  import static org.junit.Assert.fail;
23  
24  import java.io.Serializable;
25  
26  import org.apache.commons.math.FunctionEvaluationException;
27  import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
28  import org.apache.commons.math.analysis.MultivariateMatrixFunction;
29  import org.apache.commons.math.linear.BlockRealMatrix;
30  import org.apache.commons.math.linear.RealMatrix;
31  import org.apache.commons.math.optimization.general.GaussNewtonOptimizer;
32  import org.apache.commons.math.random.GaussianRandomGenerator;
33  import org.apache.commons.math.random.JDKRandomGenerator;
34  import org.apache.commons.math.random.RandomVectorGenerator;
35  import org.apache.commons.math.random.UncorrelatedRandomVectorGenerator;
36  import org.junit.Test;
37  
38  /**
39   * <p>Some of the unit tests are re-implementations of the MINPACK <a
40   * href="http://www.netlib.org/minpack/ex/file17">file17</a> and <a
41   * href="http://www.netlib.org/minpack/ex/file22">file22</a> test files. 
42   * The redistribution policy for MINPACK is available <a
43   * href="http://www.netlib.org/minpack/disclaimer">here</a>, for
44   * convenience, it is reproduced below.</p>
45  
46   * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0">
47   * <tr><td>
48   *    Minpack Copyright Notice (1999) University of Chicago.
49   *    All rights reserved
50   * </td></tr>
51   * <tr><td>
52   * Redistribution and use in source and binary forms, with or without
53   * modification, are permitted provided that the following conditions
54   * are met:
55   * <ol>
56   *  <li>Redistributions of source code must retain the above copyright
57   *      notice, this list of conditions and the following disclaimer.</li>
58   * <li>Redistributions in binary form must reproduce the above
59   *     copyright notice, this list of conditions and the following
60   *     disclaimer in the documentation and/or other materials provided
61   *     with the distribution.</li>
62   * <li>The end-user documentation included with the redistribution, if any,
63   *     must include the following acknowledgment:
64   *     <code>This product includes software developed by the University of
65   *           Chicago, as Operator of Argonne National Laboratory.</code>
66   *     Alternately, this acknowledgment may appear in the software itself,
67   *     if and wherever such third-party acknowledgments normally appear.</li>
68   * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"
69   *     WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE
70   *     UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND
71   *     THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR
72   *     IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES
73   *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE
74   *     OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY
75   *     OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR
76   *     USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF
77   *     THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)
78   *     DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION
79   *     UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL
80   *     BE CORRECTED.</strong></li>
81   * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT
82   *     HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF
83   *     ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,
84   *     INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF
85   *     ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF
86   *     PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER
87   *     SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT
88   *     (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,
89   *     EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE
90   *     POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li>
91   * <ol></td></tr>
92   * </table>
93  
94   * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests)
95   * @author Burton S. Garbow (original fortran minpack tests)
96   * @author Kenneth E. Hillstrom (original fortran minpack tests)
97   * @author Jorge J. More (original fortran minpack tests)
98   * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation)
99   */
100 public class MultiStartDifferentiableMultivariateVectorialOptimizerTest {
101 
102     @Test
103     public void testTrivial() throws FunctionEvaluationException, OptimizationException {
104         LinearProblem problem =
105             new LinearProblem(new double[][] { { 2 } }, new double[] { 3 });
106         DifferentiableMultivariateVectorialOptimizer underlyingOptimizer =
107             new GaussNewtonOptimizer(true);
108         JDKRandomGenerator g = new JDKRandomGenerator();
109         g.setSeed(16069223052l);
110         RandomVectorGenerator generator =
111             new UncorrelatedRandomVectorGenerator(1, new GaussianRandomGenerator(g));
112         MultiStartDifferentiableMultivariateVectorialOptimizer optimizer =
113             new MultiStartDifferentiableMultivariateVectorialOptimizer(underlyingOptimizer,
114                                                                        10, generator);
115         optimizer.setMaxIterations(100);
116         optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6));
117 
118         // no optima before first optimization attempt
119         try {
120             optimizer.getOptima();
121             fail("an exception should have been thrown");
122         } catch (IllegalStateException ise) {
123             // expected
124         }
125         VectorialPointValuePair optimum =
126             optimizer.optimize(problem, problem.target, new double[] { 1 }, new double[] { 0 });
127         assertEquals(1.5, optimum.getPoint()[0], 1.0e-10);
128         assertEquals(3.0, optimum.getValue()[0], 1.0e-10);
129         VectorialPointValuePair[] optima = optimizer.getOptima();
130         assertEquals(10, optima.length);
131         for (int i = 0; i < optima.length; ++i) {
132             assertEquals(1.5, optima[i].getPoint()[0], 1.0e-10);
133             assertEquals(3.0, optima[i].getValue()[0], 1.0e-10);
134         }
135         assertTrue(optimizer.getEvaluations() > 20);
136         assertTrue(optimizer.getEvaluations() < 50);
137         assertTrue(optimizer.getIterations() > 20);
138         assertTrue(optimizer.getIterations() < 50);
139         assertTrue(optimizer.getJacobianEvaluations() > 20);
140         assertTrue(optimizer.getJacobianEvaluations() < 50);
141         assertEquals(100, optimizer.getMaxIterations());
142     }
143 
144     @Test(expected = OptimizationException.class)
145     public void testNoOptimum() throws FunctionEvaluationException, OptimizationException {
146         DifferentiableMultivariateVectorialOptimizer underlyingOptimizer =
147             new GaussNewtonOptimizer(true);
148         JDKRandomGenerator g = new JDKRandomGenerator();
149         g.setSeed(12373523445l);
150         RandomVectorGenerator generator =
151             new UncorrelatedRandomVectorGenerator(1, new GaussianRandomGenerator(g));
152         MultiStartDifferentiableMultivariateVectorialOptimizer optimizer =
153             new MultiStartDifferentiableMultivariateVectorialOptimizer(underlyingOptimizer,
154                                                                        10, generator);
155         optimizer.setMaxIterations(100);
156         optimizer.setConvergenceChecker(new SimpleVectorialValueChecker(1.0e-6, 1.0e-6));
157         optimizer.optimize(new DifferentiableMultivariateVectorialFunction() {
158                 public MultivariateMatrixFunction jacobian() {
159                     return null;
160                 }
161                 public double[] value(double[] point) throws FunctionEvaluationException {
162                     throw new FunctionEvaluationException(point[0]);
163                 }
164             }, new double[] { 2 }, new double[] { 1 }, new double[] { 0 });
165     }
166 
167     private static class LinearProblem implements DifferentiableMultivariateVectorialFunction, Serializable {
168 
169         private static final long serialVersionUID = -8804268799379350190L;
170         final RealMatrix factors;
171         final double[] target;
172         public LinearProblem(double[][] factors, double[] target) {
173             this.factors = new BlockRealMatrix(factors);
174             this.target  = target;
175         }
176 
177         public double[] value(double[] variables) {
178             return factors.operate(variables);
179         }
180 
181         public MultivariateMatrixFunction jacobian() {
182             return new MultivariateMatrixFunction() {
183                 private static final long serialVersionUID = -8387467946663627585L;
184                 public double[][] value(double[] point) {
185                     return factors.getData();
186                 }
187             };
188         }
189 
190     }
191 
192 }