proxax 0.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- proxax-0.0.1/.github/workflows/publish.yml +54 -0
- proxax-0.0.1/.gitignore +32 -0
- proxax-0.0.1/AGENTS.md +56 -0
- proxax-0.0.1/DESIGN.md +57 -0
- proxax-0.0.1/LICENSE +21 -0
- proxax-0.0.1/PKG-INFO +95 -0
- proxax-0.0.1/README.md +55 -0
- proxax-0.0.1/docs/api.md +121 -0
- proxax-0.0.1/docs/conf.py +21 -0
- proxax-0.0.1/docs/index.md +22 -0
- proxax-0.0.1/docs/nc_opt_reference.md +74 -0
- proxax-0.0.1/pyproject.toml +115 -0
- proxax-0.0.1/src/proxax/__init__.py +79 -0
- proxax-0.0.1/src/proxax/_loop.py +67 -0
- proxax-0.0.1/src/proxax/_typing.py +39 -0
- proxax-0.0.1/src/proxax/certificates/__init__.py +14 -0
- proxax-0.0.1/src/proxax/certificates/stationarity.py +168 -0
- proxax-0.0.1/src/proxax/constraints/__init__.py +62 -0
- proxax-0.0.1/src/proxax/constraints/linear_op.py +542 -0
- proxax-0.0.1/src/proxax/constraints/sets.py +158 -0
- proxax-0.0.1/src/proxax/optax_compat/__init__.py +33 -0
- proxax-0.0.1/src/proxax/optax_compat/transforms.py +2598 -0
- proxax-0.0.1/src/proxax/oracle/__init__.py +39 -0
- proxax-0.0.1/src/proxax/oracle/composite.py +390 -0
- proxax-0.0.1/src/proxax/oracle/spectral.py +640 -0
- proxax-0.0.1/src/proxax/oracle/terms.py +140 -0
- proxax-0.0.1/src/proxax/problem.py +102 -0
- proxax-0.0.1/src/proxax/prox/__init__.py +42 -0
- proxax-0.0.1/src/proxax/prox/base.py +117 -0
- proxax-0.0.1/src/proxax/prox/combinators.py +83 -0
- proxax-0.0.1/src/proxax/prox/indicators.py +201 -0
- proxax-0.0.1/src/proxax/prox/norms.py +191 -0
- proxax-0.0.1/src/proxax/py.typed +0 -0
- proxax-0.0.1/src/proxax/solve.py +175 -0
- proxax-0.0.1/src/proxax/solvers/__init__.py +101 -0
- proxax-0.0.1/src/proxax/solvers/base.py +110 -0
- proxax-0.0.1/src/proxax/solvers/constrained/__init__.py +33 -0
- proxax-0.0.1/src/proxax/solvers/constrained/iaipal.py +654 -0
- proxax-0.0.1/src/proxax/solvers/constrained/ialm.py +604 -0
- proxax-0.0.1/src/proxax/solvers/constrained/qp_aipp.py +420 -0
- proxax-0.0.1/src/proxax/solvers/constrained/qp_apd.py +432 -0
- proxax-0.0.1/src/proxax/solvers/constrained/s_prox_alm.py +491 -0
- proxax-0.0.1/src/proxax/solvers/inner/__init__.py +34 -0
- proxax-0.0.1/src/proxax/solvers/inner/acg.py +335 -0
- proxax-0.0.1/src/proxax/solvers/inner/pf_acg.py +359 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/__init__.py +63 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/ac_acg.py +332 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/adap_apg.py +519 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/adap_fista.py +443 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/ag.py +377 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/aipp.py +439 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/apd.py +501 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/da_icg.py +488 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/ecg.py +409 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/ia_icg.py +458 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/nc_fista.py +321 -0
- proxax-0.0.1/src/proxax/solvers/unconstrained/upfag.py +589 -0
- proxax-0.0.1/src/proxax/tree.py +189 -0
- proxax-0.0.1/tests/conftest.py +7 -0
- proxax-0.0.1/tests/test_ac_acg.py +34 -0
- proxax-0.0.1/tests/test_adap_apg.py +36 -0
- proxax-0.0.1/tests/test_adap_fista.py +20 -0
- proxax-0.0.1/tests/test_ag.py +31 -0
- proxax-0.0.1/tests/test_aipp.py +62 -0
- proxax-0.0.1/tests/test_apd.py +101 -0
- proxax-0.0.1/tests/test_da_icg.py +37 -0
- proxax-0.0.1/tests/test_ecg.py +35 -0
- proxax-0.0.1/tests/test_ia_icg.py +35 -0
- proxax-0.0.1/tests/test_iaipal.py +50 -0
- proxax-0.0.1/tests/test_ialm.py +84 -0
- proxax-0.0.1/tests/test_linear_op_and_oracles.py +83 -0
- proxax-0.0.1/tests/test_nc_fista.py +46 -0
- proxax-0.0.1/tests/test_optax_compat.py +267 -0
- proxax-0.0.1/tests/test_prox_and_sets.py +77 -0
- proxax-0.0.1/tests/test_qp_aipp.py +76 -0
- proxax-0.0.1/tests/test_qp_apd.py +73 -0
- proxax-0.0.1/tests/test_s_prox_alm.py +40 -0
- proxax-0.0.1/tests/test_smoke.py +15 -0
- proxax-0.0.1/tests/test_upfag.py +31 -0
- proxax-0.0.1/uv.lock +2262 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
build:
|
|
14
|
+
name: Build and test distributions
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: astral-sh/setup-uv@v7
|
|
19
|
+
- name: Run lint, type-check, docs, and unit tests
|
|
20
|
+
env:
|
|
21
|
+
XLA_PYTHON_CLIENT_PREALLOCATE: "false"
|
|
22
|
+
run: |
|
|
23
|
+
uv sync --python 3.12 --extra dev --extra docs
|
|
24
|
+
uv run ruff check .
|
|
25
|
+
uv run mypy
|
|
26
|
+
uv run sphinx-build -W -b html docs site
|
|
27
|
+
uv run pytest -v
|
|
28
|
+
- name: Build sdist and wheel
|
|
29
|
+
run: uv build
|
|
30
|
+
- name: Upload distribution artifacts
|
|
31
|
+
uses: actions/upload-artifact@v4
|
|
32
|
+
with:
|
|
33
|
+
name: python-package-distributions
|
|
34
|
+
path: dist/
|
|
35
|
+
|
|
36
|
+
publish:
|
|
37
|
+
name: Publish to PyPI
|
|
38
|
+
needs: build
|
|
39
|
+
runs-on: ubuntu-latest
|
|
40
|
+
environment:
|
|
41
|
+
name: pypi
|
|
42
|
+
url: https://pypi.org/p/proxax
|
|
43
|
+
permissions:
|
|
44
|
+
id-token: write
|
|
45
|
+
contents: read
|
|
46
|
+
steps:
|
|
47
|
+
- uses: astral-sh/setup-uv@v7
|
|
48
|
+
- name: Download distribution artifacts
|
|
49
|
+
uses: actions/download-artifact@v4
|
|
50
|
+
with:
|
|
51
|
+
name: python-package-distributions
|
|
52
|
+
path: dist/
|
|
53
|
+
- name: Publish package to PyPI
|
|
54
|
+
run: uv publish --trusted-publishing always
|
proxax-0.0.1/.gitignore
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# Distribution / packaging
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
.eggs/
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# Testing, type-checking, and linting caches
|
|
18
|
+
.pytest_cache/
|
|
19
|
+
.ruff_cache/
|
|
20
|
+
.mypy_cache/
|
|
21
|
+
.pyright/
|
|
22
|
+
.coverage
|
|
23
|
+
htmlcov/
|
|
24
|
+
|
|
25
|
+
# Documentation build output
|
|
26
|
+
site/
|
|
27
|
+
|
|
28
|
+
# IDE & OS artifacts
|
|
29
|
+
.vscode/
|
|
30
|
+
.idea/
|
|
31
|
+
.DS_Store
|
|
32
|
+
Thumbs.db
|
proxax-0.0.1/AGENTS.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# `proxax` — Workspace Rules & Agent Context
|
|
2
|
+
|
|
3
|
+
`proxax` (https://github.com/wwkong/proxax) is a Python library of **certified first-order proximal point methods** for unconstrained and set/cone-constrained nonconvex composite optimization in **JAX** and **Optax**, inspired by Weiwei (William) Kong's MATLAB framework **[`wwkong/nc_opt`](https://github.com/wwkong/nc_opt)** and papers (including **`AIPP`**, **`QP-AIPP`**, **`PF.APD` / `APD`** at https://wwkong.github.io/files/publications/apd.pdf, and **`NL-IAPIAL` / `AIDAL`**).
|
|
4
|
+
|
|
5
|
+
Read `DESIGN.md` for mathematical formulations and `docs/nc_opt_reference.md` for the detailed mapping to `wwkong/nc_opt`, the complete **`PF.APD` (`apd.pdf`)** specification, and the Phase 2+ roadmap.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Environment & Verification Commands (WSL2 Primary Workspace)
|
|
10
|
+
|
|
11
|
+
- **Canonical Repo Path:** `/home/wkong/Projects/proxax` (`origin`: `https://github.com/wwkong/proxax.git`, branch `main`).
|
|
12
|
+
- **Package Manager & Runtime:** `uv` (`pyproject.toml` + `uv.lock`) with Python 3.14, `jax[cuda13]`, and `optax`.
|
|
13
|
+
- **Runtime Dependency Rule:** `src/proxax/` must depend **strictly on `jax` and `optax` only** (zero SciPy / CVXPY / Equinox / Flax runtime dependencies).
|
|
14
|
+
- **GPU Memory Rule (12 GB RTX 3060 shared with Windows host):**
|
|
15
|
+
- Always ensure `XLA_PYTHON_CLIENT_PREALLOCATE=false` when running JAX on GPU (`tests/conftest.py` and `docs/conf.py` set this automatically).
|
|
16
|
+
- **Keep unit tests tiny, fast (< 10s total), and low-memory** (2D–4D problems, tight iteration caps, `jax.lax.while_loop` over long Python dispatch loops). Never introduce large matrices or long-running benchmarks into `tests/`.
|
|
17
|
+
|
|
18
|
+
Run all four verification gates via `uv` before committing:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
uv run ruff check .
|
|
22
|
+
uv run mypy
|
|
23
|
+
XLA_PYTHON_CLIENT_PREALLOCATE=false uv run pytest -v
|
|
24
|
+
XLA_PYTHON_CLIENT_PREALLOCATE=false uv run sphinx-build -W -b html docs site
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. Strict Coding & Style Conventions (Google Python Style Guide)
|
|
30
|
+
|
|
31
|
+
1. **80-Column Line Limit:** Enforced by `ruff` (`line-length = 80`, `indent-width = 2` or standard 2/4-space blocks; match existing module style and pass `uv run ruff check .`).
|
|
32
|
+
2. **Module-Only Imports (`TID253` / Google Style):**
|
|
33
|
+
- Always import modules, never classes/functions directly (except `typing` / `collections.abc` when module-qualified):
|
|
34
|
+
- Good: `import dataclasses`, `import typing`, `from collections import abc`, `from proxax import tree`, `from proxax.prox import base as prox_base`.
|
|
35
|
+
- Bad: `from dataclasses import dataclass`, `from proxax.prox.base import ProxOperator`.
|
|
36
|
+
- Avoid `B008` function calls in default parameter values (bind module-level finals like `_ZERO_PROX: typing.Final = prox_base.Zero()`).
|
|
37
|
+
3. **Immutable PyTree Dataclasses & Strict Typing (`mypy --strict`):**
|
|
38
|
+
- Use `@dataclasses.dataclass(frozen=True, slots=True, kw_only=True)` for solvers, configs, problems, states, and results.
|
|
39
|
+
- When registering dataclasses with `meta_fields` / `data_fields`, call `jax.tree_util.register_dataclass(Cls, data_fields=[...], meta_fields=[...])` after the class definition so `mypy --strict` resolves types cleanly against JAX stubs.
|
|
40
|
+
- Use `tree.eps(dtype)` (`float(np.finfo(dtype).eps)`) instead of untyped `jnp.finfo(dtype).eps`.
|
|
41
|
+
4. **Sphinx / Google Docstrings:**
|
|
42
|
+
- Avoid trailing `'s` attached directly to single-backtick inline literals (write `` `Constraint` objects `` instead of `` `Constraint`s ``) and keep blank lines around bullet/formula blocks so `sphinx-build -W` passes with zero warnings.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 3. Core Mathematical & Numerical Invariants (Do Not Break)
|
|
47
|
+
|
|
48
|
+
1. **Exact Stationarity Certificates (`src/proxax/certificates/stationarity.py`):**
|
|
49
|
+
- Every solver returns a certified refined point `x_hat = prox_{(1/L) h}(y - (1/L) grad_f(y))` and exact composite subgradient `v_hat = grad_f(x_hat) - grad_f(y) + L * (y - x_hat) in grad_f(x_hat) + dh(x_hat)` (plus `A^*(p_hat)` in constrained problems), never raw unrefined inner iterates.
|
|
50
|
+
2. **Strongly-Convex 1-Prox `ACG` (`src/proxax/solvers/inner/acg.py`):**
|
|
51
|
+
- Maintains the exact $\mu$-strongly convex estimating sequence with $c_\mu = 1 + \mu A_t$, $b_\mu = 1 + 2\mu A_t$, $d_\mu = 1 + \mu A_{t+1}$, convex combination weights $(A_t d_\mu, a_t c_\mu)$, and exact $\varepsilon$-subgradient pair $(u_{t+1}, \eta_{t+1}) \in \partial_{\eta_{t+1}} \psi(y_{t+1})$.
|
|
52
|
+
3. **IEEE `float32` Adaptive Smoothness Noise-Floor Guard:**
|
|
53
|
+
- Only relax `L_next = L_used * ls_decrease` when `0.5 * L_used * ||y_next - x_tilde||^2 > 100 * eps * (1 + |f|)`. Without this guard, `L` decays toward `0` when step norms fall below $\sqrt{\epsilon_{\text{mach}}} \approx 3.5 \times 10^{-4}$ in `float32`.
|
|
54
|
+
- When `lower_curvature == 0.0` (convex `f`), calibrate default `lam0 = 10.0 / max(L0, 1e-6)` rather than huge values like `1e3` so `1 / lam` stays well above the `float32` precision floor in the $\sigma$-criterion.
|
|
55
|
+
4. **Curvature Preservation Across Penalty / ALM Stages (`src/proxax/oracle/composite.py`):**
|
|
56
|
+
- `PenalizedOracle` adds the convex Moreau envelope $\psi_c(x; \bar{p}) = \frac{c}{2}\|w(x) - \Pi_{\mathcal{C}}(w(x))\|_2^2 - \frac{\|\bar{p}\|_2^2}{2c}$ where $w(x) = \mathcal{A}(x) + \bar{p}/c$ and $\bar{p} = (1 - \theta) p$. Because $\psi_c$ is convex, `curvature_lower` $m$ of $f$ is unchanged as $c_k$ grows, so proximal steps $\lambda_k$ must **never** shrink as $O(1/c_k)$.
|
proxax-0.0.1/DESIGN.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Architecture & MVP Implementation Plan: `proxax`
|
|
2
|
+
|
|
3
|
+
## 1. Core Architectural Pillars & Standards
|
|
4
|
+
|
|
5
|
+
**`proxax`** is a JAX/Optax-native Python library for certified first-order proximal point methods on unconstrained and linearly/set-constrained nonconvex composite optimization problems.
|
|
6
|
+
|
|
7
|
+
### Engineering & Style Standards
|
|
8
|
+
- **Dependencies:** Strictly **`jax`** and **`optax`** at runtime (leveraging `optax.projections` and `optax.tree` directly; zero third-party framework lock-in).
|
|
9
|
+
- **Code Style:** **Google Python Style Guide**, strictly enforced via `ruff` (80-column line limit, `convention = "google"`, module-only imports via `flake8-tidy-imports` / `isort`) and `mypy --strict`:
|
|
10
|
+
- Module-only imports everywhere (`import dataclasses`, `import typing`, `from collections import abc`, `from proxax import prox`).
|
|
11
|
+
- `@dataclasses.dataclass(frozen=True, slots=True, kw_only=True)` for all configs, solvers, problems, states, and results (paired with `jax.tree_util.register_dataclass` for PyTree states/oracles). Unary math primitives (e.g., `prox.L1(0.1)`) keep their single primary value positional and optional metadata `kw_only`.
|
|
12
|
+
- Structural subtyping via **`typing.Protocol`** (`ProxOperator`, `ConvexSet`, `LinearOperator`, `CompositeOracleProtocol`).
|
|
13
|
+
- **Documentation:** **Sphinx + MyST-Parser + Furo + MathJax** (`uv run sphinx-build -W -b html docs site`).
|
|
14
|
+
- **Environment & Packaging:** **`uv`** (`pyproject.toml` + `uv.lock`) in WSL2 (`/home/wkong/Projects/proxax`), pushed to `https://github.com/wwkong/proxax`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## 2. Unified Mathematical Formulations
|
|
19
|
+
|
|
20
|
+
### 2.1. Unconstrained Composite Problem
|
|
21
|
+
$$
|
|
22
|
+
\min_{x \in \mathcal{X}} \; \phi(x) := f(x) + h(x)
|
|
23
|
+
$$
|
|
24
|
+
- $\mathcal{X}$: Arbitrary PyTree of JAX arrays (inner product $\langle u, v \rangle = \text{optax.tree.vdot}(u, v)$).
|
|
25
|
+
- $f: \mathcal{X} \to \mathbb{R}$ (`smooth`): Differentiable, $(m, L^+)$-weakly convex/smooth ($-\frac{m}{2}\|x-y\|^2 \le f(x) - f(y) - \langle \nabla f(y), x-y \rangle \le \frac{L^+}{2}\|x-y\|^2$).
|
|
26
|
+
- $h: \mathcal{X} \to (-\infty, +\infty]$ (`proximal`): Proper, closed, $\mu$-strongly convex ($\mu \ge 0$) with cheap $\operatorname{prox}_{\gamma h}$ and domain projection $\Pi_{\operatorname{dom}(h)}$.
|
|
27
|
+
- **Certified Output:** Refined pair $(\hat{x}, \hat{v})$ satisfying $\hat{v} \in \nabla f(\hat{x}) + \partial h(\hat{x})$ and $\|\hat{v}\| \le \rho$.
|
|
28
|
+
|
|
29
|
+
### 2.2. Set / Cone-Constrained Composite Problem
|
|
30
|
+
$$
|
|
31
|
+
\min_{x \in \mathcal{X}} \; f(x) + h(x) \quad \text{s.t.} \quad \mathcal{A}(x) \in \mathcal{C}
|
|
32
|
+
$$
|
|
33
|
+
- $\mathcal{A}: \mathcal{X} \to \mathcal{Y}$: Linear map between PyTrees (dense/sparse matrix, `(matvec, rmatvec)` pair, or forward-only callable bound lazily to `x0` via `jax.linear_transpose`).
|
|
34
|
+
- $\mathcal{C} \subseteq \mathcal{Y}$: **Any closed convex set** with Euclidean projection $\Pi_{\mathcal{C}}$ (singletons $\{b\}$ for $\mathcal{A}(x) = b$, halfspaces $(-\infty, b]$, boxes $[l, u]$, SOC, PSD cone, or named PyTree dicts via `ProductConvexSet`).
|
|
35
|
+
- **Unified Penalty / AL Smooth Term** (for multiplier $\bar{p}$ and penalty $c > 0$, with $\bar{p} = 0$ for pure quadratic penalty in `QPAIPP` and $\bar{p} = (1-\theta)p$ for ALM variants):
|
|
36
|
+
$$
|
|
37
|
+
\psi_c(x; \bar{p}) = \frac{c}{2}\left\|w(x) - \Pi_{\mathcal{C}}(w(x))\right\|^2 - \frac{\|\bar{p}\|^2}{2c}, \qquad w(x) := \mathcal{A}(x) + \frac{\bar{p}}{c}
|
|
38
|
+
$$
|
|
39
|
+
with smooth gradient $\nabla_x \psi_c(x; \bar{p}) = \mathcal{A}^* \hat{p}(x)$, where $\hat{p}(x) := c\big(w(x) - \Pi_{\mathcal{C}}(w(x))\big) \in \mathcal{N}_{\mathcal{C}}\big(\Pi_{\mathcal{C}}(w(x))\big)$.
|
|
40
|
+
- **Certified KKT Output:** $(\hat{x}, \hat{p}, \hat{v})$ with $\hat{v} \in \nabla f(\hat{x}) + \partial h(\hat{x}) + \mathcal{A}^* \hat{p}$, $\|\hat{v}\| \le \rho$, and $\operatorname{dist}_{\mathcal{C}}(\mathcal{A}(\hat{x})) = \|\mathcal{A}(\hat{x}) - \Pi_{\mathcal{C}}(\mathcal{A}(\hat{x}))\| \le \eta$.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 3. Key Architectural Safeguards
|
|
45
|
+
|
|
46
|
+
1. **Zero Re-Compilation Oracles:** `ProxRegularizedOracle` and `PenalizedOracle` are `@jax.tree_util.register_dataclass` structs with static callables in `meta_fields` and dynamic JAX arrays (`center`, `smooth_reg`, `prox_reg`, `multiplier`, `penalty`) in `data_fields`.
|
|
47
|
+
2. **Safe Curvature Splitting:** `ProxRegularizedOracle` splits $\frac{1}{\lambda} = \alpha_{\text{smooth}} + \mu_{\text{prox}}$ explicitly—never claiming $\mu_{\text{prox}} > 0$ unless `curvature_lower` $m$ is known or validated by adaptive descent/convexity checks.
|
|
48
|
+
3. **`vmap`-Fast Nested Loops vs. Optax Adapter:** `proxax.solve(..., jit=True)` uses nested `jax.lax.while_loop`s so `refine` only runs once per outer step even under `jax.vmap`. `proxax.optax_compat` provides the flattened per-inner-step `GradientTransformationExtraArgs` state machine while keeping `params` equal to the feasible primal iterate $y_t$.
|
|
49
|
+
4. **Safe Initialization & Flexible Stopping:** `solver.init` projects `x0` onto $\operatorname{dom}(h)$ via `proximal.domain_project(x0)` before any gradient evaluation, and `StoppingConfig` supports both $\ell_2$ and $\ell_\infty$ norms plus optional relative tolerances.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 4. MVP Execution Milestones (Atomic Git Commits)
|
|
54
|
+
|
|
55
|
+
1. **Milestone 1 — Tooling & Core Math Primitives:** `_typing.py`, `_loop.py`, `tree.py`, `prox/`, `constraints/`, `oracle/`, `certificates/stationarity.py`, `problem.py` + unit tests.
|
|
56
|
+
2. **Milestone 2 — `ACG` & Unconstrained `AIPP`:** `solvers/base.py`, `solvers/inner/acg.py`, `solvers/unconstrained/aipp.py`, `proxax.solve()` + nonconvex composite tests (`jit=True`, `jit=False`, `vmap`).
|
|
57
|
+
3. **Milestone 3 — Constrained `QPAIPP` & Optax State Machine:** `solvers/constrained/qp_aipp.py`, `optax_compat/transforms.py` + constrained nonconvex QP and PyTree Optax training-loop tests.
|
proxax-0.0.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 William Kong
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
proxax-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: proxax
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Certified first-order proximal point methods for composite optimization in JAX and Optax.
|
|
5
|
+
Project-URL: Homepage, https://github.com/wwkong/proxax
|
|
6
|
+
Project-URL: Repository, https://github.com/wwkong/proxax
|
|
7
|
+
Project-URL: Issues, https://github.com/wwkong/proxax/issues
|
|
8
|
+
Author-email: William Kong <wwkong92@gmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: augmented-lagrangian,composite-optimization,jax,nonconvex-optimization,optax,optimization,proximal
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: jax>=0.4.30
|
|
25
|
+
Requires-Dist: optax>=0.2.2
|
|
26
|
+
Provides-Extra: cuda12
|
|
27
|
+
Requires-Dist: jax[cuda12]>=0.4.30; extra == 'cuda12'
|
|
28
|
+
Provides-Extra: cuda13
|
|
29
|
+
Requires-Dist: jax[cuda13]>=0.5.0; extra == 'cuda13'
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: mypy>=1.11; extra == 'dev'
|
|
32
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
34
|
+
Provides-Extra: docs
|
|
35
|
+
Requires-Dist: furo>=2024.8; extra == 'docs'
|
|
36
|
+
Requires-Dist: myst-parser>=4.0; extra == 'docs'
|
|
37
|
+
Requires-Dist: sphinx-autodoc-typehints>=2.4; extra == 'docs'
|
|
38
|
+
Requires-Dist: sphinx>=8.0; extra == 'docs'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# `proxax`
|
|
42
|
+
|
|
43
|
+
Certified first-order proximal point methods for unconstrained and constrained
|
|
44
|
+
nonconvex composite optimization in **JAX** and **Optax**.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install proxax
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or with `uv`:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uv add proxax
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Problem Classes
|
|
59
|
+
|
|
60
|
+
1. **Unconstrained Nonconvex Composite Optimization:**
|
|
61
|
+
$$\min_{x \in \mathcal{X}} \; f(x) + h(x)$$
|
|
62
|
+
where $f$ (`smooth`) is differentiable and $(m, L^+)$-weakly convex/smooth on
|
|
63
|
+
an arbitrary JAX PyTree $\mathcal{X}$, and $h$ (`proximal`) is proper,
|
|
64
|
+
closed, convex, and proximable.
|
|
65
|
+
|
|
66
|
+
2. **Set / Cone-Constrained Nonconvex Composite Optimization:**
|
|
67
|
+
$$\min_{x \in \mathcal{X}} \; f(x) + h(x) \quad \text{s.t.} \quad \mathcal{A}(x) \in \mathcal{C}$$
|
|
68
|
+
where $\mathcal{A}: \mathcal{X} \to \mathcal{Y}$ is a linear map between
|
|
69
|
+
PyTrees and $\mathcal{C} \subseteq \mathcal{Y}$ is a closed convex set with
|
|
70
|
+
Euclidean projection $\Pi_{\mathcal{C}}$.
|
|
71
|
+
|
|
72
|
+
## Quick Example
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import jax.numpy as jnp
|
|
76
|
+
import proxax
|
|
77
|
+
from proxax import constraints
|
|
78
|
+
from proxax import prox
|
|
79
|
+
from proxax import solvers
|
|
80
|
+
|
|
81
|
+
problem = proxax.CompositeProblem(
|
|
82
|
+
smooth=lambda x: 0.5 * jnp.dot(x, q_mat @ x) + jnp.dot(c_vec, x),
|
|
83
|
+
proximal=prox.Box(lower=-1.0, upper=1.0),
|
|
84
|
+
constraints=constraints.equality(lambda x: a_mat @ x, rhs=b_vec),
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
sol = proxax.solve(problem, x0, solver=solvers.QPAIPP(opt_tol=1e-5, feas_tol=1e-5))
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Available Certified Solvers (`wwkong/nc_opt` Suite)
|
|
91
|
+
|
|
92
|
+
- **Unconstrained Composite (`CompositeProblem`):** `AIPP`, `APD` (`PF.APD`), `ECG`, `AG`, `UPFAG`, `NCFISTA`, `AdapFISTA`, `ACACG`, `AdapAPG`
|
|
93
|
+
- **Unconstrained Spectral (`SpectralProblem` / `NuclearNorm`):** `IAICG`, `DAICG`
|
|
94
|
+
- **Set / Cone-Constrained (`CompositeProblem` with `constraints`):** `QPAIPP`, `QPAPD`, `IALM` (`NL-IAPIAL` / `AIDAL`), `SProxALM`, `IAIPAL`
|
|
95
|
+
- **Optax Single-Step Transforms (`proxax.optax_compat`):** `proximal`, `aipp`, `apd`, `qp_aipp`, `qp_apd`, `ialm`
|
proxax-0.0.1/README.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# `proxax`
|
|
2
|
+
|
|
3
|
+
Certified first-order proximal point methods for unconstrained and constrained
|
|
4
|
+
nonconvex composite optimization in **JAX** and **Optax**.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install proxax
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or with `uv`:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
uv add proxax
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Problem Classes
|
|
19
|
+
|
|
20
|
+
1. **Unconstrained Nonconvex Composite Optimization:**
|
|
21
|
+
$$\min_{x \in \mathcal{X}} \; f(x) + h(x)$$
|
|
22
|
+
where $f$ (`smooth`) is differentiable and $(m, L^+)$-weakly convex/smooth on
|
|
23
|
+
an arbitrary JAX PyTree $\mathcal{X}$, and $h$ (`proximal`) is proper,
|
|
24
|
+
closed, convex, and proximable.
|
|
25
|
+
|
|
26
|
+
2. **Set / Cone-Constrained Nonconvex Composite Optimization:**
|
|
27
|
+
$$\min_{x \in \mathcal{X}} \; f(x) + h(x) \quad \text{s.t.} \quad \mathcal{A}(x) \in \mathcal{C}$$
|
|
28
|
+
where $\mathcal{A}: \mathcal{X} \to \mathcal{Y}$ is a linear map between
|
|
29
|
+
PyTrees and $\mathcal{C} \subseteq \mathcal{Y}$ is a closed convex set with
|
|
30
|
+
Euclidean projection $\Pi_{\mathcal{C}}$.
|
|
31
|
+
|
|
32
|
+
## Quick Example
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
import jax.numpy as jnp
|
|
36
|
+
import proxax
|
|
37
|
+
from proxax import constraints
|
|
38
|
+
from proxax import prox
|
|
39
|
+
from proxax import solvers
|
|
40
|
+
|
|
41
|
+
problem = proxax.CompositeProblem(
|
|
42
|
+
smooth=lambda x: 0.5 * jnp.dot(x, q_mat @ x) + jnp.dot(c_vec, x),
|
|
43
|
+
proximal=prox.Box(lower=-1.0, upper=1.0),
|
|
44
|
+
constraints=constraints.equality(lambda x: a_mat @ x, rhs=b_vec),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
sol = proxax.solve(problem, x0, solver=solvers.QPAIPP(opt_tol=1e-5, feas_tol=1e-5))
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Available Certified Solvers (`wwkong/nc_opt` Suite)
|
|
51
|
+
|
|
52
|
+
- **Unconstrained Composite (`CompositeProblem`):** `AIPP`, `APD` (`PF.APD`), `ECG`, `AG`, `UPFAG`, `NCFISTA`, `AdapFISTA`, `ACACG`, `AdapAPG`
|
|
53
|
+
- **Unconstrained Spectral (`SpectralProblem` / `NuclearNorm`):** `IAICG`, `DAICG`
|
|
54
|
+
- **Set / Cone-Constrained (`CompositeProblem` with `constraints`):** `QPAIPP`, `QPAPD`, `IALM` (`NL-IAPIAL` / `AIDAL`), `SProxALM`, `IAIPAL`
|
|
55
|
+
- **Optax Single-Step Transforms (`proxax.optax_compat`):** `proximal`, `aipp`, `apd`, `qp_aipp`, `qp_apd`, `ialm`
|
proxax-0.0.1/docs/api.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# API Reference
|
|
2
|
+
|
|
3
|
+
## Top-Level Problem & Dispatcher
|
|
4
|
+
|
|
5
|
+
```{eval-rst}
|
|
6
|
+
.. automodule:: proxax.problem
|
|
7
|
+
:members:
|
|
8
|
+
|
|
9
|
+
.. automodule:: proxax.solve
|
|
10
|
+
:members:
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Proximal Operators (`proxax.prox`)
|
|
14
|
+
|
|
15
|
+
```{eval-rst}
|
|
16
|
+
.. automodule:: proxax.prox.base
|
|
17
|
+
:members:
|
|
18
|
+
|
|
19
|
+
.. automodule:: proxax.prox.norms
|
|
20
|
+
:members:
|
|
21
|
+
|
|
22
|
+
.. automodule:: proxax.prox.indicators
|
|
23
|
+
:members:
|
|
24
|
+
|
|
25
|
+
.. automodule:: proxax.prox.combinators
|
|
26
|
+
:members:
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Convex Sets & Constraints (`proxax.constraints`)
|
|
30
|
+
|
|
31
|
+
```{eval-rst}
|
|
32
|
+
.. automodule:: proxax.constraints.sets
|
|
33
|
+
:members:
|
|
34
|
+
|
|
35
|
+
.. automodule:: proxax.constraints.linear_op
|
|
36
|
+
:members:
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Oracles & Stationarity Refinement
|
|
40
|
+
|
|
41
|
+
```{eval-rst}
|
|
42
|
+
.. automodule:: proxax.oracle.terms
|
|
43
|
+
:members:
|
|
44
|
+
|
|
45
|
+
.. automodule:: proxax.oracle.composite
|
|
46
|
+
:members:
|
|
47
|
+
|
|
48
|
+
.. automodule:: proxax.oracle.spectral
|
|
49
|
+
:members:
|
|
50
|
+
|
|
51
|
+
.. automodule:: proxax.certificates.stationarity
|
|
52
|
+
:members:
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Solvers (`proxax.solvers`)
|
|
56
|
+
|
|
57
|
+
```{eval-rst}
|
|
58
|
+
.. automodule:: proxax.solvers.base
|
|
59
|
+
:members:
|
|
60
|
+
|
|
61
|
+
.. automodule:: proxax.solvers.inner.acg
|
|
62
|
+
:members:
|
|
63
|
+
|
|
64
|
+
.. automodule:: proxax.solvers.inner.pf_acg
|
|
65
|
+
:members:
|
|
66
|
+
|
|
67
|
+
.. automodule:: proxax.solvers.unconstrained.aipp
|
|
68
|
+
:members:
|
|
69
|
+
|
|
70
|
+
.. automodule:: proxax.solvers.unconstrained.apd
|
|
71
|
+
:members:
|
|
72
|
+
|
|
73
|
+
.. automodule:: proxax.solvers.unconstrained.ecg
|
|
74
|
+
:members:
|
|
75
|
+
|
|
76
|
+
.. automodule:: proxax.solvers.unconstrained.ag
|
|
77
|
+
:members:
|
|
78
|
+
|
|
79
|
+
.. automodule:: proxax.solvers.unconstrained.upfag
|
|
80
|
+
:members:
|
|
81
|
+
|
|
82
|
+
.. automodule:: proxax.solvers.unconstrained.nc_fista
|
|
83
|
+
:members:
|
|
84
|
+
|
|
85
|
+
.. automodule:: proxax.solvers.unconstrained.adap_fista
|
|
86
|
+
:members:
|
|
87
|
+
|
|
88
|
+
.. automodule:: proxax.solvers.unconstrained.ac_acg
|
|
89
|
+
:members:
|
|
90
|
+
|
|
91
|
+
.. automodule:: proxax.solvers.unconstrained.adap_apg
|
|
92
|
+
:members:
|
|
93
|
+
|
|
94
|
+
.. automodule:: proxax.solvers.unconstrained.ia_icg
|
|
95
|
+
:members:
|
|
96
|
+
|
|
97
|
+
.. automodule:: proxax.solvers.unconstrained.da_icg
|
|
98
|
+
:members:
|
|
99
|
+
|
|
100
|
+
.. automodule:: proxax.solvers.constrained.qp_aipp
|
|
101
|
+
:members:
|
|
102
|
+
|
|
103
|
+
.. automodule:: proxax.solvers.constrained.qp_apd
|
|
104
|
+
:members:
|
|
105
|
+
|
|
106
|
+
.. automodule:: proxax.solvers.constrained.ialm
|
|
107
|
+
:members:
|
|
108
|
+
|
|
109
|
+
.. automodule:: proxax.solvers.constrained.s_prox_alm
|
|
110
|
+
:members:
|
|
111
|
+
|
|
112
|
+
.. automodule:: proxax.solvers.constrained.iaipal
|
|
113
|
+
:members:
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Optax Compatibility (`proxax.optax_compat`)
|
|
117
|
+
|
|
118
|
+
```{eval-rst}
|
|
119
|
+
.. automodule:: proxax.optax_compat.transforms
|
|
120
|
+
:members:
|
|
121
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"""Sphinx configuration for proxax documentation."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
os.environ.setdefault("XLA_PYTHON_CLIENT_PREALLOCATE", "false")
|
|
8
|
+
|
|
9
|
+
project = "proxax"
|
|
10
|
+
author = "William Kong"
|
|
11
|
+
release = "0.0.1"
|
|
12
|
+
extensions = [
|
|
13
|
+
"myst_parser",
|
|
14
|
+
"sphinx.ext.autodoc",
|
|
15
|
+
"sphinx.ext.mathjax",
|
|
16
|
+
"sphinx.ext.napoleon",
|
|
17
|
+
"sphinx.ext.viewcode",
|
|
18
|
+
]
|
|
19
|
+
myst_enable_extensions = ["dollarmath", "amsmath"]
|
|
20
|
+
html_theme = "furo"
|
|
21
|
+
autodoc_typehints = "description"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# `proxax` Documentation
|
|
2
|
+
|
|
3
|
+
Certified first-order proximal point methods for unconstrained and constrained
|
|
4
|
+
nonconvex composite optimization in **JAX** and **Optax**.
|
|
5
|
+
|
|
6
|
+
## Mathematical Scope
|
|
7
|
+
|
|
8
|
+
1. **Unconstrained Nonconvex Composite & Spectral Optimization (`AIPP`, `APD`, `ECG`, `AG`, `UPFAG`, `NCFISTA`, `AdapFISTA`, `ACACG`, `AdapAPG`, `IAICG`, `DAICG`):**
|
|
9
|
+
|
|
10
|
+
$$\min_{x \in \mathcal{X}} \; f(x) + h(x)$$
|
|
11
|
+
|
|
12
|
+
2. **Set / Cone-Constrained Nonconvex Composite Optimization (`QPAIPP`, `QPAPD`, `IALM`, `SProxALM`, `IAIPAL`):**
|
|
13
|
+
|
|
14
|
+
$$\min_{x \in \mathcal{X}} \; f(x) + h(x) \quad \text{s.t.} \quad \mathcal{A}(x) \in \mathcal{C}$$
|
|
15
|
+
|
|
16
|
+
```{toctree}
|
|
17
|
+
:maxdepth: 2
|
|
18
|
+
:caption: Contents
|
|
19
|
+
|
|
20
|
+
nc_opt_reference
|
|
21
|
+
api
|
|
22
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Reference & Roadmap from `wwkong/nc_opt` and Kong's `APD`
|
|
2
|
+
|
|
3
|
+
`proxax` brings the certified nonconvex composite proximal-point methodology of **[`wwkong/nc_opt`](https://github.com/wwkong/nc_opt)** (MATLAB) into an idiomatic, `jit`/`vmap`-compatible **JAX + Optax** architecture.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Pointers to `wwkong/nc_opt` & Primary Papers
|
|
8
|
+
|
|
9
|
+
- **Upstream MATLAB Repository:** https://github.com/wwkong/nc_opt
|
|
10
|
+
- `src/alg_framework/` — Core outer proximal-point templates, adaptive curvature / line-search routines, inner `ACG` subroutines, and refinement maps.
|
|
11
|
+
- `src/solvers/` — Unconstrained and linearly/cone-constrained composite solvers (`AIPP`, `R-AIPP`, `APD` / `PF.APD`, `QP-AIPP`, `NL-IAPIAL`, `AIDAL`, `AG`).
|
|
12
|
+
- `tests/papers/apd/` — Reference MATLAB implementation and experiments for `PF.APD` (`APD`): https://github.com/wwkong/nc_opt/tree/master/tests/papers/apd
|
|
13
|
+
- **Author Publications Page:** https://wwkong.github.io/publication/
|
|
14
|
+
|
|
15
|
+
### Key Papers by Weiwei (William) Kong et al.
|
|
16
|
+
|
|
17
|
+
1. **Parameter-Free Accelerated Proximal Descent (`PF.APD` / `APD`):**
|
|
18
|
+
- W. Kong, *"Complexity-Optimal and Parameter-Free First-Order Methods for Finding Stationary Points of Composite Optimization Problems,"* SIAM Journal on Optimization, 34(3):3005–3032, 2024 (DOI: `10.1137/22M1498826`, PDF: https://wwkong.github.io/files/publications/apd.pdf).
|
|
19
|
+
2. **Unconstrained `AIPP` & Constrained `QP-AIPP`:**
|
|
20
|
+
- W. Kong, J. G. Melo, and R. D. C. Monteiro, *"Complexity of a quadratic penalty accelerated inexact proximal point method for solving linearly constrained nonconvex composite programs,"* SIAM Journal on Optimization, 29(4):2566–2593, 2019.
|
|
21
|
+
- W. Kong, J. G. Melo, and R. D. C. Monteiro, *"An efficient adaptive accelerated inexact proximal point method for solving linearly constrained nonconvex composite problems,"* Comput. Math. Appl., 76:305–346, 2020 (`R-QP-AIPP`).
|
|
22
|
+
3. **Proximal & Dampened Augmented Lagrangian (`NL-IAPIAL` / `AIDAL`):**
|
|
23
|
+
- W. Kong, J. G. Melo, and R. D. C. Monteiro, *"Iteration-complexity of a proximal augmented Lagrangian method for solving nonconvex composite optimization problems with nonlinear convex constraints,"* Math. Oper. Res., 48(2):1066–1094, 2023.
|
|
24
|
+
- W. Kong, J. G. Melo, and R. D. C. Monteiro, *"Iteration-complexity of an inner accelerated inexact proximal augmented Lagrangian method based on the classical Lagrangian function,"* SIAM Journal on Optimization, 33(1):181–210, 2023.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 2. Deep Dive: Kong's `APD` (`PF.APD` + `PF.ACG`, SIAM J. Optim. 2024)
|
|
29
|
+
|
|
30
|
+
Unlike "Accelerated Primal-Dual" methods in saddle-point literature, Kong's **`APD`** stands for **Parameter-Free Accelerated Proximal Descent (`PF.APD`)** (https://wwkong.github.io/files/publications/apd.pdf, Algorithms 3.1–3.4). It is a premier target for `proxax`'s next unconstrained and penalty-subproblem solver:
|
|
31
|
+
|
|
32
|
+
- **Truly Parameter-Free & Optimal in Both Regimes:** Requires **no knowledge** of $(m, M)$ or boundedness of $\operatorname{dom} h$, achieving $\tilde{\mathcal{O}}(\sqrt{m M}\Delta_0 / \varepsilon^2)$ resolvent evaluations when $f$ is $m$-weakly convex and automatically improving to $\tilde{\mathcal{O}}(\sqrt{M}\min\{\sqrt{\Delta_0}/\varepsilon, d_0/\sqrt{\varepsilon}\})$ when $f$ is convex.
|
|
33
|
+
- **Rescaled Subproblem (`Algorithm 3.4`, Eq. (3.12)):** At outer step $k$ with lower-curvature estimate $\hat{m} > 0$, `PF.ACG` (`Algorithm 3.2`) is called with $\mu = 1/2$ on:
|
|
34
|
+
|
|
35
|
+
$$\psi^s(z) = \frac{f(z)}{2\hat{m}} + \frac{1}{2}\|z - z_k\|^2, \qquad \psi^n(z) = \frac{h(z)}{2\hat{m}}.$$
|
|
36
|
+
|
|
37
|
+
- **Exact Certificate at Every Inner Iteration (No Extra `refine` Needed):**
|
|
38
|
+
In `Algorithm 3.1`, $y_{j+1} = \operatorname{prox}_{\psi^n / (L_{j+1} + \mu)}\big(\tilde{x}_j - \nabla \psi^s(\tilde{x}_j) / (L_{j+1} + \mu)\big)$ with line search $\psi^s(y_{j+1}) - \ell_{\psi^s}(y_{j+1}; \tilde{x}_j) \le \frac{L_{j+1}}{2}\|y_{j+1} - \tilde{x}_j\|^2$, and `Algorithm 3.2` forms:
|
|
39
|
+
|
|
40
|
+
$$r_{j+1} = \nabla \psi^s(y_{j+1}) - \nabla \psi^s(\tilde{x}_j) + (L_{j+1} + \mu)(\tilde{x}_j - y_{j+1}) \in \nabla \psi^s(y_{j+1}) + \partial \psi^n(y_{j+1}).$$
|
|
41
|
+
|
|
42
|
+
Rescaling gives $v = 2\hat{m}(r_{j+1} + z_k - y_{j+1}) \in \nabla f(y_{j+1}) + \partial h(y_{j+1})$ directly!
|
|
43
|
+
- **Dynamic "Bad" vs. "Good" Inner Stopping Checks (Eqs. (3.5)–(3.6)):**
|
|
44
|
+
- **Bad termination (`Step 2`, Eq. (3.5)):** If $\mu A_{j+1}\|y_{j+1} - \tilde{x}_j\|^2 \le \|y_{j+1} - y_0\|^2$ or $\psi(y_0) \ge \psi(y_{j+1}) + \langle r_{j+1}, y_0 - y_{j+1}\rangle$ fails, local $\mu$-strong convexity is violated; `Algorithm 3.3` multiplies $\hat{m} \leftarrow \alpha \hat{m}$ and retries.
|
|
45
|
+
- **Good termination (`Step 3`, Eq. (3.6)):** Stops when $\|r_{j+1}\|^2 \le \sigma^2 \|y_{j+1} - y_0\|^2$ and $\|r_{j+1} + y_0 - y_{j+1}\|^2 \le \theta\big[\psi(y_0) - \psi(y_{j+1}) + \frac{1}{2}\|y_{j+1} - y_0\|^2\big]$ ($\theta > 2$, $\sigma = \rho \in (0, 1)$), certifying proximal descent (Eqs. (2.2)–(2.4)).
|
|
46
|
+
- **Practical Curvature Decay Heuristic (Eq. (6.1)):**
|
|
47
|
+
In `nc_opt/tests/papers/apd`, $\alpha = \beta = 2$, $\rho = 1/\sqrt{\alpha}$, with $L_0 \leftarrow L_0 / (1 + \beta/2)$ before `PF.ACG` and $m_{k+1} \leftarrow \max\{m_0, m_{k+1} / (1 + \alpha/2)\}$ across outer steps (guarding against the `float32` noise floor in JAX).
|
|
48
|
+
- **Constrained Penalty / ALM Integration (Sections 5 & 7 of `apd.pdf`):**
|
|
49
|
+
Using `APD` as the inner stage solver inside `QPAIPP` (`QP-APD`, with $m_0 = \varepsilon$) or proximal `iALM` yields a **completely parameter-free** constrained solver with $\tilde{\mathcal{O}}(\varepsilon^{-3})$ nonconvex complexity that automatically improves to $\tilde{\mathcal{O}}(\varepsilon^{-1.5})$ when $f$ is convex!
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 3. Mapping Current `proxax` Modules to `nc_opt`
|
|
54
|
+
|
|
55
|
+
| `nc_opt` Concept / Component | `proxax` Module & Symbols | Notes |
|
|
56
|
+
| :--- | :--- | :--- |
|
|
57
|
+
| Oracle `(f, grad_f, h, prox_h)` + curvature `(m, M)` | `proxax.oracle.terms.SmoothTerm`, `proxax.prox.base.ProxOperator`, `proxax.oracle.composite.CompositeOracle` | Arbitrary JAX PyTrees + automatic `domain_project` onto $\operatorname{cl}(\operatorname{dom}(h))$. |
|
|
58
|
+
| Spectral oracle `SpectralOracle.m` + `refine_ICG.m` | `proxax.oracle.spectral` (`SpectralOracle`, `SpectralProblem`, `refine_icg`), `proxax.prox.norms.NuclearNorm` | Curvature redistribution $\xi$, thin-SVD 1D vector reduction, and exact matrix subgradient refinement. |
|
|
59
|
+
| Refinement $(y) \mapsto (\hat{x}, \hat{v})$ | `proxax.certificates.stationarity.refine` | Exact $\hat{v} \in \nabla f(\hat{x}) + \partial h(\hat{x})$ via one adaptive composite gradient step. |
|
|
60
|
+
| Proximal subproblem $\phi(x) + \frac{1}{2\lambda_k}\|x - z_k\|^2$ | `proxax.oracle.composite.ProxRegularizedOracle`, `RescaledProxOracle` | Splits $1/\lambda_k = \alpha_{\text{smooth}} + \mu_{\text{prox}}$ (`AIPP`) or rescales $(\phi + \hat{m}\|\cdot - z_k\|^2)/(2\hat{m})$ (`APD`). |
|
|
61
|
+
| Inner `ACG`, `PF.ACG`, & `AdapAPG` | `proxax.solvers.inner.acg`, `proxax.solvers.inner.pf_acg`, `proxax.solvers.unconstrained.adap_apg.AdapAPG` | Tracks $(u_t, \eta_t)$ (`ACG`), exact refinement-free $r_{j+1}$ (`PF.ACG`), and Lin & Xiao (2014) adaptive APG (`AdapAPG`). |
|
|
62
|
+
| Unconstrained `AIPP` & `APD` (`PF.APD`) | `proxax.solvers.unconstrained` (`AIPP`, `APD`) | Known-$m$ / adaptive-$\lambda_k$ `AIPP` and parameter-free `PF.APD` + Eq. (6.1) decay. |
|
|
63
|
+
| Direct composite & FISTA-type solvers (`ECG`, `AG`, `UPFAG`, `NC_FISTA`, `ADAP_FISTA`, `AC_ACG`) | `proxax.solvers.unconstrained` (`ECG`, `AG`, `UPFAG`, `NCFISTA`, `AdapFISTA`, `ACACG`) | Exact composite gradient, Ghadimi–Lan `AG` & `UPFAG`, Liang–Monteiro–Sim `NC-FISTA` / `ADAP-NC-FISTA`, and Liang–Monteiro `AC-ACG`. |
|
|
64
|
+
| Spectral ICG solvers (`IA_ICG.m`, `DA_ICG.m`) | `proxax.solvers.unconstrained` (`IAICG`, `DAICG`) | Inner-accelerated and doubly-accelerated spectral composite solvers (Kong & Monteiro 2020). |
|
|
65
|
+
| Set/cone constraint $\mathcal{A}(x) \in \mathcal{C}$ & Moreau envelope | `proxax.constraints.sets`, `proxax.constraints.linear_op`, `proxax.oracle.composite.PenalizedOracle` | Matrix or PyTree callable $\mathcal{A}$ (`jax.linear_transpose` adjoint) + any `ConvexSet` projection $\Pi_{\mathcal{C}}$. |
|
|
66
|
+
| Constrained penalty & AL frameworks (`penalty.m`, `iALM.m`, `AIDAL.m`, `sProxALM.m`, `IAIPAL.m`) | `proxax.solvers.constrained` (`QPAIPP`, `QPAPD`, `IALM`, `SProxALM`, `IAIPAL`) | Geometric penalty (`QPAIPP`, `QPAPD`), dampened proximal AL (`IALM`), smoothed proximal ALM (`SProxALM`), and single-`ACG`-step proximal AL (`IAIPAL`). |
|
|
67
|
+
| Optax step-by-step transforms | `proxax.optax_compat.transforms` (`proximal`, `aipp`, `apd`, `qp_aipp`, `qp_apd`, `ialm`) | Single-inner-step PyTree state machines compatible with `jax.jit` and `jax.lax.while_loop`. |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 4. Completed `wwkong/nc_opt` Coverage & Extensions
|
|
72
|
+
|
|
73
|
+
1. **Complete `nc_opt` Solver & Framework Coverage:** Every solver and outer framework in `wwkong/nc_opt` (`ACG`, `PF.ACG`, `AIPP`, `APD`, `ECG`, `AG`, `UPFAG`, `NCFISTA`, `AdapFISTA`, `ACACG`, `AdapAPG`, `SpectralOracle` + `IAICG` + `DAICG`, `QPAIPP`, `QPAPD`, `IALM` / `NL-IAPIAL` / `AIDAL`, `SProxALM`, and `IAIPAL`) is implemented with exact KKT/subdifferential stationarity certificates and `jax.jit` compatibility.
|
|
74
|
+
2. **Future Extensions:** Add `sets.PSDCone` (`jnp.linalg.eigh`) and a standalone `benchmarks/` suite reproducing the paper tables from `wwkong/nc_opt/tests/papers/`.
|