001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.math.optimization.general; 019 020 import java.io.Serializable; 021 import java.util.Arrays; 022 023 import junit.framework.Test; 024 import junit.framework.TestCase; 025 import junit.framework.TestSuite; 026 027 import org.apache.commons.math.FunctionEvaluationException; 028 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction; 029 import org.apache.commons.math.analysis.MultivariateMatrixFunction; 030 import org.apache.commons.math.optimization.OptimizationException; 031 import org.apache.commons.math.optimization.VectorialPointValuePair; 032 033 /** 034 * <p>Some of the unit tests are re-implementations of the MINPACK <a 035 * href="http://www.netlib.org/minpack/ex/file17">file17</a> and <a 036 * href="http://www.netlib.org/minpack/ex/file22">file22</a> test files. 037 * The redistribution policy for MINPACK is available <a 038 * href="http://www.netlib.org/minpack/disclaimer">here</a>, for 039 * convenience, it is reproduced below.</p> 040 041 * <table border="0" width="80%" cellpadding="10" align="center" bgcolor="#E0E0E0"> 042 * <tr><td> 043 * Minpack Copyright Notice (1999) University of Chicago. 044 * All rights reserved 045 * </td></tr> 046 * <tr><td> 047 * Redistribution and use in source and binary forms, with or without 048 * modification, are permitted provided that the following conditions 049 * are met: 050 * <ol> 051 * <li>Redistributions of source code must retain the above copyright 052 * notice, this list of conditions and the following disclaimer.</li> 053 * <li>Redistributions in binary form must reproduce the above 054 * copyright notice, this list of conditions and the following 055 * disclaimer in the documentation and/or other materials provided 056 * with the distribution.</li> 057 * <li>The end-user documentation included with the redistribution, if any, 058 * must include the following acknowledgment: 059 * <code>This product includes software developed by the University of 060 * Chicago, as Operator of Argonne National Laboratory.</code> 061 * Alternately, this acknowledgment may appear in the software itself, 062 * if and wherever such third-party acknowledgments normally appear.</li> 063 * <li><strong>WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS" 064 * WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE 065 * UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND 066 * THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR 067 * IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES 068 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE 069 * OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY 070 * OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR 071 * USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF 072 * THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4) 073 * DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION 074 * UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL 075 * BE CORRECTED.</strong></li> 076 * <li><strong>LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT 077 * HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF 078 * ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT, 079 * INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF 080 * ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF 081 * PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER 082 * SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT 083 * (INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE, 084 * EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE 085 * POSSIBILITY OF SUCH LOSS OR DAMAGES.</strong></li> 086 * <ol></td></tr> 087 * </table> 088 089 * @author Argonne National Laboratory. MINPACK project. March 1980 (original fortran minpack tests) 090 * @author Burton S. Garbow (original fortran minpack tests) 091 * @author Kenneth E. Hillstrom (original fortran minpack tests) 092 * @author Jorge J. More (original fortran minpack tests) 093 * @author Luc Maisonobe (non-minpack tests and minpack tests Java translation) 094 */ 095 public class MinpackTest extends TestCase { 096 097 public MinpackTest(String name) { 098 super(name); 099 } 100 101 public void testMinpackLinearFullRank() { 102 minpackTest(new LinearFullRankFunction(10, 5, 1.0, 103 5.0, 2.23606797749979), false); 104 minpackTest(new LinearFullRankFunction(50, 5, 1.0, 105 8.06225774829855, 6.70820393249937), false); 106 } 107 108 public void testMinpackLinearRank1() { 109 minpackTest(new LinearRank1Function(10, 5, 1.0, 110 291.521868819476, 1.4638501094228), false); 111 minpackTest(new LinearRank1Function(50, 5, 1.0, 112 3101.60039334535, 3.48263016573496), false); 113 } 114 115 public void testMinpackLinearRank1ZeroColsAndRows() { 116 minpackTest(new LinearRank1ZeroColsAndRowsFunction(10, 5, 1.0), false); 117 minpackTest(new LinearRank1ZeroColsAndRowsFunction(50, 5, 1.0), false); 118 } 119 120 public void testMinpackRosenbrok() { 121 minpackTest(new RosenbrockFunction(new double[] { -1.2, 1.0 }, 122 Math.sqrt(24.2)), false); 123 minpackTest(new RosenbrockFunction(new double[] { -12.0, 10.0 }, 124 Math.sqrt(1795769.0)), false); 125 minpackTest(new RosenbrockFunction(new double[] { -120.0, 100.0 }, 126 11.0 * Math.sqrt(169000121.0)), false); 127 } 128 129 public void testMinpackHelicalValley() { 130 minpackTest(new HelicalValleyFunction(new double[] { -1.0, 0.0, 0.0 }, 131 50.0), false); 132 minpackTest(new HelicalValleyFunction(new double[] { -10.0, 0.0, 0.0 }, 133 102.95630140987), false); 134 minpackTest(new HelicalValleyFunction(new double[] { -100.0, 0.0, 0.0}, 135 991.261822123701), false); 136 } 137 138 public void testMinpackPowellSingular() { 139 minpackTest(new PowellSingularFunction(new double[] { 3.0, -1.0, 0.0, 1.0 }, 140 14.6628782986152), false); 141 minpackTest(new PowellSingularFunction(new double[] { 30.0, -10.0, 0.0, 10.0 }, 142 1270.9838708654), false); 143 minpackTest(new PowellSingularFunction(new double[] { 300.0, -100.0, 0.0, 100.0 }, 144 126887.903284750), false); 145 } 146 147 public void testMinpackFreudensteinRoth() { 148 minpackTest(new FreudensteinRothFunction(new double[] { 0.5, -2.0 }, 149 20.0124960961895, 6.99887517584575, 150 new double[] { 151 11.4124844654993, 152 -0.896827913731509 153 }), false); 154 minpackTest(new FreudensteinRothFunction(new double[] { 5.0, -20.0 }, 155 12432.833948863, 6.9988751744895, 156 new double[] { 157 11.4130046614746, 158 -0.896796038685958 159 }), false); 160 minpackTest(new FreudensteinRothFunction(new double[] { 50.0, -200.0 }, 161 11426454.595762, 6.99887517242903, 162 new double[] { 163 11.4127817857886, 164 -0.89680510749204 165 }), false); 166 } 167 168 public void testMinpackBard() { 169 minpackTest(new BardFunction(1.0, 6.45613629515967, 0.0906359603390466, 170 new double[] { 171 0.0824105765758334, 172 1.1330366534715, 173 2.34369463894115 174 }), false); 175 minpackTest(new BardFunction(10.0, 36.1418531596785, 4.17476870138539, 176 new double[] { 177 0.840666673818329, 178 -158848033.259565, 179 -164378671.653535 180 }), false); 181 minpackTest(new BardFunction(100.0, 384.114678637399, 4.17476870135969, 182 new double[] { 183 0.840666673867645, 184 -158946167.205518, 185 -164464906.857771 186 }), false); 187 } 188 189 public void testMinpackKowalikOsborne() { 190 minpackTest(new KowalikOsborneFunction(new double[] { 0.25, 0.39, 0.415, 0.39 }, 191 0.0728915102882945, 192 0.017535837721129, 193 new double[] { 194 0.192807810476249, 195 0.191262653354071, 196 0.123052801046931, 197 0.136053221150517 198 }), false); 199 minpackTest(new KowalikOsborneFunction(new double[] { 2.5, 3.9, 4.15, 3.9 }, 200 2.97937007555202, 201 0.032052192917937, 202 new double[] { 203 728675.473768287, 204 -14.0758803129393, 205 -32977797.7841797, 206 -20571594.1977912 207 }), false); 208 minpackTest(new KowalikOsborneFunction(new double[] { 25.0, 39.0, 41.5, 39.0 }, 209 29.9590617016037, 210 0.0175364017658228, 211 new double[] { 212 0.192948328597594, 213 0.188053165007911, 214 0.122430604321144, 215 0.134575665392506 216 }), false); 217 } 218 219 public void testMinpackMeyer() { 220 minpackTest(new MeyerFunction(new double[] { 0.02, 4000.0, 250.0 }, 221 41153.4665543031, 9.37794514651874, 222 new double[] { 223 0.00560963647102661, 224 6181.34634628659, 225 345.223634624144 226 }), false); 227 minpackTest(new MeyerFunction(new double[] { 0.2, 40000.0, 2500.0 }, 228 4168216.89130846, 792.917871779501, 229 new double[] { 230 1.42367074157994e-11, 231 33695.7133432541, 232 901.268527953801 233 }), true); 234 } 235 236 public void testMinpackWatson() { 237 238 minpackTest(new WatsonFunction(6, 0.0, 239 5.47722557505166, 0.0478295939097601, 240 new double[] { 241 -0.0157249615083782, 1.01243488232965, 242 -0.232991722387673, 1.26043101102818, 243 -1.51373031394421, 0.99299727291842 244 }), false); 245 minpackTest(new WatsonFunction(6, 10.0, 246 6433.12578950026, 0.0478295939096951, 247 new double[] { 248 -0.0157251901386677, 1.01243485860105, 249 -0.232991545843829, 1.26042932089163, 250 -1.51372776706575, 0.99299573426328 251 }), false); 252 minpackTest(new WatsonFunction(6, 100.0, 253 674256.040605213, 0.047829593911544, 254 new double[] { 255 -0.0157247019712586, 1.01243490925658, 256 -0.232991922761641, 1.26043292929555, 257 -1.51373320452707, 0.99299901922322 258 }), false); 259 260 minpackTest(new WatsonFunction(9, 0.0, 261 5.47722557505166, 0.00118311459212420, 262 new double[] { 263 -0.153070644166722e-4, 0.999789703934597, 264 0.0147639634910978, 0.146342330145992, 265 1.00082109454817, -2.61773112070507, 266 4.10440313943354, -3.14361226236241, 267 1.05262640378759 268 }), false); 269 minpackTest(new WatsonFunction(9, 10.0, 270 12088.127069307, 0.00118311459212513, 271 new double[] { 272 -0.153071334849279e-4, 0.999789703941234, 273 0.0147639629786217, 0.146342334818836, 274 1.00082107321386, -2.61773107084722, 275 4.10440307655564, -3.14361222178686, 276 1.05262639322589 277 }), false); 278 minpackTest(new WatsonFunction(9, 100.0, 279 1269109.29043834, 0.00118311459212384, 280 new double[] { 281 -0.153069523352176e-4, 0.999789703958371, 282 0.0147639625185392, 0.146342341096326, 283 1.00082104729164, -2.61773101573645, 284 4.10440301427286, -3.14361218602503, 285 1.05262638516774 286 }), false); 287 288 minpackTest(new WatsonFunction(12, 0.0, 289 5.47722557505166, 0.217310402535861e-4, 290 new double[] { 291 -0.660266001396382e-8, 1.00000164411833, 292 -0.000563932146980154, 0.347820540050756, 293 -0.156731500244233, 1.05281515825593, 294 -3.24727109519451, 7.2884347837505, 295 -10.271848098614, 9.07411353715783, 296 -4.54137541918194, 1.01201187975044 297 }), false); 298 minpackTest(new WatsonFunction(12, 10.0, 299 19220.7589790951, 0.217310402518509e-4, 300 new double[] { 301 -0.663710223017410e-8, 1.00000164411787, 302 -0.000563932208347327, 0.347820540486998, 303 -0.156731503955652, 1.05281517654573, 304 -3.2472711515214, 7.28843489430665, 305 -10.2718482369638, 9.07411364383733, 306 -4.54137546533666, 1.01201188830857 307 }), false); 308 minpackTest(new WatsonFunction(12, 100.0, 309 2018918.04462367, 0.217310402539845e-4, 310 new double[] { 311 -0.663806046485249e-8, 1.00000164411786, 312 -0.000563932210324959, 0.347820540503588, 313 -0.156731504091375, 1.05281517718031, 314 -3.24727115337025, 7.28843489775302, 315 -10.2718482410813, 9.07411364688464, 316 -4.54137546660822, 1.0120118885369 317 }), false); 318 319 } 320 321 public void testMinpackBox3Dimensional() { 322 minpackTest(new Box3DimensionalFunction(10, new double[] { 0.0, 10.0, 20.0 }, 323 32.1115837449572), false); 324 } 325 326 public void testMinpackJennrichSampson() { 327 minpackTest(new JennrichSampsonFunction(10, new double[] { 0.3, 0.4 }, 328 64.5856498144943, 11.1517793413499, 329 new double[] { 330 0.257819926636811, 0.257829976764542 331 }), false); 332 } 333 334 public void testMinpackBrownDennis() { 335 minpackTest(new BrownDennisFunction(20, 336 new double[] { 25.0, 5.0, -5.0, -1.0 }, 337 2815.43839161816, 292.954288244866, 338 new double[] { 339 -11.59125141003, 13.2024883984741, 340 -0.403574643314272, 0.236736269844604 341 }), false); 342 minpackTest(new BrownDennisFunction(20, 343 new double[] { 250.0, 50.0, -50.0, -10.0 }, 344 555073.354173069, 292.954270581415, 345 new double[] { 346 -11.5959274272203, 13.2041866926242, 347 -0.403417362841545, 0.236771143410386 348 }), false); 349 minpackTest(new BrownDennisFunction(20, 350 new double[] { 2500.0, 500.0, -500.0, -100.0 }, 351 61211252.2338581, 292.954306151134, 352 new double[] { 353 -11.5902596937374, 13.2020628854665, 354 -0.403688070279258, 0.236665033746463 355 }), false); 356 } 357 358 public void testMinpackChebyquad() { 359 minpackTest(new ChebyquadFunction(1, 8, 1.0, 360 1.88623796907732, 1.88623796907732, 361 new double[] { 0.5 }), false); 362 minpackTest(new ChebyquadFunction(1, 8, 10.0, 363 5383344372.34005, 1.88424820499951, 364 new double[] { 0.9817314924684 }), false); 365 minpackTest(new ChebyquadFunction(1, 8, 100.0, 366 0.118088726698392e19, 1.88424820499347, 367 new double[] { 0.9817314852934 }), false); 368 minpackTest(new ChebyquadFunction(8, 8, 1.0, 369 0.196513862833975, 0.0593032355046727, 370 new double[] { 371 0.0431536648587336, 0.193091637843267, 372 0.266328593812698, 0.499999334628884, 373 0.500000665371116, 0.733671406187302, 374 0.806908362156733, 0.956846335141266 375 }), false); 376 minpackTest(new ChebyquadFunction(9, 9, 1.0, 377 0.16994993465202, 0.0, 378 new double[] { 379 0.0442053461357828, 0.199490672309881, 380 0.23561910847106, 0.416046907892598, 381 0.5, 0.583953092107402, 382 0.764380891528940, 0.800509327690119, 383 0.955794653864217 384 }), false); 385 minpackTest(new ChebyquadFunction(10, 10, 1.0, 386 0.183747831178711, 0.0806471004038253, 387 new double[] { 388 0.0596202671753563, 0.166708783805937, 389 0.239171018813509, 0.398885290346268, 390 0.398883667870681, 0.601116332129320, 391 0.60111470965373, 0.760828981186491, 392 0.833291216194063, 0.940379732824644 393 }), false); 394 } 395 396 public void testMinpackBrownAlmostLinear() { 397 minpackTest(new BrownAlmostLinearFunction(10, 0.5, 398 16.5302162063499, 0.0, 399 new double[] { 400 0.979430303349862, 0.979430303349862, 401 0.979430303349862, 0.979430303349862, 402 0.979430303349862, 0.979430303349862, 403 0.979430303349862, 0.979430303349862, 404 0.979430303349862, 1.20569696650138 405 }), false); 406 minpackTest(new BrownAlmostLinearFunction(10, 5.0, 407 9765624.00089211, 0.0, 408 new double[] { 409 0.979430303349865, 0.979430303349865, 410 0.979430303349865, 0.979430303349865, 411 0.979430303349865, 0.979430303349865, 412 0.979430303349865, 0.979430303349865, 413 0.979430303349865, 1.20569696650135 414 }), false); 415 minpackTest(new BrownAlmostLinearFunction(10, 50.0, 416 0.9765625e17, 0.0, 417 new double[] { 418 1.0, 1.0, 1.0, 1.0, 1.0, 419 1.0, 1.0, 1.0, 1.0, 1.0 420 }), false); 421 minpackTest(new BrownAlmostLinearFunction(30, 0.5, 422 83.476044467848, 0.0, 423 new double[] { 424 0.997754216442807, 0.997754216442807, 425 0.997754216442807, 0.997754216442807, 426 0.997754216442807, 0.997754216442807, 427 0.997754216442807, 0.997754216442807, 428 0.997754216442807, 0.997754216442807, 429 0.997754216442807, 0.997754216442807, 430 0.997754216442807, 0.997754216442807, 431 0.997754216442807, 0.997754216442807, 432 0.997754216442807, 0.997754216442807, 433 0.997754216442807, 0.997754216442807, 434 0.997754216442807, 0.997754216442807, 435 0.997754216442807, 0.997754216442807, 436 0.997754216442807, 0.997754216442807, 437 0.997754216442807, 0.997754216442807, 438 0.997754216442807, 1.06737350671578 439 }), false); 440 minpackTest(new BrownAlmostLinearFunction(40, 0.5, 441 128.026364472323, 0.0, 442 new double[] { 443 1.00000000000002, 1.00000000000002, 444 1.00000000000002, 1.00000000000002, 445 1.00000000000002, 1.00000000000002, 446 1.00000000000002, 1.00000000000002, 447 1.00000000000002, 1.00000000000002, 448 1.00000000000002, 1.00000000000002, 449 1.00000000000002, 1.00000000000002, 450 1.00000000000002, 1.00000000000002, 451 1.00000000000002, 1.00000000000002, 452 1.00000000000002, 1.00000000000002, 453 1.00000000000002, 1.00000000000002, 454 1.00000000000002, 1.00000000000002, 455 1.00000000000002, 1.00000000000002, 456 1.00000000000002, 1.00000000000002, 457 1.00000000000002, 1.00000000000002, 458 1.00000000000002, 1.00000000000002, 459 1.00000000000002, 1.00000000000002, 460 0.999999999999121 461 }), false); 462 } 463 464 public void testMinpackOsborne1() { 465 minpackTest(new Osborne1Function(new double[] { 0.5, 1.5, -1.0, 0.01, 0.02, }, 466 0.937564021037838, 0.00739249260904843, 467 new double[] { 468 0.375410049244025, 1.93584654543108, 469 -1.46468676748716, 0.0128675339110439, 470 0.0221227011813076 471 }), false); 472 } 473 474 public void testMinpackOsborne2() { 475 476 minpackTest(new Osborne2Function(new double[] { 477 1.3, 0.65, 0.65, 0.7, 0.6, 478 3.0, 5.0, 7.0, 2.0, 4.5, 5.5 479 }, 480 1.44686540984712, 0.20034404483314, 481 new double[] { 482 1.30997663810096, 0.43155248076, 483 0.633661261602859, 0.599428560991695, 484 0.754179768272449, 0.904300082378518, 485 1.36579949521007, 4.82373199748107, 486 2.39868475104871, 4.56887554791452, 487 5.67534206273052 488 }), false); 489 } 490 491 private void minpackTest(MinpackFunction function, boolean exceptionExpected) { 492 LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer(); 493 optimizer.setMaxIterations(100 * (function.getN() + 1)); 494 optimizer.setCostRelativeTolerance(Math.sqrt(2.22044604926e-16)); 495 optimizer.setParRelativeTolerance(Math.sqrt(2.22044604926e-16)); 496 optimizer.setOrthoTolerance(2.22044604926e-16); 497 // assertTrue(function.checkTheoreticalStartCost(optimizer.getRMS())); 498 try { 499 VectorialPointValuePair optimum = 500 optimizer.optimize(function, 501 function.getTarget(), function.getWeight(), 502 function.getStartPoint()); 503 assertFalse(exceptionExpected); 504 assertTrue(function.checkTheoreticalMinCost(optimizer.getRMS())); 505 assertTrue(function.checkTheoreticalMinParams(optimum)); 506 } catch (OptimizationException lsse) { 507 assertTrue(exceptionExpected); 508 } catch (FunctionEvaluationException fe) { 509 assertTrue(exceptionExpected); 510 } 511 } 512 513 private static abstract class MinpackFunction 514 implements DifferentiableMultivariateVectorialFunction, Serializable { 515 516 private static final long serialVersionUID = -6209760235478794233L; 517 protected int n; 518 protected int m; 519 protected double[] startParams; 520 protected double theoreticalMinCost; 521 protected double[] theoreticalMinParams; 522 protected double costAccuracy; 523 protected double paramsAccuracy; 524 525 protected MinpackFunction(int m, double[] startParams, 526 double theoreticalMinCost, double[] theoreticalMinParams) { 527 this.m = m; 528 this.n = startParams.length; 529 this.startParams = startParams.clone(); 530 this.theoreticalMinCost = theoreticalMinCost; 531 this.theoreticalMinParams = theoreticalMinParams; 532 this.costAccuracy = 1.0e-8; 533 this.paramsAccuracy = 1.0e-5; 534 } 535 536 protected static double[] buildArray(int n, double x) { 537 double[] array = new double[n]; 538 Arrays.fill(array, x); 539 return array; 540 } 541 542 public double[] getTarget() { 543 return buildArray(m, 0.0); 544 } 545 546 public double[] getWeight() { 547 return buildArray(m, 1.0); 548 } 549 550 public double[] getStartPoint() { 551 return startParams.clone(); 552 } 553 554 protected void setCostAccuracy(double costAccuracy) { 555 this.costAccuracy = costAccuracy; 556 } 557 558 protected void setParamsAccuracy(double paramsAccuracy) { 559 this.paramsAccuracy = paramsAccuracy; 560 } 561 562 public int getN() { 563 return startParams.length; 564 } 565 566 public boolean checkTheoreticalMinCost(double rms) { 567 double threshold = costAccuracy * (1.0 + theoreticalMinCost); 568 return Math.abs(Math.sqrt(m) * rms - theoreticalMinCost) <= threshold; 569 } 570 571 public boolean checkTheoreticalMinParams(VectorialPointValuePair optimum) { 572 double[] params = optimum.getPointRef(); 573 if (theoreticalMinParams != null) { 574 for (int i = 0; i < theoreticalMinParams.length; ++i) { 575 double mi = theoreticalMinParams[i]; 576 double vi = params[i]; 577 if (Math.abs(mi - vi) > (paramsAccuracy * (1.0 + Math.abs(mi)))) { 578 return false; 579 } 580 } 581 } 582 return true; 583 } 584 585 public MultivariateMatrixFunction jacobian() { 586 return new MultivariateMatrixFunction() { 587 private static final long serialVersionUID = -2435076097232923678L; 588 public double[][] value(double[] point) { 589 return jacobian(point); 590 } 591 }; 592 } 593 594 public abstract double[][] jacobian(double[] variables); 595 596 public abstract double[] value(double[] variables); 597 598 } 599 600 private static class LinearFullRankFunction extends MinpackFunction { 601 602 private static final long serialVersionUID = -9030323226268039536L; 603 604 public LinearFullRankFunction(int m, int n, double x0, 605 double theoreticalStartCost, 606 double theoreticalMinCost) { 607 super(m, buildArray(n, x0), theoreticalMinCost, 608 buildArray(n, -1.0)); 609 } 610 611 @Override 612 public double[][] jacobian(double[] variables) { 613 double t = 2.0 / m; 614 double[][] jacobian = new double[m][]; 615 for (int i = 0; i < m; ++i) { 616 jacobian[i] = new double[n]; 617 for (int j = 0; j < n; ++j) { 618 jacobian[i][j] = (i == j) ? (1 - t) : -t; 619 } 620 } 621 return jacobian; 622 } 623 624 @Override 625 public double[] value(double[] variables) { 626 double sum = 0; 627 for (int i = 0; i < n; ++i) { 628 sum += variables[i]; 629 } 630 double t = 1 + 2 * sum / m; 631 double[] f = new double[m]; 632 for (int i = 0; i < n; ++i) { 633 f[i] = variables[i] - t; 634 } 635 Arrays.fill(f, n, m, -t); 636 return f; 637 } 638 639 } 640 641 private static class LinearRank1Function extends MinpackFunction { 642 643 private static final long serialVersionUID = 8494863245104608300L; 644 645 public LinearRank1Function(int m, int n, double x0, 646 double theoreticalStartCost, 647 double theoreticalMinCost) { 648 super(m, buildArray(n, x0), theoreticalMinCost, null); 649 } 650 651 @Override 652 public double[][] jacobian(double[] variables) { 653 double[][] jacobian = new double[m][]; 654 for (int i = 0; i < m; ++i) { 655 jacobian[i] = new double[n]; 656 for (int j = 0; j < n; ++j) { 657 jacobian[i][j] = (i + 1) * (j + 1); 658 } 659 } 660 return jacobian; 661 } 662 663 @Override 664 public double[] value(double[] variables) { 665 double[] f = new double[m]; 666 double sum = 0; 667 for (int i = 0; i < n; ++i) { 668 sum += (i + 1) * variables[i]; 669 } 670 for (int i = 0; i < m; ++i) { 671 f[i] = (i + 1) * sum - 1; 672 } 673 return f; 674 } 675 676 } 677 678 private static class LinearRank1ZeroColsAndRowsFunction extends MinpackFunction { 679 680 private static final long serialVersionUID = -3316653043091995018L; 681 682 public LinearRank1ZeroColsAndRowsFunction(int m, int n, double x0) { 683 super(m, buildArray(n, x0), 684 Math.sqrt((m * (m + 3) - 6) / (2.0 * (2 * m - 3))), 685 null); 686 } 687 688 @Override 689 public double[][] jacobian(double[] variables) { 690 double[][] jacobian = new double[m][]; 691 for (int i = 0; i < m; ++i) { 692 jacobian[i] = new double[n]; 693 jacobian[i][0] = 0; 694 for (int j = 1; j < (n - 1); ++j) { 695 if (i == 0) { 696 jacobian[i][j] = 0; 697 } else if (i != (m - 1)) { 698 jacobian[i][j] = i * (j + 1); 699 } else { 700 jacobian[i][j] = 0; 701 } 702 } 703 jacobian[i][n - 1] = 0; 704 } 705 return jacobian; 706 } 707 708 @Override 709 public double[] value(double[] variables) { 710 double[] f = new double[m]; 711 double sum = 0; 712 for (int i = 1; i < (n - 1); ++i) { 713 sum += (i + 1) * variables[i]; 714 } 715 for (int i = 0; i < (m - 1); ++i) { 716 f[i] = i * sum - 1; 717 } 718 f[m - 1] = -1; 719 return f; 720 } 721 722 } 723 724 private static class RosenbrockFunction extends MinpackFunction { 725 726 private static final long serialVersionUID = 2893438180956569134L; 727 728 public RosenbrockFunction(double[] startParams, double theoreticalStartCost) { 729 super(2, startParams, 0.0, buildArray(2, 1.0)); 730 } 731 732 @Override 733 public double[][] jacobian(double[] variables) { 734 double x1 = variables[0]; 735 return new double[][] { { -20 * x1, 10 }, { -1, 0 } }; 736 } 737 738 @Override 739 public double[] value(double[] variables) { 740 double x1 = variables[0]; 741 double x2 = variables[1]; 742 return new double[] { 10 * (x2 - x1 * x1), 1 - x1 }; 743 } 744 745 } 746 747 private static class HelicalValleyFunction extends MinpackFunction { 748 749 private static final long serialVersionUID = 220613787843200102L; 750 751 public HelicalValleyFunction(double[] startParams, 752 double theoreticalStartCost) { 753 super(3, startParams, 0.0, new double[] { 1.0, 0.0, 0.0 }); 754 } 755 756 @Override 757 public double[][] jacobian(double[] variables) { 758 double x1 = variables[0]; 759 double x2 = variables[1]; 760 double tmpSquare = x1 * x1 + x2 * x2; 761 double tmp1 = twoPi * tmpSquare; 762 double tmp2 = Math.sqrt(tmpSquare); 763 return new double[][] { 764 { 100 * x2 / tmp1, -100 * x1 / tmp1, 10 }, 765 { 10 * x1 / tmp2, 10 * x2 / tmp2, 0 }, 766 { 0, 0, 1 } 767 }; 768 } 769 770 @Override 771 public double[] value(double[] variables) { 772 double x1 = variables[0]; 773 double x2 = variables[1]; 774 double x3 = variables[2]; 775 double tmp1; 776 if (x1 == 0) { 777 tmp1 = (x2 >= 0) ? 0.25 : -0.25; 778 } else { 779 tmp1 = Math.atan(x2 / x1) / twoPi; 780 if (x1 < 0) { 781 tmp1 += 0.5; 782 } 783 } 784 double tmp2 = Math.sqrt(x1 * x1 + x2 * x2); 785 return new double[] { 786 10.0 * (x3 - 10 * tmp1), 787 10.0 * (tmp2 - 1), 788 x3 789 }; 790 } 791 792 private static final double twoPi = 2.0 * Math.PI; 793 794 } 795 796 private static class PowellSingularFunction extends MinpackFunction { 797 798 private static final long serialVersionUID = 7298364171208142405L; 799 800 public PowellSingularFunction(double[] startParams, 801 double theoreticalStartCost) { 802 super(4, startParams, 0.0, buildArray(4, 0.0)); 803 } 804 805 @Override 806 public double[][] jacobian(double[] variables) { 807 double x1 = variables[0]; 808 double x2 = variables[1]; 809 double x3 = variables[2]; 810 double x4 = variables[3]; 811 return new double[][] { 812 { 1, 10, 0, 0 }, 813 { 0, 0, sqrt5, -sqrt5 }, 814 { 0, 2 * (x2 - 2 * x3), -4 * (x2 - 2 * x3), 0 }, 815 { 2 * sqrt10 * (x1 - x4), 0, 0, -2 * sqrt10 * (x1 - x4) } 816 }; 817 } 818 819 @Override 820 public double[] value(double[] variables) { 821 double x1 = variables[0]; 822 double x2 = variables[1]; 823 double x3 = variables[2]; 824 double x4 = variables[3]; 825 return new double[] { 826 x1 + 10 * x2, 827 sqrt5 * (x3 - x4), 828 (x2 - 2 * x3) * (x2 - 2 * x3), 829 sqrt10 * (x1 - x4) * (x1 - x4) 830 }; 831 } 832 833 private static final double sqrt5 = Math.sqrt( 5.0); 834 private static final double sqrt10 = Math.sqrt(10.0); 835 836 } 837 838 private static class FreudensteinRothFunction extends MinpackFunction { 839 840 private static final long serialVersionUID = 2892404999344244214L; 841 842 public FreudensteinRothFunction(double[] startParams, 843 double theoreticalStartCost, 844 double theoreticalMinCost, 845 double[] theoreticalMinParams) { 846 super(2, startParams, theoreticalMinCost, 847 theoreticalMinParams); 848 } 849 850 @Override 851 public double[][] jacobian(double[] variables) { 852 double x2 = variables[1]; 853 return new double[][] { 854 { 1, x2 * (10 - 3 * x2) - 2 }, 855 { 1, x2 * ( 2 + 3 * x2) - 14, } 856 }; 857 } 858 859 @Override 860 public double[] value(double[] variables) { 861 double x1 = variables[0]; 862 double x2 = variables[1]; 863 return new double[] { 864 -13.0 + x1 + ((5.0 - x2) * x2 - 2.0) * x2, 865 -29.0 + x1 + ((1.0 + x2) * x2 - 14.0) * x2 866 }; 867 } 868 869 } 870 871 private static class BardFunction extends MinpackFunction { 872 873 private static final long serialVersionUID = 5990442612572087668L; 874 875 public BardFunction(double x0, 876 double theoreticalStartCost, 877 double theoreticalMinCost, 878 double[] theoreticalMinParams) { 879 super(15, buildArray(3, x0), theoreticalMinCost, 880 theoreticalMinParams); 881 } 882 883 @Override 884 public double[][] jacobian(double[] variables) { 885 double x2 = variables[1]; 886 double x3 = variables[2]; 887 double[][] jacobian = new double[m][]; 888 for (int i = 0; i < m; ++i) { 889 double tmp1 = i + 1; 890 double tmp2 = 15 - i; 891 double tmp3 = (i <= 7) ? tmp1 : tmp2; 892 double tmp4 = x2 * tmp2 + x3 * tmp3; 893 tmp4 *= tmp4; 894 jacobian[i] = new double[] { -1, tmp1 * tmp2 / tmp4, tmp1 * tmp3 / tmp4 }; 895 } 896 return jacobian; 897 } 898 899 @Override 900 public double[] value(double[] variables) { 901 double x1 = variables[0]; 902 double x2 = variables[1]; 903 double x3 = variables[2]; 904 double[] f = new double[m]; 905 for (int i = 0; i < m; ++i) { 906 double tmp1 = i + 1; 907 double tmp2 = 15 - i; 908 double tmp3 = (i <= 7) ? tmp1 : tmp2; 909 f[i] = y[i] - (x1 + tmp1 / (x2 * tmp2 + x3 * tmp3)); 910 } 911 return f; 912 } 913 914 private static final double[] y = { 915 0.14, 0.18, 0.22, 0.25, 0.29, 916 0.32, 0.35, 0.39, 0.37, 0.58, 917 0.73, 0.96, 1.34, 2.10, 4.39 918 }; 919 920 } 921 922 private static class KowalikOsborneFunction extends MinpackFunction { 923 924 private static final long serialVersionUID = -4867445739880495801L; 925 926 public KowalikOsborneFunction(double[] startParams, 927 double theoreticalStartCost, 928 double theoreticalMinCost, 929 double[] theoreticalMinParams) { 930 super(11, startParams, theoreticalMinCost, 931 theoreticalMinParams); 932 if (theoreticalStartCost > 20.0) { 933 setCostAccuracy(2.0e-4); 934 setParamsAccuracy(5.0e-3); 935 } 936 } 937 938 @Override 939 public double[][] jacobian(double[] variables) { 940 double x1 = variables[0]; 941 double x2 = variables[1]; 942 double x3 = variables[2]; 943 double x4 = variables[3]; 944 double[][] jacobian = new double[m][]; 945 for (int i = 0; i < m; ++i) { 946 double tmp = v[i] * (v[i] + x3) + x4; 947 double j1 = -v[i] * (v[i] + x2) / tmp; 948 double j2 = -v[i] * x1 / tmp; 949 double j3 = j1 * j2; 950 double j4 = j3 / v[i]; 951 jacobian[i] = new double[] { j1, j2, j3, j4 }; 952 } 953 return jacobian; 954 } 955 956 @Override 957 public double[] value(double[] variables) { 958 double x1 = variables[0]; 959 double x2 = variables[1]; 960 double x3 = variables[2]; 961 double x4 = variables[3]; 962 double[] f = new double[m]; 963 for (int i = 0; i < m; ++i) { 964 f[i] = y[i] - x1 * (v[i] * (v[i] + x2)) / (v[i] * (v[i] + x3) + x4); 965 } 966 return f; 967 } 968 969 private static final double[] v = { 970 4.0, 2.0, 1.0, 0.5, 0.25, 0.167, 0.125, 0.1, 0.0833, 0.0714, 0.0625 971 }; 972 973 private static final double[] y = { 974 0.1957, 0.1947, 0.1735, 0.1600, 0.0844, 0.0627, 975 0.0456, 0.0342, 0.0323, 0.0235, 0.0246 976 }; 977 978 } 979 980 private static class MeyerFunction extends MinpackFunction { 981 982 private static final long serialVersionUID = -838060619150131027L; 983 984 public MeyerFunction(double[] startParams, 985 double theoreticalStartCost, 986 double theoreticalMinCost, 987 double[] theoreticalMinParams) { 988 super(16, startParams, theoreticalMinCost, 989 theoreticalMinParams); 990 if (theoreticalStartCost > 1.0e6) { 991 setCostAccuracy(7.0e-3); 992 setParamsAccuracy(2.0e-2); 993 } 994 } 995 996 @Override 997 public double[][] jacobian(double[] variables) { 998 double x1 = variables[0]; 999 double x2 = variables[1]; 1000 double x3 = variables[2]; 1001 double[][] jacobian = new double[m][]; 1002 for (int i = 0; i < m; ++i) { 1003 double temp = 5.0 * (i + 1) + 45.0 + x3; 1004 double tmp1 = x2 / temp; 1005 double tmp2 = Math.exp(tmp1); 1006 double tmp3 = x1 * tmp2 / temp; 1007 jacobian[i] = new double[] { tmp2, tmp3, -tmp1 * tmp3 }; 1008 } 1009 return jacobian; 1010 } 1011 1012 @Override 1013 public double[] value(double[] variables) { 1014 double x1 = variables[0]; 1015 double x2 = variables[1]; 1016 double x3 = variables[2]; 1017 double[] f = new double[m]; 1018 for (int i = 0; i < m; ++i) { 1019 f[i] = x1 * Math.exp(x2 / (5.0 * (i + 1) + 45.0 + x3)) - y[i]; 1020 } 1021 return f; 1022 } 1023 1024 private static final double[] y = { 1025 34780.0, 28610.0, 23650.0, 19630.0, 1026 16370.0, 13720.0, 11540.0, 9744.0, 1027 8261.0, 7030.0, 6005.0, 5147.0, 1028 4427.0, 3820.0, 3307.0, 2872.0 1029 }; 1030 1031 } 1032 1033 private static class WatsonFunction extends MinpackFunction { 1034 1035 private static final long serialVersionUID = -9034759294980218927L; 1036 1037 public WatsonFunction(int n, double x0, 1038 double theoreticalStartCost, 1039 double theoreticalMinCost, 1040 double[] theoreticalMinParams) { 1041 super(31, buildArray(n, x0), theoreticalMinCost, 1042 theoreticalMinParams); 1043 } 1044 1045 @Override 1046 public double[][] jacobian(double[] variables) { 1047 1048 double[][] jacobian = new double[m][]; 1049 1050 for (int i = 0; i < (m - 2); ++i) { 1051 double div = (i + 1) / 29.0; 1052 double s2 = 0.0; 1053 double dx = 1.0; 1054 for (int j = 0; j < n; ++j) { 1055 s2 += dx * variables[j]; 1056 dx *= div; 1057 } 1058 double temp= 2 * div * s2; 1059 dx = 1.0 / div; 1060 jacobian[i] = new double[n]; 1061 for (int j = 0; j < n; ++j) { 1062 jacobian[i][j] = dx * (j - temp); 1063 dx *= div; 1064 } 1065 } 1066 1067 jacobian[m - 2] = new double[n]; 1068 jacobian[m - 2][0] = 1; 1069 1070 jacobian[m - 1] = new double[n]; 1071 jacobian[m - 1][0]= -2 * variables[0]; 1072 jacobian[m - 1][1]= 1; 1073 1074 return jacobian; 1075 1076 } 1077 1078 @Override 1079 public double[] value(double[] variables) { 1080 double[] f = new double[m]; 1081 for (int i = 0; i < (m - 2); ++i) { 1082 double div = (i + 1) / 29.0; 1083 double s1 = 0; 1084 double dx = 1; 1085 for (int j = 1; j < n; ++j) { 1086 s1 += j * dx * variables[j]; 1087 dx *= div; 1088 } 1089 double s2 =0; 1090 dx =1; 1091 for (int j = 0; j < n; ++j) { 1092 s2 += dx * variables[j]; 1093 dx *= div; 1094 } 1095 f[i] = s1 - s2 * s2 - 1; 1096 } 1097 1098 double x1 = variables[0]; 1099 double x2 = variables[1]; 1100 f[m - 2] = x1; 1101 f[m - 1] = x2 - x1 * x1 - 1; 1102 1103 return f; 1104 1105 } 1106 1107 } 1108 1109 private static class Box3DimensionalFunction extends MinpackFunction { 1110 1111 private static final long serialVersionUID = 5511403858142574493L; 1112 1113 public Box3DimensionalFunction(int m, double[] startParams, 1114 double theoreticalStartCost) { 1115 super(m, startParams, 0.0, 1116 new double[] { 1.0, 10.0, 1.0 }); 1117 } 1118 1119 @Override 1120 public double[][] jacobian(double[] variables) { 1121 double x1 = variables[0]; 1122 double x2 = variables[1]; 1123 double[][] jacobian = new double[m][]; 1124 for (int i = 0; i < m; ++i) { 1125 double tmp = (i + 1) / 10.0; 1126 jacobian[i] = new double[] { 1127 -tmp * Math.exp(-tmp * x1), 1128 tmp * Math.exp(-tmp * x2), 1129 Math.exp(-i - 1) - Math.exp(-tmp) 1130 }; 1131 } 1132 return jacobian; 1133 } 1134 1135 @Override 1136 public double[] value(double[] variables) { 1137 double x1 = variables[0]; 1138 double x2 = variables[1]; 1139 double x3 = variables[2]; 1140 double[] f = new double[m]; 1141 for (int i = 0; i < m; ++i) { 1142 double tmp = (i + 1) / 10.0; 1143 f[i] = Math.exp(-tmp * x1) - Math.exp(-tmp * x2) 1144 + (Math.exp(-i - 1) - Math.exp(-tmp)) * x3; 1145 } 1146 return f; 1147 } 1148 1149 } 1150 1151 private static class JennrichSampsonFunction extends MinpackFunction { 1152 1153 private static final long serialVersionUID = -2489165190443352947L; 1154 1155 public JennrichSampsonFunction(int m, double[] startParams, 1156 double theoreticalStartCost, 1157 double theoreticalMinCost, 1158 double[] theoreticalMinParams) { 1159 super(m, startParams, theoreticalMinCost, 1160 theoreticalMinParams); 1161 } 1162 1163 @Override 1164 public double[][] jacobian(double[] variables) { 1165 double x1 = variables[0]; 1166 double x2 = variables[1]; 1167 double[][] jacobian = new double[m][]; 1168 for (int i = 0; i < m; ++i) { 1169 double t = i + 1; 1170 jacobian[i] = new double[] { -t * Math.exp(t * x1), -t * Math.exp(t * x2) }; 1171 } 1172 return jacobian; 1173 } 1174 1175 @Override 1176 public double[] value(double[] variables) { 1177 double x1 = variables[0]; 1178 double x2 = variables[1]; 1179 double[] f = new double[m]; 1180 for (int i = 0; i < m; ++i) { 1181 double temp = i + 1; 1182 f[i] = 2 + 2 * temp - Math.exp(temp * x1) - Math.exp(temp * x2); 1183 } 1184 return f; 1185 } 1186 1187 } 1188 1189 private static class BrownDennisFunction extends MinpackFunction { 1190 1191 private static final long serialVersionUID = 8340018645694243910L; 1192 1193 public BrownDennisFunction(int m, double[] startParams, 1194 double theoreticalStartCost, 1195 double theoreticalMinCost, 1196 double[] theoreticalMinParams) { 1197 super(m, startParams, theoreticalMinCost, 1198 theoreticalMinParams); 1199 setCostAccuracy(2.5e-8); 1200 } 1201 1202 @Override 1203 public double[][] jacobian(double[] variables) { 1204 double x1 = variables[0]; 1205 double x2 = variables[1]; 1206 double x3 = variables[2]; 1207 double x4 = variables[3]; 1208 double[][] jacobian = new double[m][]; 1209 for (int i = 0; i < m; ++i) { 1210 double temp = (i + 1) / 5.0; 1211 double ti = Math.sin(temp); 1212 double tmp1 = x1 + temp * x2 - Math.exp(temp); 1213 double tmp2 = x3 + ti * x4 - Math.cos(temp); 1214 jacobian[i] = new double[] { 1215 2 * tmp1, 2 * temp * tmp1, 2 * tmp2, 2 * ti * tmp2 1216 }; 1217 } 1218 return jacobian; 1219 } 1220 1221 @Override 1222 public double[] value(double[] variables) { 1223 double x1 = variables[0]; 1224 double x2 = variables[1]; 1225 double x3 = variables[2]; 1226 double x4 = variables[3]; 1227 double[] f = new double[m]; 1228 for (int i = 0; i < m; ++i) { 1229 double temp = (i + 1) / 5.0; 1230 double tmp1 = x1 + temp * x2 - Math.exp(temp); 1231 double tmp2 = x3 + Math.sin(temp) * x4 - Math.cos(temp); 1232 f[i] = tmp1 * tmp1 + tmp2 * tmp2; 1233 } 1234 return f; 1235 } 1236 1237 } 1238 1239 private static class ChebyquadFunction extends MinpackFunction { 1240 1241 private static final long serialVersionUID = -2394877275028008594L; 1242 1243 private static double[] buildChebyquadArray(int n, double factor) { 1244 double[] array = new double[n]; 1245 double inv = factor / (n + 1); 1246 for (int i = 0; i < n; ++i) { 1247 array[i] = (i + 1) * inv; 1248 } 1249 return array; 1250 } 1251 1252 public ChebyquadFunction(int n, int m, double factor, 1253 double theoreticalStartCost, 1254 double theoreticalMinCost, 1255 double[] theoreticalMinParams) { 1256 super(m, buildChebyquadArray(n, factor), theoreticalMinCost, 1257 theoreticalMinParams); 1258 } 1259 1260 @Override 1261 public double[][] jacobian(double[] variables) { 1262 1263 double[][] jacobian = new double[m][]; 1264 for (int i = 0; i < m; ++i) { 1265 jacobian[i] = new double[n]; 1266 } 1267 1268 double dx = 1.0 / n; 1269 for (int j = 0; j < n; ++j) { 1270 double tmp1 = 1; 1271 double tmp2 = 2 * variables[j] - 1; 1272 double temp = 2 * tmp2; 1273 double tmp3 = 0; 1274 double tmp4 = 2; 1275 for (int i = 0; i < m; ++i) { 1276 jacobian[i][j] = dx * tmp4; 1277 double ti = 4 * tmp2 + temp * tmp4 - tmp3; 1278 tmp3 = tmp4; 1279 tmp4 = ti; 1280 ti = temp * tmp2 - tmp1; 1281 tmp1 = tmp2; 1282 tmp2 = ti; 1283 } 1284 } 1285 1286 return jacobian; 1287 1288 } 1289 1290 @Override 1291 public double[] value(double[] variables) { 1292 1293 double[] f = new double[m]; 1294 1295 for (int j = 0; j < n; ++j) { 1296 double tmp1 = 1; 1297 double tmp2 = 2 * variables[j] - 1; 1298 double temp = 2 * tmp2; 1299 for (int i = 0; i < m; ++i) { 1300 f[i] += tmp2; 1301 double ti = temp * tmp2 - tmp1; 1302 tmp1 = tmp2; 1303 tmp2 = ti; 1304 } 1305 } 1306 1307 double dx = 1.0 / n; 1308 boolean iev = false; 1309 for (int i = 0; i < m; ++i) { 1310 f[i] *= dx; 1311 if (iev) { 1312 f[i] += 1.0 / (i * (i + 2)); 1313 } 1314 iev = ! iev; 1315 } 1316 1317 return f; 1318 1319 } 1320 1321 } 1322 1323 private static class BrownAlmostLinearFunction extends MinpackFunction { 1324 1325 private static final long serialVersionUID = 8239594490466964725L; 1326 1327 public BrownAlmostLinearFunction(int m, double factor, 1328 double theoreticalStartCost, 1329 double theoreticalMinCost, 1330 double[] theoreticalMinParams) { 1331 super(m, buildArray(m, factor), theoreticalMinCost, 1332 theoreticalMinParams); 1333 } 1334 1335 @Override 1336 public double[][] jacobian(double[] variables) { 1337 double[][] jacobian = new double[m][]; 1338 for (int i = 0; i < m; ++i) { 1339 jacobian[i] = new double[n]; 1340 } 1341 1342 double prod = 1; 1343 for (int j = 0; j < n; ++j) { 1344 prod *= variables[j]; 1345 for (int i = 0; i < n; ++i) { 1346 jacobian[i][j] = 1; 1347 } 1348 jacobian[j][j] = 2; 1349 } 1350 1351 for (int j = 0; j < n; ++j) { 1352 double temp = variables[j]; 1353 if (temp == 0) { 1354 temp = 1; 1355 prod = 1; 1356 for (int k = 0; k < n; ++k) { 1357 if (k != j) { 1358 prod *= variables[k]; 1359 } 1360 } 1361 } 1362 jacobian[n - 1][j] = prod / temp; 1363 } 1364 1365 return jacobian; 1366 1367 } 1368 1369 @Override 1370 public double[] value(double[] variables) { 1371 double[] f = new double[m]; 1372 double sum = -(n + 1); 1373 double prod = 1; 1374 for (int j = 0; j < n; ++j) { 1375 sum += variables[j]; 1376 prod *= variables[j]; 1377 } 1378 for (int i = 0; i < n; ++i) { 1379 f[i] = variables[i] + sum; 1380 } 1381 f[n - 1] = prod - 1; 1382 return f; 1383 } 1384 1385 } 1386 1387 private static class Osborne1Function extends MinpackFunction { 1388 1389 private static final long serialVersionUID = 4006743521149849494L; 1390 1391 public Osborne1Function(double[] startParams, 1392 double theoreticalStartCost, 1393 double theoreticalMinCost, 1394 double[] theoreticalMinParams) { 1395 super(33, startParams, theoreticalMinCost, 1396 theoreticalMinParams); 1397 } 1398 1399 @Override 1400 public double[][] jacobian(double[] variables) { 1401 double x2 = variables[1]; 1402 double x3 = variables[2]; 1403 double x4 = variables[3]; 1404 double x5 = variables[4]; 1405 double[][] jacobian = new double[m][]; 1406 for (int i = 0; i < m; ++i) { 1407 double temp = 10.0 * i; 1408 double tmp1 = Math.exp(-temp * x4); 1409 double tmp2 = Math.exp(-temp * x5); 1410 jacobian[i] = new double[] { 1411 -1, -tmp1, -tmp2, temp * x2 * tmp1, temp * x3 * tmp2 1412 }; 1413 } 1414 return jacobian; 1415 } 1416 1417 @Override 1418 public double[] value(double[] variables) { 1419 double x1 = variables[0]; 1420 double x2 = variables[1]; 1421 double x3 = variables[2]; 1422 double x4 = variables[3]; 1423 double x5 = variables[4]; 1424 double[] f = new double[m]; 1425 for (int i = 0; i < m; ++i) { 1426 double temp = 10.0 * i; 1427 double tmp1 = Math.exp(-temp * x4); 1428 double tmp2 = Math.exp(-temp * x5); 1429 f[i] = y[i] - (x1 + x2 * tmp1 + x3 * tmp2); 1430 } 1431 return f; 1432 } 1433 1434 private static final double[] y = { 1435 0.844, 0.908, 0.932, 0.936, 0.925, 0.908, 0.881, 0.850, 0.818, 0.784, 0.751, 1436 0.718, 0.685, 0.658, 0.628, 0.603, 0.580, 0.558, 0.538, 0.522, 0.506, 0.490, 1437 0.478, 0.467, 0.457, 0.448, 0.438, 0.431, 0.424, 0.420, 0.414, 0.411, 0.406 1438 }; 1439 1440 } 1441 1442 private static class Osborne2Function extends MinpackFunction { 1443 1444 private static final long serialVersionUID = -8418268780389858746L; 1445 1446 public Osborne2Function(double[] startParams, 1447 double theoreticalStartCost, 1448 double theoreticalMinCost, 1449 double[] theoreticalMinParams) { 1450 super(65, startParams, theoreticalMinCost, 1451 theoreticalMinParams); 1452 } 1453 1454 @Override 1455 public double[][] jacobian(double[] variables) { 1456 double x01 = variables[0]; 1457 double x02 = variables[1]; 1458 double x03 = variables[2]; 1459 double x04 = variables[3]; 1460 double x05 = variables[4]; 1461 double x06 = variables[5]; 1462 double x07 = variables[6]; 1463 double x08 = variables[7]; 1464 double x09 = variables[8]; 1465 double x10 = variables[9]; 1466 double x11 = variables[10]; 1467 double[][] jacobian = new double[m][]; 1468 for (int i = 0; i < m; ++i) { 1469 double temp = i / 10.0; 1470 double tmp1 = Math.exp(-x05 * temp); 1471 double tmp2 = Math.exp(-x06 * (temp - x09) * (temp - x09)); 1472 double tmp3 = Math.exp(-x07 * (temp - x10) * (temp - x10)); 1473 double tmp4 = Math.exp(-x08 * (temp - x11) * (temp - x11)); 1474 jacobian[i] = new double[] { 1475 -tmp1, 1476 -tmp2, 1477 -tmp3, 1478 -tmp4, 1479 temp * x01 * tmp1, 1480 x02 * (temp - x09) * (temp - x09) * tmp2, 1481 x03 * (temp - x10) * (temp - x10) * tmp3, 1482 x04 * (temp - x11) * (temp - x11) * tmp4, 1483 -2 * x02 * x06 * (temp - x09) * tmp2, 1484 -2 * x03 * x07 * (temp - x10) * tmp3, 1485 -2 * x04 * x08 * (temp - x11) * tmp4 1486 }; 1487 } 1488 return jacobian; 1489 } 1490 1491 @Override 1492 public double[] value(double[] variables) { 1493 double x01 = variables[0]; 1494 double x02 = variables[1]; 1495 double x03 = variables[2]; 1496 double x04 = variables[3]; 1497 double x05 = variables[4]; 1498 double x06 = variables[5]; 1499 double x07 = variables[6]; 1500 double x08 = variables[7]; 1501 double x09 = variables[8]; 1502 double x10 = variables[9]; 1503 double x11 = variables[10]; 1504 double[] f = new double[m]; 1505 for (int i = 0; i < m; ++i) { 1506 double temp = i / 10.0; 1507 double tmp1 = Math.exp(-x05 * temp); 1508 double tmp2 = Math.exp(-x06 * (temp - x09) * (temp - x09)); 1509 double tmp3 = Math.exp(-x07 * (temp - x10) * (temp - x10)); 1510 double tmp4 = Math.exp(-x08 * (temp - x11) * (temp - x11)); 1511 f[i] = y[i] - (x01 * tmp1 + x02 * tmp2 + x03 * tmp3 + x04 * tmp4); 1512 } 1513 return f; 1514 } 1515 1516 private static final double[] y = { 1517 1.366, 1.191, 1.112, 1.013, 0.991, 1518 0.885, 0.831, 0.847, 0.786, 0.725, 1519 0.746, 0.679, 0.608, 0.655, 0.616, 1520 0.606, 0.602, 0.626, 0.651, 0.724, 1521 0.649, 0.649, 0.694, 0.644, 0.624, 1522 0.661, 0.612, 0.558, 0.533, 0.495, 1523 0.500, 0.423, 0.395, 0.375, 0.372, 1524 0.391, 0.396, 0.405, 0.428, 0.429, 1525 0.523, 0.562, 0.607, 0.653, 0.672, 1526 0.708, 0.633, 0.668, 0.645, 0.632, 1527 0.591, 0.559, 0.597, 0.625, 0.739, 1528 0.710, 0.729, 0.720, 0.636, 0.581, 1529 0.428, 0.292, 0.162, 0.098, 0.054 1530 }; 1531 1532 } 1533 1534 public static Test suite() { 1535 return new TestSuite(MinpackTest.class); 1536 } 1537 1538 }