samer@0
|
1 /*
|
samer@0
|
2 * Copyright (c) 2000, Samer Abdallah, King's College London.
|
samer@0
|
3 * All rights reserved.
|
samer@0
|
4 *
|
samer@0
|
5 * This software is provided AS iS and WITHOUT ANY WARRANTY;
|
samer@0
|
6 * without even the implied warranty of MERCHANTABILITY or
|
samer@0
|
7 * FITNESS FOR A PARTICULAR PURPOSE.
|
samer@0
|
8 */
|
samer@0
|
9
|
samer@0
|
10 package samer.maths.opt;
|
samer@0
|
11 import samer.maths.*;
|
samer@0
|
12 import samer.core.*;
|
samer@0
|
13
|
samer@0
|
14
|
samer@0
|
15 public class CubicLineSearch
|
samer@0
|
16 {
|
samer@0
|
17 double ZETA=0.0625; // factor for safeguarding
|
samer@0
|
18 State S;
|
samer@0
|
19
|
samer@0
|
20 public CubicLineSearch(State s) { S=s; }
|
samer@0
|
21
|
samer@0
|
22 public void setSafeguardFactor( double z) { ZETA=z; }
|
samer@0
|
23
|
samer@0
|
24 protected final double extrapolate()
|
samer@0
|
25 {
|
samer@0
|
26 double beta=S.cubic()-S.alpha;
|
samer@0
|
27
|
samer@0
|
28 if (Double.isInfinite(beta) || Double.isNaN(beta)) {
|
samer@0
|
29 return S.alpha*1.6;
|
samer@0
|
30 } else if (beta>0) {
|
samer@0
|
31 if (beta<0.5*S.alpha) beta=S.alpha*0.5;
|
samer@0
|
32 else if (beta>2*S.alpha) beta=2*S.alpha;
|
samer@0
|
33 return beta;
|
samer@0
|
34 } else {
|
samer@0
|
35 return S.alpha*1.6;
|
samer@0
|
36 // if (beta>8) beta=8;
|
samer@0
|
37 }
|
samer@0
|
38 }
|
samer@0
|
39
|
samer@0
|
40 protected final double interpolate()
|
samer@0
|
41 {
|
samer@0
|
42 if (S.P2.s>0) {
|
samer@0
|
43 double beta=S.cubic();
|
samer@0
|
44 double safe=ZETA*S.alpha;
|
samer@0
|
45 if (Double.isNaN(beta) || Double.isInfinite(beta)) {
|
samer@0
|
46 beta=S.alpha/2; // bisect
|
samer@0
|
47 } else if (beta<=safe || beta>=(S.alpha-safe)) {
|
samer@0
|
48 beta=S.alpha/2; // bisect
|
samer@0
|
49 }
|
samer@0
|
50 if (S.alpha<0.1) beta/=2; // adust
|
samer@0
|
51 return beta;
|
samer@0
|
52 } else {
|
samer@0
|
53 return S.alpha/2;
|
samer@0
|
54 }
|
samer@0
|
55 }
|
samer@0
|
56
|
samer@0
|
57 public void run(Condition convergence)
|
samer@0
|
58 {
|
samer@0
|
59 while (!convergence.test()) {
|
samer@0
|
60 if (S.P2.f<S.P1.f && S.P2.s<0) {
|
samer@0
|
61 double beta=extrapolate();
|
samer@0
|
62 S.move();
|
samer@0
|
63 S.step(beta);
|
samer@0
|
64 } else
|
samer@0
|
65 S.step(interpolate());
|
samer@0
|
66 }
|
samer@0
|
67 }
|
samer@0
|
68 }
|
samer@0
|
69
|