gcubed.reporting.baseline_diagnostics

Reusable diagnostics for first-year baseline projection problems.

The diagnostics in this module are deliberately observational. They decompose the already solved linear state-space system and report the conditioning of the intertemporal-constant calculation; they do not alter equations, data, wedges, constants, or projections.

DIAGNOSTIC_REGIONS: tuple[str, ...] = ('LKA', 'VNM')
FIRST_YEAR_TARGET_PREFIXES: tuple[str, ...] = ('GDPR', 'OUTP', 'INVT', 'TOB', 'TOBY', 'LAM', 'LAMY', 'WAGE', 'LABO')
RATE_PREFIXES: frozenset[str] = frozenset({'INFX', 'TOB', 'INTL', 'TOBZ', 'INTF', 'LAMY', 'LAMZ', 'INFL', 'TOBY', 'INTN', 'INTR', 'EPRC', 'LAM', 'EYGR'})
def sector_from_variable_details(details: pandas.Series) -> str | None:

Extract a sector-like set member from SYM variable metadata.

def variable_scale(variable_name: str, value: float, *, logged: bool = False) -> float:

Return a documented, unit-aware scale for one model variable.

Rates use one percentage point in the model's decimal units. Logged levels use the log change associated with a one-percent level change. Other variables use one percent of their magnitude with a small absolute floor.

def scaled_residual_denominator( lhs: float, rhs_term_contributions: Iterable[float], floor: float) -> float:

Return the denominator used to compare equation residuals.

def conditioning_summary( jacobian: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[numpy.float64]], row_scales: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[numpy.float64]], column_scales: numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[numpy.float64]]) -> dict[str, typing.Any]:

Scale a Jacobian and report its singular-value conditioning.

The scaled Jacobian maps a one-unit scaled constant perturbation into a one-unit scaled target response: diag(1 / row_scales) @ jacobian @ diag(column_scales).

def first_year_source_sensitivities( parameters: gcubed.projections.gcubed_parameters.GCubedParameters, target_vector: str, target_sequence: int, projection_years_count: int, target_year_index: int = 1) -> dict[str, numpy.ndarray[tuple[typing.Any, ...], numpy.dtype[numpy.float64]]]:

Recursively unwind first-transition sensitivities exactly once.

This is a reverse pass through the same h3 and c4 recursion used by the projection code. It returns coefficients for the starting state, every exogenous variable/year cell, and each combined wedge/constant vector. Because the solved state-space system is linear, multiplying these coefficients by the corresponding source values gives exact additive contributions.

def first_year_attribution_report( baseline: gcubed.projections.baseline_projections.BaselineProjections, *, regions: Iterable[str] = ('LKA', 'VNM'), target_prefixes: Iterable[str] = ('GDPR', 'OUTP', 'INVT', 'TOB', 'TOBY', 'LAM', 'LAMY', 'WAGE', 'LABO')) -> pandas.DataFrame:

Build an exact source attribution for selected first-year targets.

def intertemporal_conditioning_report( baseline: gcubed.projections.baseline_projections.BaselineProjections) -> pandas.DataFrame:

Build a scaled conditioning and signed-response report.

def lka_vnm_baseline_comparison_report( baseline: gcubed.projections.baseline_projections.BaselineProjections, attribution: pandas.DataFrame) -> pandas.DataFrame:

Build a long-form LKA/VNM baseline and diagnostic comparison.

def write_baseline_diagnostic_reports( baseline: gcubed.projections.baseline_projections.BaselineProjections, output_directory: pathlib.Path | None = None) -> None:

Write the reusable attribution and conditioning reports.