Skip to content

liblaf.peach.optim.scipy

SciPy optimizer adapter.

Classes:

  • ScipyOptimizer

    Adapter around scipy.optimize.minimize.

  • ScipyState

    Optimizer state backed by SciPy's OptimizeResult.

  • ScipyStats

    Stats placeholder for the SciPy optimizer adapter.

ScipyOptimizer

Bases: Optimizer[ScipyState, ScipyStats]


              flowchart TD
              liblaf.peach.optim.scipy.ScipyOptimizer[ScipyOptimizer]
              liblaf.peach.optim.base._optimizer.Optimizer[Optimizer]

                              liblaf.peach.optim.base._optimizer.Optimizer --> liblaf.peach.optim.scipy.ScipyOptimizer
                


              click liblaf.peach.optim.scipy.ScipyOptimizer href "" "liblaf.peach.optim.scipy.ScipyOptimizer"
              click liblaf.peach.optim.base._optimizer.Optimizer href "" "liblaf.peach.optim.base._optimizer.Optimizer"
            

Adapter around scipy.optimize.minimize.

Parameters:

  • method (str | None, default: None ) –
  • options (Mapping[str, Any] | None, default: None ) –
  • tol (float | None, default: None ) –

Type Aliases:

Classes:

  • Result

    Result code returned by optimizers.

Methods:

  • init

    Initialize SciPy state from the starting parameters.

  • minimize

    Run scipy.optimize.minimize against a Peach problem.

  • postprocess

    Build the SciPy optimizer solution object.

  • step

    Advance the optimizer by one step.

  • terminate

    Return whether optimization should stop and why.

Attributes:

method class-attribute instance-attribute

method: str | None = None

options class-attribute instance-attribute

options: Mapping[str, Any] | None = None

tol class-attribute instance-attribute

tol: float | None = None

Solution

Optimizer output bundle.

Parameters:

  • result (Result) –
  • state (S) –
  • stats (T) –

Result

Bases: StrEnum


              flowchart TD
              liblaf.peach.optim.scipy.ScipyOptimizer.Result[Result]

              

              click liblaf.peach.optim.scipy.ScipyOptimizer.Result href "" "liblaf.peach.optim.scipy.ScipyOptimizer.Result"
            

Result code returned by optimizers.

Attributes:

INTERRUPT class-attribute instance-attribute

INTERRUPT = auto()

MAX_STEPS_REACHED class-attribute instance-attribute

MAX_STEPS_REACHED = auto()

NAN class-attribute instance-attribute

NAN = auto()

PRIMARY_SUCCESS class-attribute instance-attribute

PRIMARY_SUCCESS = auto()

SECONDARY_SUCCESS class-attribute instance-attribute

SECONDARY_SUCCESS = auto()

STAGNATION class-attribute instance-attribute

STAGNATION = auto()

SUCCESS class-attribute instance-attribute

SUCCESS = auto()

UNKNOWN_ERROR class-attribute instance-attribute

UNKNOWN_ERROR = auto()

success property

success: bool

Whether the result represents an accepted optimization outcome.

init

init[X](
    problem: BaseProblem[X],
    model_state: X,
    params: Vector,
) -> ScipyState

Initialize SciPy state from the starting parameters.

Source code in src/liblaf/peach/optim/scipy/_scipy.py
@override
def init[X](self, problem: BaseProblem[X], model_state: X, params: Vector) -> State:
    """Initialize SciPy state from the starting parameters."""
    res: OptimizeResult = OptimizeResult({"x": params})  # ty:ignore[too-many-positional-arguments]
    return self.State(res)

minimize

minimize[X](
    problem: BaseProblem[X],
    model_state: X,
    params: Vector,
) -> Solution

Run scipy.optimize.minimize against a Peach problem.

Source code in src/liblaf/peach/optim/scipy/_scipy.py
@override
def minimize[X](
    self, problem: BaseProblem[X], model_state: X, params: Vector
) -> Solution:
    """Run `scipy.optimize.minimize` against a Peach problem."""
    problem: Problem[X] = cast("Problem[X]", problem)
    opt_state: ScipyState = self.init(problem, model_state, params)
    wrapper: _ProblemWrapper[X] = _ProblemWrapper(problem, model_state=model_state)
    fun, jac = (
        (wrapper.fun, wrapper.grad)
        if wrapper.value_and_grad is None
        else (wrapper.value_and_grad, True)
    )
    opt_state.__wrapped__ = scipy.optimize.minimize(
        fun=fun,
        x0=opt_state.params,
        method=self.method,
        jac=jac,
        hessp=wrapper.hessp,
        tol=self.tol,
        callback=self._wraps_callback(wrapper, opt_state),
        options=self.options,
    )  # ty:ignore[no-matching-overload]
    result: Result = (
        Result.SUCCESS if opt_state["success"] else Result.UNKNOWN_ERROR
    )
    solution: ScipyOptimizer.Solution = self.postprocess(
        problem, model_state, opt_state, result
    )
    return solution

