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