Skip to content

Batch Least Squares

Iterative batch least squares estimator for offline orbit determination.

BatchLeastSquares

BatchLeastSquares(epoch: Any, initial_state: Any, initial_covariance: Any, propagation_config: Any, force_config: Any, measurement_models: Any, config: Any = None, params: Any = None, additional_dynamics: Any = None, control_input: Any = None)

Batch Least Squares estimator for orbit determination.

Processes all observations simultaneously through an iterative Gauss-Newton algorithm. Supports both normal equations and stacked observation matrix solver formulations.

Example
import brahe as bh
import numpy as np

bh.initialize_eop()

epoch = bh.Epoch(2024, 1, 1, 0, 0, 0.0)
state = np.array([6878e3, 0.0, 0.0, 0.0, 7612.0, 0.0])
p0 = np.diag([1e6, 1e6, 1e6, 1e2, 1e2, 1e2])

bls = bh.BatchLeastSquares(
    epoch, state, p0,
    propagation_config=bh.NumericalPropagationConfig.default(),
    force_config=bh.ForceModelConfig.two_body_gravity(),
    measurement_models=[bh.InertialPositionMeasurementModel(10.0)],
)

Initialize instance.

builder staticmethod

builder(epoch: Epoch, state: ndarray, apriori_covariance: ndarray, force_config: ForceModelConfig, config: BLSConfig) -> BatchLeastSquaresBuilder

Create a builder for constructing a BatchLeastSquares estimator.

The builder takes the required inputs directly; optional inputs (propagation config, params, additional dynamics, control input, measurement models) are set through chained setter calls before calling build().

Parameters:

Name Type Description Default
epoch Epoch

Initial (reference) epoch.

required
state ndarray

Initial state vector in ECI [x,y,z,vx,vy,vz,...] (meters, m/s).

required
apriori_covariance ndarray

A priori covariance matrix (n x n).

required
force_config ForceModelConfig

Force model configuration.

required
config BLSConfig

BLS configuration.

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

New builder instance.

Example
1
2
3
4
5
6
7
8
9
import brahe as bh

bls = (
    bh.BatchLeastSquares.builder(
        epoch, state, p0, bh.ForceModelConfig.two_body(), bh.BLSConfig.default(),
    )
    .measurement_model(bh.InertialPositionMeasurementModel(10.0))
    .build()
)

consider_covariance method descriptor

consider_covariance() -> Union[ndarray, None]

Consider covariance contribution.

Returns:

Type Description
Union[ndarray, None]

numpy.ndarray or None: Consider covariance matrix, or None if consider parameters are not configured.

converged method descriptor

converged() -> bool

Whether the solver has converged.

Returns:

Name Type Description
bool bool

True if converged.

current_covariance method descriptor

current_covariance() -> ndarray

Get current formal covariance (solve-for partition).

Use total_covariance() for the formal + consider contribution.

Returns:

Type Description
ndarray

numpy.ndarray: Formal covariance matrix (n_solve x n_solve).

current_epoch method descriptor

current_epoch() -> Epoch

Get current epoch (reference epoch for the batch).

Returns:

Name Type Description
Epoch Epoch

Current epoch.

current_state method descriptor

current_state() -> ndarray

Get current state estimate at the reference epoch.

Returns:

Type Description
ndarray

numpy.ndarray: Current state vector.

final_cost method descriptor

final_cost() -> float

Final cost function value J.

Returns:

Name Type Description
float float

Final cost.

formal_covariance method descriptor

formal_covariance() -> ndarray

Formal covariance (solve-for partition only).

Returns:

Type Description
ndarray

numpy.ndarray: Formal covariance matrix.

iteration_records method descriptor

iteration_records() -> list[BLSIterationRecord]

Per-iteration diagnostic records.

Only populated when config.store_iteration_records is True.

Returns:

Type Description
list[BLSIterationRecord]

list[BLSIterationRecord]: List of iteration records.

iterations_completed method descriptor

iterations_completed() -> int

Number of Gauss-Newton iterations completed.

Returns:

Name Type Description
int int

Number of iterations.

observation_residuals method descriptor

observation_residuals() -> list[list[BLSObservationResidual]]

Per-observation residuals for each iteration.

Only populated when config.store_observation_residuals is True. Outer list is indexed by iteration, inner list by observation.

Returns:

Type Description
list[list[BLSObservationResidual]]

list[list[BLSObservationResidual]]: Nested list of observation residuals.

solve method descriptor

solve(observations: list[Observation]) -> Any

Solve the batch least squares problem.

Iteratively processes all observations to find the state that minimizes the weighted sum of squared residuals.

Parameters:

Name Type Description Default
observations list[Observation]

List of observations to process.

required
Example
1
2
3
bls.solve(observations)
print(f"Converged: {bls.converged()}")
print(f"Iterations: {bls.iterations_completed()}")

Raises:

Type Description
Exception

Propagates the original exception raised by an additional-dynamics or control-input callback, or a BraheError if propagation or the least-squares solve fails.

total_covariance method descriptor

