Spaces:
Running on Zero
Running on Zero
| """Robust control and uncertain system tools.""" | |
| from __future__ import annotations | |
| from typing import Any | |
| import numpy as np | |
| from controlai_agent.registry import registry | |
| def kharitonov_stability_test(lower_bounds: list[float], upper_bounds: list[float]) -> dict[str, Any]: | |
| lows = np.array(lower_bounds, dtype=float) | |
| highs = np.array(upper_bounds, dtype=float) | |
| polys = [ | |
| [lows[0], lows[1], highs[2], highs[3]], | |
| [highs[0], highs[1], lows[2], lows[3]], | |
| [highs[0], lows[1], lows[2], highs[3]], | |
| [lows[0], highs[1], highs[2], lows[3]], | |
| ] | |
| pole_sets = [] | |
| stable_flags = [] | |
| for poly in polys: | |
| desc_poly = poly[::-1] # descending for np.roots | |
| roots = np.roots(desc_poly) | |
| pole_sets.append([[float(r.real), float(r.imag)] for r in roots]) | |
| stable_flags.append(bool(np.all(np.real(roots) < 0))) | |
| robustly_stable = all(stable_flags) | |
| return { | |
| "kharitonov_polynomials_ascending": polys, | |
| "stable_flags": stable_flags, | |
| "is_robustly_hurwitz": robustly_stable, | |
| "poles": pole_sets, | |
| } | |
| def small_gain_test(gamma1: float, gamma2: float) -> dict[str, Any]: | |
| product = gamma1 * gamma2 | |
| certified = bool(product < 1.0) | |
| return { | |
| "norm_product": product, | |
| "is_stability_certified": certified, | |
| "stability_margin": 1.0 - product if certified else 0.0, | |
| } | |
| def multiplicative_uncertainty_test( | |
| weights: list[float], complementary_sensitivity: list[float] | |
| ) -> dict[str, Any]: | |
| w_arr = np.array(weights, dtype=float) | |
| t_arr = np.array(complementary_sensitivity, dtype=float) | |
| products = w_arr * t_arr | |
| peak = float(np.max(products)) | |
| is_satisfied = bool(peak < 1.0) | |
| return { | |
| "pointwise_products": products.tolist(), | |
| "peak_weighted_product": peak, | |
| "is_robustly_stable_on_grid": is_satisfied, | |
| } | |