From 5537e673bc43b9cbb2a5fe72cad871cd629fb47a Mon Sep 17 00:00:00 2001 From: Christoph Hansknecht Date: Tue, 23 Jan 2024 18:55:32 +0100 Subject: [PATCH 1/4] Remove iteration limit by default --- pygradflow/params.py | 3 ++- pygradflow/solver.py | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pygradflow/params.py b/pygradflow/params.py index 044e87b..c4e8fa9 100644 --- a/pygradflow/params.py +++ b/pygradflow/params.py @@ -2,6 +2,7 @@ import enum from dataclasses import dataclass from enum import Enum, Flag, auto +from typing import Optional import numpy as np @@ -167,7 +168,7 @@ class Params: validate_input: bool = True - iteration_limit: int = 1000 + iteration_limit: Optional[int] = None time_limit: float = np.inf display_interval: float = 0.1 diff --git a/pygradflow/solver.py b/pygradflow/solver.py index af29ec6..1a8fa25 100644 --- a/pygradflow/solver.py +++ b/pygradflow/solver.py @@ -356,8 +356,9 @@ def solve( path_dist = 0.0 initial_iterate = iterate accepted_steps = 0 + iteration = 0 - for iteration in range(params.iteration_limit): + while True: if line_diff == header_interval: line_diff = 0 logger.info(display.header) @@ -442,9 +443,14 @@ def solve( status = SolverStatus.Optimal break - else: - status = SolverStatus.IterationLimit - logger.debug("Iteration limit reached") + iteration += 1 + + if (params.iteration_limit is not None) and ( + iteration >= params.iteration_limit + ): + status = SolverStatus.IterationLimit + logger.debug("Iteration limit reached") + break curr_time = time.time() total_time = curr_time - start_time From 9ff1f43a4f995035d972b233a88560b45e43ac02 Mon Sep 17 00:00:00 2001 From: Christoph Hansknecht Date: Tue, 23 Jan 2024 18:56:16 +0100 Subject: [PATCH 2/4] Improve formatting in solver --- pygradflow/solver.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pygradflow/solver.py b/pygradflow/solver.py index 1a8fa25..58bfffc 100644 --- a/pygradflow/solver.py +++ b/pygradflow/solver.py @@ -265,25 +265,25 @@ def print_result( ) -> None: rho = self.rho - desc = "{:>30s}".format(SolverStatus.description(status)) + desc = "{:>45s}".format(SolverStatus.description(status)) status_desc = Format.redgreen(desc, SolverStatus.success(status), bold=True) - status_name = Format.bold("{:>30s}".format("Status")) + status_name = Format.bold("{:>20s}".format("Status")) - logger.info("%30s: %30s", status_name, status_desc) - logger.info("%30s: %30s", "Time", f"{total_time:.2f}s") - logger.info("%30s: %30d", "Iterations", iterations) - logger.info("%30s: %30d", "Accepted steps", accepted_steps) + logger.info("%20s: %45s", status_name, status_desc) + logger.info("%20s: %45s", "Time", f"{total_time:.2f}s") + logger.info("%20s: %45d", "Iterations", iterations) + logger.info("%20s: %45d", "Accepted steps", accepted_steps) - logger.info("%30s: %30e", "Distance factor", dist_factor) + logger.info("%20s: %45e", "Distance factor", dist_factor) - logger.info("%30s: %30e", "Objective", iterate.obj) - logger.info("%30s: %30e", "Aug Lag violation", iterate.aug_lag_violation(rho)) - logger.info("%30s: %30e", "Aug Lag dual", iterate.aug_lag_dual()) + logger.info("%20s: %45e", "Objective", iterate.obj) + logger.info("%20s: %45e", "Aug Lag violation", iterate.aug_lag_violation(rho)) + logger.info("%20s: %45e", "Aug Lag dual", iterate.aug_lag_dual()) - logger.info("%30s: %30e", "Bound violation", iterate.bound_violation) - logger.info("%30s: %30e", "Constraint violation", iterate.cons_violation) - logger.info("%30s: %30e", "Dual violation", iterate.stat_res) + logger.info("%20s: %45e", "Bound violation", iterate.bound_violation) + logger.info("%20s: %45e", "Constraint violation", iterate.cons_violation) + logger.info("%20s: %45e", "Dual violation", iterate.stat_res) def solve( self, x0: Optional[np.ndarray] = None, y0: Optional[np.ndarray] = None From de2a5745275956b3bd6a1bdf9d76dd5d97bd5bd5 Mon Sep 17 00:00:00 2001 From: Christoph Hansknecht Date: Tue, 23 Jan 2024 19:10:18 +0100 Subject: [PATCH 3/4] Capture warnings in runners --- pygradflow/runners/runner.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pygradflow/runners/runner.py b/pygradflow/runners/runner.py index 0859bbb..20b2d66 100644 --- a/pygradflow/runners/runner.py +++ b/pygradflow/runners/runner.py @@ -26,6 +26,11 @@ def try_solve_instance(instance, params, log_filename): logger.addHandler(handler) logger.setLevel(logging.INFO) + logging.captureWarnings(True) + warn_logger = logging.getLogger("py.warnings") + warn_logger.addHandler(handler) + warn_logger.setLevel(logging.WARN) + def solve(): return instance.solve(params) From 35c71238ee29ee196e1ac684226932b815cf991e Mon Sep 17 00:00:00 2001 From: Christoph Hansknecht Date: Tue, 23 Jan 2024 19:11:19 +0100 Subject: [PATCH 4/4] Bump version --- docs/conf.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index caf329e..c1f742f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ project = "pygradflow" copyright = "2023, Christoph Hansknecht" author = "Christoph Hansknecht" -release = "0.3.8" +release = "0.3.9" # -- General configuration --------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration diff --git a/pyproject.toml b/pyproject.toml index e6b735f..13d48d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pygradflow" -version = "0.3.8" +version = "0.3.9" description = "PyGradFlow is a simple implementation of the sequential homotopy method to be used to solve general nonlinear programs." authors = ["Christoph Hansknecht "] readme = "README.md"