total_covariance() -> ndarray

Get total covariance: formal + consider contribution.

Returns the formal covariance if consider parameters are not configured.

Returns:

Type Description
ndarray

numpy.ndarray: Total covariance matrix (n_solve x n_solve).


BatchLeastSquaresBuilder

BatchLeastSquaresBuilder()

Builder for [BatchLeastSquares].

Created by BatchLeastSquares.builder(), which takes the required inputs (epoch, state, apriori_covariance, force_config, config). Remaining inputs are provided through chained setters and default to None / empty (NumericalPropagationConfig.default() for the propagation configuration, no measurement models). build() delegates to BatchLeastSquares's flat constructor; the builder is single-use, and calling build() a second time raises RuntimeError.

Example
import brahe as bh

bls = (
    bh.BatchLeastSquares.builder(
        epoch, state, p0, bh.ForceModelConfig.two_body(), bh.BLSConfig.default(),
    )
    .propagation_config(bh.NumericalPropagationConfig.default())
    .measurement_model(bh.InertialPositionMeasurementModel(10.0))
    .build()
)

Initialize instance.

additional_dynamics method descriptor

additional_dynamics(dynamics: callable) -> BatchLeastSquaresBuilder

Set additional dynamics for extended state dimensions beyond the orbital state.

Parameters:

Name Type Description Default
dynamics callable

Function computing derivatives for extra state elements. Signature: f(t, state, params) -> derivative.

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

The builder, for method chaining.

build method descriptor

build() -> BatchLeastSquares

Construct the estimator from the accumulated configuration.

This consumes the builder. The builder is single-use: calling build() a second time raises RuntimeError.

Returns:

Name Type Description
BatchLeastSquares BatchLeastSquares

Initialized estimator ready to solve.

Raises:

Type Description
RuntimeError

If the builder was already consumed by a prior build() call, or if the underlying estimator construction fails (no measurement models, mismatched covariance dimensions, no convergence threshold configured, or the propagator could not be constructed).

Exception

Propagates the original exception raised by a dynamics or control-input callback invoked during construction (e.g. computing the initial acceleration when store_accelerations is enabled).

control_input method descriptor

control_input(control: callable) -> BatchLeastSquaresBuilder

Set a continuous control-input function that adds an acceleration perturbation.

Parameters:

Name Type Description Default
control callable

Control function returning an acceleration perturbation vector. Signature: f(t, state, params) -> acceleration.

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

The builder, for method chaining.

measurement_model method descriptor

measurement_model(model: MeasurementModel) -> BatchLeastSquaresBuilder

Append a measurement model.

Call multiple times to register multiple measurement types; Observation's model_index selects among them.

Parameters:

Name Type Description Default
model MeasurementModel

Measurement model to append (built-in or custom).

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

The builder, for method chaining.

measurement_models method descriptor

measurement_models(models: List) -> BatchLeastSquaresBuilder

Replace the full list of measurement models.

Parameters:

Name Type Description Default
models list

Measurement models, replacing any previously set.

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

The builder, for method chaining.

params method descriptor

params(params: ndarray) -> BatchLeastSquaresBuilder

Set the parameter vector [mass, drag_area, Cd, srp_area, Cr, ...].

Required when force_config references parameter indices for drag or SRP.

Parameters:

Name Type Description Default
params ndarray

Parameter vector.

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

The builder, for method chaining.

propagation_config method descriptor

Set the propagation configuration (integrator method, tolerances, and step sizes).

Defaults to NumericalPropagationConfig.default() if not called. STM propagation is force-enabled regardless, since BLS requires it for Jacobian mapping.

Parameters:

Name Type Description Default
config NumericalPropagationConfig

Numerical propagation configuration.

required

Returns:

Name Type Description
BatchLeastSquaresBuilder BatchLeastSquaresBuilder

The builder, for method chaining.


BLSConfig

BLSConfig(solver_method: Any = 0, max_iterations: Any = 10, state_correction_threshold: Any = Ellipsis, cost_convergence_threshold: Any = None, consider_params: Any = None, store_iteration_records: Any = True, store_observation_residuals: Any = True)

Configuration for the Batch Least Squares estimator.

Example
1
2
3
4
import brahe as bh

config = bh.BLSConfig()  # All defaults
config = bh.BLSConfig(max_iterations=20, solver_method=bh.BLSSolverMethod.STACKED_OBSERVATION_MATRIX)

Initialize instance.

cost_convergence_threshold property

cost_convergence_threshold: Union[float, None]

Cost convergence threshold.

Returns:

Type Description
Union[float, None]

float or None: Threshold value.

max_iterations property

max_iterations: int

Maximum number of iterations.

Returns:

Name Type Description
int int

Maximum iterations.

solver_method property

solver_method: int

Solver method (0 = NormalEquations, 1 = StackedObservationMatrix).

Returns:

Name Type Description
int int

Solver method identifier.

state_correction_threshold property

state_correction_threshold: Union[float, None]

State correction convergence threshold.

Returns:

Type Description
Union[float, None]

float or None: Threshold value.

