├── 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 |
--------------------------------------------------------------------------------