1616 */
1717package org .hipparchus .optim .nonlinear .vector .constrained ;
1818
19-
2019import org .hipparchus .linear .Array2DRowRealMatrix ;
2120import org .hipparchus .linear .ArrayRealVector ;
2221import org .hipparchus .linear .CholeskyDecomposition ;
3837 * <li>Automatic Hessian reset after configurable failures</li>
3938 * </ul>
4039 *
41- * @since 4.1
40+ * @deprecated as of 4.1, replaced by {@link BFGSUpdater2}
4241 */
42+ @ Deprecated
4343public class BFGSUpdater {
4444
45- /**
46- * Damping factor.
47- */
45+ /** Damping factor. */
4846 private static final double GAMMA = 0.2 ;
4947
50- /**
51- * AutoScaling Flag.
52- */
53- private final boolean scale ;
54-
55- /**
56- * EPS.
57- */
58- private final double eps ;
48+ /** Regularization factor for diagonal of Hessian. */
49+ private final double regFactor ;
5950
60- /**
61- * trigger skip update for diagonal of Hessian.
62- */
63- private final double sqrtEPSmachine = FastMath .sqrt (Precision .EPSILON );
64-
65- /**
66- * Tolerance for symmetric matrices decomposition.
67- *
51+ /** Tolerance for symmetric matrices decomposition.
6852 * @since 4.1
6953 */
7054 private final double decompositionEpsilon ;
7155
72- /**
73- * Stored initial Hessian for resets.
74- */
56+ /** Stored initial Hessian for resets. */
7557 private final RealMatrix initialH ;
7658
77- /**
78- * Current Cholesky factor L such that H = L·Lᵀ.
79- */
59+ /** Current Cholesky factor L such that H = L·Lᵀ. */
8060 private RealMatrix L ;
8161
8262 /**
8363 * Creates a new updater.
84- *
85- * @param initialHess initial positive‐definite Hessian matrix
86- * @param eps treshold to apply auto scale sty<sqrt(eps)
87- * @param autoScale true apply auto hessian rescaling
88- * @param decompositionEpsilon tolerance for symmetric matrices
89- * decomposition
64+ * @param initialHess initial positive‐definite Hessian matrix
65+ * @param regFactor regularization factor to add on diagonal
66+ * @param decompositionEpsilon tolerance for symmetric matrices decomposition
9067 */
91- public BFGSUpdater (final RealMatrix initialHess , final double eps , final boolean autoScale , final double decompositionEpsilon ) {
92- this .initialH = new Array2DRowRealMatrix (initialHess .getData ());
93- this .eps = eps ;
94- this .scale = autoScale ;
68+ public BFGSUpdater (final RealMatrix initialHess , final double regFactor , final double decompositionEpsilon ) {
69+ this .initialH = new Array2DRowRealMatrix (initialHess .getData ());
70+ this .regFactor = regFactor ;
9571 this .decompositionEpsilon = decompositionEpsilon ;
9672 resetHessian ();
9773 }
@@ -109,61 +85,20 @@ public RealMatrix getHessian() {
10985 * Updates the Hessian approximation using the BFGS formula.
11086 * <p>
11187 * If curvature condition fails, applies damping or regularization.
112- * </p>
88+ *</p>
11389 *
11490 * @param s displacement vector (x_{k+1} − x_k)
11591 * @param y1 gradient difference (∇f_{k+1} − ∇f_k)
116- * @return type of update
117- * 0: update is done
118- * 1:sHs too small skip update
119- * 2:sty<gamma*sHs skipped update
120- * 3:sty<sqrt(eps)auto scale gamma*Hini
121- * 4:singulatity detected during downdate reset to gamma*Hinit
12292 */
123- public int update (RealVector s , RealVector y1 ) {
124- RealVector Hs = L .operate (L .preMultiply (s )); // al posto di getHessian().operate(s)
125- double sHs = s .dotProduct (Hs );
126- if (sHs <= 0.0 ) {
127-
128- // double sty = s.dotProduct(y1);
129- // double yy = y1.dotProduct(y1);
130- // double gamma =yy /sty;
131- // if (sty>0) {
132- // gamma = FastMath.max(sqrtEPSmachine, FastMath.min(1/sqrtEPSmachine, gamma));
133- // this.resetHessian(gamma);
134- // return 1;
135- // }
136- // this.resetHessian();
137- return 1 ;
138- }
139-
140- RealVector y = damp (s , y1 , Hs , sHs );
141- if (y == null ) {
142-
143- return 2 ;//damp failed
93+ public void update (RealVector s , RealVector y1 ) {
94+ RealVector y = damp (s , y1 );
95+ if (y == null ) {
96+ return ;
14497 }
145-
146-
147-
148-
149- if (scale ) {
150- double sty = s .dotProduct (y );
151- double yy = y .dotProduct (y );
152- double gamma =yy /sty ;
153- if (gamma < FastMath .sqrt (eps )) {
154- gamma = FastMath .max (sqrtEPSmachine , FastMath .min (1 /sqrtEPSmachine , gamma ));
155- this .resetHessian (gamma );
156- return 3 ;
157- }
158- }
159-
16098 // Attempt rank‐one BFGS update; regularize on failure
161- if (rankOneUpdate (s , y , Hs , sHs )) return 0 ;
162-
163- return 4 ;
99+ rankOneUpdate (s , y );
164100 }
165101
166-
167102 /**
168103 * Resets the Hessian approximation to its initial value.
169104 */
@@ -172,80 +107,54 @@ public void resetHessian() {
172107 L = ch .getL ();
173108 }
174109
175- /**
176- * Resets the Hessian approximation with information on the curvature.
177- *
178- * @param gamma scale factor
179- */
180- public void resetHessian (double gamma ) {
181- final CholeskyDecomposition ch = new CholeskyDecomposition (initialH .scalarMultiply (gamma ), decompositionEpsilon , decompositionEpsilon );
182- L = ch .getL ();
183- }
184-
185110 /**
186111 * Applies dynamic damping to y to satisfy curvature condition sᵀy ≥ γ sᵀHs.
187112 *
188113 * @param s search direction
189114 * @param y1 raw gradient difference
190- * @param Hs vector
191- * @param sHs value
192115 * @return damped y, or null if update should be skipped
193116 */
194- public RealVector damp (RealVector s , RealVector y1 , RealVector Hs , double sHs ) {
117+ public RealVector damp (RealVector s , RealVector y1 ) {
195118 RealVector y = new ArrayRealVector (y1 );
196119 double sty = s .dotProduct (y1 );
197-
120+ RealVector Hs = getHessian ().operate (s );
121+ double sHs = s .dotProduct (Hs );
122+ if (sty <= Precision .EPSILON ) {
123+ return null ;
124+ }
198125 if (sty < GAMMA * sHs ) {
199126 double phi = (1.0 - GAMMA ) * sHs / (sHs - sty );
200- if (phi >= 1.0 ) return y1 ;
201- else if (phi <= 0.0 ) return Hs ;
202- //
203- y = (y1 .mapMultiply (phi )).add (Hs .mapMultiply (1.0 - phi ));
127+ // clamp phi to [0,1]
128+ phi = FastMath .max (0.0 , FastMath .min (1.0 , phi ));
129+ y = y1 .mapMultiply (phi ).add (Hs .mapMultiply (1.0 - phi ));
204130 sty = s .dotProduct (y );
205-
206-
207131 if (sty < GAMMA * sHs ) {
208-
209132 return null ;
210133 }
211-
212134 }
213135 return y ;
214136 }
215137
216-
217-
218138 /**
219139 * Performs a BFGS rank‐one update on L.
220140 *
221141 * @param s displacement vector
222142 * @param y gradient difference vector
223- * @param Hs vector
224- * @param sHs value
225143 * @return true if update succeeded, false otherwise
226144 */
227- private boolean rankOneUpdate (RealVector s , RealVector y , RealVector Hs , double sHs ) {
145+ private boolean rankOneUpdate (RealVector s , RealVector y ) {
228146 RealMatrix Lcopy = new Array2DRowRealMatrix (L .getData ());
147+ RealVector Hs = L .operate (L .preMultiply (s ));
229148 double rho = 1.0 / FastMath .sqrt (s .dotProduct (y ));
230- double theta = 1.0 / FastMath .sqrt (sHs );
149+ double theta = 1.0 / FastMath .sqrt (s . dotProduct ( Hs ) );
231150 RealVector v = y .mapMultiply (rho );
232151 RealVector w = Hs .mapMultiply (theta );
233- cholupdateLower (v ,+1 );//upgrade
234- if (!cholupdateLower (w ,-1 )) { //downdate
235- double gamma = 1.0 ;
236- double sty = s .dotProduct (y );
237- double yy = y .dotProduct (y );
238- if (sty > Precision .SAFE_MIN ) {
239- gamma =yy /sty ;
240- gamma = FastMath .max (sqrtEPSmachine , FastMath .min (1 /sqrtEPSmachine , gamma ));
241- this .resetHessian (gamma );
242- }
243- else this .resetHessian ();
244-
152+ cholupdateLower (v , +1 ) ;
245153
246- return false ;
154+ if (!cholupdateLower (w , -1 )) {
155+ //try to regularize
156+ L .setSubMatrix (Lcopy .getData (), 0 , 0 );
247157 }
248-
249158 return true ;
250159 }
251160
@@ -266,13 +175,9 @@ private boolean cholupdateLower(RealVector u, int sigma) {
266175 double lii = L .getEntry (i , i );
267176 double ui = temp .getEntry (i );
268177 double r2 = lii * lii + sigma * ui * ui ;
269-
270- //skip or update
271- if (sigma < 0 && r2 < this .sqrtEPSmachine * lii * lii ) {
272- // if (sigma < 0 && r2 < Precision.EPSILON) {
178+ if (r2 < regFactor ) {
273179 return false ;
274180 }
275-
276181 double r = Math .sqrt (r2 );
277182 double c = r / lii ;
278183 double s = ui / lii ;
@@ -289,8 +194,4 @@ private boolean cholupdateLower(RealVector u, int sigma) {
289194 return true ;
290195 }
291196
292-
293-
294-
295-
296197}
0 commit comments