store_iteration_records property

store_iteration_records: bool

Whether iteration records are stored.

Returns:

Name Type Description
bool bool

True if records are stored.

store_observation_residuals property

store_observation_residuals: bool

Whether observation residuals are stored.

Returns:

Name Type Description
bool bool

True if residuals are stored.

default staticmethod

default() -> BLSConfig

Create a default BLS configuration.

Returns:

Name Type Description
BLSConfig BLSConfig

Default configuration (normal equations, 10 iterations, threshold 1e-8).


BLSSolverMethod

BLSSolverMethod()

Solver formulation for Batch Least Squares.

Available methods
  • BLSSolverMethod.NORMAL_EQUATIONS (0): Accumulate information matrix, solve via Cholesky. Memory-efficient O(n^2).
  • BLSSolverMethod.STACKED_OBSERVATION_MATRIX (1): Build full H matrix, better numerical conditioning. Memory O(m*n).
Example
1
2
3
import brahe as bh
method = bh.BLSSolverMethod.NORMAL_EQUATIONS
config = bh.BLSConfig(solver_method=method)

Initialize instance.

NORMAL_EQUATIONS class-attribute

NORMAL_EQUATIONS: Any = 0

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer iteral.

int('0b100', base=0) 4

STACKED_OBSERVATION_MATRIX class-attribute

STACKED_OBSERVATION_MATRIX: Any = 1

int([x]) -> integer int(x, base=10) -> integer

Convert a number or string to an integer, or return 0 if no arguments are given. If x is a number, return x.int(). For floating-point numbers, this truncates towards zero.

If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in the given base. The literal can be preceded by '+' or '-' and be surrounded by whitespace. The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to interpret the base from the string as an integer iteral.

int('0b100', base=0) 4


ConsiderParameterConfig

ConsiderParameterConfig(n_solve: Any, consider_covariance: Any)

Configuration for consider parameters in batch estimation.

Partitions the state into solve-for (first n_solve elements) and consider (remaining elements) parameters. The consider parameters are not estimated but their uncertainty is accounted for in the covariance.

Example
1
2
3
4
5
6
import brahe as bh
import numpy as np

# 6D state: first 6 are solve-for, next 1 is consider (e.g., Cd)
consider_cov = np.array([[0.01]])
config = bh.ConsiderParameterConfig(n_solve=6, consider_covariance=consider_cov)

Initialize instance.

consider_covariance property

consider_covariance: ndarray

A priori covariance for consider parameters.

Returns:

Type Description
ndarray

numpy.ndarray: Consider covariance matrix (n_c x n_c).

n_solve property

n_solve: int

Number of solve-for parameters.

Returns:

Name Type Description
int int

Number of solve-for parameters.


BLSIterationRecord

BLSIterationRecord()

Record of a single BLS iteration.

Contains the state estimate, covariance, state correction, cost, and residual statistics at each Gauss-Newton iteration.

Initialize instance.

cost property

cost: float

Cost function value J at this iteration.

Returns:

Name Type Description
float float

Cost function value.

covariance property

covariance: ndarray

Covariance at this iteration (formal, solve-for only).

Returns:

Type Description
ndarray

numpy.ndarray: Covariance matrix.

epoch property

epoch: Epoch

Reference epoch for this iteration.

Returns:

Name Type Description
Epoch Epoch

Iteration epoch.

iteration property

iteration: int

Iteration number (0-indexed).

Returns:

Name Type Description
int int

Iteration number.

rms_postfit_residual property

rms_postfit_residual: float

RMS of all post-fit residuals at this iteration.

Returns:

Name Type Description
float float

Post-fit RMS.

rms_prefit_residual property

rms_prefit_residual: float

RMS of all pre-fit residuals at this iteration.

Returns:

Name Type Description
float float

Pre-fit RMS.

state property

state: ndarray

State estimate at this iteration.

Returns:

Type Description
ndarray

numpy.ndarray: State vector.

state_correction property

state_correction: ndarray

State correction applied at this iteration.

Returns:

Type Description
ndarray

numpy.ndarray: State correction vector delta_x.

state_correction_norm property

state_correction_norm: float

Norm of the state correction ||delta_x||.

Returns:

Name Type Description
float float

State correction norm.


BLSObservationResidual

BLSObservationResidual()

Per-observation residual from a BLS iteration.

Contains pre-fit and post-fit residuals for a single observation.

Initialize instance.

epoch property

epoch: Epoch

Epoch of the observation.

Returns:

Name Type Description
Epoch Epoch

Observation epoch.

model_name property

model_name: str

Name of the measurement model used.

Returns:

Name Type Description
str str

Model name.

postfit_residual property

postfit_residual: ndarray

Post-fit residual: y - h(x_{k+1}, t) after state correction.

Returns:

Type Description
ndarray

numpy.ndarray: Post-fit residual vector.

prefit_residual property

prefit_residual: ndarray

Pre-fit residual: y - h(x_k, t) before state correction.

Returns:

Type Description
ndarray

numpy.ndarray: Pre-fit residual vector.

See Also