Skip to main content

Semantiva Optimize

Optimization extension for Semantiva. It provides a generic OptimizerContextProcessor and pluggable strategies.

Currently available strategies:

  • Local Convex — L-BFGS-B (bounds), SLSQP (simple constraints)
  • Nelder–Mead — gradient-free simplex search

Works anywhere you can provide an objective(x) (and optionally gradient(x)), with optional constraints, bounds, and multi-start fan-in.


Install

pip install semantiva-optimize

Quick Start (Python)

from semantiva.registry import load_extensions
from semantiva.context_processors.context_observer import _ContextObserver
from semantiva.context_processors.context_types import ContextType

# If your environment doesn't auto-load entry points, do it explicitly:
load_extensions("semantiva_optimize.extension")

from semantiva_optimize.processors.optimizer_processor import OptimizerContextProcessor
from semantiva_optimize.factory import make_strategy
from semantiva_optimize.termination import Termination

# Simple quadratic: min (x-3)^2
class QuadraticModel:
    def objective(self, x): return float((x[0] - 3.0) ** 2)
    def gradient(self, x):  return [2.0 * (x[0] - 3.0)]

p = OptimizerContextProcessor()
ctx, obs = ContextType(), _ContextObserver()

p.operate_context(
    context=ctx, context_observer=obs,
    strategy=make_strategy("local"),     # aliases: "local", "local-convex"
    x0=[0.0],
    bounds=[(-100.0, 100.0)],
    termination=Termination(max_evals=200, ftol_abs=1e-12, xtol_abs=1e-12),
    model=QuadraticModel(),
    controller=None,
    constraints=None,
    strategy_params={},
)

print(ctx.get_value("optimizer.best_candidate"))
# → {'x': [2.999999...], 'value': ~0.0, 'feasible': True, 'meta': {}}

Nelder–Mead (gradient-free)

from semantiva_optimize.termination import Termination

class PolyModel:
    def objective(self, x):
        p = x[0] * x[0] - 2.0
        return float(p * p)
    def gradient(self, x):
        return None  # intentionally None

p = OptimizerContextProcessor()
ctx, obs = ContextType(), _ContextObserver()

p.operate_context(
    context=ctx, context_observer=obs,
    strategy=make_strategy("nelder-mead"),  # alias: "nelder_mead"
    x0=[0.1],
    bounds=None,
    termination=Termination(max_evals=500, ftol_abs=1e-12, xtol_abs=1e-12),
    model=PolyModel(),
    controller=None,
    constraints=None,
    strategy_params={},
)

print(ctx.get_value("optimizer.best_candidate"))

Constraints (quick example)

from semantiva_optimize.constraints import Constraints

# Inequality: x[0] >= 0  →  ineq(x) = x[0] - 0 >= 0
def ineq(x): return [x[0] - 0.0]

cons = Constraints(ineq=[ineq], eq=[])

p = OptimizerContextProcessor()
ctx, obs = ContextType(), _ContextObserver()

p.operate_context(
    context=ctx, context_observer=obs,
    strategy=make_strategy("local"),
    x0=[-1.0],
    bounds=[(-10.0, 10.0)],
    termination=Termination(max_evals=100),
    model=QuadraticModel(),
    controller=None,
    constraints=cons,
    strategy_params={},
)
print(ctx.get_value("optimizer.best_candidate"))

Multi-start execution

starts = [[-5.0], [0.0], [10.0]]

p = OptimizerContextProcessor()
ctx, obs = ContextType(), _ContextObserver()

p.operate_context(
    context=ctx, context_observer=obs,
    strategy=make_strategy("local"),
    x0=[0.0],                   # seed (unused when multi_start provided)
    multi_start=starts,         # list of x0 vectors
    bounds=[(-10.0, 10.0)],
    termination=Termination(max_evals=100),
    model=QuadraticModel(),
    controller=None,
    constraints=None,
    strategy_params={},
)

print(ctx.get_value("optimizer.runs"))        # three independent runs
print(ctx.get_value("optimizer.best_candidate"))

