Skip to content

Commit dc4f04d

Browse files
committed
Final implementation done
1 parent 9516efe commit dc4f04d

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

dfols/controller.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -460,13 +460,13 @@ def evaluate_criticality_measure(self, params):
460460
d, gnew, crvmin = ctrsbox_sfista(self.model.xopt(abs_coordinates=True), gopt, np.zeros(H.shape), self.model.projections, 1,
461461
self.h, self.lh, self.prox_uh, argsh = self.argsh, argsprox=self.argsprox, func_tol=func_tol,
462462
max_iters=params("func_tol.max_iters"), d_max_iters=params("dykstra.max_iters"), d_tol=params("dykstra.d_tol"),
463-
scaling_changes=self.scaling_changes)
463+
scaling_changes=self.scaling_changes, sfista_iters_scale=params("sfista.max_iters_scaling"))
464464
else:
465465
proj = lambda x: pbox(x, self.model.sl, self.model.su)
466466
d, gnew, crvmin = ctrsbox_sfista(self.model.xopt(abs_coordinates=True), gopt, np.zeros(H.shape), [proj], 1,
467467
self.h, self.lh, self.prox_uh, argsh = self.argsh, argsprox=self.argsprox, func_tol=func_tol,
468468
max_iters=params("func_tol.max_iters"), d_max_iters=params("dykstra.max_iters"), d_tol=params("dykstra.d_tol"),
469-
scaling_changes=self.scaling_changes)
469+
scaling_changes=self.scaling_changes, sfista_iters_scale=params("sfista.max_iters_scaling"))
470470

471471
# Calculate criticality measure
472472
criticality_measure = self.h(remove_scaling(self.model.xopt(abs_coordinates=True), self.scaling_changes), *self.argsh) - model_value(gopt, np.zeros(H.shape), d, self.model.xopt(abs_coordinates=True), self.h, self.argsh, self.scaling_changes)
@@ -505,15 +505,15 @@ def trust_region_step(self, params, criticality_measure=1e-2):
505505
d, gnew, crvmin = ctrsbox_sfista(self.model.xopt(abs_coordinates=True), gopt, H, self.model.projections, self.delta,
506506
self.h, self.lh, self.prox_uh, argsh = self.argsh, argsprox=self.argsprox, func_tol=func_tol,
507507
max_iters=params("func_tol.max_iters"), d_max_iters=params("dykstra.max_iters"), d_tol=params("dykstra.d_tol"),
508-
scaling_changes=self.scaling_changes)
508+
scaling_changes=self.scaling_changes, sfista_iters_scale=params("sfista.max_iters_scaling"))
509509
else:
510510
# NOTE: alternative way if using trsbox
511511
# d, gnew, crvmin = trsbox(self.model.xopt(), gopt, H, self.model.sl, self.model.su, self.delta)
512512
proj = lambda x: pbox(x, self.model.sl, self.model.su)
513513
d, gnew, crvmin = ctrsbox_sfista(self.model.xopt(abs_coordinates=True), gopt, H, [proj], self.delta,
514514
self.h, self.lh, self.prox_uh, argsh = self.argsh, argsprox=self.argsprox, func_tol=func_tol,
515515
max_iters=params("func_tol.max_iters"), d_max_iters=params("dykstra.max_iters"), d_tol=params("dykstra.d_tol"),
516-
scaling_changes=self.scaling_changes)
516+
scaling_changes=self.scaling_changes, sfista_iters_scale=params("sfista.max_iters_scaling"))
517517

518518
# NOTE: check sufficient decrease. If increase in the model, set zero step
519519
pred_reduction = self.h(remove_scaling(self.model.xopt(abs_coordinates=True), self.scaling_changes), *self.argsh) - model_value(gopt, H, d, self.model.xopt(abs_coordinates=True), self.h, self.argsh, self.scaling_changes)

