Skip to content

liblaf.peach.linalg

Linear-system protocols and solver backends.

Modules:

  • base

    Base protocols and result containers for linear solvers.

  • cupy

    CuPy-backed linear solvers.

  • fallback

    Fallback linear-solver orchestration.

Classes:

  • BaseProblem

    Marker protocol for linear-system problems.

  • CupyCG
  • CupyMinRes
  • CupySolver

    Base class for linear solvers backed by CuPy sparse routines.

  • FallbackSolver
  • LinearSolver

    Base class for linear solvers.

  • Problem

    Protocol for a linear system A x = b.

  • Result

    Result code returned by linear solvers.

  • Solution

    Linear-solver output bundle.

  • State

    Protocol for solver states that expose solution parameters.

  • Stats

    Protocol for solver-specific summary statistics.

BaseProblem

Bases: Protocol


              flowchart TD
              liblaf.peach.linalg.BaseProblem[BaseProblem]

              

              click liblaf.peach.linalg.BaseProblem href "" "liblaf.peach.linalg.BaseProblem"
            

Marker protocol for linear-system problems.

CupyCG

Bases: CupySolver


              flowchart TD
              liblaf.peach.linalg.CupyCG[CupyCG]
              liblaf.peach.linalg.cupy._base.CupySolver[CupySolver]
              liblaf.peach.linalg.base._solver.LinearSolver[LinearSolver]

                              liblaf.peach.linalg.cupy._base.CupySolver --> liblaf.peach.linalg.CupyCG
                                liblaf.peach.linalg.base._solver.LinearSolver --> liblaf.peach.linalg.cupy._base.CupySolver
                



              click liblaf.peach.linalg.CupyCG href "" "liblaf.peach.linalg.CupyCG"
              click liblaf.peach.linalg.cupy._base.CupySolver href "" "liblaf.peach.linalg.cupy._base.CupySolver"
              click liblaf.peach.linalg.base._solver.LinearSolver href "" "liblaf.peach.linalg.base._solver.LinearSolver"
            

Parameters:

  • maxiter (int | None, default: None ) –
  • rtol (float, default: 1e-05 ) –
  • atol (float, default: 0.0 ) –

Type Aliases:

  • Solution

    Linear-solver output bundle.

Classes:

  • State

    State recorded by CuPy-backed linear solvers.

  • Stats

    Stats placeholder for CuPy-backed linear solvers.

Methods:

  • compute

    Run one complete solve from an initialized state.

  • init

    Create solver state from an initial parameter vector.

  • postprocess

    Wrap final state and result metadata in a solution object.

  • solve

    Initialize, compute, and postprocess a linear solve.

Attributes:

atol class-attribute instance-attribute

atol: float = 0.0

maxiter class-attribute instance-attribute

maxiter: int | None = None

rtol class-attribute instance-attribute

rtol: float = 1e-05

Solution

Linear-solver output bundle.

Parameters:

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

State

Bases: State


              flowchart TD
              liblaf.peach.linalg.CupyCG.State[State]
              liblaf.peach.linalg.base._types.State[State]

                              liblaf.peach.linalg.base._types.State --> liblaf.peach.linalg.CupyCG.State
                


              click liblaf.peach.linalg.CupyCG.State href "" "liblaf.peach.linalg.CupyCG.State"
              click liblaf.peach.linalg.base._types.State href "" "liblaf.peach.linalg.base._types.State"
            

State recorded by CuPy-backed linear solvers.

Parameters:

  • params (Vector) –

    Current solution estimate.

  • info (int, default: -1 ) –
  • step (int | None, default: None ) –

Attributes:

info class-attribute instance-attribute

info: int = -1

params instance-attribute

params: Vector

Current solution estimate.

step class-attribute instance-attribute

step: int | None = None

Stats

Bases: Stats


              flowchart TD
              liblaf.peach.linalg.CupyCG.Stats[Stats]
              liblaf.peach.linalg.base._types.Stats[Stats]

                              liblaf.peach.linalg.base._types.Stats --> liblaf.peach.linalg.CupyCG.Stats
                


              click liblaf.peach.linalg.CupyCG.Stats href "" "liblaf.peach.linalg.CupyCG.Stats"
              click liblaf.peach.linalg.base._types.Stats href "" "liblaf.peach.linalg.base._types.Stats"
            

