def test_history(self): x0 = -np.array([1.3, 2.7]) opt = BFGS(self.oracle, x0, line_search_options={ 'method': 'Constant', 'c': 1.0 }, tolerance=1e-6) opt.run(10) x_min = opt.hist['x_star'] func_steps = [25.635000000000005, 22.99, -9.48707349065929, -9.5] grad_norm_steps = [11.629703349613008, 11.4, 0.22738961577617722, 0.0] time_steps = [0.0] * 4 # Dummy values x_steps = [ np.array([-1.3, -2.7]), np.array([1.0, 8.7]), np.array([1.0, 2.88630519]), np.array([1., 3.]) ] true_history = dict(grad_norm=grad_norm_steps, time=time_steps, x=x_steps, func=func_steps) check_equal_histories(opt.hist, true_history)
def test_quality(self): opt = BFGS(self.oracle, self.x0, tolerance=1e-5) opt.run(5) x_min = opt.hist['x_star'] # x_min, message, _ = LBFGS(self.oracle, self.x0, tolerance=1e-5) f_min = self.oracle.func(x_min) g_k_norm_sqr = norm(self.A.dot(x_min) - self.b, 2)**2 g_0_norm_sqr = norm(self.A.dot(self.x0) - self.b, 2)**2 self.assertLessEqual(g_k_norm_sqr, 1e-5 * g_0_norm_sqr) self.assertLessEqual(abs(f_min - self.f_star), 1e-5 * g_0_norm_sqr)
def test_default(self): """Check if everything works correctly with default parameters.""" opt = BFGS(self.oracle, self.x0) opt.run()
def test_max_iter(self): """Check if argument `max_iter` is supported.""" opt = BFGS(self.oracle, self.x0) opt.run(max_iter=0)
def run_all_methods(oracle, sketch_sizes, mat, max_iter, output_folder, x_0=None, sigma_tolerance=1e-10, method_tolerance=1e-16, stopping_criteria='func_abs', add_text='', random_state=None, linesearch_methods=['Wolfe'], methods=None, overwrite=False): import os os.system('mkdir -p {}'.format(output_folder)) if methods is None: methods = ['svd', 'svd-no-sigma', 'gauss', 'coord', 'bfgs', 'nesterov'] np.random.seed(random_state) if x_0 is None: x_0 = np.random.normal(loc=0., scale=1., size=mat.shape[1]) add_text = '_{}'.format(add_text) if add_text != '' else '' def run_rbfgs(mat_distr, line_search_options, distr_name, **kwargs): output_file = '{}/rbfgs_{}_linesearch={}{}.pkl'.format( output_folder, distr_name, line_search_options['method'].lower(), add_text) run_rbfgs_experiment(oracle, x_0, mat_distr=mat_distr, sketch_sizes=sketch_sizes, max_iter=max_iter, tolerance=method_tolerance, stopping_criteria=stopping_criteria, output_file=output_file, overwrite=overwrite, **kwargs) if 'svd' in methods or 'svd-no-sigma' in methods: try: with open('{}/svd.pkl'.format(output_folder), 'rb') as file: U, sigma_diag, Vh = pickle.load(file) print('Read SVD from {}/svd.pkl'.format(output_folder)) except FileNotFoundError: print('Computing SVD...', end='') U, sigma_diag, Vh = scipy.linalg.svd(mat.T, full_matrices=False) print('Done') with open('{}/svd.pkl'.format(output_folder), 'wb') as file: pickle.dump((U, sigma_diag, Vh), file) nondeg_count = (sigma_diag > sigma_tolerance).sum() print('Singular values above tolerance: {}'.format(nondeg_count)) print() if 'svd' in methods: print('RBFGS-SVD sketch... ', end='') mat_distr = CustomDiscrete(U[:, :nondeg_count], sort_ids=True) for ls in linesearch_methods: run_rbfgs(mat_distr, {'method': ls}, 'svd') print('Done') if 'svd-no-sigma' in methods: print('RBFGS-SVD sketch no sigma... ', end='') mat_distr = CustomDiscrete(U, sort_ids=True) for ls in linesearch_methods: run_rbfgs(mat_distr, {'method': ls}, 'svd-no-sigma') print('Done') if 'gauss' in methods: print('RBFGS-gauss... ', end='') mat_distr = Gaussian(-1., 1., [mat.shape[1], 1]) for ls in linesearch_methods: run_rbfgs(mat_distr, {'method': ls}, 'gauss') print('Done') if 'coord' in methods: print('RBFGS-coord...', end='') mat_distr = CustomDiscrete(np.eye(mat.shape[1]), sort_ids=True) for ls in linesearch_methods: run_rbfgs(mat_distr, {'method': ls}, 'coord') print('Done') if 'bfgs' in methods: print('BFGS... ', end='') for ls in linesearch_methods: if 'bfgs_linesearch={}{}.pkl'\ .format(ls.lower(), add_text) not in os.listdir(output_folder): method = BFGS(oracle, x_0, tolerance=method_tolerance, stopping_criteria=stopping_criteria, line_search_options={'method': 'Wolfe'}) method.run(max_iter) method.oracle = None method.H_k = None method.x_0 = None with open('{}/bfgs_linesearch={}{}.pkl'\ .format(output_folder, ls.lower(), add_text), 'wb') as file: pickle.dump(method, file) print('Done') print() print('All runs completed.')