Source code for biogeme.mdcev.gamma_profile

"""Implementation of the "gamma profile" MDCEV model. See section 3.1 in
the technical report.

:author: Michel Bierlaire
:date: Sun Nov  5 15:56:36 2023

"""
from typing import Optional
from biogeme.expressions import Expression, log
from .mdcev import mdcev, info_gamma_parameters, SpecificModel


[docs] def gamma_profile( baseline_utilities: dict[int, Expression], consumed_quantities: dict[int, Expression], gamma_parameters: dict[int, Optional[Expression]], prices: Optional[dict[int, Expression]] = None, ): """Calculates the determinant entries for the linear expenditure system :param baseline_utilities: see the module documentation :mod:`biogeme.mdcev` :param consumed_quantities: see the module documentation :mod:`biogeme.mdcev` :param gamma_parameters: see the module documentation :mod:`biogeme.mdcev` :param prices: see the module documentation :mod:`biogeme.mdcev`. If None, assumed to be 1. """ info_gamma_parameters(gamma_parameters) def calculate_utility( the_id: int, consumption: Expression, price: Optional[Expression] ) -> Expression: """Calculate the utility. The formula is different is it is an outside good, characterized by the absence of a gamma parameter. :param the_id: identifier of the good. :param consumption: expression for the consumption. :param price: expression for the price, or None if prices are not considered. """ gamma = gamma_parameters[the_id] if gamma is None: return baseline_utilities[the_id] - log(consumption) if price is None: return baseline_utilities[the_id] + log(gamma) - log(consumption + gamma) return ( baseline_utilities[the_id] + log(gamma) - log(consumption + price * gamma) ) def calculate_log_determinant( the_id: int, consumption: Expression, price: Optional[Expression] ) -> Expression: """Calculate the log of the entries for the determinant. For the outside good, gamma is equal to 0. :param the_id: identifier of the good. :param consumption: expression for the consumption. :param price: expression for the price, or None if prices are not considered. """ gamma = gamma_parameters[the_id] if gamma is None: return -log(consumption) if price is None: return -log(consumption + gamma) return -log(consumption + price * gamma) def calculate_inverse_determinant( the_id: int, consumption: Expression, price: Optional[Expression] ) -> Expression: """Calculate the inverse of the entries for the determinant. For the outside good, gamma is equal to 0. :param the_id: identifier of the good. :param consumption: expression for the consumption. :param price: expression for the price, or None if prices are not considered. """ gamma = gamma_parameters[the_id] if gamma is None: return consumption if price is None: return consumption + gamma return consumption + price * gamma if prices: utilities = { the_id: (calculate_utility(the_id, consumption, prices[the_id])) for the_id, consumption in consumed_quantities.items() } log_determinant_entries = { the_id: calculate_log_determinant(the_id, consumption, prices[the_id]) for the_id, consumption in consumed_quantities.items() } inverse_of_determinant_entries = { the_id: calculate_inverse_determinant(the_id, consumption, prices[the_id]) for the_id, consumption in consumed_quantities.items() } return SpecificModel( utilities=utilities, log_determinant_entries=log_determinant_entries, inverse_of_determinant_entries=inverse_of_determinant_entries, ) utilities = { the_id: calculate_utility(the_id, consumption, None) for the_id, consumption in consumed_quantities.items() } log_determinant_entries = { the_id: calculate_log_determinant(the_id, consumption, None) for the_id, consumption in consumed_quantities.items() } inverse_of_determinant_entries = { the_id: calculate_inverse_determinant(the_id, consumption, None) for the_id, consumption in consumed_quantities.items() } return SpecificModel( utilities=utilities, log_determinant_entries=log_determinant_entries, inverse_of_determinant_entries=inverse_of_determinant_entries, )
[docs] def mdcev_gamma( number_of_chosen_alternatives: Expression, consumed_quantities: dict[int, Expression], baseline_utilities: dict[int, Expression], gamma_parameters: dict[int, Optional[Expression]], prices: Optional[dict[int, Expression]] = None, scale_parameter: Optional[Expression] = None, ): """Generate the Biogeme formula for the log probability of the MDCEV model using the linear expenditure system. :param number_of_chosen_alternatives: see the module documentation :mod:`biogeme.mdcev` :param consumed_quantities: see the module documentation :mod:`biogeme.mdcev` :param baseline_utilities: see the module documentation :mod:`biogeme.mdcev` :param gamma_parameters: see the module documentation :mod:`biogeme.mdcev` :param prices: see the module documentation :mod:`biogeme.mdcev` :param scale_parameter: see the module documentation :mod:`biogeme.mdcev` A detailed explanation is provided in the technical report "Estimating the MDCEV model with Biogeme" """ specific_model = gamma_profile( baseline_utilities, consumed_quantities, gamma_parameters, prices, ) return mdcev( number_of_chosen_alternatives=number_of_chosen_alternatives, consumed_quantities=consumed_quantities, specific_model=specific_model, scale_parameter=scale_parameter, )