dfols/params.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,20 @@ def __init__(self, n, npt, maxfun, objfun_has_noise=False):
109109
self.params["growing.full_rank.min_sing_val"] = 1e-6 # absolute floor on singular values
110110
self.params["growing.full_rank.svd_max_jac_cond"] = 1e8 # maximum condition number of Jacobian
111111
self.params["growing.perturb_trust_region_step"] = False # add random direction onto TRS solution?
112+
112113
# Dykstra's algorithm
113114
self.params["dykstra.d_tol"] = 1e-10
114115
self.params["dykstra.max_iters"] = 100
116+
115117
# Matrix rank algorithm
116118
self.params["matrix_rank.r_tol"] = 1e-18
119+
117120
# Function tolerance when applying S-FISTA method
118121
self.params["func_tol.criticality_measure"] = 1e-3
119122
self.params["func_tol.tr_step"] = 1-1e-1
120123
self.params["func_tol.max_iters"] = 500
124+
self.params["sfista.max_iters_scaling"] = 2.0
125+
121126
self.params_changed = {}
122127
for p in self.params:
123128
self.params_changed[p] = False
@@ -277,6 +282,8 @@ def param_type(self, key, npt):
277282
type_str, nonetype_ok, lower, upper = 'float', False, 0.0, 1.0
278283
elif key == "func_tol.max_iters":
279284
type_str, nonetype_ok, lower, upper = 'int', False, 0, None
285+
elif key == "sfista.max_iters_scaling":
286+
type_str, nonetype_ok, lower, upper = 'float', False, 1.0, None
280287
else:
281288
assert False, "ParameterList.param_type() has unknown key: %s" % key
282289
return type_str, nonetype_ok, lower, upper

dfols/trust_region.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585

8686
ZERO_THRESH = 1e-14
8787

88-
def ctrsbox_sfista(xopt, g, H, projections, delta, h, L_h, prox_uh, argsh=(), argsprox=(), func_tol=1e-3, max_iters=500, d_max_iters=100, d_tol=1e-10, use_fortran=USE_FORTRAN, scaling_changes=None):
88+
def ctrsbox_sfista(xopt, g, H, projections, delta, h, L_h, prox_uh, argsh=(), argsprox=(), func_tol=1e-3, max_iters=500, d_max_iters=100, d_tol=1e-10, use_fortran=USE_FORTRAN, scaling_changes=None, sfista_iters_scale=1.0):
8989
n = xopt.size
9090
assert xopt.shape == (n,), "xopt has wrong shape (should be vector)"
9191
assert g.shape == (n,), "g and xopt have incompatible sizes"
@@ -107,11 +107,12 @@ def ctrsbox_sfista(xopt, g, H, projections, delta, h, L_h, prox_uh, argsh=(), ar
107107
# results on p313 (K1 for number of iterations, and the immediate next line for mu)
108108
# Note: in the book's notation, Gamma=delta^2, alpha=1, beta=L_h^2/2, Lf=k_H [alpha and beta from Thm 10.51]
109109
try:
110-
MAX_LOOP_ITERS = ceil(delta*(L_h+sqrt(L_h*L_h+2*k_H*func_tol)) / func_tol)
110+
MAX_LOOP_ITERS = ceil(sfista_iters_scale * delta * (L_h+sqrt(L_h*L_h+2*k_H*func_tol)) / func_tol)
111111
MAX_LOOP_ITERS = min(MAX_LOOP_ITERS, max_iters)
112112
except ValueError:
113113
MAX_LOOP_ITERS = max_iters
114114
u = 2 * delta / (MAX_LOOP_ITERS * L_h) # smoothing parameter
115+
# u = 2 * func_tol / (L_h ** 2 + L_h * sqrt(L_h ** 2 + 2 * k_H * func_tol)) # the above choice works better in practice
115116

116117
def gradient_Fu(xopt, g, H, u, prox_uh, d):
117118
# Calculate gradient_Fu,

0 commit comments

Comments
 (0)