postprocess

postprocess[X](
    problem: BaseProblem[X],
    model_state: X,
    opt_state: ScipyState,
    result: Result,
) -> Solution

Build the SciPy optimizer solution object.

Source code in src/liblaf/peach/optim/scipy/_scipy.py
@override
def postprocess[X](
    self, problem: BaseProblem[X], model_state: X, opt_state: State, result: Result
) -> Solution:
    """Build the SciPy optimizer solution object."""
    return Solution(result=result, state=opt_state, stats=self.Stats())

step

step[X](
    problem: BaseProblem[X], model_state: X, opt_state: S
) -> None

Advance the optimizer by one step.

Implementations should mutate model_state and opt_state with any accepted parameter, gradient, or diagnostic updates.

Source code in src/liblaf/peach/optim/base/_optimizer.py
def step[X](self, problem: BaseProblem[X], model_state: X, opt_state: S) -> None:
    """Advance the optimizer by one step.

    Implementations should mutate `model_state` and `opt_state` with any
    accepted parameter, gradient, or diagnostic updates.
    """
    raise NotImplementedError

terminate

terminate[X](
    problem: BaseProblem[X], model_state: X, opt_state: S
) -> tuple[bool, Result]

Return whether optimization should stop and why.

Source code in src/liblaf/peach/optim/base/_optimizer.py
def terminate[X](
    self, problem: BaseProblem[X], model_state: X, opt_state: S
) -> tuple[bool, Result]:
    """Return whether optimization should stop and why."""
    raise NotImplementedError

ScipyState

Bases: Mapping[str, Any], State


              flowchart TD
              liblaf.peach.optim.scipy.ScipyState[ScipyState]
              liblaf.peach.optim.base._protocols.State[State]

                              liblaf.peach.optim.base._protocols.State --> liblaf.peach.optim.scipy.ScipyState
                


              click liblaf.peach.optim.scipy.ScipyState href "" "liblaf.peach.optim.scipy.ScipyState"
              click liblaf.peach.optim.base._protocols.State href "" "liblaf.peach.optim.base._protocols.State"
            

Optimizer state backed by SciPy's OptimizeResult.

Methods:

  • __getitem__

    Return an item from the wrapped SciPy result.

  • __iter__

    Iterate over keys in the wrapped SciPy result.

  • __len__

    Return the number of keys in the wrapped SciPy result.

Attributes:

  • __wrapped__ (OptimizeResult) –
  • params (Vector) –

    Final parameter vector from the SciPy result.

__wrapped__ class-attribute instance-attribute

__wrapped__: OptimizeResult = field(factory=OptimizeResult)

params property

params: Vector

Final parameter vector from the SciPy result.

__getitem__

__getitem__(key: str) -> Any

Return an item from the wrapped SciPy result.

Source code in src/liblaf/peach/optim/scipy/_types.py
def __getitem__(self, key: str) -> Any:
    """Return an item from the wrapped SciPy result."""
    return self.__wrapped__[key]

__iter__

__iter__() -> Iterator[str]

Iterate over keys in the wrapped SciPy result.

Source code in src/liblaf/peach/optim/scipy/_types.py
def __iter__(self) -> Iterator[str]:
    """Iterate over keys in the wrapped SciPy result."""
    yield from self.__wrapped__

__len__

__len__() -> int

Return the number of keys in the wrapped SciPy result.

Source code in src/liblaf/peach/optim/scipy/_types.py
def __len__(self) -> int:
    """Return the number of keys in the wrapped SciPy result."""
    return len(self.__wrapped__)

ScipyStats

Bases: Stats


              flowchart TD
              liblaf.peach.optim.scipy.ScipyStats[ScipyStats]
              liblaf.peach.optim.base._protocols.Stats[Stats]

                              liblaf.peach.optim.base._protocols.Stats --> liblaf.peach.optim.scipy.ScipyStats
                


              click liblaf.peach.optim.scipy.ScipyStats href "" "liblaf.peach.optim.scipy.ScipyStats"
              click liblaf.peach.optim.base._protocols.Stats href "" "liblaf.peach.optim.base._protocols.Stats"
            

Stats placeholder for the SciPy optimizer adapter.