├── nbproject ├── genfiles.properties ├── project.xml ├── project.properties └── build-impl.xml ├── src └── com │ └── cureos │ └── numerics │ ├── CobylaExitStatus.java │ ├── Calcfc.java │ └── Cobyla.java ├── README.rdoc └── test └── com └── cureos └── numerics └── CobylaTest.java /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=8e26265b 2 | build.xml.script.CRC32=e43e3322 3 | build.xml.stylesheet.CRC32=28e38971@1.50.2.46 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=8e26265b 7 | nbproject/build-impl.xml.script.CRC32=b89a0382 8 | nbproject/build-impl.xml.stylesheet.CRC32=fcddb364@1.50.2.46 9 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | jcobyla 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/com/cureos/numerics/CobylaExitStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * jcobyla 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012 Anders Gustafsson, Cureos AB. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 11 | * subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * Remarks: 21 | * 22 | * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk) 23 | * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998 24 | */ 25 | package com.cureos.numerics; 26 | 27 | /** 28 | * Enumeration of exit statuses associated with COBYLA2 optimization. 29 | * 30 | * @author Anders Gustafsson, Cureos AB. 31 | */ 32 | public enum CobylaExitStatus { 33 | /** 34 | * Optimization successfully completed. 35 | */ 36 | Normal, 37 | 38 | /** 39 | * Maximum number of iterations (function/constraints evaluations) reached during optimization. 40 | */ 41 | MaxIterationsReached, 42 | 43 | /** 44 | * Size of rounding error is becoming damaging, terminating prematurely. 45 | */ 46 | DivergingRoundingErrors 47 | } 48 | -------------------------------------------------------------------------------- /src/com/cureos/numerics/Calcfc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * jcobyla 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012 Anders Gustafsson, Cureos AB. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 11 | * subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * Remarks: 21 | * 22 | * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk) 23 | * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998 24 | */ 25 | package com.cureos.numerics; 26 | 27 | /** 28 | * Interface for calculation of objective function and constraints in COBYLA2 optimization. 29 | * 30 | * @author Anders Gustafsson, Cureos AB. 31 | */ 32 | public interface Calcfc { 33 | /** 34 | * The objective and constraints function evaluation method used in COBYLA2 minimization. 35 | * @param n Number of variables. 36 | * @param m Number of constraints. 37 | * @param x Variable values to be employed in function and constraints calculation. 38 | * @param con Calculated function values of the constraints. 39 | * @return Calculated objective function value. 40 | */ 41 | double Compute(int n, int m, double[] x, double[] con); 42 | } 43 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | annotation.processing.enabled=true 2 | annotation.processing.enabled.in.editor=false 3 | annotation.processing.processor.options= 4 | annotation.processing.processors.list= 5 | annotation.processing.run.all.processors=true 6 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output 7 | build.classes.dir=${build.dir}/classes 8 | build.classes.excludes=**/*.java,**/*.form 9 | # This directory is removed when the project is cleaned: 10 | build.dir=build 11 | build.generated.dir=${build.dir}/generated 12 | build.generated.sources.dir=${build.dir}/generated-sources 13 | # Only compile against the classpath explicitly listed here: 14 | build.sysclasspath=ignore 15 | build.test.classes.dir=${build.dir}/test/classes 16 | build.test.results.dir=${build.dir}/test/results 17 | # Uncomment to specify the preferred debugger connection transport: 18 | #debug.transport=dt_socket 19 | debug.classpath=\ 20 | ${run.classpath} 21 | debug.test.classpath=\ 22 | ${run.test.classpath} 23 | # This directory is removed when the project is cleaned: 24 | dist.dir=dist 25 | dist.jar=${dist.dir}/jcobyla.jar 26 | dist.javadoc.dir=${dist.dir}/javadoc 27 | excludes= 28 | includes=** 29 | jar.compress=false 30 | javac.classpath= 31 | # Space-separated list of extra javac options 32 | javac.compilerargs= 33 | javac.deprecation=false 34 | javac.processorpath=\ 35 | ${javac.classpath} 36 | javac.source=1.7 37 | javac.target=1.7 38 | javac.test.classpath=\ 39 | ${javac.classpath}:\ 40 | ${build.classes.dir}:\ 41 | ${libs.junit_4.classpath} 42 | javac.test.processorpath=\ 43 | ${javac.test.classpath} 44 | javadoc.additionalparam= 45 | javadoc.author=false 46 | javadoc.encoding=${source.encoding} 47 | javadoc.noindex=false 48 | javadoc.nonavbar=false 49 | javadoc.notree=false 50 | javadoc.private=false 51 | javadoc.splitindex=true 52 | javadoc.use=true 53 | javadoc.version=false 54 | javadoc.windowtitle= 55 | meta.inf.dir=${src.dir}/META-INF 56 | mkdist.disabled=true 57 | platform.active=default_platform 58 | run.classpath=\ 59 | ${javac.classpath}:\ 60 | ${build.classes.dir} 61 | # Space-separated list of JVM arguments used when running the project 62 | # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value 63 | # or test-sys-prop.name=value to set system properties for unit tests): 64 | run.jvmargs= 65 | run.test.classpath=\ 66 | ${javac.test.classpath}:\ 67 | ${build.test.classes.dir} 68 | source.encoding=UTF-8 69 | src.dir=src 70 | test.src.dir=test 71 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | =jcobyla 2 | 3 | Constrained Optimization BY Linear Approximation in Java 4 | 5 | COBYLA2 is an implementation of Powell’s nonlinear derivative–free constrained optimization that uses a linear approximation approach. 6 | The algorithm is a sequential trust–region algorithm that employs linear approximations to the objective and constraint functions, 7 | where the approximations are formed by linear interpolation at n + 1 points in the space of the variables and tries to maintain a 8 | regular–shaped simplex over iterations. 9 | 10 | It solves nonsmooth NLP with a moderate number of variables (about 100). Inequality constraints only. 11 | 12 | The initial point X is taken as one vertex of the initial simplex with zero being another, so, X should not be entered as the zero vector. 13 | 14 | ==Links 15 | 16 | * This is a Java version of Mike Powell's F77 implementation of COBYLA2, available at ftp://plato.la.asu.edu/pub/other_software/cobyla2.tar.gz 17 | * The Java version is a straightforward translation of the C# port, available at https://github.com/cureos/cscobyla 18 | * Mike Powell's paper on Direct Search methods is available at http://www.damtp.cam.ac.uk/user/na/NA_papers/NA1998_04.ps.gz 19 | 20 | ==Usage 21 | 22 | The files _Cobyla.java_, _Calcfc.java_ and _CobylaExitStatus.java_ can be included in the package _com.cureos.numerics_ of any Java project. 23 | 24 | The Java implementation is relatively faithful to the original Fortran 77 and 90 implementations. It should be noted however that the 25 | indexing of the variables and constraints arrays in the _public_ interface is zero-based, i.e. for a problem with 3 variables, x[0], 26 | x[1] and x[2] should be employed in the objective and constraints function evaluations. 27 | 28 | The objective function and (potentially) constraints functions computation should be is represented by the _Compute_ method in the _Calcfc_ interface. 29 | Implement the interface explicitly or anonymously. The _Compute_ method exhibits the following signature: 30 | 31 | double Compute(int n, int m, double[] x, double[] con) 32 | 33 | where _n_ is the number of variables, _m_ is the number of constraints, _x_ is the variable array, and _con_ is the array of calculated constraints 34 | function values. The method should return the value of the objective function. 35 | 36 | To minimize the objective function subject to constraints, call the static _Cobyla.FindMinimum_ method: 37 | 38 | CobylaExitStatus FindMinimum(Calcfc calcfc, int n, int m, double[] x, 39 | double rhobeg, double rhoend, int iprint, int maxfun); 40 | 41 | where _x_ on input is the initial variable array, _rhobeg_ and _rhoend_ are the initial and final values of the simplex, _iprint_ (0..3) 42 | specifies the level of output to the console, and _maxfun_ is the maximum allowed number of function evaluations. On output _x_ is the 43 | optimal obtained variable values. The method returns final optimization status, which is one of normal termination, maximum iterations 44 | reached or diverging rounding errors. 45 | 46 | For usage examples with anonymous interface implementations, please review the _CobylaTest.java_ file in the _test_ folder. 47 | 48 | ==The MIT License 49 | 50 | Copyright (c) 2012 Anders Gustafsson, Cureos AB. 51 | 52 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 53 | (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 54 | publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 55 | subject to the following conditions: 56 | 57 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 60 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 61 | FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 62 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 63 | 64 | ==Revision history 65 | 66 | * May 2, 2012: Reference to usage examples. 67 | * May 1, 2012: Initial document. 68 | -------------------------------------------------------------------------------- /test/com/cureos/numerics/CobylaTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * jcobyla 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012 Anders Gustafsson, Cureos AB. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 11 | * subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * Remarks: 21 | * 22 | * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk) 23 | * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998 24 | */ 25 | package com.cureos.numerics; 26 | 27 | import static org.junit.Assert.assertArrayEquals; 28 | import org.junit.Test; 29 | 30 | /** 31 | * Test class for COBYLA2 employing tests from Report DAMTP 1992/NA5. 32 | * 33 | * @author Anders Gustafsson, Cureos AB. 34 | */ 35 | public class CobylaTest { 36 | 37 | // FIELDS 38 | 39 | private double rhobeg = 0.5; 40 | private double rhoend = 1.0e-6; 41 | private int iprint = 1; 42 | private int maxfun = 3500; 43 | 44 | // TESTS 45 | 46 | /** 47 | * Minimization of a simple quadratic function of two variables. 48 | */ 49 | @Test 50 | public void test01FindMinimum() { 51 | System.out.format("%nOutput from test problem 1 (Simple quadratic)%n"); 52 | Calcfc calcfc = new Calcfc() { 53 | @Override 54 | public double Compute(int n, int m, double[] x, double[] con) { 55 | return 10.0 * Math.pow(x[0] + 1.0, 2.0) + Math.pow(x[1], 2.0); 56 | } 57 | }; 58 | double[] x = {1.0, 1.0 }; 59 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 0, x, rhobeg, rhoend, iprint, maxfun); 60 | assertArrayEquals(null, new double[] { -1.0, 0.0 }, x, 1.0e-5); 61 | } 62 | 63 | /** 64 | * Easy two dimensional minimization in unit circle. 65 | */ 66 | @Test 67 | public void test02FindMinimum() { 68 | System.out.format("%nOutput from test problem 2 (2D unit circle calculation)%n"); 69 | Calcfc calcfc = new Calcfc() { 70 | @Override 71 | public double Compute(int n, int m, double[] x, double[] con) { 72 | con[0] = 1.0 - x[0] * x[0] - x[1] * x[1]; 73 | return x[0] * x[1]; 74 | } 75 | }; 76 | double[] x = {1.0, 1.0 }; 77 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 1, x, rhobeg, rhoend, iprint, maxfun); 78 | assertArrayEquals(null, new double[] { Math.sqrt(0.5), -Math.sqrt(0.5) }, x, 1.0e-5); 79 | } 80 | 81 | /** 82 | * Easy three dimensional minimization in ellipsoid. 83 | */ 84 | @Test 85 | public void test03FindMinimum() { 86 | System.out.format("%nOutput from test problem 3 (3D ellipsoid calculation)%n"); 87 | Calcfc calcfc = new Calcfc() { 88 | @Override 89 | public double Compute(int n, int m, double[] x, double[] con) { 90 | con[0] = 1.0 - x[0] * x[0] - 2.0 * x[1] * x[1] - 3.0 * x[2] * x[2]; 91 | return x[0] * x[1] * x[2]; 92 | } 93 | }; 94 | double[] x = {1.0, 1.0, 1.0 }; 95 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 3, 1, x, rhobeg, rhoend, iprint, maxfun); 96 | assertArrayEquals(null, new double[] { 1.0 / Math.sqrt(3.0), 1.0 / Math.sqrt(6.0), -1.0 / 3.0 }, x, 1.0e-5); 97 | } 98 | 99 | /** 100 | * Weak version of Rosenbrock's problem. 101 | */ 102 | @Test 103 | public void test04FindMinimum() { 104 | System.out.format("%nOutput from test problem 4 (Weak Rosenbrock)%n"); 105 | Calcfc calcfc = new Calcfc() { 106 | @Override 107 | public double Compute(int n, int m, double[] x, double[] con) { 108 | return Math.pow(x[0] * x[0] - x[1], 2.0) + Math.pow(1.0 + x[0], 2.0); 109 | } 110 | }; 111 | double[] x = {1.0, 1.0 }; 112 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 0, x, rhobeg, rhoend, iprint, maxfun); 113 | assertArrayEquals(null, new double[] { -1.0, 1.0 }, x, 1.0e-4); 114 | } 115 | 116 | /** 117 | * Intermediate version of Rosenbrock's problem. 118 | */ 119 | @Test 120 | public void test05FindMinimum() { 121 | System.out.format("%nOutput from test problem 5 (Intermediate Rosenbrock)%n"); 122 | Calcfc calcfc = new Calcfc() { 123 | @Override 124 | public double Compute(int n, int m, double[] x, double[] con) { 125 | return 10.0 * Math.pow(x[0] * x[0] - x[1], 2.0) + Math.pow(1.0 + x[0], 2.0); 126 | } 127 | }; 128 | double[] x = {1.0, 1.0 }; 129 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 0, x, rhobeg, rhoend, iprint, maxfun); 130 | assertArrayEquals(null, new double[] { -1.0, 1.0 }, x, 3.0e-4); 131 | } 132 | 133 | /** 134 | * This problem is taken from Fletcher's book Practical Methods of 135 | * Optimization and has the equation number (9.1.15). 136 | */ 137 | @Test 138 | public void test06FindMinimum() { 139 | System.out.format("%nOutput from test problem 6 (Equation (9.1.15) in Fletcher's book)%n"); 140 | Calcfc calcfc = new Calcfc() { 141 | @Override 142 | public double Compute(int n, int m, double[] x, double[] con) { 143 | con[0] = x[1] - x[0] * x[0]; 144 | con[1] = 1.0 - x[0] * x[0] - x[1] * x[1]; 145 | return -x[0] - x[1]; 146 | } 147 | }; 148 | double[] x = {1.0, 1.0 }; 149 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 2, 2, x, rhobeg, rhoend, iprint, maxfun); 150 | assertArrayEquals(null, new double[] { Math.sqrt(0.5), Math.sqrt(0.5) }, x, 1.0e-5); 151 | } 152 | 153 | /** 154 | * This problem is taken from Fletcher's book Practical Methods of 155 | * Optimization and has the equation number (14.4.2). 156 | */ 157 | @Test 158 | public void test07FindMinimum() { 159 | System.out.format("%nOutput from test problem 7 (Equation (14.4.2) in Fletcher)%n"); 160 | Calcfc calcfc = new Calcfc() { 161 | @Override 162 | public double Compute(int n, int m, double[] x, double[] con) { 163 | con[0] = 5.0 * x[0] - x[1] + x[2]; 164 | con[1] = x[2] - x[0] * x[0] - x[1] * x[1] - 4.0 * x[1]; 165 | con[2] = x[2] - 5.0 * x[0] - x[1]; 166 | return x[2]; 167 | } 168 | }; 169 | double[] x = {1.0, 1.0, 1.0 }; 170 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 3, 3, x, rhobeg, rhoend, iprint, maxfun); 171 | assertArrayEquals(null, new double[] { 0.0, -3.0, -3.0 }, x, 1.0e-5); 172 | } 173 | 174 | /** 175 | * This problem is taken from page 66 of Hock and Schittkowski's book Test 176 | * Examples for Nonlinear Programming Codes. It is their test problem Number 177 | * 43, and has the name Rosen-Suzuki. 178 | */ 179 | @Test 180 | public void test08FindMinimum() { 181 | System.out.format("%nOutput from test problem 8 (Rosen-Suzuki)%n"); 182 | Calcfc calcfc = new Calcfc() { 183 | @Override 184 | public double Compute(int n, int m, double[] x, double[] con) { 185 | 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]; 186 | 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]; 187 | 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]; 188 | return x[0] * x[0] + x[1] * x[1] + 2.0 * x[2] * x[2] + x[3] * x[3] - 5.0 * x[0] - 189 | 5.0 * x[1] - 21.0 * x[2] + 7.0 * x[3]; 190 | } 191 | }; 192 | double[] x = {1.0, 1.0, 1.0, 1.0 }; 193 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 4, 3, x, rhobeg, rhoend, iprint, maxfun); 194 | assertArrayEquals(null, new double[] { 0.0, 1.0, 2.0, -1.0 }, x, 1.0e-5); 195 | } 196 | 197 | /** 198 | * This problem is taken from page 111 of Hock and Schittkowski's 199 | * book Test Examples for Nonlinear Programming Codes. It is their 200 | * test problem Number 100. 201 | */ 202 | @Test 203 | public void test09FindMinimum() { 204 | System.out.format("%nOutput from test problem 9 (Hock and Schittkowski 100)%n"); 205 | Calcfc calcfc = new Calcfc() { 206 | @Override 207 | public double Compute(int n, int m, double[] x, double[] con) { 208 | 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]; 209 | con[1] = 282.0 - 7.0 * x[0] - 3.0 * x[1] - 10.0 * x[2] * x[2] - x[3] + x[4]; 210 | con[2] = 196.0 - 23.0 * x[0] - x[1] * x[1] - 6.0 * x[5] * x[5] + 8.0 * x[6]; 211 | 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]; 212 | 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) + 213 | 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) - 214 | 4.0 * x[5] * x[6] - 10.0 * x[5] - 8.0 * x[6]; 215 | } 216 | }; 217 | double[] x = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; 218 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 7, 4, x, rhobeg, rhoend, iprint, maxfun); 219 | assertArrayEquals(null, 220 | new double[] { 2.330499, 1.951372, -0.4775414, 4.365726, -0.624487, 1.038131, 1.594227 }, x, 1.0e-5); 221 | } 222 | 223 | /** 224 | * This problem is taken from page 415 of Luenberger's book Applied 225 | * Nonlinear Programming. It is to maximize the area of a hexagon of 226 | * unit diameter. 227 | */ 228 | @Test 229 | public void test10FindMinimum() { 230 | System.out.format("%nOutput from test problem 10 (Hexagon area)%n"); 231 | Calcfc calcfc = new Calcfc() { 232 | @Override 233 | public double Compute(int n, int m, double[] x, double[] con) { 234 | con[0] = 1.0 - x[2] * x[2] - x[3] * x[3]; 235 | con[1] = 1.0 - x[8] * x[8]; 236 | con[2] = 1.0 - x[4] * x[4] - x[5] * x[5]; 237 | con[3] = 1.0 - x[0] * x[0] - Math.pow(x[1] - x[8], 2.0); 238 | con[4] = 1.0 - Math.pow(x[0] - x[4], 2.0) - Math.pow(x[1] - x[5], 2.0); 239 | con[5] = 1.0 - Math.pow(x[0] - x[6], 2.0) - Math.pow(x[1] - x[7], 2.0); 240 | con[6] = 1.0 - Math.pow(x[2] - x[4], 2.0) - Math.pow(x[3] - x[5], 2.0); 241 | con[7] = 1.0 - Math.pow(x[2] - x[6], 2.0) - Math.pow(x[3] - x[7], 2.0); 242 | con[8] = 1.0 - x[6] * x[6] - Math.pow(x[7] - x[8], 2.0); 243 | con[9] = x[0] * x[3] - x[1] * x[2]; 244 | con[10] = x[2] * x[8]; 245 | con[11] = -x[4] * x[8]; 246 | con[12] = x[4] * x[7] - x[5] * x[6]; 247 | con[13] = x[8]; 248 | 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]); 249 | } 250 | }; 251 | double[] x = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0 }; 252 | CobylaExitStatus result = Cobyla.FindMinimum(calcfc, 9, 14, x, rhobeg, rhoend, iprint, maxfun); 253 | assertArrayEquals(null, 254 | new double[] { x[0], x[1], x[2], x[3], x[0], x[1], x[2], x[3], 0.0 }, x, 1.0e-4); 255 | } 256 | } 257 | -------------------------------------------------------------------------------- /nbproject/build-impl.xml: -------------------------------------------------------------------------------- 1 | 2 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | Must set src.dir 210 | Must set test.src.dir 211 | Must set build.dir 212 | Must set dist.dir 213 | Must set build.classes.dir 214 | Must set dist.javadoc.dir 215 | Must set build.test.classes.dir 216 | Must set build.test.results.dir 217 | Must set build.classes.excludes 218 | Must set dist.jar 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | Must set javac.includes 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | Must set JVM to use for profiling in profiler.info.jvm 407 | Must set profiler agent JVM arguments in profiler.info.jvmargs.agent 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | Must select some files in the IDE or set javac.includes 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | To run this application from the command line without Ant, try: 661 | 662 | 663 | 664 | 665 | 666 | 667 | java -cp "${run.classpath.with.dist.jar}" ${main.class} 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | To run this application from the command line without Ant, try: 693 | 694 | java -jar "${dist.jar.resolved}" 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | Must select one file in the IDE or set run.class 724 | 725 | 726 | 727 | Must select one file in the IDE or set run.class 728 | 729 | 730 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | Must select one file in the IDE or set debug.class 755 | 756 | 757 | 758 | 759 | Must select one file in the IDE or set debug.class 760 | 761 | 762 | 763 | 764 | Must set fix.includes 765 | 766 | 767 | 768 | 769 | 770 | 771 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | Must select one file in the IDE or set profile.class 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | 837 | 842 | 843 | 844 | 845 | 846 | 847 | 848 | 849 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 863 | 864 | 865 | 866 | 867 | 868 | 869 | 870 | 871 | 872 | 873 | 874 | 875 | 876 | 877 | 878 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 904 | 905 | 906 | 907 | 908 | 909 | Must select some files in the IDE or set javac.includes 910 | 911 | 912 | 913 | 914 | 915 | 916 | 917 | 918 | 919 | 920 | 921 | 926 | 927 | 928 | 929 | 930 | 931 | 932 | 933 | Some tests failed; see details above. 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | Must select some files in the IDE or set test.includes 943 | 944 | 945 | 946 | Some tests failed; see details above. 947 | 948 | 949 | 954 | 955 | Must select one file in the IDE or set test.class 956 | 957 | 958 | 959 | 960 | 961 | 962 | 963 | 964 | 965 | 966 | 967 | 968 | 969 | 970 | 971 | 972 | 973 | 974 | 975 | 976 | 977 | 978 | 979 | 980 | 985 | 986 | Must select one file in the IDE or set applet.url 987 | 988 | 989 | 990 | 991 | 992 | 993 | 998 | 999 | Must select one file in the IDE or set applet.url 1000 | 1001 | 1002 | 1003 | 1004 | 1005 | 1006 | 1007 | 1012 | 1013 | 1014 | 1015 | 1016 | 1017 | 1018 | 1019 | 1020 | 1021 | 1022 | 1023 | 1024 | 1025 | 1026 | 1027 | 1028 | 1029 | 1030 | 1031 | 1032 | 1033 | 1034 | 1035 | 1036 | 1037 | 1038 | 1039 | 1040 | 1041 | 1042 | 1043 | 1044 | 1045 | 1046 | 1047 | 1048 | 1049 | 1050 | 1051 | 1052 | 1053 | 1054 | -------------------------------------------------------------------------------- /src/com/cureos/numerics/Cobyla.java: -------------------------------------------------------------------------------- 1 | /* 2 | * jcobyla 3 | * 4 | * The MIT License 5 | * 6 | * Copyright (c) 2012 Anders Gustafsson, Cureos AB. 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files 9 | * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, 10 | * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, 11 | * subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE 17 | * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 18 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | * 20 | * Remarks: 21 | * 22 | * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk) 23 | * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998 24 | */ 25 | package com.cureos.numerics; 26 | 27 | /** 28 | * Constrained Optimization BY Linear Approximation in Java. 29 | * 30 | * COBYLA2 is an implementation of Powell’s nonlinear derivative–free constrained optimization that uses 31 | * a linear approximation approach. The algorithm is a sequential trust–region algorithm that employs linear 32 | * approximations to the objective and constraint functions, where the approximations are formed by linear 33 | * interpolation at n + 1 points in the space of the variables and tries to maintain a regular–shaped simplex 34 | * over iterations. 35 | * 36 | * It solves nonsmooth NLP with a moderate number of variables (about 100). Inequality constraints only. 37 | * 38 | * The initial point X is taken as one vertex of the initial simplex with zero being another, so, X should 39 | * not be entered as the zero vector. 40 | * 41 | * @author Anders Gustafsson, Cureos AB. 42 | */ 43 | public class Cobyla 44 | { 45 | /** 46 | * Minimizes the objective function F with respect to a set of inequality constraints CON, 47 | * and returns the optimal variable array. F and CON may be non-linear, and should preferably be smooth. 48 | * 49 | * @param calcfc Interface implementation for calculating objective function and constraints. 50 | * @param n Number of variables. 51 | * @param m Number of constraints. 52 | * @param x On input initial values of the variables (zero-based array). On output 53 | * optimal values of the variables obtained in the COBYLA minimization. 54 | * @param rhobeg Initial size of the simplex. 55 | * @param rhoend Final value of the simplex. 56 | * @param iprint Print level, 0 <= iprint <= 3, where 0 provides no output and 57 | * 3 provides full output to the console. 58 | * @param maxfun Maximum number of function evaluations before terminating. 59 | * @return Exit status of the COBYLA2 optimization. 60 | */ 61 | public static CobylaExitStatus FindMinimum(final Calcfc calcfc, int n, int m, double[] x, double rhobeg, double rhoend, int iprint, int maxfun) 62 | { 63 | // This subroutine minimizes an objective function F(X) subject to M 64 | // inequality constraints on X, where X is a vector of variables that has 65 | // N components. The algorithm employs linear approximations to the 66 | // objective and constraint functions, the approximations being formed by 67 | // linear interpolation at N+1 points in the space of the variables. 68 | // We regard these interpolation points as vertices of a simplex. The 69 | // parameter RHO controls the size of the simplex and it is reduced 70 | // automatically from RHOBEG to RHOEND. For each RHO the subroutine tries 71 | // to achieve a good vector of variables for the current size, and then 72 | // RHO is reduced until the value RHOEND is reached. Therefore RHOBEG and 73 | // RHOEND should be set to reasonable initial changes to and the required 74 | // accuracy in the variables respectively, but this accuracy should be 75 | // viewed as a subject for experimentation because it is not guaranteed. 76 | // The subroutine has an advantage over many of its competitors, however, 77 | // which is that it treats each constraint individually when calculating 78 | // a change to the variables, instead of lumping the constraints together 79 | // into a single penalty function. The name of the subroutine is derived 80 | // from the phrase Constrained Optimization BY Linear Approximations. 81 | 82 | // The user must set the values of N, M, RHOBEG and RHOEND, and must 83 | // provide an initial vector of variables in X. Further, the value of 84 | // IPRINT should be set to 0, 1, 2 or 3, which controls the amount of 85 | // printing during the calculation. Specifically, there is no output if 86 | // IPRINT=0 and there is output only at the end of the calculation if 87 | // IPRINT=1. Otherwise each new value of RHO and SIGMA is printed. 88 | // Further, the vector of variables and some function information are 89 | // given either when RHO is reduced or when each new value of F(X) is 90 | // computed in the cases IPRINT=2 or IPRINT=3 respectively. Here SIGMA 91 | // is a penalty parameter, it being assumed that a change to X is an 92 | // improvement if it reduces the merit function 93 | // F(X)+SIGMA*MAX(0.0, - C1(X), - C2(X),..., - CM(X)), 94 | // where C1,C2,...,CM denote the constraint functions that should become 95 | // nonnegative eventually, at least to the precision of RHOEND. In the 96 | // printed output the displayed term that is multiplied by SIGMA is 97 | // called MAXCV, which stands for 'MAXimum Constraint Violation'. The 98 | // argument ITERS is an integer variable that must be set by the user to a 99 | // limit on the number of calls of CALCFC, the purpose of this routine being 100 | // given below. The value of ITERS will be altered to the number of calls 101 | // of CALCFC that are made. 102 | 103 | // In order to define the objective and constraint functions, we require 104 | // a subroutine that has the name and arguments 105 | // SUBROUTINE CALCFC (N,M,X,F,CON) 106 | // DIMENSION X(:),CON(:) . 107 | // The values of N and M are fixed and have been defined already, while 108 | // X is now the current vector of variables. The subroutine should return 109 | // the objective and constraint functions at X in F and CON(1),CON(2), 110 | // ...,CON(M). Note that we are trying to adjust X so that F(X) is as 111 | // small as possible subject to the constraint functions being nonnegative. 112 | 113 | // Local variables 114 | int mpp = m + 2; 115 | 116 | // Internal base-1 X array 117 | double[] iox = new double[n + 1]; 118 | System.arraycopy(x, 0, iox, 1, n); 119 | 120 | // Internal representation of the objective and constraints calculation method, 121 | // accounting for that X and CON arrays in the cobylb method are base-1 arrays. 122 | Calcfc fcalcfc = new Calcfc() 123 | { 124 | /** 125 | * 126 | * @param n the value of n 127 | * @param m the value of m 128 | * @param x the value of x 129 | * @param con the value of con 130 | * @return the double 131 | */ 132 | @Override 133 | public double Compute(int n, int m, double[] x, double[] con) 134 | { 135 | double[] ix = new double[n]; 136 | System.arraycopy(x, 1, ix, 0, n); 137 | double[] ocon = new double[m]; 138 | double f = calcfc.Compute(n, m, ix, ocon); 139 | System.arraycopy(ocon, 0, con, 1, m); 140 | return f; 141 | } 142 | }; 143 | 144 | CobylaExitStatus status = cobylb(fcalcfc, n, m, mpp, iox, rhobeg, rhoend, iprint, maxfun); 145 | System.arraycopy(iox, 1, x, 0, n); 146 | 147 | return status; 148 | } 149 | 150 | private static CobylaExitStatus cobylb(Calcfc calcfc, int n, int m, int mpp, double[] x, 151 | double rhobeg, double rhoend, int iprint, int maxfun) 152 | { 153 | // N.B. Arguments CON, SIM, SIMI, DATMAT, A, VSIG, VETA, SIGBAR, DX, W & IACT 154 | // have been removed. 155 | 156 | // Set the initial values of some parameters. The last column of SIM holds 157 | // the optimal vertex of the current simplex, and the preceding N columns 158 | // hold the displacements from the optimal vertex to the other vertices. 159 | // Further, SIMI holds the inverse of the matrix that is contained in the 160 | // first N columns of SIM. 161 | 162 | // Local variables 163 | 164 | CobylaExitStatus status; 165 | 166 | double alpha = 0.25; 167 | double beta = 2.1; 168 | double gamma = 0.5; 169 | double delta = 1.1; 170 | 171 | double f = 0.0; 172 | double resmax = 0.0; 173 | double total; 174 | 175 | int np = n + 1; 176 | int mp = m + 1; 177 | double rho = rhobeg; 178 | double parmu = 0.0; 179 | 180 | boolean iflag = false; 181 | boolean ifull = false; 182 | double parsig = 0.0; 183 | double prerec = 0.0; 184 | double prerem = 0.0; 185 | 186 | double[] con = new double[1 + mpp]; 187 | double[][] sim = new double[1 + n][1 + np]; 188 | double[][] simi = new double[1 + n][1 + n]; 189 | double[][] datmat = new double[1 + mpp][1 + np]; 190 | double[][] a = new double[1 + n][1 + mp]; 191 | double[] vsig = new double[1 + n]; 192 | double[] veta = new double[1 + n]; 193 | double[] sigbar = new double[1 + n]; 194 | double[] dx = new double[1 + n]; 195 | double[] w = new double[1 + n]; 196 | 197 | if (iprint >= 2) System.out.format("%nThe initial value of RHO is %13.6f and PARMU is set to zero.%n", rho); 198 | 199 | int nfvals = 0; 200 | double temp = 1.0 / rho; 201 | 202 | for (int i = 1; i <= n; ++i) 203 | { 204 | sim[i][np] = x[i]; 205 | sim[i][i] = rho; 206 | simi[i][i] = temp; 207 | } 208 | 209 | int jdrop = np; 210 | boolean ibrnch = false; 211 | 212 | // Make the next call of the user-supplied subroutine CALCFC. These 213 | // instructions are also used for calling CALCFC during the iterations of 214 | // the algorithm. 215 | 216 | L_40: 217 | do 218 | { 219 | if (nfvals >= maxfun && nfvals > 0) 220 | { 221 | status = CobylaExitStatus.MaxIterationsReached; 222 | break L_40; 223 | } 224 | 225 | ++nfvals; 226 | 227 | f = calcfc.Compute(n, m, x, con); 228 | resmax = 0.0; for (int k = 1; k <= m; ++k) resmax = Math.max(resmax, -con[k]); 229 | 230 | if (nfvals == iprint - 1 || iprint == 3) 231 | { 232 | PrintIterationResult(nfvals, f, resmax, x, n); 233 | } 234 | 235 | con[mp] = f; 236 | con[mpp] = resmax; 237 | 238 | // Set the recently calculated function values in a column of DATMAT. This 239 | // array has a column for each vertex of the current simplex, the entries of 240 | // each column being the values of the constraint functions (if any) 241 | // followed by the objective function and the greatest constraint violation 242 | // at the vertex. 243 | 244 | boolean skipVertexIdent = true; 245 | if (!ibrnch) 246 | { 247 | skipVertexIdent = false; 248 | 249 | for (int i = 1; i <= mpp; ++i) datmat[i][jdrop] = con[i]; 250 | 251 | if (nfvals <= np) 252 | { 253 | // Exchange the new vertex of the initial simplex with the optimal vertex if 254 | // necessary. Then, if the initial simplex is not complete, pick its next 255 | // vertex and calculate the function values there. 256 | 257 | if (jdrop <= n) 258 | { 259 | if (datmat[mp][np] <= f) 260 | { 261 | x[jdrop] = sim[jdrop][np]; 262 | } 263 | else 264 | { 265 | sim[jdrop][np] = x[jdrop]; 266 | for (int k = 1; k <= mpp; ++k) 267 | { 268 | datmat[k][jdrop] = datmat[k][np]; 269 | datmat[k][np] = con[k]; 270 | } 271 | for (int k = 1; k <= jdrop; ++k) 272 | { 273 | sim[jdrop][k] = -rho; 274 | temp = 0.0; for (int i = k; i <= jdrop; ++i) temp -= simi[i][k]; 275 | simi[jdrop][k] = temp; 276 | } 277 | } 278 | } 279 | if (nfvals <= n) 280 | { 281 | jdrop = nfvals; 282 | x[jdrop] += rho; 283 | continue L_40; 284 | } 285 | } 286 | 287 | ibrnch = true; 288 | } 289 | 290 | L_140: 291 | do 292 | { 293 | L_550: 294 | do 295 | { 296 | if (!skipVertexIdent) 297 | { 298 | // Identify the optimal vertex of the current simplex. 299 | 300 | double phimin = datmat[mp][np] + parmu * datmat[mpp][np]; 301 | int nbest = np; 302 | 303 | for (int j = 1; j <= n; ++j) 304 | { 305 | temp = datmat[mp][j] + parmu * datmat[mpp][j]; 306 | if (temp < phimin) 307 | { 308 | nbest = j; 309 | phimin = temp; 310 | } 311 | else if (temp == phimin && parmu == 0.0 && datmat[mpp][j] < datmat[mpp][nbest]) 312 | { 313 | nbest = j; 314 | } 315 | } 316 | 317 | // Switch the best vertex into pole position if it is not there already, 318 | // and also update SIM, SIMI and DATMAT. 319 | 320 | if (nbest <= n) 321 | { 322 | for (int i = 1; i <= mpp; ++i) 323 | { 324 | temp = datmat[i][np]; 325 | datmat[i][np] = datmat[i][nbest]; 326 | datmat[i][nbest] = temp; 327 | } 328 | for (int i = 1; i <= n; ++i) 329 | { 330 | temp = sim[i][nbest]; 331 | sim[i][nbest] = 0.0; 332 | sim[i][np] += temp; 333 | 334 | double tempa = 0.0; 335 | for (int k = 1; k <= n; ++k) 336 | { 337 | sim[i][k] -= temp; 338 | tempa -= simi[k][i]; 339 | } 340 | simi[nbest][i] = tempa; 341 | } 342 | } 343 | 344 | // Make an error return if SIGI is a poor approximation to the inverse of 345 | // the leading N by N submatrix of SIG. 346 | 347 | double error = 0.0; 348 | for (int i = 1; i <= n; ++i) 349 | { 350 | for (int j = 1; j <= n; ++j) 351 | { 352 | temp = DOT_PRODUCT(PART(ROW(simi, i), 1, n), PART(COL(sim, j), 1, n)) - (i == j ? 1.0 : 0.0); 353 | error = Math.max(error, Math.abs(temp)); 354 | } 355 | } 356 | if (error > 0.1) 357 | { 358 | status = CobylaExitStatus.DivergingRoundingErrors; 359 | break L_40; 360 | } 361 | 362 | // Calculate the coefficients of the linear approximations to the objective 363 | // and constraint functions, placing minus the objective function gradient 364 | // after the constraint gradients in the array A. The vector W is used for 365 | // working space. 366 | 367 | for (int k = 1; k <= mp; ++k) 368 | { 369 | con[k] = -datmat[k][np]; 370 | for (int j = 1; j <= n; ++j) w[j] = datmat[k][j] + con[k]; 371 | 372 | for (int i = 1; i <= n; ++i) 373 | { 374 | a[i][k] = (k == mp ? -1.0 : 1.0) * DOT_PRODUCT(PART(w, 1, n), PART(COL(simi, i), 1, n)); 375 | } 376 | } 377 | 378 | // Calculate the values of sigma and eta, and set IFLAG = 0 if the current 379 | // simplex is not acceptable. 380 | 381 | iflag = true; 382 | parsig = alpha * rho; 383 | double pareta = beta * rho; 384 | 385 | for (int j = 1; j <= n; ++j) 386 | { 387 | double wsig = 0.0; for (int k = 1; k <= n; ++k) wsig += simi[j][k] * simi[j][k]; 388 | double weta = 0.0; for (int k = 1; k <= n; ++k) weta += sim[k][j] * sim[k][j]; 389 | vsig[j] = 1.0 / Math.sqrt(wsig); 390 | veta[j] = Math.sqrt(weta); 391 | if (vsig[j] < parsig || veta[j] > pareta) iflag = false; 392 | } 393 | 394 | // If a new vertex is needed to improve acceptability, then decide which 395 | // vertex to drop from the simplex. 396 | 397 | if (!ibrnch && !iflag) 398 | { 399 | jdrop = 0; 400 | temp = pareta; 401 | for (int j = 1; j <= n; ++j) 402 | { 403 | if (veta[j] > temp) 404 | { 405 | jdrop = j; 406 | temp = veta[j]; 407 | } 408 | } 409 | if (jdrop == 0) 410 | { 411 | for (int j = 1; j <= n; ++j) 412 | { 413 | if (vsig[j] < temp) 414 | { 415 | jdrop = j; 416 | temp = vsig[j]; 417 | } 418 | } 419 | } 420 | 421 | // Calculate the step to the new vertex and its sign. 422 | 423 | temp = gamma * rho * vsig[jdrop]; 424 | for (int k = 1; k <= n; ++k) dx[k] = temp * simi[jdrop][k]; 425 | double cvmaxp = 0.0; 426 | double cvmaxm = 0.0; 427 | 428 | total = 0.0; 429 | for (int k = 1; k <= mp; ++k) 430 | { 431 | total = DOT_PRODUCT(PART(COL(a, k), 1, n), PART(dx, 1, n)); 432 | if (k < mp) 433 | { 434 | temp = datmat[k][np]; 435 | cvmaxp = Math.max(cvmaxp, -total - temp); 436 | cvmaxm = Math.max(cvmaxm, total - temp); 437 | } 438 | } 439 | double dxsign = parmu * (cvmaxp - cvmaxm) > 2.0 * total ? -1.0 : 1.0; 440 | 441 | // Update the elements of SIM and SIMI, and set the next X. 442 | 443 | temp = 0.0; 444 | for (int i = 1; i <= n; ++i) 445 | { 446 | dx[i] = dxsign * dx[i]; 447 | sim[i][jdrop] = dx[i]; 448 | temp += simi[jdrop][i] * dx[i]; 449 | } 450 | for (int k = 1; k <= n; ++k) simi[jdrop][k] /= temp; 451 | 452 | for (int j = 1; j <= n; ++j) 453 | { 454 | if (j != jdrop) 455 | { 456 | temp = DOT_PRODUCT(PART(ROW(simi, j), 1, n), PART(dx, 1, n)); 457 | for (int k = 1; k <= n; ++k) simi[j][k] -= temp * simi[jdrop][k]; 458 | } 459 | x[j] = sim[j][np] + dx[j]; 460 | } 461 | continue L_40; 462 | } 463 | 464 | // Calculate DX = x(*)-x(0). 465 | // Branch if the length of DX is less than 0.5*RHO. 466 | 467 | ifull = trstlp(n, m, a, con, rho, dx); 468 | if (!ifull) 469 | { 470 | temp = 0.0; for (int k = 1; k <= n; ++k) temp += dx[k] * dx[k]; 471 | if (temp < 0.25 * rho * rho) 472 | { 473 | ibrnch = true; 474 | break L_550; 475 | } 476 | } 477 | 478 | // Predict the change to F and the new maximum constraint violation if the 479 | // variables are altered from x(0) to x(0) + DX. 480 | 481 | total = 0.0; 482 | double resnew = 0.0; 483 | con[mp] = 0.0; 484 | for (int k = 1; k <= mp; ++k) 485 | { 486 | total = con[k] - DOT_PRODUCT(PART(COL(a, k), 1, n), PART(dx, 1, n)); 487 | if (k < mp) resnew = Math.max(resnew, total); 488 | } 489 | 490 | // Increase PARMU if necessary and branch back if this change alters the 491 | // optimal vertex. Otherwise PREREM and PREREC will be set to the predicted 492 | // reductions in the merit function and the maximum constraint violation 493 | // respectively. 494 | 495 | prerec = datmat[mpp][np] - resnew; 496 | double barmu = prerec > 0.0 ? total / prerec : 0.0; 497 | if (parmu < 1.5 * barmu) 498 | { 499 | parmu = 2.0 * barmu; 500 | if (iprint >= 2) System.out.format("%nIncrease in PARMU to %13.6f%n", parmu); 501 | double phi = datmat[mp][np] + parmu * datmat[mpp][np]; 502 | for (int j = 1; j <= n; ++j) 503 | { 504 | temp = datmat[mp][j] + parmu * datmat[mpp][j]; 505 | if (temp < phi || (temp == phi && parmu == 0.0 && datmat[mpp][j] < datmat[mpp][np])) continue L_140; 506 | } 507 | } 508 | prerem = parmu * prerec - total; 509 | 510 | // Calculate the constraint and objective functions at x(*). 511 | // Then find the actual reduction in the merit function. 512 | 513 | for (int k = 1; k <= n; ++k) x[k] = sim[k][np] + dx[k]; 514 | ibrnch = true; 515 | continue L_40; 516 | } 517 | 518 | skipVertexIdent = false; 519 | double vmold = datmat[mp][np] + parmu * datmat[mpp][np]; 520 | double vmnew = f + parmu * resmax; 521 | double trured = vmold - vmnew; 522 | if (parmu == 0.0 && f == datmat[mp][np]) 523 | { 524 | prerem = prerec; 525 | trured = datmat[mpp][np] - resmax; 526 | } 527 | 528 | // Begin the operations that decide whether x(*) should replace one of the 529 | // vertices of the current simplex, the change being mandatory if TRURED is 530 | // positive. Firstly, JDROP is set to the index of the vertex that is to be 531 | // replaced. 532 | 533 | double ratio = trured <= 0.0 ? 1.0 : 0.0; 534 | jdrop = 0; 535 | for (int j = 1; j <= n; ++j) 536 | { 537 | temp = Math.abs(DOT_PRODUCT(PART(ROW(simi, j), 1, n), PART(dx, 1, n))); 538 | if (temp > ratio) 539 | { 540 | jdrop = j; 541 | ratio = temp; 542 | } 543 | sigbar[j] = temp * vsig[j]; 544 | } 545 | 546 | // Calculate the value of ell. 547 | 548 | double edgmax = delta * rho; 549 | int l = 0; 550 | for (int j = 1; j <= n; ++j) 551 | { 552 | if (sigbar[j] >= parsig || sigbar[j] >= vsig[j]) 553 | { 554 | temp = veta[j]; 555 | if (trured > 0.0) 556 | { 557 | temp = 0.0; for (int k = 1; k <= n; ++k) temp += Math.pow(dx[k] - sim[k][j], 2.0); 558 | temp = Math.sqrt(temp); 559 | } 560 | if (temp > edgmax) 561 | { 562 | l = j; 563 | edgmax = temp; 564 | } 565 | } 566 | } 567 | if (l > 0) jdrop = l; 568 | 569 | if (jdrop != 0) 570 | { 571 | // Revise the simplex by updating the elements of SIM, SIMI and DATMAT. 572 | 573 | temp = 0.0; 574 | for (int i = 1; i <= n; ++i) 575 | { 576 | sim[i][jdrop] = dx[i]; 577 | temp += simi[jdrop][i] * dx[i]; 578 | } 579 | for (int k = 1; k <= n; ++k) simi[jdrop][k] /= temp; 580 | for (int j = 1; j <= n; ++j) 581 | { 582 | if (j != jdrop) 583 | { 584 | temp = DOT_PRODUCT(PART(ROW(simi, j), 1, n), PART(dx, 1, n)); 585 | for (int k = 1; k <= n; ++k) simi[j][k] -= temp * simi[jdrop][k]; 586 | } 587 | } 588 | for (int k = 1; k <= mpp; ++k) datmat[k][jdrop] = con[k]; 589 | 590 | // Branch back for further iterations with the current RHO. 591 | 592 | if (trured > 0.0 && trured >= 0.1 * prerem) continue L_140; 593 | } 594 | } while (false); 595 | 596 | if (!iflag) 597 | { 598 | ibrnch = false; 599 | continue L_140; 600 | } 601 | 602 | if (rho <= rhoend) 603 | { 604 | status = CobylaExitStatus.Normal; 605 | break L_40; 606 | } 607 | 608 | // Otherwise reduce RHO if it is not at its least value and reset PARMU. 609 | 610 | double cmin = 0.0, cmax = 0.0; 611 | 612 | rho *= 0.5; 613 | if (rho <= 1.5 * rhoend) rho = rhoend; 614 | if (parmu > 0.0) 615 | { 616 | double denom = 0.0; 617 | for (int k = 1; k <= mp; ++k) 618 | { 619 | cmin = datmat[k][np]; 620 | cmax = cmin; 621 | for (int i = 1; i <= n; ++i) 622 | { 623 | cmin = Math.min(cmin, datmat[k][i]); 624 | cmax = Math.max(cmax, datmat[k][i]); 625 | } 626 | if (k <= m && cmin < 0.5 * cmax) 627 | { 628 | temp = Math.max(cmax, 0.0) - cmin; 629 | denom = denom <= 0.0 ? temp : Math.min(denom, temp); 630 | } 631 | } 632 | if (denom == 0.0) 633 | { 634 | parmu = 0.0; 635 | } 636 | else if (cmax - cmin < parmu * denom) 637 | { 638 | parmu = (cmax - cmin) / denom; 639 | } 640 | } 641 | if (iprint >= 2) 642 | System.out.format("%nReduction in RHO to %1$13.6f and PARMU = %2$13.6f%n", rho, parmu); 643 | if (iprint == 2) 644 | PrintIterationResult(nfvals, datmat[mp][np], datmat[mpp][np], COL(sim, np), n); 645 | 646 | } while (true); 647 | } while (true); 648 | 649 | switch (status) 650 | { 651 | case Normal: 652 | if (iprint >= 1) System.out.format("%nNormal return from subroutine COBYLA%n"); 653 | if (ifull) 654 | { 655 | if (iprint >= 1) PrintIterationResult(nfvals, f, resmax, x, n); 656 | return status; 657 | } 658 | break; 659 | case MaxIterationsReached: 660 | if (iprint >= 1) 661 | System.out.format("%nReturn from subroutine COBYLA because the MAXFUN limit has been reached.%n"); 662 | break; 663 | case DivergingRoundingErrors: 664 | if (iprint >= 1) 665 | System.out.format("%nReturn from subroutine COBYLA because rounding errors are becoming damaging.%n"); 666 | break; 667 | } 668 | 669 | for (int k = 1; k <= n; ++k) x[k] = sim[k][np]; 670 | f = datmat[mp][np]; 671 | resmax = datmat[mpp][np]; 672 | if (iprint >= 1) PrintIterationResult(nfvals, f, resmax, x, n); 673 | 674 | return status; 675 | } 676 | 677 | private static boolean trstlp(int n, int m, double[][] a, double[] b, double rho, double[] dx) 678 | { 679 | // N.B. Arguments Z, ZDOTA, VMULTC, SDIRN, DXNEW, VMULTD & IACT have been removed. 680 | 681 | // This subroutine calculates an N-component vector DX by applying the 682 | // following two stages. In the first stage, DX is set to the shortest 683 | // vector that minimizes the greatest violation of the constraints 684 | // A(1,K)*DX(1)+A(2,K)*DX(2)+...+A(N,K)*DX(N) .GE. B(K), K = 2,3,...,M, 685 | // subject to the Euclidean length of DX being at most RHO. If its length is 686 | // strictly less than RHO, then we use the resultant freedom in DX to 687 | // minimize the objective function 688 | // -A(1,M+1)*DX(1) - A(2,M+1)*DX(2) - ... - A(N,M+1)*DX(N) 689 | // subject to no increase in any greatest constraint violation. This 690 | // notation allows the gradient of the objective function to be regarded as 691 | // the gradient of a constraint. Therefore the two stages are distinguished 692 | // by MCON .EQ. M and MCON .GT. M respectively. It is possible that a 693 | // degeneracy may prevent DX from attaining the target length RHO. Then the 694 | // value IFULL = 0 would be set, but usually IFULL = 1 on return. 695 | 696 | // In general NACT is the number of constraints in the active set and 697 | // IACT(1),...,IACT(NACT) are their indices, while the remainder of IACT 698 | // contains a permutation of the remaining constraint indices. Further, Z 699 | // is an orthogonal matrix whose first NACT columns can be regarded as the 700 | // result of Gram-Schmidt applied to the active constraint gradients. For 701 | // J = 1,2,...,NACT, the number ZDOTA(J) is the scalar product of the J-th 702 | // column of Z with the gradient of the J-th active constraint. DX is the 703 | // current vector of variables and here the residuals of the active 704 | // constraints should be zero. Further, the active constraints have 705 | // nonnegative Lagrange multipliers that are held at the beginning of 706 | // VMULTC. The remainder of this vector holds the residuals of the inactive 707 | // constraints at DX, the ordering of the components of VMULTC being in 708 | // agreement with the permutation of the indices of the constraints that is 709 | // in IACT. All these residuals are nonnegative, which is achieved by the 710 | // shift RESMAX that makes the least residual zero. 711 | 712 | // Initialize Z and some other variables. The value of RESMAX will be 713 | // appropriate to DX = 0, while ICON will be the index of a most violated 714 | // constraint if RESMAX is positive. Usually during the first stage the 715 | // vector SDIRN gives a search direction that reduces all the active 716 | // constraint violations by one simultaneously. 717 | 718 | // Local variables 719 | 720 | double temp; 721 | 722 | int nactx = 0; 723 | double resold = 0.0; 724 | 725 | double[][] z = new double[1 + n][1 + n]; 726 | double[] zdota = new double[2 + m]; 727 | double[] vmultc = new double[2 + m]; 728 | double[] sdirn = new double[1 + n]; 729 | double[] dxnew = new double[1 + n]; 730 | double[] vmultd = new double[2 + m]; 731 | int[] iact = new int[2 + m]; 732 | 733 | int mcon = m; 734 | int nact = 0; 735 | for (int i = 1; i <= n; ++i) 736 | { 737 | z[i][i] = 1.0; 738 | dx[i] = 0.0; 739 | } 740 | 741 | int icon = 0; 742 | double resmax = 0.0; 743 | if (m >= 1) 744 | { 745 | for (int k = 1; k <= m; ++k) 746 | { 747 | if (b[k] > resmax) 748 | { 749 | resmax = b[k]; 750 | icon = k; 751 | } 752 | } 753 | for (int k = 1; k <= m; ++k) 754 | { 755 | iact[k] = k; 756 | vmultc[k] = resmax - b[k]; 757 | } 758 | } 759 | 760 | // End the current stage of the calculation if 3 consecutive iterations 761 | // have either failed to reduce the best calculated value of the objective 762 | // function or to increase the number of active constraints since the best 763 | // value was calculated. This strategy prevents cycling, but there is a 764 | // remote possibility that it will cause premature termination. 765 | 766 | boolean first = true; 767 | do 768 | { 769 | L_60: 770 | do 771 | { 772 | if (!first || (first && resmax == 0.0)) 773 | { 774 | mcon = m + 1; 775 | icon = mcon; 776 | iact[mcon] = mcon; 777 | vmultc[mcon] = 0.0; 778 | } 779 | first = false; 780 | 781 | double optold = 0.0; 782 | int icount = 0; 783 | 784 | double step, stpful; 785 | 786 | L_70: 787 | do 788 | { 789 | double optnew = mcon == m ? resmax : -DOT_PRODUCT(PART(dx, 1, n), PART(COL(a, mcon), 1, n)); 790 | 791 | if (icount == 0 || optnew < optold) 792 | { 793 | optold = optnew; 794 | nactx = nact; 795 | icount = 3; 796 | } 797 | else if (nact > nactx) 798 | { 799 | nactx = nact; 800 | icount = 3; 801 | } 802 | else 803 | { 804 | --icount; 805 | } 806 | if (icount == 0) break L_60; 807 | 808 | // If ICON exceeds NACT, then we add the constraint with index IACT(ICON) to 809 | // the active set. Apply Givens rotations so that the last N-NACT-1 columns 810 | // of Z are orthogonal to the gradient of the new constraint, a scalar 811 | // product being set to zero if its nonzero value could be due to computer 812 | // rounding errors. The array DXNEW is used for working space. 813 | 814 | double ratio; 815 | if (icon <= nact) 816 | { 817 | if (icon < nact) 818 | { 819 | // Delete the constraint that has the index IACT(ICON) from the active set. 820 | 821 | int isave = iact[icon]; 822 | double vsave = vmultc[icon]; 823 | int k = icon; 824 | do 825 | { 826 | int kp = k + 1; 827 | int kk = iact[kp]; 828 | double sp = DOT_PRODUCT(PART(COL(z, k), 1, n), PART(COL(a, kk), 1, n)); 829 | temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]); 830 | double alpha = zdota[kp] / temp; 831 | double beta = sp / temp; 832 | zdota[kp] = alpha * zdota[k]; 833 | zdota[k] = temp; 834 | for (int i = 1; i <= n; ++i) 835 | { 836 | temp = alpha * z[i][kp] + beta * z[i][k]; 837 | z[i][kp] = alpha * z[i][k] - beta * z[i][kp]; 838 | z[i][k] = temp; 839 | } 840 | iact[k] = kk; 841 | vmultc[k] = vmultc[kp]; 842 | k = kp; 843 | } while (k < nact); 844 | 845 | iact[k] = isave; 846 | vmultc[k] = vsave; 847 | } 848 | --nact; 849 | 850 | // If stage one is in progress, then set SDIRN to the direction of the next 851 | // change to the current vector of variables. 852 | 853 | if (mcon > m) 854 | { 855 | // Pick the next search direction of stage two. 856 | 857 | temp = 1.0 / zdota[nact]; 858 | for (int k = 1; k <= n; ++k) sdirn[k] = temp * z[k][nact]; 859 | } 860 | else 861 | { 862 | temp = DOT_PRODUCT(PART(sdirn, 1, n), PART(COL(z, nact + 1), 1, n)); 863 | for (int k = 1; k <= n; ++k) sdirn[k] -= temp * z[k][nact + 1]; 864 | } 865 | } 866 | else 867 | { 868 | int kk = iact[icon]; 869 | for (int k = 1; k <= n; ++k) dxnew[k] = a[k][kk]; 870 | double tot = 0.0; 871 | 872 | { 873 | int k = n; 874 | while (k > nact) 875 | { 876 | double sp = 0.0; 877 | double spabs = 0.0; 878 | for (int i = 1; i <= n; ++i) 879 | { 880 | temp = z[i][k] * dxnew[i]; 881 | sp += temp; 882 | spabs += Math.abs(temp); 883 | } 884 | double acca = spabs + 0.1 * Math.abs(sp); 885 | double accb = spabs + 0.2 * Math.abs(sp); 886 | if (spabs >= acca || acca >= accb) sp = 0.0; 887 | if (tot == 0.0) 888 | { 889 | tot = sp; 890 | } 891 | else 892 | { 893 | int kp = k + 1; 894 | temp = Math.sqrt(sp * sp + tot * tot); 895 | double alpha = sp / temp; 896 | double beta = tot / temp; 897 | tot = temp; 898 | for (int i = 1; i <= n; ++i) 899 | { 900 | temp = alpha * z[i][k] + beta * z[i][kp]; 901 | z[i][kp] = alpha * z[i][kp] - beta * z[i][k]; 902 | z[i][k] = temp; 903 | } 904 | } 905 | --k; 906 | } 907 | } 908 | 909 | if (tot == 0.0) 910 | { 911 | // The next instruction is reached if a deletion has to be made from the 912 | // active set in order to make room for the new active constraint, because 913 | // the new constraint gradient is a linear combination of the gradients of 914 | // the old active constraints. Set the elements of VMULTD to the multipliers 915 | // of the linear combination. Further, set IOUT to the index of the 916 | // constraint to be deleted, but branch if no suitable index can be found. 917 | 918 | ratio = -1.0; 919 | { 920 | int k = nact; 921 | do 922 | { 923 | double zdotv = 0.0; 924 | double zdvabs = 0.0; 925 | 926 | for (int i = 1; i <= n; ++i) 927 | { 928 | temp = z[i][k] * dxnew[i]; 929 | zdotv += temp; 930 | zdvabs += Math.abs(temp); 931 | } 932 | double acca = zdvabs + 0.1 * Math.abs(zdotv); 933 | double accb = zdvabs + 0.2 * Math.abs(zdotv); 934 | if (zdvabs < acca && acca < accb) 935 | { 936 | temp = zdotv / zdota[k]; 937 | if (temp > 0.0 && iact[k] <= m) 938 | { 939 | double tempa = vmultc[k] / temp; 940 | if (ratio < 0.0 || tempa < ratio) ratio = tempa; 941 | } 942 | 943 | if (k >= 2) 944 | { 945 | int kw = iact[k]; 946 | for (int i = 1; i <= n; ++i) dxnew[i] -= temp * a[i][kw]; 947 | } 948 | vmultd[k] = temp; 949 | } 950 | else 951 | { 952 | vmultd[k] = 0.0; 953 | } 954 | } while (--k > 0); 955 | } 956 | if (ratio < 0.0) break L_60; 957 | 958 | // Revise the Lagrange multipliers and reorder the active constraints so 959 | // that the one to be replaced is at the end of the list. Also calculate the 960 | // new value of ZDOTA(NACT) and branch if it is not acceptable. 961 | 962 | for (int k = 1; k <= nact; ++k) 963 | vmultc[k] = Math.max(0.0, vmultc[k] - ratio * vmultd[k]); 964 | if (icon < nact) 965 | { 966 | int isave = iact[icon]; 967 | double vsave = vmultc[icon]; 968 | int k = icon; 969 | do 970 | { 971 | int kp = k + 1; 972 | int kw = iact[kp]; 973 | double sp = DOT_PRODUCT(PART(COL(z, k), 1, n), PART(COL(a, kw), 1, n)); 974 | temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]); 975 | double alpha = zdota[kp] / temp; 976 | double beta = sp / temp; 977 | zdota[kp] = alpha * zdota[k]; 978 | zdota[k] = temp; 979 | for (int i = 1; i <= n; ++i) 980 | { 981 | temp = alpha * z[i][kp] + beta * z[i][k]; 982 | z[i][kp] = alpha * z[i][k] - beta * z[i][kp]; 983 | z[i][k] = temp; 984 | } 985 | iact[k] = kw; 986 | vmultc[k] = vmultc[kp]; 987 | k = kp; 988 | } while (k < nact); 989 | iact[k] = isave; 990 | vmultc[k] = vsave; 991 | } 992 | temp = DOT_PRODUCT(PART(COL(z, nact), 1, n), PART(COL(a, kk), 1, n)); 993 | if (temp == 0.0) break L_60; 994 | zdota[nact] = temp; 995 | vmultc[icon] = 0.0; 996 | vmultc[nact] = ratio; 997 | } 998 | else 999 | { 1000 | // Add the new constraint if this can be done without a deletion from the 1001 | // active set. 1002 | 1003 | ++nact; 1004 | zdota[nact] = tot; 1005 | vmultc[icon] = vmultc[nact]; 1006 | vmultc[nact] = 0.0; 1007 | } 1008 | 1009 | // Update IACT and ensure that the objective function continues to be 1010 | // treated as the last active constraint when MCON>M. 1011 | 1012 | iact[icon] = iact[nact]; 1013 | iact[nact] = kk; 1014 | if (mcon > m && kk != mcon) 1015 | { 1016 | int k = nact - 1; 1017 | double sp = DOT_PRODUCT(PART(COL(z, k), 1, n), PART(COL(a, kk), 1, n)); 1018 | temp = Math.sqrt(sp * sp + zdota[nact] * zdota[nact]); 1019 | double alpha = zdota[nact] / temp; 1020 | double beta = sp / temp; 1021 | zdota[nact] = alpha * zdota[k]; 1022 | zdota[k] = temp; 1023 | for (int i = 1; i <= n; ++i) 1024 | { 1025 | temp = alpha * z[i][nact] + beta * z[i][k]; 1026 | z[i][nact] = alpha * z[i][k] - beta * z[i][nact]; 1027 | z[i][k] = temp; 1028 | } 1029 | iact[nact] = iact[k]; 1030 | iact[k] = kk; 1031 | temp = vmultc[k]; 1032 | vmultc[k] = vmultc[nact]; 1033 | vmultc[nact] = temp; 1034 | } 1035 | 1036 | // If stage one is in progress, then set SDIRN to the direction of the next 1037 | // change to the current vector of variables. 1038 | 1039 | if (mcon > m) 1040 | { 1041 | // Pick the next search direction of stage two. 1042 | 1043 | temp = 1.0 / zdota[nact]; 1044 | for (int k = 1; k <= n; ++k) sdirn[k] = temp * z[k][nact]; 1045 | } 1046 | else 1047 | { 1048 | kk = iact[nact]; 1049 | temp = (DOT_PRODUCT(PART(sdirn, 1, n), PART(COL(a, kk), 1, n)) - 1.0) / zdota[nact]; 1050 | for (int k = 1; k <= n; ++k) sdirn[k] -= temp * z[k][nact]; 1051 | } 1052 | } 1053 | 1054 | // Calculate the step to the boundary of the trust region or take the step 1055 | // that reduces RESMAX to zero. The two statements below that include the 1056 | // factor 1.0E-6 prevent some harmless underflows that occurred in a test 1057 | // calculation. Further, we skip the step if it could be zero within a 1058 | // reasonable tolerance for computer rounding errors. 1059 | 1060 | double dd = rho * rho; 1061 | double sd = 0.0; 1062 | double ss = 0.0; 1063 | for (int i = 1; i <= n; ++i) 1064 | { 1065 | if (Math.abs(dx[i]) >= 1.0E-6 * rho) dd -= dx[i] * dx[i]; 1066 | sd += dx[i] * sdirn[i]; 1067 | ss += sdirn[i] * sdirn[i]; 1068 | } 1069 | if (dd <= 0.0) break L_60; 1070 | temp = Math.sqrt(ss * dd); 1071 | if (Math.abs(sd) >= 1.0E-6 * temp) temp = Math.sqrt(ss * dd + sd * sd); 1072 | stpful = dd / (temp + sd); 1073 | step = stpful; 1074 | if (mcon == m) 1075 | { 1076 | double acca = step + 0.1 * resmax; 1077 | double accb = step + 0.2 * resmax; 1078 | if (step >= acca || acca >= accb) break L_70; 1079 | step = Math.min(step, resmax); 1080 | } 1081 | 1082 | // Set DXNEW to the new variables if STEP is the steplength, and reduce 1083 | // RESMAX to the corresponding maximum residual if stage one is being done. 1084 | // Because DXNEW will be changed during the calculation of some Lagrange 1085 | // multipliers, it will be restored to the following value later. 1086 | 1087 | for (int k = 1; k <= n; ++k) dxnew[k] = dx[k] + step * sdirn[k]; 1088 | if (mcon == m) 1089 | { 1090 | resold = resmax; 1091 | resmax = 0.0; 1092 | for (int k = 1; k <= nact; ++k) 1093 | { 1094 | int kk = iact[k]; 1095 | temp = b[kk] - DOT_PRODUCT(PART(COL(a, kk), 1, n), PART(dxnew, 1, n)); 1096 | resmax = Math.max(resmax, temp); 1097 | } 1098 | } 1099 | 1100 | // Set VMULTD to the VMULTC vector that would occur if DX became DXNEW. A 1101 | // device is included to force VMULTD(K) = 0.0 if deviations from this value 1102 | // can be attributed to computer rounding errors. First calculate the new 1103 | // Lagrange multipliers. 1104 | 1105 | { 1106 | int k = nact; 1107 | do 1108 | { 1109 | double zdotw = 0.0; 1110 | double zdwabs = 0.0; 1111 | for (int i = 1; i <= n; ++i) 1112 | { 1113 | temp = z[i][k] * dxnew[i]; 1114 | zdotw += temp; 1115 | zdwabs += Math.abs(temp); 1116 | } 1117 | double acca = zdwabs + 0.1 * Math.abs(zdotw); 1118 | double accb = zdwabs + 0.2 * Math.abs(zdotw); 1119 | if (zdwabs >= acca || acca >= accb) zdotw = 0.0; 1120 | vmultd[k] = zdotw / zdota[k]; 1121 | if (k >= 2) 1122 | { 1123 | int kk = iact[k]; 1124 | for (int i = 1; i <= n; ++i) dxnew[i] -= vmultd[k] * a[i][kk]; 1125 | } 1126 | } while (k-- >= 2); 1127 | if (mcon > m) vmultd[nact] = Math.max(0.0, vmultd[nact]); 1128 | } 1129 | 1130 | // Complete VMULTC by finding the new constraint residuals. 1131 | 1132 | for (int k = 1; k <= n; ++k) dxnew[k] = dx[k] + step * sdirn[k]; 1133 | if (mcon > nact) 1134 | { 1135 | int kl = nact + 1; 1136 | for (int k = kl; k <= mcon; ++k) 1137 | { 1138 | int kk = iact[k]; 1139 | double total = resmax - b[kk]; 1140 | double sumabs = resmax + Math.abs(b[kk]); 1141 | for (int i = 1; i <= n; ++i) 1142 | { 1143 | temp = a[i][kk] * dxnew[i]; 1144 | total += temp; 1145 | sumabs += Math.abs(temp); 1146 | } 1147 | double acca = sumabs + 0.1 * Math.abs(total); 1148 | double accb = sumabs + 0.2 * Math.abs(total); 1149 | if (sumabs >= acca || acca >= accb) total = 0.0; 1150 | vmultd[k] = total; 1151 | } 1152 | } 1153 | 1154 | // Calculate the fraction of the step from DX to DXNEW that will be taken. 1155 | 1156 | ratio = 1.0; 1157 | icon = 0; 1158 | for (int k = 1; k <= mcon; ++k) 1159 | { 1160 | if (vmultd[k] < 0.0) 1161 | { 1162 | temp = vmultc[k] / (vmultc[k] - vmultd[k]); 1163 | if (temp < ratio) 1164 | { 1165 | ratio = temp; 1166 | icon = k; 1167 | } 1168 | } 1169 | } 1170 | 1171 | // Update DX, VMULTC and RESMAX. 1172 | 1173 | temp = 1.0 - ratio; 1174 | for (int k = 1; k <= n; ++k) dx[k] = temp * dx[k] + ratio * dxnew[k]; 1175 | for (int k = 1; k <= mcon; ++k) 1176 | vmultc[k] = Math.max(0.0, temp * vmultc[k] + ratio * vmultd[k]); 1177 | if (mcon == m) resmax = resold + ratio * (resmax - resold); 1178 | 1179 | // If the full step is not acceptable then begin another iteration. 1180 | // Otherwise switch to stage two or end the calculation. 1181 | 1182 | } while (icon > 0); 1183 | 1184 | if (step == stpful) return true; 1185 | 1186 | } while (true); 1187 | 1188 | // We employ any freedom that may be available to reduce the objective 1189 | // function before returning a DX whose length is less than RHO. 1190 | 1191 | } while (mcon == m); 1192 | 1193 | return false; 1194 | } 1195 | 1196 | private static void PrintIterationResult(int nfvals, double f, double resmax, double[] x, int n) 1197 | { 1198 | System.out.format("%nNFVALS = %1$5d F = %2$13.6f MAXCV = %3$13.6e%n", nfvals, f, resmax); 1199 | System.out.format("X = %s%n", FORMAT(PART(x, 1, n))); 1200 | } 1201 | 1202 | private static double[] ROW(double[][] src, int rowidx) 1203 | { 1204 | int cols = src[0].length; 1205 | double[] dest = new double[cols]; 1206 | for (int col = 0; col < cols; ++col) dest[col] = src[rowidx][col]; 1207 | return dest; 1208 | } 1209 | 1210 | private static double[] COL(double[][] src, int colidx) 1211 | { 1212 | int rows = src.length; 1213 | double[] dest = new double[rows]; 1214 | for (int row = 0; row < rows; ++row) dest[row] = src[row][colidx]; 1215 | return dest; 1216 | } 1217 | 1218 | private static double[] PART(double[] src, int from, int to) 1219 | { 1220 | double[] dest = new double[to - from + 1]; 1221 | int destidx = 0; 1222 | for (int srcidx = from; srcidx <= to; ++srcidx, ++destidx) dest[destidx] = src[srcidx]; 1223 | return dest; 1224 | } 1225 | 1226 | private static String FORMAT(double[] x) 1227 | { 1228 | String fmt = ""; 1229 | for (int i = 0; i < x.length; ++i) fmt = fmt + String.format("%13.6f", x[i]); 1230 | return fmt; 1231 | } 1232 | 1233 | private static double DOT_PRODUCT(double[] lhs, double[] rhs) 1234 | { 1235 | double sum = 0.0; for (int i = 0; i < lhs.length; ++i) sum += lhs[i] * rhs[i]; 1236 | return sum; 1237 | } 1238 | } 1239 | --------------------------------------------------------------------------------