Stats placeholder for CuPy-backed linear solvers.

Parameters:

  • absolute_residual (Scalar, default: None ) –
  • relative_residual (Scalar, default: None ) –

Attributes:

absolute_residual class-attribute instance-attribute

absolute_residual: Scalar = field(default=None)

relative_residual class-attribute instance-attribute

relative_residual: Scalar = field(default=None)

compute

compute(problem: BaseProblem, state: CupyState) -> Result

Run one complete solve from an initialized state.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def compute(self, problem: BaseProblem, state: State) -> Result:
    problem: Problem = cast("Problem", problem)
    lop: linalg.LinearOperator = _as_lop(problem)
    options: dict[str, Any] = self._options(problem)
    with cp.cuda.Stream.from_external(torch.cuda.current_stream()):
        x, info = self._wrapped(
            lop, cp.asarray(problem.b), cp.asarray(state.params), **options
        )
    state.params = torch.as_tensor(x)
    result: Result = self._result(state, info)
    return result

init

init(problem: BaseProblem, params: Vector) -> CupyState

Create solver state from an initial parameter vector.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def init(self, problem: BaseProblem, params: Vector) -> State:
    return self.State(params=params)

postprocess

postprocess(
    problem: BaseProblem, state: CupyState, result: Result
) -> Solution

Wrap final state and result metadata in a solution object.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def postprocess(
    self, problem: BaseProblem, state: State, result: Result
) -> Solution:
    problem: Problem = cast("Problem", problem)
    stats: CupySolver.Stats = self.Stats()
    if state.info >= 0:
        stats.absolute_residual = torch.linalg.vector_norm(
            problem.matvec(state.params) - problem.b
        )
        stats.relative_residual = (
            stats.absolute_residual / torch.linalg.vector_norm(problem.b).item()
        )
    return LinearSolver.Solution(result=result, state=state, stats=stats)

solve

solve(
    problem: BaseProblem, params: Vector
) -> Solution[S, T]

Initialize, compute, and postprocess a linear solve.

Source code in src/liblaf/peach/linalg/base/_solver.py
def solve(self, problem: BaseProblem, params: Vector) -> Solution[S, T]:
    """Initialize, compute, and postprocess a linear solve."""
    state: S = self.init(problem, params)
    result: Result = self.compute(problem, state)
    return self.postprocess(problem, state, result)

CupyMinRes

Bases: CupySolver


              flowchart TD
              liblaf.peach.linalg.CupyMinRes[CupyMinRes]
              liblaf.peach.linalg.cupy._base.CupySolver[CupySolver]
              liblaf.peach.linalg.base._solver.LinearSolver[LinearSolver]

                              liblaf.peach.linalg.cupy._base.CupySolver --> liblaf.peach.linalg.CupyMinRes
                                liblaf.peach.linalg.base._solver.LinearSolver --> liblaf.peach.linalg.cupy._base.CupySolver
                



              click liblaf.peach.linalg.CupyMinRes href "" "liblaf.peach.linalg.CupyMinRes"
              click liblaf.peach.linalg.cupy._base.CupySolver href "" "liblaf.peach.linalg.cupy._base.CupySolver"
              click liblaf.peach.linalg.base._solver.LinearSolver href "" "liblaf.peach.linalg.base._solver.LinearSolver"
            

Parameters:

  • maxiter (int | None, default: None ) –
  • shift (float, default: 0.0 ) –
  • tol (float, default: 1e-05 ) –

Type Aliases:

  • Solution

    Linear-solver output bundle.

Classes:

  • State

    State recorded by CuPy-backed linear solvers.

  • Stats

    Stats placeholder for CuPy-backed linear solvers.

Methods:

  • compute

    Run one complete solve from an initialized state.

  • init

    Create solver state from an initial parameter vector.

  • postprocess

    Wrap final state and result metadata in a solution object.

  • solve

    Initialize, compute, and postprocess a linear solve.

