Source code for biogeme.expressions.convert

"""Convert expressions to float and vice versa

Michel Bierlaire
Tue Mar 25 18:43:36 2025
"""

from __future__ import annotations

from biogeme.exceptions import BiogemeError
from .base_expressions import ExpressionOrNumeric, Expression
from .numeric_expressions import Numeric
from .numeric_tools import is_numeric


[docs] def validate_and_convert(expression: ExpressionOrNumeric) -> Expression: """Validates the expression and returns the converted expression if necessary.""" if isinstance(expression, bool): return Numeric(1) if expression else Numeric(0) if is_numeric(expression): return Numeric(expression) if not isinstance(expression, Expression): raise TypeError( f'This is not a valid expression: {expression}. It is of type {type(expression)}' ) return expression
[docs] def expression_to_value( expression: ExpressionOrNumeric, betas: dict[str, float] | None = None ) -> float: """ Convert an expression to a float value, if possible. :param expression: The expression to convert. Can be a boolean, a numeric value, or an instance of Expression. :param betas: Optional dictionary of beta values used to initialize the expression, if applicable. :return: The numerical value of the expression as a float. :raises TypeError: If the input is not a valid expression type. :raises BiogemeError: If the expression cannot be evaluated to a numeric value. """ if isinstance(expression, bool) or is_numeric(expression): return float(expression) if not isinstance(expression, Expression): raise TypeError(f'This is not a valid expression: {expression}') if betas is not None: expression.change_init_values(betas=betas) try: value = expression.get_value() except BiogemeError as e: error_msg = f'Expression {expression} too complex to be associated with a numeric value: {e}' raise BiogemeError(error_msg) from e return value
[docs] def get_dict_values( the_dict: dict[int, ExpressionOrNumeric], betas: dict[str, float] | None = None ) -> dict[int, float]: """If the dictionary contains Expressions, they are transformed into a numerical expression.""" return { key: expression_to_value(expression=expr, betas=betas) for key, expr in the_dict.items() }
[docs] def get_dict_expressions( the_dict: dict[int, ExpressionOrNumeric], ) -> dict[int, Expression]: """If the dictionary contains float, they are transformed into a numerical expression.""" return {key: validate_and_convert(value) for key, value in the_dict.items()}