1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.math3.optimization.direct;
20
21 import org.apache.commons.math3.analysis.MultivariateFunction;
22 import org.apache.commons.math3.exception.MathIllegalStateException;
23 import org.apache.commons.math3.exception.NumberIsTooSmallException;
24 import org.apache.commons.math3.exception.OutOfRangeException;
25 import org.apache.commons.math3.exception.util.LocalizedFormats;
26 import org.apache.commons.math3.linear.Array2DRowRealMatrix;
27 import org.apache.commons.math3.linear.ArrayRealVector;
28 import org.apache.commons.math3.linear.RealVector;
29 import org.apache.commons.math3.optimization.GoalType;
30 import org.apache.commons.math3.optimization.PointValuePair;
31 import org.apache.commons.math3.optimization.MultivariateOptimizer;
32 import org.apache.commons.math3.util.FastMath;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 @Deprecated
53 public class BOBYQAOptimizer
54 extends BaseAbstractMultivariateSimpleBoundsOptimizer<MultivariateFunction>
55 implements MultivariateOptimizer {
56
57 public static final int MINIMUM_PROBLEM_DIMENSION = 2;
58
59 public static final double DEFAULT_INITIAL_RADIUS = 10.0;
60
61 public static final double DEFAULT_STOPPING_RADIUS = 1E-8;
62
63 private static final double ZERO = 0d;
64 private static final double ONE = 1d;
65 private static final double TWO = 2d;
66 private static final double TEN = 10d;
67 private static final double SIXTEEN = 16d;
68 private static final double TWO_HUNDRED_FIFTY = 250d;
69 private static final double MINUS_ONE = -ONE;
70 private static final double HALF = ONE / 2;
71 private static final double ONE_OVER_FOUR = ONE / 4;
72 private static final double ONE_OVER_EIGHT = ONE / 8;
73 private static final double ONE_OVER_TEN = ONE / 10;
74 private static final double ONE_OVER_A_THOUSAND = ONE / 1000;
75
76
77
78
79 private final int numberOfInterpolationPoints;
80
81
82
83 private double initialTrustRegionRadius;
84
85
86
87 private final double stoppingTrustRegionRadius;
88
89 private boolean isMinimize;
90
91
92
93
94
95 private ArrayRealVector currentBest;
96
97 private double[] boundDifference;
98
99
100
101 private int trustRegionCenterInterpolationPointIndex;
102
103
104
105
106
107 private Array2DRowRealMatrix bMatrix;
108
109
110
111
112
113
114 private Array2DRowRealMatrix zMatrix;
115
116
117
118
119 private Array2DRowRealMatrix interpolationPoints;
120
121
122
123
124
125 private ArrayRealVector originShift;
126
127
128
129
130 private ArrayRealVector fAtInterpolationPoints;
131
132
133
134
135 private ArrayRealVector trustRegionCenterOffset;
136
137
138
139
140
141 private ArrayRealVector gradientAtTrustRegionCenter;
142
143
144
145
146
147
148
149
150
151
152 private ArrayRealVector lowerDifference;
153
154
155
156
157
158
159
160
161
162
163 private ArrayRealVector upperDifference;
164
165
166
167
168 private ArrayRealVector modelSecondDerivativesParameters;
169
170
171
172
173
174
175
176
177
178
179 private ArrayRealVector newPoint;
180
181
182
183
184
185
186
187 private ArrayRealVector alternativeNewPoint;
188
189
190
191
192
193 private ArrayRealVector trialStepPoint;
194
195
196
197
198 private ArrayRealVector lagrangeValuesAtNewPoint;
199
200
201
202
203 private ArrayRealVector modelSecondDerivativesValues;
204
205
206
207
208
209
210
211 public BOBYQAOptimizer(int numberOfInterpolationPoints) {
212 this(numberOfInterpolationPoints,
213 DEFAULT_INITIAL_RADIUS,
214 DEFAULT_STOPPING_RADIUS);
215 }
216
217
218
219
220
221
222
223
224
225 public BOBYQAOptimizer(int numberOfInterpolationPoints,
226 double initialTrustRegionRadius,
227 double stoppingTrustRegionRadius) {
228 super(null);
229 this.numberOfInterpolationPoints = numberOfInterpolationPoints;
230 this.initialTrustRegionRadius = initialTrustRegionRadius;
231 this.stoppingTrustRegionRadius = stoppingTrustRegionRadius;
232 }
233
234
235 @Override
236 protected PointValuePair doOptimize() {
237 final double[] lowerBound = getLowerBound();
238 final double[] upperBound = getUpperBound();
239
240
241 setup(lowerBound, upperBound);
242
243 isMinimize = (getGoalType() == GoalType.MINIMIZE);
244 currentBest = new ArrayRealVector(getStartPoint());
245
246 final double value = bobyqa(lowerBound, upperBound);
247
248 return new PointValuePair(currentBest.getDataRef(),
249 isMinimize ? value : -value);
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 private double bobyqa(double[] lowerBound,
288 double[] upperBound) {
289 printMethod();
290
291 final int n = currentBest.getDimension();
292
293
294
295
296
297
298
299
300 for (int j = 0; j < n; j++) {
301 final double boundDiff = boundDifference[j];
302 lowerDifference.setEntry(j, lowerBound[j] - currentBest.getEntry(j));
303 upperDifference.setEntry(j, upperBound[j] - currentBest.getEntry(j));
304 if (lowerDifference.getEntry(j) >= -initialTrustRegionRadius) {
305 if (lowerDifference.getEntry(j) >= ZERO) {
306 currentBest.setEntry(j, lowerBound[j]);
307 lowerDifference.setEntry(j, ZERO);
308 upperDifference.setEntry(j, boundDiff);
309 } else {
310 currentBest.setEntry(j, lowerBound[j] + initialTrustRegionRadius);
311 lowerDifference.setEntry(j, -initialTrustRegionRadius);
312
313 final double deltaOne = upperBound[j] - currentBest.getEntry(j);
314 upperDifference.setEntry(j, FastMath.max(deltaOne, initialTrustRegionRadius));
315 }
316 } else if (upperDifference.getEntry(j) <= initialTrustRegionRadius) {
317 if (upperDifference.getEntry(j) <= ZERO) {
318 currentBest.setEntry(j, upperBound[j]);
319 lowerDifference.setEntry(j, -boundDiff);
320 upperDifference.setEntry(j, ZERO);
321 } else {
322 currentBest.setEntry(j, upperBound[j] - initialTrustRegionRadius);
323
324 final double deltaOne = lowerBound[j] - currentBest.getEntry(j);
325 final double deltaTwo = -initialTrustRegionRadius;
326 lowerDifference.setEntry(j, FastMath.min(deltaOne, deltaTwo));
327 upperDifference.setEntry(j, initialTrustRegionRadius);
328 }
329 }
330 }
331
332
333
334 return bobyqb(lowerBound, upperBound);
335 }
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376 private double bobyqb(double[] lowerBound,
377 double[] upperBound) {
378 printMethod();
379
380 final int n = currentBest.getDimension();
381 final int npt = numberOfInterpolationPoints;
382 final int np = n + 1;
383 final int nptm = npt - np;
384 final int nh = n * np / 2;
385
386 final ArrayRealVector work1 = new ArrayRealVector(n);
387 final ArrayRealVector work2 = new ArrayRealVector(npt);
388 final ArrayRealVector work3 = new ArrayRealVector(npt);
389
390 double cauchy = Double.NaN;
391 double alpha = Double.NaN;
392 double dsq = Double.NaN;
393 double crvmin = Double.NaN;
394
395
396
397
398
399
400
401
402
403
404
405
406
407 trustRegionCenterInterpolationPointIndex = 0;
408
409 prelim(lowerBound, upperBound);
410 double xoptsq = ZERO;
411 for (int i = 0; i < n; i++) {
412 trustRegionCenterOffset.setEntry(i, interpolationPoints.getEntry(trustRegionCenterInterpolationPointIndex, i));
413
414 final double deltaOne = trustRegionCenterOffset.getEntry(i);
415 xoptsq += deltaOne * deltaOne;
416 }
417 double fsave = fAtInterpolationPoints.getEntry(0);
418 final int kbase = 0;
419
420
421
422 int ntrits = 0;
423 int itest = 0;
424 int knew = 0;
425 int nfsav = getEvaluations();
426 double rho = initialTrustRegionRadius;
427 double delta = rho;
428 double diffa = ZERO;
429 double diffb = ZERO;
430 double diffc = ZERO;
431 double f = ZERO;
432 double beta = ZERO;
433 double adelt = ZERO;
434 double denom = ZERO;
435 double ratio = ZERO;
436 double dnorm = ZERO;
437 double scaden = ZERO;
438 double biglsq = ZERO;
439 double distsq = ZERO;
440
441
442
443
444 int state = 20;
445 for(;;) switch (state) {
446 case 20: {
447 printState(20);
448 if (trustRegionCenterInterpolationPointIndex != kbase) {
449 int ih = 0;
450 for (int j = 0; j < n; j++) {
451 for (int i = 0; i <= j; i++) {
452 if (i < j) {
453 gradientAtTrustRegionCenter.setEntry(j, gradientAtTrustRegionCenter.getEntry(j) + modelSecondDerivativesValues.getEntry(ih) * trustRegionCenterOffset.getEntry(i));
454 }
455 gradientAtTrustRegionCenter.setEntry(i, gradientAtTrustRegionCenter.getEntry(i) + modelSecondDerivativesValues.getEntry(ih) * trustRegionCenterOffset.getEntry(j));
456 ih++;
457 }
458 }
459 if (getEvaluations() > npt) {
460 for (int k = 0; k < npt; k++) {
461 double temp = ZERO;
462 for (int j = 0; j < n; j++) {
463 temp += interpolationPoints.getEntry(k, j) * trustRegionCenterOffset.getEntry(j);
464 }
465 temp *= modelSecondDerivativesParameters.getEntry(k);
466 for (int i = 0; i < n; i++) {
467 gradientAtTrustRegionCenter.setEntry(i, gradientAtTrustRegionCenter.getEntry(i) + temp * interpolationPoints.getEntry(k, i));
468 }
469 }
470
471 }
472 }
473
474
475
476
477
478
479
480
481 }
482 case 60: {
483 printState(60);
484 final ArrayRealVector gnew = new ArrayRealVector(n);
485 final ArrayRealVector xbdi = new ArrayRealVector(n);
486 final ArrayRealVector s = new ArrayRealVector(n);
487 final ArrayRealVector hs = new ArrayRealVector(n);
488 final ArrayRealVector hred = new ArrayRealVector(n);
489
490 final double[] dsqCrvmin = trsbox(delta, gnew, xbdi, s,
491 hs, hred);
492 dsq = dsqCrvmin[0];
493 crvmin = dsqCrvmin[1];
494
495
496 double deltaOne = delta;
497 double deltaTwo = FastMath.sqrt(dsq);
498 dnorm = FastMath.min(deltaOne, deltaTwo);
499 if (dnorm < HALF * rho) {
500 ntrits = -1;
501
502 deltaOne = TEN * rho;
503 distsq = deltaOne * deltaOne;
504 if (getEvaluations() <= nfsav + 2) {
505 state = 650; break;
506 }
507
508
509
510
511
512
513
514
515 deltaOne = FastMath.max(diffa, diffb);
516 final double errbig = FastMath.max(deltaOne, diffc);
517 final double frhosq = rho * ONE_OVER_EIGHT * rho;
518 if (crvmin > ZERO &&
519 errbig > frhosq * crvmin) {
520 state = 650; break;
521 }
522 final double bdtol = errbig / rho;
523 for (int j = 0; j < n; j++) {
524 double bdtest = bdtol;
525 if (newPoint.getEntry(j) == lowerDifference.getEntry(j)) {
526 bdtest = work1.getEntry(j);
527 }
528 if (newPoint.getEntry(j) == upperDifference.getEntry(j)) {
529 bdtest = -work1.getEntry(j);
530 }
531 if (bdtest < bdtol) {
532 double curv = modelSecondDerivativesValues.getEntry((j + j * j) / 2);
533 for (int k = 0; k < npt; k++) {
534
535 final double d1 = interpolationPoints.getEntry(k, j);
536 curv += modelSecondDerivativesParameters.getEntry(k) * (d1 * d1);
537 }
538 bdtest += HALF * curv * rho;
539 if (bdtest < bdtol) {
540 state = 650; break;
541 }
542
543 }
544 }
545 state = 680; break;
546 }
547 ++ntrits;
548
549
550
551
552
553
554
555 }
556 case 90: {
557 printState(90);
558 if (dsq <= xoptsq * ONE_OVER_A_THOUSAND) {
559 final double fracsq = xoptsq * ONE_OVER_FOUR;
560 double sumpq = ZERO;
561
562
563 for (int k = 0; k < npt; k++) {
564 sumpq += modelSecondDerivativesParameters.getEntry(k);
565 double sum = -HALF * xoptsq;
566 for (int i = 0; i < n; i++) {
567 sum += interpolationPoints.getEntry(k, i) * trustRegionCenterOffset.getEntry(i);
568 }
569
570 work2.setEntry(k, sum);
571 final double temp = fracsq - HALF * sum;
572 for (int i = 0; i < n; i++) {
573 work1.setEntry(i, bMatrix.getEntry(k, i));
574 lagrangeValuesAtNewPoint.setEntry(i, sum * interpolationPoints.getEntry(k, i) + temp * trustRegionCenterOffset.getEntry(i));
575 final int ip = npt + i;
576 for (int j = 0; j <= i; j++) {
577 bMatrix.setEntry(ip, j,
578 bMatrix.getEntry(ip, j)
579 + work1.getEntry(i) * lagrangeValuesAtNewPoint.getEntry(j)
580 + lagrangeValuesAtNewPoint.getEntry(i) * work1.getEntry(j));
581 }
582 }
583 }
584
585
586
587 for (int m = 0; m < nptm; m++) {
588 double sumz = ZERO;
589 double sumw = ZERO;
590 for (int k = 0; k < npt; k++) {
591 sumz += zMatrix.getEntry(k, m);
592 lagrangeValuesAtNewPoint.setEntry(k, work2.getEntry(k) * zMatrix.getEntry(k, m));
593 sumw += lagrangeValuesAtNewPoint.getEntry(k);
594 }
595 for (int j = 0; j < n; j++) {
596 double sum = (fracsq * sumz - HALF * sumw) * trustRegionCenterOffset.getEntry(j);
597 for (int k = 0; k < npt; k++) {
598 sum += lagrangeValuesAtNewPoint.getEntry(k) * interpolationPoints.getEntry(k, j);
599 }
600 work1.setEntry(j, sum);
601 for (int k = 0; k < npt; k++) {
602 bMatrix.setEntry(k, j,
603 bMatrix.getEntry(k, j)
604 + sum * zMatrix.getEntry(k, m));
605 }
606 }
607 for (int i = 0; i < n; i++) {
608 final int ip = i + npt;
609 final double temp = work1.getEntry(i);
610 for (int j = 0; j <= i; j++) {
611 bMatrix.setEntry(ip, j,
612 bMatrix.getEntry(ip, j)
613 + temp * work1.getEntry(j));
614 }
615 }
616 }
617
618
619
620
621 int ih = 0;
622 for (int j = 0; j < n; j++) {
623 work1.setEntry(j, -HALF * sumpq * trustRegionCenterOffset.getEntry(j));
624 for (int k = 0; k < npt; k++) {
625 work1.setEntry(j, work1.getEntry(j) + modelSecondDerivativesParameters.getEntry(k) * interpolationPoints.getEntry(k, j));
626 interpolationPoints.setEntry(k, j, interpolationPoints.getEntry(k, j) - trustRegionCenterOffset.getEntry(j));
627 }
628 for (int i = 0; i <= j; i++) {
629 modelSecondDerivativesValues.setEntry(ih,
630 modelSecondDerivativesValues.getEntry(ih)
631 + work1.getEntry(i) * trustRegionCenterOffset.getEntry(j)
632 + trustRegionCenterOffset.getEntry(i) * work1.getEntry(j));
633 bMatrix.setEntry(npt + i, j, bMatrix.getEntry(npt + j, i));
634 ih++;
635 }
636 }
637 for (int i = 0; i < n; i++) {
638 originShift.setEntry(i, originShift.getEntry(i) + trustRegionCenterOffset.getEntry(i));
639 newPoint.setEntry(i, newPoint.getEntry(i) - trustRegionCenterOffset.getEntry(i));
640 lowerDifference.setEntry(i, lowerDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i));
641 upperDifference.setEntry(i, upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i));
642 trustRegionCenterOffset.setEntry(i, ZERO);
643 }
644 xoptsq = ZERO;
645 }
646 if (ntrits == 0) {
647 state = 210; break;
648 }
649 state = 230; break;
650
651
652
653
654
655
656
657
658
659
660 }
661 case 210: {
662 printState(210);
663
664
665
666
667
668
669
670
671
672
673
674 final double[] alphaCauchy = altmov(knew, adelt);
675 alpha = alphaCauchy[0];
676 cauchy = alphaCauchy[1];
677
678 for (int i = 0; i < n; i++) {
679 trialStepPoint.setEntry(i, newPoint.getEntry(i) - trustRegionCenterOffset.getEntry(i));
680 }
681
682
683
684
685
686 }
687 case 230: {
688 printState(230);
689 for (int k = 0; k < npt; k++) {
690 double suma = ZERO;
691 double sumb = ZERO;
692 double sum = ZERO;
693 for (int j = 0; j < n; j++) {
694 suma += interpolationPoints.getEntry(k, j) * trialStepPoint.getEntry(j);
695 sumb += interpolationPoints.getEntry(k, j) * trustRegionCenterOffset.getEntry(j);
696 sum += bMatrix.getEntry(k, j) * trialStepPoint.getEntry(j);
697 }
698 work3.setEntry(k, suma * (HALF * suma + sumb));
699 lagrangeValuesAtNewPoint.setEntry(k, sum);
700 work2.setEntry(k, suma);
701 }
702 beta = ZERO;
703 for (int m = 0; m < nptm; m++) {
704 double sum = ZERO;
705 for (int k = 0; k < npt; k++) {
706 sum += zMatrix.getEntry(k, m) * work3.getEntry(k);
707 }
708 beta -= sum * sum;
709 for (int k = 0; k < npt; k++) {
710 lagrangeValuesAtNewPoint.setEntry(k, lagrangeValuesAtNewPoint.getEntry(k) + sum * zMatrix.getEntry(k, m));
711 }
712 }
713 dsq = ZERO;
714 double bsum = ZERO;
715 double dx = ZERO;
716 for (int j = 0; j < n; j++) {
717
718 final double d1 = trialStepPoint.getEntry(j);
719 dsq += d1 * d1;
720 double sum = ZERO;
721 for (int k = 0; k < npt; k++) {
722 sum += work3.getEntry(k) * bMatrix.getEntry(k, j);
723 }
724 bsum += sum * trialStepPoint.getEntry(j);
725 final int jp = npt + j;
726 for (int i = 0; i < n; i++) {
727 sum += bMatrix.getEntry(jp, i) * trialStepPoint.getEntry(i);
728 }
729 lagrangeValuesAtNewPoint.setEntry(jp, sum);
730 bsum += sum * trialStepPoint.getEntry(j);
731 dx += trialStepPoint.getEntry(j) * trustRegionCenterOffset.getEntry(j);
732 }
733
734 beta = dx * dx + dsq * (xoptsq + dx + dx + HALF * dsq) + beta - bsum;
735
736
737
738 lagrangeValuesAtNewPoint.setEntry(trustRegionCenterInterpolationPointIndex,
739 lagrangeValuesAtNewPoint.getEntry(trustRegionCenterInterpolationPointIndex) + ONE);
740
741
742
743
744
745 if (ntrits == 0) {
746
747 final double d1 = lagrangeValuesAtNewPoint.getEntry(knew);
748 denom = d1 * d1 + alpha * beta;
749 if (denom < cauchy && cauchy > ZERO) {
750 for (int i = 0; i < n; i++) {
751 newPoint.setEntry(i, alternativeNewPoint.getEntry(i));
752 trialStepPoint.setEntry(i, newPoint.getEntry(i) - trustRegionCenterOffset.getEntry(i));
753 }
754 cauchy = ZERO;
755 state = 230; break;
756 }
757
758
759
760
761
762
763 } else {
764 final double delsq = delta * delta;
765 scaden = ZERO;
766 biglsq = ZERO;
767 knew = 0;
768 for (int k = 0; k < npt; k++) {
769 if (k == trustRegionCenterInterpolationPointIndex) {
770 continue;
771 }
772 double hdiag = ZERO;
773 for (int m = 0; m < nptm; m++) {
774
775 final double d1 = zMatrix.getEntry(k, m);
776 hdiag += d1 * d1;
777 }
778
779 final double d2 = lagrangeValuesAtNewPoint.getEntry(k);
780 final double den = beta * hdiag + d2 * d2;
781 distsq = ZERO;
782 for (int j = 0; j < n; j++) {
783
784 final double d3 = interpolationPoints.getEntry(k, j) - trustRegionCenterOffset.getEntry(j);
785 distsq += d3 * d3;
786 }
787
788
789 final double d4 = distsq / delsq;
790 final double temp = FastMath.max(ONE, d4 * d4);
791 if (temp * den > scaden) {
792 scaden = temp * den;
793 knew = k;
794 denom = den;
795 }
796
797
798 final double d5 = lagrangeValuesAtNewPoint.getEntry(k);
799 biglsq = FastMath.max(biglsq, temp * (d5 * d5));
800 }
801 }
802
803
804
805
806
807
808
809 }
810 case 360: {
811 printState(360);
812 for (int i = 0; i < n; i++) {
813
814
815 final double d3 = lowerBound[i];
816 final double d4 = originShift.getEntry(i) + newPoint.getEntry(i);
817 final double d1 = FastMath.max(d3, d4);
818 final double d2 = upperBound[i];
819 currentBest.setEntry(i, FastMath.min(d1, d2));
820 if (newPoint.getEntry(i) == lowerDifference.getEntry(i)) {
821 currentBest.setEntry(i, lowerBound[i]);
822 }
823 if (newPoint.getEntry(i) == upperDifference.getEntry(i)) {
824 currentBest.setEntry(i, upperBound[i]);
825 }
826 }
827
828 f = computeObjectiveValue(currentBest.toArray());
829
830 if (!isMinimize)
831 f = -f;
832 if (ntrits == -1) {
833 fsave = f;
834 state = 720; break;
835 }
836
837
838
839
840 final double fopt = fAtInterpolationPoints.getEntry(trustRegionCenterInterpolationPointIndex);
841 double vquad = ZERO;
842 int ih = 0;
843 for (int j = 0; j < n; j++) {
844 vquad += trialStepPoint.getEntry(j) * gradientAtTrustRegionCenter.getEntry(j);
845 for (int i = 0; i <= j; i++) {
846 double temp = trialStepPoint.getEntry(i) * trialStepPoint.getEntry(j);
847 if (i == j) {
848 temp *= HALF;
849 }
850 vquad += modelSecondDerivativesValues.getEntry(ih) * temp;
851 ih++;
852 }
853 }
854 for (int k = 0; k < npt; k++) {
855
856 final double d1 = work2.getEntry(k);
857 final double d2 = d1 * d1;
858 vquad += HALF * modelSecondDerivativesParameters.getEntry(k) * d2;
859 }
860 final double diff = f - fopt - vquad;
861 diffc = diffb;
862 diffb = diffa;
863 diffa = FastMath.abs(diff);
864 if (dnorm > rho) {
865 nfsav = getEvaluations();
866 }
867
868
869
870 if (ntrits > 0) {
871 if (vquad >= ZERO) {
872 throw new MathIllegalStateException(LocalizedFormats.TRUST_REGION_STEP_FAILED, vquad);
873 }
874 ratio = (f - fopt) / vquad;
875 final double hDelta = HALF * delta;
876 if (ratio <= ONE_OVER_TEN) {
877
878 delta = FastMath.min(hDelta, dnorm);
879 } else if (ratio <= .7) {
880
881 delta = FastMath.max(hDelta, dnorm);
882 } else {
883
884 delta = FastMath.max(hDelta, 2 * dnorm);
885 }
886 if (delta <= rho * 1.5) {
887 delta = rho;
888 }
889
890
891
892 if (f < fopt) {
893 final int ksav = knew;
894 final double densav = denom;
895 final double delsq = delta * delta;
896 scaden = ZERO;
897 biglsq = ZERO;
898 knew = 0;
899 for (int k = 0; k < npt; k++) {
900 double hdiag = ZERO;
901 for (int m = 0; m < nptm; m++) {
902
903 final double d1 = zMatrix.getEntry(k, m);
904 hdiag += d1 * d1;
905 }
906
907 final double d1 = lagrangeValuesAtNewPoint.getEntry(k);
908 final double den = beta * hdiag + d1 * d1;
909 distsq = ZERO;
910 for (int j = 0; j < n; j++) {
911
912 final double d2 = interpolationPoints.getEntry(k, j) - newPoint.getEntry(j);
913 distsq += d2 * d2;
914 }
915
916
917 final double d3 = distsq / delsq;
918 final double temp = FastMath.max(ONE, d3 * d3);
919 if (temp * den > scaden) {
920 scaden = temp * den;
921 knew = k;
922 denom = den;
923 }
924
925
926 final double d4 = lagrangeValuesAtNewPoint.getEntry(k);
927 final double d5 = temp * (d4 * d4);
928 biglsq = FastMath.max(biglsq, d5);
929 }
930 if (scaden <= HALF * biglsq) {
931 knew = ksav;
932 denom = densav;
933 }
934 }
935 }
936
937
938
939
940 update(beta, denom, knew);
941
942 ih = 0;
943 final double pqold = modelSecondDerivativesParameters.getEntry(knew);
944 modelSecondDerivativesParameters.setEntry(knew, ZERO);
945 for (int i = 0; i < n; i++) {
946 final double temp = pqold * interpolationPoints.getEntry(knew, i);
947 for (int j = 0; j <= i; j++) {
948 modelSecondDerivativesValues.setEntry(ih, modelSecondDerivativesValues.getEntry(ih) + temp * interpolationPoints.getEntry(knew, j));
949 ih++;
950 }
951 }
952 for (int m = 0; m < nptm; m++) {
953 final double temp = diff * zMatrix.getEntry(knew, m);
954 for (int k = 0; k < npt; k++) {
955 modelSecondDerivativesParameters.setEntry(k, modelSecondDerivativesParameters.getEntry(k) + temp * zMatrix.getEntry(k, m));
956 }
957 }
958
959
960
961
962 fAtInterpolationPoints.setEntry(knew, f);
963 for (int i = 0; i < n; i++) {
964 interpolationPoints.setEntry(knew, i, newPoint.getEntry(i));
965 work1.setEntry(i, bMatrix.getEntry(knew, i));
966 }
967 for (int k = 0; k < npt; k++) {
968 double suma = ZERO;
969 for (int m = 0; m < nptm; m++) {
970 suma += zMatrix.getEntry(knew, m) * zMatrix.getEntry(k, m);
971 }
972 double sumb = ZERO;
973 for (int j = 0; j < n; j++) {
974 sumb += interpolationPoints.getEntry(k, j) * trustRegionCenterOffset.getEntry(j);
975 }
976 final double temp = suma * sumb;
977 for (int i = 0; i < n; i++) {
978 work1.setEntry(i, work1.getEntry(i) + temp * interpolationPoints.getEntry(k, i));
979 }
980 }
981 for (int i = 0; i < n; i++) {
982 gradientAtTrustRegionCenter.setEntry(i, gradientAtTrustRegionCenter.getEntry(i) + diff * work1.getEntry(i));
983 }
984
985
986
987 if (f < fopt) {
988 trustRegionCenterInterpolationPointIndex = knew;
989 xoptsq = ZERO;
990 ih = 0;
991 for (int j = 0; j < n; j++) {
992 trustRegionCenterOffset.setEntry(j, newPoint.getEntry(j));
993
994 final double d1 = trustRegionCenterOffset.getEntry(j);
995 xoptsq += d1 * d1;
996 for (int i = 0; i <= j; i++) {
997 if (i < j) {
998 gradientAtTrustRegionCenter.setEntry(j, gradientAtTrustRegionCenter.getEntry(j) + modelSecondDerivativesValues.getEntry(ih) * trialStepPoint.getEntry(i));
999 }
1000 gradientAtTrustRegionCenter.setEntry(i, gradientAtTrustRegionCenter.getEntry(i) + modelSecondDerivativesValues.getEntry(ih) * trialStepPoint.getEntry(j));
1001 ih++;
1002 }
1003 }
1004 for (int k = 0; k < npt; k++) {
1005 double temp = ZERO;
1006 for (int j = 0; j < n; j++) {
1007 temp += interpolationPoints.getEntry(k, j) * trialStepPoint.getEntry(j);
1008 }
1009 temp *= modelSecondDerivativesParameters.getEntry(k);
1010 for (int i = 0; i < n; i++) {
1011 gradientAtTrustRegionCenter.setEntry(i, gradientAtTrustRegionCenter.getEntry(i) + temp * interpolationPoints.getEntry(k, i));
1012 }
1013 }
1014 }
1015
1016
1017
1018
1019
1020 if (ntrits > 0) {
1021 for (int k = 0; k < npt; k++) {
1022 lagrangeValuesAtNewPoint.setEntry(k, fAtInterpolationPoints.getEntry(k) - fAtInterpolationPoints.getEntry(trustRegionCenterInterpolationPointIndex));
1023 work3.setEntry(k, ZERO);
1024 }
1025 for (int j = 0; j < nptm; j++) {
1026 double sum = ZERO;
1027 for (int k = 0; k < npt; k++) {
1028 sum += zMatrix.getEntry(k, j) * lagrangeValuesAtNewPoint.getEntry(k);
1029 }
1030 for (int k = 0; k < npt; k++) {
1031 work3.setEntry(k, work3.getEntry(k) + sum * zMatrix.getEntry(k, j));
1032 }
1033 }
1034 for (int k = 0; k < npt; k++) {
1035 double sum = ZERO;
1036 for (int j = 0; j < n; j++) {
1037 sum += interpolationPoints.getEntry(k, j) * trustRegionCenterOffset.getEntry(j);
1038 }
1039 work2.setEntry(k, work3.getEntry(k));
1040 work3.setEntry(k, sum * work3.getEntry(k));
1041 }
1042 double gqsq = ZERO;
1043 double gisq = ZERO;
1044 for (int i = 0; i < n; i++) {
1045 double sum = ZERO;
1046 for (int k = 0; k < npt; k++) {
1047 sum += bMatrix.getEntry(k, i) *
1048 lagrangeValuesAtNewPoint.getEntry(k) + interpolationPoints.getEntry(k, i) * work3.getEntry(k);
1049 }
1050 if (trustRegionCenterOffset.getEntry(i) == lowerDifference.getEntry(i)) {
1051
1052
1053 final double d1 = FastMath.min(ZERO, gradientAtTrustRegionCenter.getEntry(i));
1054 gqsq += d1 * d1;
1055
1056 final double d2 = FastMath.min(ZERO, sum);
1057 gisq += d2 * d2;
1058 } else if (trustRegionCenterOffset.getEntry(i) == upperDifference.getEntry(i)) {
1059
1060
1061 final double d1 = FastMath.max(ZERO, gradientAtTrustRegionCenter.getEntry(i));
1062 gqsq += d1 * d1;
1063
1064 final double d2 = FastMath.max(ZERO, sum);
1065 gisq += d2 * d2;
1066 } else {
1067
1068 final double d1 = gradientAtTrustRegionCenter.getEntry(i);
1069 gqsq += d1 * d1;
1070 gisq += sum * sum;
1071 }
1072 lagrangeValuesAtNewPoint.setEntry(npt + i, sum);
1073 }
1074
1075
1076
1077
1078 ++itest;
1079 if (gqsq < TEN * gisq) {
1080 itest = 0;
1081 }
1082 if (itest >= 3) {
1083 for (int i = 0, max = FastMath.max(npt, nh); i < max; i++) {
1084 if (i < n) {
1085 gradientAtTrustRegionCenter.setEntry(i, lagrangeValuesAtNewPoint.getEntry(npt + i));
1086 }
1087 if (i < npt) {
1088 modelSecondDerivativesParameters.setEntry(i, work2.getEntry(i));
1089 }
1090 if (i < nh) {
1091 modelSecondDerivativesValues.setEntry(i, ZERO);
1092 }
1093 itest = 0;
1094 }
1095 }
1096 }
1097
1098
1099
1100
1101
1102 if (ntrits == 0) {
1103 state = 60; break;
1104 }
1105 if (f <= fopt + ONE_OVER_TEN * vquad) {
1106 state = 60; break;
1107 }
1108
1109
1110
1111
1112
1113
1114 final double d1 = TWO * delta;
1115
1116 final double d2 = TEN * rho;
1117 distsq = FastMath.max(d1 * d1, d2 * d2);
1118 }
1119 case 650: {
1120 printState(650);
1121 knew = -1;
1122 for (int k = 0; k < npt; k++) {
1123 double sum = ZERO;
1124 for (int j = 0; j < n; j++) {
1125
1126 final double d1 = interpolationPoints.getEntry(k, j) - trustRegionCenterOffset.getEntry(j);
1127 sum += d1 * d1;
1128 }
1129 if (sum > distsq) {
1130 knew = k;
1131 distsq = sum;
1132 }
1133 }
1134
1135
1136
1137
1138
1139
1140
1141 if (knew >= 0) {
1142 final double dist = FastMath.sqrt(distsq);
1143 if (ntrits == -1) {
1144
1145 delta = FastMath.min(ONE_OVER_TEN * delta, HALF * dist);
1146 if (delta <= rho * 1.5) {
1147 delta = rho;
1148 }
1149 }
1150 ntrits = 0;
1151
1152
1153 final double d1 = FastMath.min(ONE_OVER_TEN * dist, delta);
1154 adelt = FastMath.max(d1, rho);
1155 dsq = adelt * adelt;
1156 state = 90; break;
1157 }
1158 if (ntrits == -1) {
1159 state = 680; break;
1160 }
1161 if (ratio > ZERO) {
1162 state = 60; break;
1163 }
1164 if (FastMath.max(delta, dnorm) > rho) {
1165 state = 60; break;
1166 }
1167
1168
1169
1170 }
1171 case 680: {
1172 printState(680);
1173 if (rho > stoppingTrustRegionRadius) {
1174 delta = HALF * rho;
1175 ratio = rho / stoppingTrustRegionRadius;
1176 if (ratio <= SIXTEEN) {
1177 rho = stoppingTrustRegionRadius;
1178 } else if (ratio <= TWO_HUNDRED_FIFTY) {
1179 rho = FastMath.sqrt(ratio) * stoppingTrustRegionRadius;
1180 } else {
1181 rho *= ONE_OVER_TEN;
1182 }
1183 delta = FastMath.max(delta, rho);
1184 ntrits = 0;
1185 nfsav = getEvaluations();
1186 state = 60; break;
1187 }
1188
1189
1190
1191
1192 if (ntrits == -1) {
1193 state = 360; break;
1194 }
1195 }
1196 case 720: {
1197 printState(720);
1198 if (fAtInterpolationPoints.getEntry(trustRegionCenterInterpolationPointIndex) <= fsave) {
1199 for (int i = 0; i < n; i++) {
1200
1201
1202 final double d3 = lowerBound[i];
1203 final double d4 = originShift.getEntry(i) + trustRegionCenterOffset.getEntry(i);
1204 final double d1 = FastMath.max(d3, d4);
1205 final double d2 = upperBound[i];
1206 currentBest.setEntry(i, FastMath.min(d1, d2));
1207 if (trustRegionCenterOffset.getEntry(i) == lowerDifference.getEntry(i)) {
1208 currentBest.setEntry(i, lowerBound[i]);
1209 }
1210 if (trustRegionCenterOffset.getEntry(i) == upperDifference.getEntry(i)) {
1211 currentBest.setEntry(i, upperBound[i]);
1212 }
1213 }
1214 f = fAtInterpolationPoints.getEntry(trustRegionCenterInterpolationPointIndex);
1215 }
1216 return f;
1217 }
1218 default: {
1219 throw new MathIllegalStateException(LocalizedFormats.SIMPLE_MESSAGE, "bobyqb");
1220 }}
1221 }
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258 private double[] altmov(
1259 int knew,
1260 double adelt
1261 ) {
1262 printMethod();
1263
1264 final int n = currentBest.getDimension();
1265 final int npt = numberOfInterpolationPoints;
1266
1267 final ArrayRealVector glag = new ArrayRealVector(n);
1268 final ArrayRealVector hcol = new ArrayRealVector(npt);
1269
1270 final ArrayRealVector work1 = new ArrayRealVector(n);
1271 final ArrayRealVector work2 = new ArrayRealVector(n);
1272
1273 for (int k = 0; k < npt; k++) {
1274 hcol.setEntry(k, ZERO);
1275 }
1276 for (int j = 0, max = npt - n - 1; j < max; j++) {
1277 final double tmp = zMatrix.getEntry(knew, j);
1278 for (int k = 0; k < npt; k++) {
1279 hcol.setEntry(k, hcol.getEntry(k) + tmp * zMatrix.getEntry(k, j));
1280 }
1281 }
1282 final double alpha = hcol.getEntry(knew);
1283 final double ha = HALF * alpha;
1284
1285
1286
1287 for (int i = 0; i < n; i++) {
1288 glag.setEntry(i, bMatrix.getEntry(knew, i));
1289 }
1290 for (int k = 0; k < npt; k++) {
1291 double tmp = ZERO;
1292 for (int j = 0; j < n; j++) {
1293 tmp += interpolationPoints.getEntry(k, j) * trustRegionCenterOffset.getEntry(j);
1294 }
1295 tmp *= hcol.getEntry(k);
1296 for (int i = 0; i < n; i++) {
1297 glag.setEntry(i, glag.getEntry(i) + tmp * interpolationPoints.getEntry(k, i));
1298 }
1299 }
1300
1301
1302
1303
1304
1305
1306
1307 double presav = ZERO;
1308 double step = Double.NaN;
1309 int ksav = 0;
1310 int ibdsav = 0;
1311 double stpsav = 0;
1312 for (int k = 0; k < npt; k++) {
1313 if (k == trustRegionCenterInterpolationPointIndex) {
1314 continue;
1315 }
1316 double dderiv = ZERO;
1317 double distsq = ZERO;
1318 for (int i = 0; i < n; i++) {
1319 final double tmp = interpolationPoints.getEntry(k, i) - trustRegionCenterOffset.getEntry(i);
1320 dderiv += glag.getEntry(i) * tmp;
1321 distsq += tmp * tmp;
1322 }
1323 double subd = adelt / FastMath.sqrt(distsq);
1324 double slbd = -subd;
1325 int ilbd = 0;
1326 int iubd = 0;
1327 final double sumin = FastMath.min(ONE, subd);
1328
1329
1330
1331 for (int i = 0; i < n; i++) {
1332 final double tmp = interpolationPoints.getEntry(k, i) - trustRegionCenterOffset.getEntry(i);
1333 if (tmp > ZERO) {
1334 if (slbd * tmp < lowerDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) {
1335 slbd = (lowerDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) / tmp;
1336 ilbd = -i - 1;
1337 }
1338 if (subd * tmp > upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) {
1339
1340 subd = FastMath.max(sumin,
1341 (upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) / tmp);
1342 iubd = i + 1;
1343 }
1344 } else if (tmp < ZERO) {
1345 if (slbd * tmp > upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) {
1346 slbd = (upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) / tmp;
1347 ilbd = i + 1;
1348 }
1349 if (subd * tmp < lowerDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) {
1350
1351 subd = FastMath.max(sumin,
1352 (lowerDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i)) / tmp);
1353 iubd = -i - 1;
1354 }
1355 }
1356 }
1357
1358
1359
1360
1361 step = slbd;
1362 int isbd = ilbd;
1363 double vlag = Double.NaN;
1364 if (k == knew) {
1365 final double diff = dderiv - ONE;
1366 vlag = slbd * (dderiv - slbd * diff);
1367 final double d1 = subd * (dderiv - subd * diff);
1368 if (FastMath.abs(d1) > FastMath.abs(vlag)) {
1369 step = subd;
1370 vlag = d1;
1371 isbd = iubd;
1372 }
1373 final double d2 = HALF * dderiv;
1374 final double d3 = d2 - diff * slbd;
1375 final double d4 = d2 - diff * subd;
1376 if (d3 * d4 < ZERO) {
1377 final double d5 = d2 * d2 / diff;
1378 if (FastMath.abs(d5) > FastMath.abs(vlag)) {
1379 step = d2 / diff;
1380 vlag = d5;
1381 isbd = 0;
1382 }
1383 }
1384
1385
1386
1387 } else {
1388 vlag = slbd * (ONE - slbd);
1389 final double tmp = subd * (ONE - subd);
1390 if (FastMath.abs(tmp) > FastMath.abs(vlag)) {
1391 step = subd;
1392 vlag = tmp;
1393 isbd = iubd;
1394 }
1395 if (subd > HALF && FastMath.abs(vlag) < ONE_OVER_FOUR) {
1396 step = HALF;
1397 vlag = ONE_OVER_FOUR;
1398 isbd = 0;
1399 }
1400 vlag *= dderiv;
1401 }
1402
1403
1404
1405 final double tmp = step * (ONE - step) * distsq;
1406 final double predsq = vlag * vlag * (vlag * vlag + ha * tmp * tmp);
1407 if (predsq > presav) {
1408 presav = predsq;
1409 ksav = k;
1410 stpsav = step;
1411 ibdsav = isbd;
1412 }
1413 }
1414
1415
1416
1417 for (int i = 0; i < n; i++) {
1418 final double tmp = trustRegionCenterOffset.getEntry(i) + stpsav * (interpolationPoints.getEntry(ksav, i) - trustRegionCenterOffset.getEntry(i));
1419 newPoint.setEntry(i, FastMath.max(lowerDifference.getEntry(i),
1420 FastMath.min(upperDifference.getEntry(i), tmp)));
1421 }
1422 if (ibdsav < 0) {
1423 newPoint.setEntry(-ibdsav - 1, lowerDifference.getEntry(-ibdsav - 1));
1424 }
1425 if (ibdsav > 0) {
1426 newPoint.setEntry(ibdsav - 1, upperDifference.getEntry(ibdsav - 1));
1427 }
1428
1429
1430
1431
1432
1433 final double bigstp = adelt + adelt;
1434 int iflag = 0;
1435 double cauchy = Double.NaN;
1436 double csave = ZERO;
1437 while (true) {
1438 double wfixsq = ZERO;
1439 double ggfree = ZERO;
1440 for (int i = 0; i < n; i++) {
1441 final double glagValue = glag.getEntry(i);
1442 work1.setEntry(i, ZERO);
1443 if (FastMath.min(trustRegionCenterOffset.getEntry(i) - lowerDifference.getEntry(i), glagValue) > ZERO ||
1444 FastMath.max(trustRegionCenterOffset.getEntry(i) - upperDifference.getEntry(i), glagValue) < ZERO) {
1445 work1.setEntry(i, bigstp);
1446
1447 ggfree += glagValue * glagValue;
1448 }
1449 }
1450 if (ggfree == ZERO) {
1451 return new double[] { alpha, ZERO };
1452 }
1453
1454
1455 final double tmp1 = adelt * adelt - wfixsq;
1456 if (tmp1 > ZERO) {
1457 step = FastMath.sqrt(tmp1 / ggfree);
1458 ggfree = ZERO;
1459 for (int i = 0; i < n; i++) {
1460 if (work1.getEntry(i) == bigstp) {
1461 final double tmp2 = trustRegionCenterOffset.getEntry(i) - step * glag.getEntry(i);
1462 if (tmp2 <= lowerDifference.getEntry(i)) {
1463 work1.setEntry(i, lowerDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i));
1464
1465 final double d1 = work1.getEntry(i);
1466 wfixsq += d1 * d1;
1467 } else if (tmp2 >= upperDifference.getEntry(i)) {
1468 work1.setEntry(i, upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i));
1469
1470 final double d1 = work1.getEntry(i);
1471 wfixsq += d1 * d1;
1472 } else {
1473
1474 final double d1 = glag.getEntry(i);
1475 ggfree += d1 * d1;
1476 }
1477 }
1478 }
1479 }
1480
1481
1482
1483
1484 double gw = ZERO;
1485 for (int i = 0; i < n; i++) {
1486 final double glagValue = glag.getEntry(i);
1487 if (work1.getEntry(i) == bigstp) {
1488 work1.setEntry(i, -step * glagValue);
1489 final double min = FastMath.min(upperDifference.getEntry(i),
1490 trustRegionCenterOffset.getEntry(i) + work1.getEntry(i));
1491 alternativeNewPoint.setEntry(i, FastMath.max(lowerDifference.getEntry(i), min));
1492 } else if (work1.getEntry(i) == ZERO) {
1493 alternativeNewPoint.setEntry(i, trustRegionCenterOffset.getEntry(i));
1494 } else if (glagValue > ZERO) {
1495 alternativeNewPoint.setEntry(i, lowerDifference.getEntry(i));
1496 } else {
1497 alternativeNewPoint.setEntry(i, upperDifference.getEntry(i));
1498 }
1499 gw += glagValue * work1.getEntry(i);
1500 }
1501
1502
1503
1504
1505
1506
1507 double curv = ZERO;
1508 for (int k = 0; k < npt; k++) {
1509 double tmp = ZERO;
1510 for (int j = 0; j < n; j++) {
1511 tmp += interpolationPoints.getEntry(k, j) * work1.getEntry(j);
1512 }
1513 curv += hcol.getEntry(k) * tmp * tmp;
1514 }
1515 if (iflag == 1) {
1516 curv = -curv;
1517 }
1518 if (curv > -gw &&
1519 curv < -gw * (ONE + FastMath.sqrt(TWO))) {
1520 final double scale = -gw / curv;
1521 for (int i = 0; i < n; i++) {
1522 final double tmp = trustRegionCenterOffset.getEntry(i) + scale * work1.getEntry(i);
1523 alternativeNewPoint.setEntry(i, FastMath.max(lowerDifference.getEntry(i),
1524 FastMath.min(upperDifference.getEntry(i), tmp)));
1525 }
1526
1527 final double d1 = HALF * gw * scale;
1528 cauchy = d1 * d1;
1529 } else {
1530
1531 final double d1 = gw + HALF * curv;
1532 cauchy = d1 * d1;
1533 }
1534
1535
1536
1537
1538
1539 if (iflag == 0) {
1540 for (int i = 0; i < n; i++) {
1541 glag.setEntry(i, -glag.getEntry(i));
1542 work2.setEntry(i, alternativeNewPoint.getEntry(i));
1543 }
1544 csave = cauchy;
1545 iflag = 1;
1546 } else {
1547 break;
1548 }
1549 }
1550 if (csave > cauchy) {
1551 for (int i = 0; i < n; i++) {
1552 alternativeNewPoint.setEntry(i, work2.getEntry(i));
1553 }
1554 cauchy = csave;
1555 }
1556
1557 return new double[] { alpha, cauchy };
1558 }
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582 private void prelim(double[] lowerBound,
1583 double[] upperBound) {
1584 printMethod();
1585
1586 final int n = currentBest.getDimension();
1587 final int npt = numberOfInterpolationPoints;
1588 final int ndim = bMatrix.getRowDimension();
1589
1590 final double rhosq = initialTrustRegionRadius * initialTrustRegionRadius;
1591 final double recip = 1d / rhosq;
1592 final int np = n + 1;
1593
1594
1595
1596
1597 for (int j = 0; j < n; j++) {
1598 originShift.setEntry(j, currentBest.getEntry(j));
1599 for (int k = 0; k < npt; k++) {
1600 interpolationPoints.setEntry(k, j, ZERO);
1601 }
1602 for (int i = 0; i < ndim; i++) {
1603 bMatrix.setEntry(i, j, ZERO);
1604 }
1605 }
1606 for (int i = 0, max = n * np / 2; i < max; i++) {
1607 modelSecondDerivativesValues.setEntry(i, ZERO);
1608 }
1609 for (int k = 0; k < npt; k++) {
1610 modelSecondDerivativesParameters.setEntry(k, ZERO);
1611 for (int j = 0, max = npt - np; j < max; j++) {
1612 zMatrix.setEntry(k, j, ZERO);
1613 }
1614 }
1615
1616
1617
1618
1619
1620 int ipt = 0;
1621 int jpt = 0;
1622 double fbeg = Double.NaN;
1623 do {
1624 final int nfm = getEvaluations();
1625 final int nfx = nfm - n;
1626 final int nfmm = nfm - 1;
1627 final int nfxm = nfx - 1;
1628 double stepa = 0;
1629 double stepb = 0;
1630 if (nfm <= 2 * n) {
1631 if (nfm >= 1 &&
1632 nfm <= n) {
1633 stepa = initialTrustRegionRadius;
1634 if (upperDifference.getEntry(nfmm) == ZERO) {
1635 stepa = -stepa;
1636
1637 }
1638 interpolationPoints.setEntry(nfm, nfmm, stepa);
1639 } else if (nfm > n) {
1640 stepa = interpolationPoints.getEntry(nfx, nfxm);
1641 stepb = -initialTrustRegionRadius;
1642 if (lowerDifference.getEntry(nfxm) == ZERO) {
1643 stepb = FastMath.min(TWO * initialTrustRegionRadius, upperDifference.getEntry(nfxm));
1644
1645 }
1646 if (upperDifference.getEntry(nfxm) == ZERO) {
1647 stepb = FastMath.max(-TWO * initialTrustRegionRadius, lowerDifference.getEntry(nfxm));
1648
1649 }
1650 interpolationPoints.setEntry(nfm, nfxm, stepb);
1651 }
1652 } else {
1653 final int tmp1 = (nfm - np) / n;
1654 jpt = nfm - tmp1 * n - n;
1655 ipt = jpt + tmp1;
1656 if (ipt > n) {
1657 final int tmp2 = jpt;
1658 jpt = ipt - n;
1659 ipt = tmp2;
1660
1661 }
1662 final int iptMinus1 = ipt - 1;
1663 final int jptMinus1 = jpt - 1;
1664 interpolationPoints.setEntry(nfm, iptMinus1, interpolationPoints.getEntry(ipt, iptMinus1));
1665 interpolationPoints.setEntry(nfm, jptMinus1, interpolationPoints.getEntry(jpt, jptMinus1));
1666 }
1667
1668
1669
1670
1671 for (int j = 0; j < n; j++) {
1672 currentBest.setEntry(j, FastMath.min(FastMath.max(lowerBound[j],
1673 originShift.getEntry(j) + interpolationPoints.getEntry(nfm, j)),
1674 upperBound[j]));
1675 if (interpolationPoints.getEntry(nfm, j) == lowerDifference.getEntry(j)) {
1676 currentBest.setEntry(j, lowerBound[j]);
1677 }
1678 if (interpolationPoints.getEntry(nfm, j) == upperDifference.getEntry(j)) {
1679 currentBest.setEntry(j, upperBound[j]);
1680 }
1681 }
1682
1683 final double objectiveValue = computeObjectiveValue(currentBest.toArray());
1684 final double f = isMinimize ? objectiveValue : -objectiveValue;
1685 final int numEval = getEvaluations();
1686 fAtInterpolationPoints.setEntry(nfm, f);
1687
1688 if (numEval == 1) {
1689 fbeg = f;
1690 trustRegionCenterInterpolationPointIndex = 0;
1691 } else if (f < fAtInterpolationPoints.getEntry(trustRegionCenterInterpolationPointIndex)) {
1692 trustRegionCenterInterpolationPointIndex = nfm;
1693 }
1694
1695
1696
1697
1698
1699
1700
1701 if (numEval <= 2 * n + 1) {
1702 if (numEval >= 2 &&
1703 numEval <= n + 1) {
1704 gradientAtTrustRegionCenter.setEntry(nfmm, (f - fbeg) / stepa);
1705 if (npt < numEval + n) {
1706 final double oneOverStepA = ONE / stepa;
1707 bMatrix.setEntry(0, nfmm, -oneOverStepA);
1708 bMatrix.setEntry(nfm, nfmm, oneOverStepA);
1709 bMatrix.setEntry(npt + nfmm, nfmm, -HALF * rhosq);
1710
1711 }
1712 } else if (numEval >= n + 2) {
1713 final int ih = nfx * (nfx + 1) / 2 - 1;
1714 final double tmp = (f - fbeg) / stepb;
1715 final double diff = stepb - stepa;
1716 modelSecondDerivativesValues.setEntry(ih, TWO * (tmp - gradientAtTrustRegionCenter.getEntry(nfxm)) / diff);
1717 gradientAtTrustRegionCenter.setEntry(nfxm, (gradientAtTrustRegionCenter.getEntry(nfxm) * stepb - tmp * stepa) / diff);
1718 if (stepa * stepb < ZERO && f < fAtInterpolationPoints.getEntry(nfm - n)) {
1719 fAtInterpolationPoints.setEntry(nfm, fAtInterpolationPoints.getEntry(nfm - n));
1720 fAtInterpolationPoints.setEntry(nfm - n, f);
1721 if (trustRegionCenterInterpolationPointIndex == nfm) {
1722 trustRegionCenterInterpolationPointIndex = nfm - n;
1723 }
1724 interpolationPoints.setEntry(nfm - n, nfxm, stepb);
1725 interpolationPoints.setEntry(nfm, nfxm, stepa);
1726 }
1727 bMatrix.setEntry(0, nfxm, -(stepa + stepb) / (stepa * stepb));
1728 bMatrix.setEntry(nfm, nfxm, -HALF / interpolationPoints.getEntry(nfm - n, nfxm));
1729 bMatrix.setEntry(nfm - n, nfxm,
1730 -bMatrix.getEntry(0, nfxm) - bMatrix.getEntry(nfm, nfxm));
1731 zMatrix.setEntry(0, nfxm, FastMath.sqrt(TWO) / (stepa * stepb));
1732 zMatrix.setEntry(nfm, nfxm, FastMath.sqrt(HALF) / rhosq);
1733
1734 zMatrix.setEntry(nfm - n, nfxm,
1735 -zMatrix.getEntry(0, nfxm) - zMatrix.getEntry(nfm, nfxm));
1736 }
1737
1738
1739
1740
1741 } else {
1742 zMatrix.setEntry(0, nfxm, recip);
1743 zMatrix.setEntry(nfm, nfxm, recip);
1744 zMatrix.setEntry(ipt, nfxm, -recip);
1745 zMatrix.setEntry(jpt, nfxm, -recip);
1746
1747 final int ih = ipt * (ipt - 1) / 2 + jpt - 1;
1748 final double tmp = interpolationPoints.getEntry(nfm, ipt - 1) * interpolationPoints.getEntry(nfm, jpt - 1);
1749 modelSecondDerivativesValues.setEntry(ih, (fbeg - fAtInterpolationPoints.getEntry(ipt) - fAtInterpolationPoints.getEntry(jpt) + f) / tmp);
1750
1751 }
1752 } while (getEvaluations() < npt);
1753 }
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802 private double[] trsbox(
1803 double delta,
1804 ArrayRealVector gnew,
1805 ArrayRealVector xbdi,
1806 ArrayRealVector s,
1807 ArrayRealVector hs,
1808 ArrayRealVector hred
1809 ) {
1810 printMethod();
1811
1812 final int n = currentBest.getDimension();
1813 final int npt = numberOfInterpolationPoints;
1814
1815 double dsq = Double.NaN;
1816 double crvmin = Double.NaN;
1817
1818
1819 double ds;
1820 int iu;
1821 double dhd, dhs, cth, shs, sth, ssq, beta=0, sdec, blen;
1822 int iact = -1;
1823 int nact = 0;
1824 double angt = 0, qred;
1825 int isav;
1826 double temp = 0, xsav = 0, xsum = 0, angbd = 0, dredg = 0, sredg = 0;
1827 int iterc;
1828 double resid = 0, delsq = 0, ggsav = 0, tempa = 0, tempb = 0,
1829 redmax = 0, dredsq = 0, redsav = 0, gredsq = 0, rednew = 0;
1830 int itcsav = 0;
1831 double rdprev = 0, rdnext = 0, stplen = 0, stepsq = 0;
1832 int itermax = 0;
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845 iterc = 0;
1846 nact = 0;
1847 for (int i = 0; i < n; i++) {
1848 xbdi.setEntry(i, ZERO);
1849 if (trustRegionCenterOffset.getEntry(i) <= lowerDifference.getEntry(i)) {
1850 if (gradientAtTrustRegionCenter.getEntry(i) >= ZERO) {
1851 xbdi.setEntry(i, MINUS_ONE);
1852 }
1853 } else if (trustRegionCenterOffset.getEntry(i) >= upperDifference.getEntry(i) &&
1854 gradientAtTrustRegionCenter.getEntry(i) <= ZERO) {
1855 xbdi.setEntry(i, ONE);
1856 }
1857 if (xbdi.getEntry(i) != ZERO) {
1858 ++nact;
1859 }
1860 trialStepPoint.setEntry(i, ZERO);
1861 gnew.setEntry(i, gradientAtTrustRegionCenter.getEntry(i));
1862 }
1863 delsq = delta * delta;
1864 qred = ZERO;
1865 crvmin = MINUS_ONE;
1866
1867
1868
1869
1870
1871
1872
1873 int state = 20;
1874 for(;;) {
1875 switch (state) {
1876 case 20: {
1877 printState(20);
1878 beta = ZERO;
1879 }
1880 case 30: {
1881 printState(30);
1882 stepsq = ZERO;
1883 for (int i = 0; i < n; i++) {
1884 if (xbdi.getEntry(i) != ZERO) {
1885 s.setEntry(i, ZERO);
1886 } else if (beta == ZERO) {
1887 s.setEntry(i, -gnew.getEntry(i));
1888 } else {
1889 s.setEntry(i, beta * s.getEntry(i) - gnew.getEntry(i));
1890 }
1891
1892 final double d1 = s.getEntry(i);
1893 stepsq += d1 * d1;
1894 }
1895 if (stepsq == ZERO) {
1896 state = 190; break;
1897 }
1898 if (beta == ZERO) {
1899 gredsq = stepsq;
1900 itermax = iterc + n - nact;
1901 }
1902 if (gredsq * delsq <= qred * 1e-4 * qred) {
1903 state = 190; break;
1904 }
1905
1906
1907
1908
1909
1910
1911 state = 210; break;
1912 }
1913 case 50: {
1914 printState(50);
1915 resid = delsq;
1916 ds = ZERO;
1917 shs = ZERO;
1918 for (int i = 0; i < n; i++) {
1919 if (xbdi.getEntry(i) == ZERO) {
1920
1921 final double d1 = trialStepPoint.getEntry(i);
1922 resid -= d1 * d1;
1923 ds += s.getEntry(i) * trialStepPoint.getEntry(i);
1924 shs += s.getEntry(i) * hs.getEntry(i);
1925 }
1926 }
1927 if (resid <= ZERO) {
1928 state = 90; break;
1929 }
1930 temp = FastMath.sqrt(stepsq * resid + ds * ds);
1931 if (ds < ZERO) {
1932 blen = (temp - ds) / stepsq;
1933 } else {
1934 blen = resid / (temp + ds);
1935 }
1936 stplen = blen;
1937 if (shs > ZERO) {
1938
1939 stplen = FastMath.min(blen, gredsq / shs);
1940 }
1941
1942
1943
1944
1945 iact = -1;
1946 for (int i = 0; i < n; i++) {
1947 if (s.getEntry(i) != ZERO) {
1948 xsum = trustRegionCenterOffset.getEntry(i) + trialStepPoint.getEntry(i);
1949 if (s.getEntry(i) > ZERO) {
1950 temp = (upperDifference.getEntry(i) - xsum) / s.getEntry(i);
1951 } else {
1952 temp = (lowerDifference.getEntry(i) - xsum) / s.getEntry(i);
1953 }
1954 if (temp < stplen) {
1955 stplen = temp;
1956 iact = i;
1957 }
1958 }
1959 }
1960
1961
1962
1963 sdec = ZERO;
1964 if (stplen > ZERO) {
1965 ++iterc;
1966 temp = shs / stepsq;
1967 if (iact == -1 && temp > ZERO) {
1968 crvmin = FastMath.min(crvmin,temp);
1969 if (crvmin == MINUS_ONE) {
1970 crvmin = temp;
1971 }
1972 }
1973 ggsav = gredsq;
1974 gredsq = ZERO;
1975 for (int i = 0; i < n; i++) {
1976 gnew.setEntry(i, gnew.getEntry(i) + stplen * hs.getEntry(i));
1977 if (xbdi.getEntry(i) == ZERO) {
1978
1979 final double d1 = gnew.getEntry(i);
1980 gredsq += d1 * d1;
1981 }
1982 trialStepPoint.setEntry(i, trialStepPoint.getEntry(i) + stplen * s.getEntry(i));
1983 }
1984
1985 final double d1 = stplen * (ggsav - HALF * stplen * shs);
1986 sdec = FastMath.max(d1, ZERO);
1987 qred += sdec;
1988 }
1989
1990
1991
1992 if (iact >= 0) {
1993 ++nact;
1994 xbdi.setEntry(iact, ONE);
1995 if (s.getEntry(iact) < ZERO) {
1996 xbdi.setEntry(iact, MINUS_ONE);
1997 }
1998
1999 final double d1 = trialStepPoint.getEntry(iact);
2000 delsq -= d1 * d1;
2001 if (delsq <= ZERO) {
2002 state = 190; break;
2003 }
2004 state = 20; break;
2005 }
2006
2007
2008
2009
2010 if (stplen < blen) {
2011 if (iterc == itermax) {
2012 state = 190; break;
2013 }
2014 if (sdec <= qred * .01) {
2015 state = 190; break;
2016 }
2017 beta = gredsq / ggsav;
2018 state = 30; break;
2019 }
2020 }
2021 case 90: {
2022 printState(90);
2023 crvmin = ZERO;
2024
2025
2026
2027
2028
2029 }
2030 case 100: {
2031 printState(100);
2032 if (nact >= n - 1) {
2033 state = 190; break;
2034 }
2035 dredsq = ZERO;
2036 dredg = ZERO;
2037 gredsq = ZERO;
2038 for (int i = 0; i < n; i++) {
2039 if (xbdi.getEntry(i) == ZERO) {
2040
2041 double d1 = trialStepPoint.getEntry(i);
2042 dredsq += d1 * d1;
2043 dredg += trialStepPoint.getEntry(i) * gnew.getEntry(i);
2044
2045 d1 = gnew.getEntry(i);
2046 gredsq += d1 * d1;
2047 s.setEntry(i, trialStepPoint.getEntry(i));
2048 } else {
2049 s.setEntry(i, ZERO);
2050 }
2051 }
2052 itcsav = iterc;
2053 state = 210; break;
2054
2055
2056 }
2057 case 120: {
2058 printState(120);
2059 ++iterc;
2060 temp = gredsq * dredsq - dredg * dredg;
2061 if (temp <= qred * 1e-4 * qred) {
2062 state = 190; break;
2063 }
2064 temp = FastMath.sqrt(temp);
2065 for (int i = 0; i < n; i++) {
2066 if (xbdi.getEntry(i) == ZERO) {
2067 s.setEntry(i, (dredg * trialStepPoint.getEntry(i) - dredsq * gnew.getEntry(i)) / temp);
2068 } else {
2069 s.setEntry(i, ZERO);
2070 }
2071 }
2072 sredg = -temp;
2073
2074
2075
2076
2077
2078
2079 angbd = ONE;
2080 iact = -1;
2081 for (int i = 0; i < n; i++) {
2082 if (xbdi.getEntry(i) == ZERO) {
2083 tempa = trustRegionCenterOffset.getEntry(i) + trialStepPoint.getEntry(i) - lowerDifference.getEntry(i);
2084 tempb = upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i) - trialStepPoint.getEntry(i);
2085 if (tempa <= ZERO) {
2086 ++nact;
2087 xbdi.setEntry(i, MINUS_ONE);
2088 state = 100; break;
2089 } else if (tempb <= ZERO) {
2090 ++nact;
2091 xbdi.setEntry(i, ONE);
2092 state = 100; break;
2093 }
2094
2095 double d1 = trialStepPoint.getEntry(i);
2096
2097 double d2 = s.getEntry(i);
2098 ssq = d1 * d1 + d2 * d2;
2099
2100 d1 = trustRegionCenterOffset.getEntry(i) - lowerDifference.getEntry(i);
2101 temp = ssq - d1 * d1;
2102 if (temp > ZERO) {
2103 temp = FastMath.sqrt(temp) - s.getEntry(i);
2104 if (angbd * temp > tempa) {
2105 angbd = tempa / temp;
2106 iact = i;
2107 xsav = MINUS_ONE;
2108 }
2109 }
2110
2111 d1 = upperDifference.getEntry(i) - trustRegionCenterOffset.getEntry(i);
2112 temp = ssq - d1 * d1;
2113 if (temp > ZERO) {
2114 temp = FastMath.sqrt(temp) + s.getEntry(i);
2115 if (angbd * temp > tempb) {
2116 angbd = tempb / temp;
2117 iact = i;
2118 xsav = ONE;
2119 }
2120 }
2121 }
2122 }
2123
2124
2125
2126 state = 210; break;
2127 }
2128 case 150: {
2129 printState(150);
2130 shs = ZERO;
2131 dhs = ZERO;
2132 dhd = ZERO;
2133 for (int i = 0; i < n; i++) {
2134 if (xbdi.getEntry(i) == ZERO) {
2135 shs += s.getEntry(i) * hs.getEntry(i);
2136 dhs += trialStepPoint.getEntry(i) * hs.getEntry(i);
2137 dhd += trialStepPoint.getEntry(i) * hred.getEntry(i);
2138 }
2139 }
2140
2141
2142
2143
2144
2145 redmax = ZERO;
2146 isav = -1;
2147 redsav = ZERO;
2148 iu = (int) (angbd * 17. + 3.1);
2149 for (int i = 0; i < iu; i++) {
2150 angt = angbd * i / iu;
2151 sth = (angt + angt) / (ONE + angt * angt);
2152 temp = shs + angt * (angt * dhd - dhs - dhs);
2153 rednew = sth * (angt * dredg - sredg - HALF * sth * temp);
2154 if (rednew > redmax) {
2155 redmax = rednew;
2156 isav = i;
2157 rdprev = redsav;
2158 } else if (i == isav + 1) {
2159 rdnext = rednew;
2160 }
2161 redsav = rednew;
2162 }
2163
2164
2165
2166
2167 if (isav < 0) {
2168 state = 190; break;
2169 }
2170 if (isav < iu) {
2171 temp = (rdnext - rdprev) / (redmax + redmax - rdprev - rdnext);
2172 angt = angbd * (isav + HALF * temp) / iu;
2173 }
2174 cth = (ONE - angt * angt) / (ONE + angt * angt);
2175 sth = (angt + angt) / (ONE + angt * angt);
2176 temp = shs + angt * (angt * dhd - dhs - dhs);
2177 sdec = sth * (angt * dredg - sredg - HALF * sth * temp);
2178 if (sdec <= ZERO) {
2179 state = 190; break;
2180 }
2181
2182
2183
2184
2185
2186 dredg = ZERO;
2187 gredsq = ZERO;
2188 for (int i = 0; i < n; i++) {
2189 gnew.setEntry(i, gnew.getEntry(i) + (cth - ONE) * hred.getEntry(i) + sth * hs.getEntry(i));
2190 if (xbdi.getEntry(i) == ZERO) {
2191 trialStepPoint.setEntry(i, cth * trialStepPoint.getEntry(i) + sth * s.getEntry(i));
2192 dredg += trialStepPoint.getEntry(i) * gnew.getEntry(i);
2193
2194 final double d1 = gnew.getEntry(i);
2195 gredsq += d1 * d1;
2196 }
2197 hred.setEntry(i, cth * hred.getEntry(i) + sth * hs.getEntry(i));
2198 }
2199 qred += sdec;
2200 if (iact >= 0 && isav == iu) {
2201 ++nact;
2202 xbdi.setEntry(iact, xsav);
2203 state = 100; break;
2204 }
2205
2206
2207
2208
2209 if (sdec > qred * .01) {
2210 state = 120; break;
2211 }
2212 }
2213 case 190: {
2214 printState(190);
2215 dsq = ZERO;
2216 for (int i = 0; i < n; i++) {
2217
2218
2219 final double min = FastMath.min(trustRegionCenterOffset.getEntry(i) + trialStepPoint.getEntry(i),
2220 upperDifference.getEntry(i));
2221 newPoint.setEntry(i, FastMath.max(min, lowerDifference.getEntry(i)));
2222 if (xbdi.getEntry(i) == MINUS_ONE) {
2223 newPoint.setEntry(i, lowerDifference.getEntry(i));
2224 }
2225 if (xbdi.getEntry(i) == ONE) {
2226 newPoint.setEntry(i, upperDifference.getEntry(i));
2227 }
2228 trialStepPoint.setEntry(i, newPoint.getEntry(i) - trustRegionCenterOffset.getEntry(i));
2229
2230 final double d1 = trialStepPoint.getEntry(i);
2231 dsq += d1 * d1;
2232 }
2233 return new double[] { dsq, crvmin };
2234
2235
2236
2237
2238 }
2239 case 210: {
2240 printState(210);
2241 int ih = 0;
2242 for (int j = 0; j < n; j++) {
2243 hs.setEntry(j, ZERO);
2244 for (int i = 0; i <= j; i++) {
2245 if (i < j) {
2246 hs.setEntry(j, hs.getEntry(j) + modelSecondDerivativesValues.getEntry(ih) * s.getEntry(i));
2247 }
2248 hs.setEntry(i, hs.getEntry(i) + modelSecondDerivativesValues.getEntry(ih) * s.getEntry(j));
2249 ih++;
2250 }
2251 }
2252 final RealVector tmp = interpolationPoints.operate(s).ebeMultiply(modelSecondDerivativesParameters);
2253 for (int k = 0; k < npt; k++) {
2254 if (modelSecondDerivativesParameters.getEntry(k) != ZERO) {
2255 for (int i = 0; i < n; i++) {
2256 hs.setEntry(i, hs.getEntry(i) + tmp.getEntry(k) * interpolationPoints.getEntry(k, i));
2257 }
2258 }
2259 }
2260 if (crvmin != ZERO) {
2261 state = 50; break;
2262 }
2263 if (iterc > itcsav) {
2264 state = 150; break;
2265 }
2266 for (int i = 0; i < n; i++) {
2267 hred.setEntry(i, hs.getEntry(i));
2268 }
2269 state = 120; break;
2270 }
2271 default: {
2272 throw new MathIllegalStateException(LocalizedFormats.SIMPLE_MESSAGE, "trsbox");
2273 }}
2274 }
2275 }
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292 private void update(
2293 double beta,
2294 double denom,
2295 int knew
2296 ) {
2297 printMethod();
2298
2299 final int n = currentBest.getDimension();
2300 final int npt = numberOfInterpolationPoints;
2301 final int nptm = npt - n - 1;
2302
2303
2304 final ArrayRealVector work = new ArrayRealVector(npt + n);
2305
2306 double ztest = ZERO;
2307 for (int k = 0; k < npt; k++) {
2308 for (int j = 0; j < nptm; j++) {
2309
2310 ztest = FastMath.max(ztest, FastMath.abs(zMatrix.getEntry(k, j)));
2311 }
2312 }
2313 ztest *= 1e-20;
2314
2315
2316
2317 for (int j = 1; j < nptm; j++) {
2318 final double d1 = zMatrix.getEntry(knew, j);
2319 if (FastMath.abs(d1) > ztest) {
2320
2321 final double d2 = zMatrix.getEntry(knew, 0);
2322
2323 final double d3 = zMatrix.getEntry(knew, j);
2324 final double d4 = FastMath.sqrt(d2 * d2 + d3 * d3);
2325 final double d5 = zMatrix.getEntry(knew, 0) / d4;
2326 final double d6 = zMatrix.getEntry(knew, j) / d4;
2327 for (int i = 0; i < npt; i++) {
2328 final double d7 = d5 * zMatrix.getEntry(i, 0) + d6 * zMatrix.getEntry(i, j);
2329 zMatrix.setEntry(i, j, d5 * zMatrix.getEntry(i, j) - d6 * zMatrix.getEntry(i, 0));
2330 zMatrix.setEntry(i, 0, d7);
2331 }
2332 }
2333 zMatrix.setEntry(knew, j, ZERO);
2334 }
2335
2336
2337
2338
2339 for (int i = 0; i < npt; i++) {
2340 work.setEntry(i, zMatrix.getEntry(knew, 0) * zMatrix.getEntry(i, 0));
2341 }
2342 final double alpha = work.getEntry(knew);
2343 final double tau = lagrangeValuesAtNewPoint.getEntry(knew);
2344 lagrangeValuesAtNewPoint.setEntry(knew, lagrangeValuesAtNewPoint.getEntry(knew) - ONE);
2345
2346
2347
2348 final double sqrtDenom = FastMath.sqrt(denom);
2349 final double d1 = tau / sqrtDenom;
2350 final double d2 = zMatrix.getEntry(knew, 0) / sqrtDenom;
2351 for (int i = 0; i < npt; i++) {
2352 zMatrix.setEntry(i, 0,
2353 d1 * zMatrix.getEntry(i, 0) - d2 * lagrangeValuesAtNewPoint.getEntry(i));
2354 }
2355
2356
2357
2358 for (int j = 0; j < n; j++) {
2359 final int jp = npt + j;
2360 work.setEntry(jp, bMatrix.getEntry(knew, j));
2361 final double d3 = (alpha * lagrangeValuesAtNewPoint.getEntry(jp) - tau * work.getEntry(jp)) / denom;
2362 final double d4 = (-beta * work.getEntry(jp) - tau * lagrangeValuesAtNewPoint.getEntry(jp)) / denom;
2363 for (int i = 0; i <= jp; i++) {
2364 bMatrix.setEntry(i, j,
2365 bMatrix.getEntry(i, j) + d3 * lagrangeValuesAtNewPoint.getEntry(i) + d4 * work.getEntry(i));
2366 if (i >= npt) {
2367 bMatrix.setEntry(jp, (i - npt), bMatrix.getEntry(i, j));
2368 }
2369 }
2370 }
2371 }
2372
2373
2374
2375
2376
2377
2378
2379 private void setup(double[] lowerBound,
2380 double[] upperBound) {
2381 printMethod();
2382
2383 double[] init = getStartPoint();
2384 final int dimension = init.length;
2385
2386
2387 if (dimension < MINIMUM_PROBLEM_DIMENSION) {
2388 throw new NumberIsTooSmallException(dimension, MINIMUM_PROBLEM_DIMENSION, true);
2389 }
2390
2391 final int[] nPointsInterval = { dimension + 2, (dimension + 2) * (dimension + 1) / 2 };
2392 if (numberOfInterpolationPoints < nPointsInterval[0] ||
2393 numberOfInterpolationPoints > nPointsInterval[1]) {
2394 throw new OutOfRangeException(LocalizedFormats.NUMBER_OF_INTERPOLATION_POINTS,
2395 numberOfInterpolationPoints,
2396 nPointsInterval[0],
2397 nPointsInterval[1]);
2398 }
2399
2400
2401 boundDifference = new double[dimension];
2402
2403 double requiredMinDiff = 2 * initialTrustRegionRadius;
2404 double minDiff = Double.POSITIVE_INFINITY;
2405 for (int i = 0; i < dimension; i++) {
2406 boundDifference[i] = upperBound[i] - lowerBound[i];
2407 minDiff = FastMath.min(minDiff, boundDifference[i]);
2408 }
2409 if (minDiff < requiredMinDiff) {
2410 initialTrustRegionRadius = minDiff / 3.0;
2411 }
2412
2413
2414 bMatrix = new Array2DRowRealMatrix(dimension + numberOfInterpolationPoints,
2415 dimension);
2416 zMatrix = new Array2DRowRealMatrix(numberOfInterpolationPoints,
2417 numberOfInterpolationPoints - dimension - 1);
2418 interpolationPoints = new Array2DRowRealMatrix(numberOfInterpolationPoints,
2419 dimension);
2420 originShift = new ArrayRealVector(dimension);
2421 fAtInterpolationPoints = new ArrayRealVector(numberOfInterpolationPoints);
2422 trustRegionCenterOffset = new ArrayRealVector(dimension);
2423 gradientAtTrustRegionCenter = new ArrayRealVector(dimension);
2424 lowerDifference = new ArrayRealVector(dimension);
2425 upperDifference = new ArrayRealVector(dimension);
2426 modelSecondDerivativesParameters = new ArrayRealVector(numberOfInterpolationPoints);
2427 newPoint = new ArrayRealVector(dimension);
2428 alternativeNewPoint = new ArrayRealVector(dimension);
2429 trialStepPoint = new ArrayRealVector(dimension);
2430 lagrangeValuesAtNewPoint = new ArrayRealVector(dimension + numberOfInterpolationPoints);
2431 modelSecondDerivativesValues = new ArrayRealVector(dimension * (dimension + 1) / 2);
2432 }
2433
2434
2435 private static String caller(int n) {
2436 final Throwable t = new Throwable();
2437 final StackTraceElement[] elements = t.getStackTrace();
2438 final StackTraceElement e = elements[n];
2439 return e.getMethodName() + " (at line " + e.getLineNumber() + ")";
2440 }
2441
2442 private static void printState(int s) {
2443
2444 }
2445
2446 private static void printMethod() {
2447
2448 }
2449
2450
2451
2452
2453
2454 private static class PathIsExploredException extends RuntimeException {
2455 private static final long serialVersionUID = 745350979634801853L;
2456
2457 private static final String PATH_IS_EXPLORED
2458 = "If this exception is thrown, just remove it from the code";
2459
2460 PathIsExploredException() {
2461 super(PATH_IS_EXPLORED + " " + BOBYQAOptimizer.caller(3));
2462 }
2463 }
2464 }
2465