Source code for biogeme.latent_variables.structural_equation
"""Structural equations for latent variables.This module defines :class:`StructuralEquation`, a lightweight specification oflatent-variable structural equations. A structural equation consists of:- a latent variable name,- a set of explanatory variables entering the deterministic part,- a stochastic error term built from simulation draws, scaled by a strictly positive parameter (sigma).The deterministic part is a linear-in-parameters expression built with onecoefficient per explanatory variable.The full structural equation returned by :meth:`StructuralEquation.expression`creates a :class:`~biogeme.expressions.DistributedParameter` whose child is thesum of the deterministic component and a random term``sigma * Draws(draw_type=...)``.Michel BierlaireTue Dec 23 2025, 16:00:07"""fromcollections.abcimportIterablefromdataclassesimportdataclassfrombiogeme.expressionsimport(Beta,DistributedParameter,Draws,Expression,LinearTermTuple,LinearUtility,Numeric,Variable,)from.positive_parameter_factoryimportSigmaFactory
[docs]@dataclassclassStructuralEquation:"""Specification of a latent-variable structural equation. The structural equation defines the deterministic part as a linear utility over the explanatory variables and adds a stochastic term based on draws. :param name: Name of the latent variable. :param explanatory_variables: Iterable of variable names entering the deterministic part. :param sigma_factory: Factory creating a strictly positive scale parameter (sigma) used to scale the draw-based stochastic term. Required unless an explicit ``scale_parameter`` is provided to :meth:`expression`. """name:strexplanatory_variables:Iterable[str]sigma_factory:SigmaFactory|None=None@propertydefprefix(self)->str:"""Prefix used to namespace parameters belonging to this structural equation."""returnf'struct_{self.name}'
[docs]defget_expression_deterministic_part(self)->Expression:"""Construct the deterministic part of the structural equation. A coefficient :class:`~biogeme.expressions.Beta` is created for each explanatory variable and assembled into a :class:`~biogeme.expressions.LinearUtility`. :return: A linear expression representing the deterministic component. """coefficients={variable_name:Beta(f'{self.prefix}_{variable_name}',0.0,None,None,0)forvariable_nameinself.explanatory_variables}ifnotcoefficients:returnNumeric(0)the_expression=LinearUtility([LinearTermTuple(beta=coefficients[variable_name],x=Variable(variable_name),)forvariable_nameinself.explanatory_variables])returnthe_expression
[docs]defexpression(self,*,draw_type:str,scale_parameter:Expression|None=None)->Expression:"""Construct the full structural equation including the stochastic term. If ``scale_parameter`` is not provided, the method uses :attr:`sigma_factory` to create a strictly positive sigma parameter named with :attr:`prefix`. The returned expression is a :class:`~biogeme.expressions.DistributedParameter` with child expression: ``deterministic + scale_parameter * Draws(draw_type=draw_type)``. :param draw_type: Draw type identifier used by :class:`~biogeme.expressions.Draws`. :param scale_parameter: Optional scale parameter (sigma). If None, it is created through :attr:`sigma_factory`. :return: Expression representing the full structural equation. :raises ValueError: If ``scale_parameter`` is None and :attr:`sigma_factory` is undefined. """ifscale_parameterisNone:ifself.sigma_factoryisNone:raiseValueError('Sigma factory is undefined.')scale_parameter=self.sigma_factory(prefix=self.prefix)draws=Draws(name=f'{self.prefix}_draws',draw_type=draw_type)deterministic=self.get_expression_deterministic_part()returnDistributedParameter(self.name,child=deterministic+scale_parameter*draws)