Attributes:

maxiter class-attribute instance-attribute

maxiter: int | None = None

shift class-attribute instance-attribute

shift: float = 0.0

tol class-attribute instance-attribute

tol: float = 1e-05

Solution

Linear-solver output bundle.

Parameters:

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

State

Bases: State


              flowchart TD
              liblaf.peach.linalg.CupyMinRes.State[State]
              liblaf.peach.linalg.base._types.State[State]

                              liblaf.peach.linalg.base._types.State --> liblaf.peach.linalg.CupyMinRes.State
                


              click liblaf.peach.linalg.CupyMinRes.State href "" "liblaf.peach.linalg.CupyMinRes.State"
              click liblaf.peach.linalg.base._types.State href "" "liblaf.peach.linalg.base._types.State"
            

State recorded by CuPy-backed linear solvers.

Parameters:

  • params (Vector) –

    Current solution estimate.

  • info (int, default: -1 ) –
  • step (int | None, default: None ) –

Attributes:

info class-attribute instance-attribute

info: int = -1

params instance-attribute

params: Vector

Current solution estimate.

step class-attribute instance-attribute

step: int | None = None

Stats

Bases: Stats


              flowchart TD
              liblaf.peach.linalg.CupyMinRes.Stats[Stats]
              liblaf.peach.linalg.base._types.Stats[Stats]

                              liblaf.peach.linalg.base._types.Stats --> liblaf.peach.linalg.CupyMinRes.Stats
                


              click liblaf.peach.linalg.CupyMinRes.Stats href "" "liblaf.peach.linalg.CupyMinRes.Stats"
              click liblaf.peach.linalg.base._types.Stats href "" "liblaf.peach.linalg.base._types.Stats"
            

Stats placeholder for CuPy-backed linear solvers.

Parameters:

  • absolute_residual (Scalar, default: None ) –
  • relative_residual (Scalar, default: None ) –

Attributes:

absolute_residual class-attribute instance-attribute

absolute_residual: Scalar = field(default=None)

relative_residual class-attribute instance-attribute

relative_residual: Scalar = field(default=None)

compute

compute(problem: BaseProblem, state: CupyState) -> Result

Run one complete solve from an initialized state.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def compute(self, problem: BaseProblem, state: State) -> Result:
    problem: Problem = cast("Problem", problem)
    lop: linalg.LinearOperator = _as_lop(problem)
    options: dict[str, Any] = self._options(problem)
    with cp.cuda.Stream.from_external(torch.cuda.current_stream()):
        x, info = self._wrapped(
            lop, cp.asarray(problem.b), cp.asarray(state.params), **options
        )
    state.params = torch.as_tensor(x)
    result: Result = self._result(state, info)
    return result

init

init(problem: BaseProblem, params: Vector) -> CupyState

Create solver state from an initial parameter vector.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def init(self, problem: BaseProblem, params: Vector) -> State:
    return self.State(params=params)

postprocess

postprocess(
    problem: BaseProblem, state: CupyState, result: Result
) -> Solution

Wrap final state and result metadata in a solution object.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def postprocess(
    self, problem: BaseProblem, state: State, result: Result
) -> Solution:
    problem: Problem = cast("Problem", problem)
    stats: CupySolver.Stats = self.Stats()
    if state.info >= 0:
        stats.absolute_residual = torch.linalg.vector_norm(
            problem.matvec(state.params) - problem.b
        )
        stats.relative_residual = (
            stats.absolute_residual / torch.linalg.vector_norm(problem.b).item()
        )
    return LinearSolver.Solution(result=result, state=state, stats=stats)

solve

solve(
    problem: BaseProblem, params: Vector
) -> Solution[S, T]

Initialize, compute, and postprocess a linear solve.

Source code in src/liblaf/peach/linalg/base/_solver.py
def solve(self, problem: BaseProblem, params: Vector) -> Solution[S, T]:
    """Initialize, compute, and postprocess a linear solve."""
    state: S = self.init(problem, params)
    result: Result = self.compute(problem, state)
    return self.postprocess(problem, state, result)

CupySolver