Pipeline YAML wiring

pipeline:
  nodes:
    - processor: DataSlicerProcessor
      parameters:
        values:
          starts:
            - [-5.0]
            - [0.0]
            - [10.0]

    - processor: OptimizerContextProcessor
      parameters:
        strategy: "local"                 # aliases: local, local-convex
        x0: [0.0]                         # seed (ignored if multi_start provided)
        multi_start: "{{ slice.values.starts }}"
        bounds: [[-10.0, 10.0]]
        termination: { max_evals: 100, ftol_abs: 1e-10, xtol_abs: 1e-10 }
        strategy_params: {}

Run with -v to enable DEBUG logs:

semantiva run examples/quadratic_local.yaml -v

Example log lines:

[optimize] start strategy=LocalConvex bounds=[(-10, 10)] x0=[0]
[optimize] iter=0 x=[0] f=9 feas=True viol=0
[optimize] done reason=completed best_x=[3] best_f=0

Field meanings

  • iter — internal iteration counter
  • x — current candidate
  • f — objective value
  • feas — whether safety/constraints are satisfied
  • viol — max constraint violation observed

See examples/ for:

  • quadratic_local.yaml: minimize $f(x) = (x-3)^2$
  • polyroot_local.yaml: find a root of $x^2 - 2 = 0$ by minimizing the squared residual

API surface (at a glance)

OptimizerContextProcessor.operate_context(...) key parameters

  • strategy: result of make_strategy(name, **strategy_params)
    • Accepted names: "local", "local-convex", "nelder-mead", "nelder_mead"
  • x0: list/array initial guess
  • multi_start: list of x0 (each a list/array); if provided, runs independently and selects best
  • bounds: list of (low, high) per dimension, or None
  • termination: Termination(max_evals, ftol_abs, xtol_abs, ...)
  • model: object with objective(x) -> float and optional gradient(x) -> array | None
  • controller: optional adapter with reset/apply/safe (for HIL/sim)
  • constraints: Constraints(ineq=[fn,...], eq=[fn,...]) with each fn(x) -> list/array
  • strategy_params: dict passed to the chosen strategy

Context outputs

  • optimizer.strategy: str
  • optimizer.params: dict (bounds, termination, strategy params)
  • optimizer.history: list[dict] (step records kept in context)
  • optimizer.runs: list[{x, value, feasible, meta}] (one per start)
  • optimizer.best_candidate: {"x": [...], "value": float, "feasible": bool, "meta": {...}}
  • optimizer.termination: {"reason": str, "metrics": dict, "budget": dict}

Iteration details are recorded inside the context. Semantiva’s core trace remains node-level.


License

Apache-2.0

Metadata

Release files for semantiva-optimize 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for semantiva-optimize 0.1.0
File Size Uploaded
semantiva_optimize-0.1.0.tar.gz 13.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for semantiva-optimize 0.1.0
File Interpreter ABI Platform
semantiva_optimize-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 24.6 kB

Release files / semantiva_optimize-0.1.0.tar.gz

Download URL semantiva_optimize-0.1.0.tar.gz
Size 13.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9cedcbe45ac5e3624faad2e202738577114b2e49e71dd6aa17237763834e9c89
BLAKE2b-256 checksum
How to use checksums
fb4e0730f463619e95787973ece6b2736bbc6664fe5ac9fbae2af5aeefd5cc98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via pdm/2.25.9 CPython/3.10.12 Linux/6.11.0-1018-azure

Release files / semantiva_optimize-0.1.0-py3-none-any.whl

Download URL semantiva_optimize-0.1.0-py3-none-any.whl
Size 11.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
078a95f69361128480bfb21aee048109f558febb04b23f33e95456cb27cbf631
BLAKE2b-256 checksum
How to use checksums
7bda90fee542f8333fc44ed8ec924433bac5bc2ef7faba24f032462866136a91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via pdm/2.25.9 CPython/3.10.12 Linux/6.11.0-1018-azure

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page