Source code for biogeme.latent_variables.resolved

from __future__ import annotations

"""Resolved semantic model used by all outputs."""

from dataclasses import dataclass, field
from enum import Enum

from .context import EstimationMode
from .model_spec import MeasurementModel
from .normalization_refs import ParameterRef


[docs] class MeasurementErrorDistribution(str, Enum): GAUSSIAN = 'gaussian' LOGISTIC = 'logistic'
[docs] class ThresholdConstructionKind(str, Enum): SYMMETRIC = 'symmetric' MONOTONE = 'monotone'
[docs] class ParameterStatus(str, Enum): FIXED = 'fixed' FREE = 'free'
[docs] class ParameterCreationKind(str, Enum): NUMERIC_CONSTANT = 'numeric_constant' FREE_BETA = 'free_beta' FIXED_BETA = 'fixed_beta' LOG_EXP_BETA = 'log_exp_beta' BOUNDED_BETA = 'bounded_beta'
[docs] class PositivityStrategy(str, Enum): NONE = 'none' LOG_EXP = 'log_exp' LOWER_BOUND = 'lower_bound'
[docs] class ParameterRole(str, Enum): STRUCTURAL_INTERCEPT = 'structural_intercept' STRUCTURAL_COEFFICIENT = 'structural_coefficient' STRUCTURAL_SIGMA = 'structural_sigma' MEASUREMENT_INTERCEPT = 'measurement_intercept' MEASUREMENT_LOADING = 'measurement_loading' MEASUREMENT_SIGMA = 'measurement_sigma' THRESHOLD_FIRST = 'threshold_first' THRESHOLD_DELTA = 'threshold_delta'
[docs] class CutpointKind(str, Enum): FREE = 'free' FIXED = 'fixed' DERIVED = 'derived'
[docs] @dataclass(frozen=True, slots=True) class ResolvedParameter: semantic_ref: ParameterRef | None final_name: str role: ParameterRole status: ParameterStatus fixed_value: float | None initial_value: float lower_bound: float | None upper_bound: float | None positivity_strategy: PositivityStrategy | None creation_kind: ParameterCreationKind notes: list[str] = field(default_factory=list)
[docs] @dataclass(frozen=True, slots=True) class ResolvedParameterRef: final_name: str semantic_ref: ParameterRef | None = None
[docs] @dataclass(frozen=True, slots=True) class ResolvedConstant: value: float
[docs] @dataclass(frozen=True, slots=True) class ResolvedLinearTerm: coefficient: ResolvedParameterRef | ResolvedConstant variable_name: str
[docs] @dataclass(frozen=True, slots=True) class ResolvedLinearCombination: intercept: ResolvedParameterRef | ResolvedConstant | None terms: list[ResolvedLinearTerm]
[docs] @dataclass(frozen=True, slots=True) class ResolvedStructuralEquation: latent_name: str expression_name: str systematic_part: ResolvedLinearCombination sigma: ResolvedParameterRef | None draw_name: str draw_type: str error_distribution: str
[docs] @dataclass(frozen=True, slots=True) class ResolvedCutpoint: symbol_name: str kind: CutpointKind expression_text: str source_parameter_names: list[str]
[docs] @dataclass(frozen=True, slots=True) class ResolvedThresholdSystem: type_name: str symmetric: bool categories: list[int] neutral_labels: list[int] construction_kind: ThresholdConstructionKind cutpoints: list[ResolvedCutpoint] used_by_indicators: list[str] normalization_notes: list[str]
[docs] @dataclass(frozen=True, slots=True) class ResolvedMeasurementEquation: indicator_name: str statement: str type_name: str measurement_model: MeasurementModel systematic_part: ResolvedLinearCombination sigma: ResolvedParameterRef | None observed_variable_name: str threshold_system_name: str | None error_distribution: MeasurementErrorDistribution normalization_notes: list[str]
[docs] @dataclass(frozen=True, slots=True) class ResolvedNormalizationRule: scope: str target_name: str value: float | str reason: str
[docs] @dataclass(frozen=True, slots=True) class ResolvedNormalizationSummary: rules: list[ResolvedNormalizationRule] warnings: list[str] disclaimer: str
[docs] @dataclass(frozen=True, slots=True) class ResolvedLatentVariable: name: str structural_equation: ResolvedStructuralEquation indicator_names: list[str] reference_indicator: str | None normalization_notes: list[str]
[docs] @dataclass(frozen=True, slots=True) class ResolvedModelMetadata: estimation_mode: EstimationMode measurement_models_present: list[MeasurementModel] has_gaussian: bool has_ordered_probit: bool has_ordered_logit: bool has_ordinal: bool n_latent_variables: int n_indicators: int n_threshold_systems: int
[docs] @dataclass(frozen=True, slots=True) class ResolvedModel: metadata: ResolvedModelMetadata latent_variables: dict[str, ResolvedLatentVariable] measurement_equations: dict[str, ResolvedMeasurementEquation] threshold_systems: dict[str, ResolvedThresholdSystem] parameters: dict[str, ResolvedParameter] normalization: ResolvedNormalizationSummary
[docs] def free_parameters(self) -> list[ResolvedParameter]: """Return the parameters that are estimated. Fixed parameters and numeric constants are excluded because they do not appear in the estimation results. The order follows the insertion order of ``self.parameters``. :return: list of free resolved parameters. """ return [ parameter for parameter in self.parameters.values() if parameter.status == ParameterStatus.FREE ]