Bases: LinearSolver[CupyState, CupyStats]


              flowchart TD
              liblaf.peach.linalg.CupySolver[CupySolver]
              liblaf.peach.linalg.base._solver.LinearSolver[LinearSolver]

                              liblaf.peach.linalg.base._solver.LinearSolver --> liblaf.peach.linalg.CupySolver
                


              click liblaf.peach.linalg.CupySolver href "" "liblaf.peach.linalg.CupySolver"
              click liblaf.peach.linalg.base._solver.LinearSolver href "" "liblaf.peach.linalg.base._solver.LinearSolver"
            

Base class for linear solvers backed by CuPy sparse routines.

Parameters:

  • maxiter (int | None, default: None ) –

Type Aliases:

  • Solution

    Linear-solver output bundle.

Methods:

  • compute

    Run one complete solve from an initialized state.

  • init

    Create solver state from an initial parameter vector.

  • postprocess

    Wrap final state and result metadata in a solution object.

  • solve

    Initialize, compute, and postprocess a linear solve.

Attributes:

maxiter class-attribute instance-attribute

maxiter: int | None = None

Solution

Linear-solver output bundle.

Parameters:

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

compute

compute(problem: BaseProblem, state: CupyState) -> Result

Run one complete solve from an initialized state.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def compute(self, problem: BaseProblem, state: State) -> Result:
    problem: Problem = cast("Problem", problem)
    lop: linalg.LinearOperator = _as_lop(problem)
    options: dict[str, Any] = self._options(problem)
    with cp.cuda.Stream.from_external(torch.cuda.current_stream()):
        x, info = self._wrapped(
            lop, cp.asarray(problem.b), cp.asarray(state.params), **options
        )
    state.params = torch.as_tensor(x)
    result: Result = self._result(state, info)
    return result

init

init(problem: BaseProblem, params: Vector) -> CupyState

Create solver state from an initial parameter vector.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def init(self, problem: BaseProblem, params: Vector) -> State:
    return self.State(params=params)

postprocess

postprocess(
    problem: BaseProblem, state: CupyState, result: Result
) -> Solution

Wrap final state and result metadata in a solution object.

Source code in src/liblaf/peach/linalg/cupy/_base.py
@override
def postprocess(
    self, problem: BaseProblem, state: State, result: Result
) -> Solution:
    problem: Problem = cast("Problem", problem)
    stats: CupySolver.Stats = self.Stats()
    if state.info >= 0:
        stats.absolute_residual = torch.linalg.vector_norm(
            problem.matvec(state.params) - problem.b
        )
        stats.relative_residual = (
            stats.absolute_residual / torch.linalg.vector_norm(problem.b).item()
        )
    return LinearSolver.Solution(result=result, state=state, stats=stats)

solve

solve(
    problem: BaseProblem, params: Vector
) -> Solution[S, T]

Initialize, compute, and postprocess a linear solve.

Source code in src/liblaf/peach/linalg/base/_solver.py
def solve(self, problem: BaseProblem, params: Vector) -> Solution[S, T]:
    """Initialize, compute, and postprocess a linear solve."""
    state: S = self.init(problem, params)
    result: Result = self.compute(problem, state)
    return self.postprocess(problem, state, result)

FallbackSolver

Bases: LinearSolver[FallbackState, FallbackStats]


              flowchart TD
              liblaf.peach.linalg.FallbackSolver[FallbackSolver]
              liblaf.peach.linalg.base._solver.LinearSolver[LinearSolver]

                              liblaf.peach.linalg.base._solver.LinearSolver --> liblaf.peach.linalg.FallbackSolver
                


              click liblaf.peach.linalg.FallbackSolver href "" "liblaf.peach.linalg.FallbackSolver"
              click liblaf.peach.linalg.base._solver.LinearSolver href "" "liblaf.peach.linalg.base._solver.LinearSolver"
            

Parameters:

  • solvers (list[LinearSolver], default: [CupyCG(maxiter=None, rtol=1e-05, atol=0.0), CupyMinRes(maxiter=None, shift=0.0, tol=1e-05)] ) –

