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