Type Aliases:

  • Solution

    Linear-solver output bundle.

Methods:

  • compute

    Run one complete solve from an initialized state.

  • init

    Create solver state from an initial parameter vector.

  • postprocess

    Wrap final state and result metadata in a solution object.

  • solve

    Initialize, compute, and postprocess a linear solve.

Attributes:

solvers class-attribute instance-attribute

solvers: list[LinearSolver] = field(
    factory=_default_solvers
)

Solution

Linear-solver output bundle.

Parameters:

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

compute

compute(
    problem: BaseProblem, state: FallbackState
) -> Result

Run one complete solve from an initialized state.

Source code in src/liblaf/peach/linalg/fallback/_fallback.py
@override
def compute(self, problem: BaseProblem, state: State) -> Result:
    problem: Problem = cast("Problem", problem)
    results: list[Result] = []
    absolute_residuals: list[Scalar] = []
    relative_residuals: list[Scalar] = []
    for solver in self.solvers:
        solution: Solution = solver.solve(problem, state.init_params)
        state.solutions.append(solution)
        results.append(solution.result)
        absolute_residual: Scalar = torch.linalg.vector_norm(
            problem.matvec(solution.state.params) - problem.b
        )
        relative_residual: Scalar = absolute_residual / torch.linalg.vector_norm(
            problem.b
        )
        absolute_residuals.append(absolute_residual)
        relative_residuals.append(relative_residual)
        if solution.success:
            break
    state.absolute_residuals = torch.as_tensor(absolute_residuals)
    state.relative_residuals = torch.as_tensor(relative_residuals)
    state.best_index = torch.argmin(state.absolute_residuals)
    return state.result

init

init(problem: BaseProblem, params: Vector) -> FallbackState

Create solver state from an initial parameter vector.

Source code in src/liblaf/peach/linalg/fallback/_fallback.py
@override
def init(self, problem: BaseProblem, params: Vector) -> State:
    return self.State(init_params=params)

postprocess

postprocess(
    problem: BaseProblem, state: S, result: Result
) -> Solution[S, T]

Wrap final state and result metadata in a solution object.

Source code in src/liblaf/peach/linalg/base/_solver.py
def postprocess(
    self, problem: BaseProblem, state: S, result: Result
) -> Solution[S, T]:
    """Wrap final state and result metadata in a solution object."""
    del problem
    stats: T = cast("T", self.Stats())  # ty:ignore[call-non-callable]
    return Solution(result=result, state=state, stats=stats)

solve

solve(
    problem: BaseProblem, params: Vector
) -> Solution[S, T]

Initialize, compute, and postprocess a linear solve.

Source code in src/liblaf/peach/linalg/base/_solver.py
def solve(self, problem: BaseProblem, params: Vector) -> Solution[S, T]:
    """Initialize, compute, and postprocess a linear solve."""
    state: S = self.init(problem, params)
    result: Result = self.compute(problem, state)
    return self.postprocess(problem, state, result)

LinearSolver

Base class for linear solvers.

Methods:

  • compute

    Run one complete solve from an initialized state.

  • init

    Create solver state from an initial parameter vector.

  • postprocess

    Wrap final state and result metadata in a solution object.

  • solve

    Initialize, compute, and postprocess a linear solve.

compute

compute(problem: BaseProblem, state: S) -> Result

Run one complete solve from an initialized state.

Source code in src/liblaf/peach/linalg/base/_solver.py
def compute(self, problem: BaseProblem, state: S) -> Result:
    """Run one complete solve from an initialized state."""
    raise NotImplementedError

init

init(problem: BaseProblem, params: Vector) -> S

Create solver state from an initial parameter vector.

Source code in src/liblaf/peach/linalg/base/_solver.py
def init(self, problem: BaseProblem, params: Vector) -> S:
    """Create solver state from an initial parameter vector."""
    raise NotImplementedError

postprocess

postprocess(
    problem: BaseProblem, state: S, result: Result
) -> Solution[S, T]

Wrap final state and result metadata in a solution object.

Source code in src/liblaf/peach/linalg/base/_solver.py
def postprocess(
    self, problem: BaseProblem, state: S, result: Result
) -> Solution[S, T]:
    """Wrap final state and result metadata in a solution object."""
    del problem
    stats: T = cast("T", self.Stats())  # ty:ignore[call-non-callable]
    return Solution(result=result, state=state, stats=stats)

solve

solve(
    problem: BaseProblem, params: Vector
) -> Solution[S, T]

Initialize, compute, and postprocess a linear solve.

Source code in src/liblaf/peach/linalg/base/_solver.py
def solve(self, problem: BaseProblem, params: Vector) -> Solution[S, T]:
    """Initialize, compute, and postprocess a linear solve."""
    state: S = self.init(problem, params)
    result: Result = self.compute(problem, state)
    return self.postprocess(problem, state, result)

Problem

Bases: Protocol


              flowchart TD
              liblaf.peach.linalg.Problem[Problem]

              

              click liblaf.peach.linalg.Problem href "" "liblaf.peach.linalg.Problem"
            

Protocol for a linear system A x = b.

Methods:

  • matvec

    Apply the system matrix to x.

  • precondition

    Apply an optional left preconditioner to x.

  • rmatvec

    Apply the transpose or adjoint system matrix to x.

  • rprecondition

    Apply an optional transpose or adjoint preconditioner to x.

Attributes:

  • b (Vector) –

    Right-hand-side vector.

b property

b: Vector

Right-hand-side vector.

matvec

matvec(x: Vector) -> Vector

Apply the system matrix to x.

Source code in src/liblaf/peach/linalg/base/_problem.py
@not_implemented
def matvec(self, x: Vector, /) -> Vector:
    """Apply the system matrix to `x`."""

precondition

precondition(x: Vector) -> Vector

Apply an optional left preconditioner to x.

Source code in src/liblaf/peach/linalg/base/_problem.py
@not_implemented
def precondition(self, x: Vector, /) -> Vector:
    """Apply an optional left preconditioner to `x`."""

rmatvec

rmatvec(x: Vector) -> Vector

Apply the transpose or adjoint system matrix to x.

Source code in src/liblaf/peach/linalg/base/_problem.py
@not_implemented
def rmatvec(self, x: Vector, /) -> Vector:
    """Apply the transpose or adjoint system matrix to `x`."""

rprecondition

rprecondition(x: Vector) -> Vector

Apply an optional transpose or adjoint preconditioner to x.

Source code in src/liblaf/peach/linalg/base/_problem.py
@not_implemented
def rprecondition(self, x: Vector, /) -> Vector:
    """Apply an optional transpose or adjoint preconditioner to `x`."""

Result

Bases: StrEnum


              flowchart TD
              liblaf.peach.linalg.Result[Result]

              

              click liblaf.peach.linalg.Result href "" "liblaf.peach.linalg.Result"
            

Result code returned by linear solvers.

Attributes:

BREAKDOWN class-attribute instance-attribute

BREAKDOWN = auto()

MAX_STEPS_REACHED class-attribute instance-attribute

MAX_STEPS_REACHED = auto()

PRIMARY_SUCCESS class-attribute instance-attribute

PRIMARY_SUCCESS = auto()

SECONDARY_SUCCESS class-attribute instance-attribute

SECONDARY_SUCCESS = 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 solution.

Solution

Linear-solver output bundle.

Parameters:

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

Attributes:

params property

params: Vector

Final solution parameters.

result instance-attribute

result: Result

state instance-attribute

state: S

stats instance-attribute

stats: T

success property

success: bool

Whether result is successful.

State

Bases: Protocol


              flowchart TD
              liblaf.peach.linalg.State[State]

              

              click liblaf.peach.linalg.State href "" "liblaf.peach.linalg.State"
            

Protocol for solver states that expose solution parameters.

Attributes:

  • params (Vector) –

    Current solution estimate.

params property

params: Vector

Current solution estimate.

Stats

Bases: Protocol


              flowchart TD
              liblaf.peach.linalg.Stats[Stats]

              

              click liblaf.peach.linalg.Stats href "" "liblaf.peach.linalg.Stats"
            

Protocol for solver-specific summary statistics.