Ejemplo n.º 1
0
def get_lambda(e: sp.Basic,
               *,
               to_str: bool = False) -> tuple[Union[Callable, str], list[str]]:
    """
    Converts the input expression to a lambda function
    with valid identifiers as parameter names.

    Parameters
    ----------
    e : sp.Basic
        Input expression
    to_str : bool, optional
        Whether to return the string representation of the lambda function, by default False

    Returns
    -------
    Tuple[Union[Callable, str], list[str]]
        The lambda function (or string representation) and the list
        of parameters to the function
    """

    # sorted list of function parameters (as valid identifiers)
    args = get_args(e)

    # substitute the symbols with the identifier version,
    # otherwise they will be converted to dummy identifiers (even if dummify=False)
    e_identifiers = e.subs({
        n: sp.Symbol(to_identifier(n), **n.assumptions0)
        for n in e.free_symbols
    })

    _lambda_func = lambdastr if to_str else lambdify
    fcn = _lambda_func(args, e_identifiers, dummify=False)

    return fcn, args
Ejemplo n.º 2
0
def recursive_subs(e: sp.Basic,
                   replacements: list[tuple[sp.Symbol, sp.Basic]]) -> sp.Basic:
    """
    Substitute the expressions in ``replacements`` recursively.
    This might not be necessary in all cases, Sympy's builtin
    ``subs()`` method should also do this recursively.

    .. note::
        The order of the tuples in ``replacements`` might matter,
        make sure to order these sensibly in case the expression contains
        a lot of nested substitutions.

    Parameters
    ----------
    e : sp.Basic
        Input expression
    replacements : list[tuple[sp.Symbol, sp.Basic]]
        List of replacements: ``symbol, replace``

    Returns
    -------
    sp.Basic
        Substituted expression
    """

    for _ in range(0, len(replacements) + 1):

        new_e = e.subs(replacements)

        if new_e == e:
            return new_e
        else:
            e = new_e

    return new_e
Ejemplo n.º 3
0
 def resolve_offset(self, expr: Basic, values: Dict[str, int]):
     for f_sym in list(expr.free_symbols):
         if str(f_sym) in values:
             expr = expr.subs(f_sym, values[str(f_sym)])
     if not isinstance(expr, (Integer, Integral)):
         raise TypeError(f"Unable to compute domain domain_offsets because offset is not an integer:"
                         f"Offset: {expr}\tType: {type(expr)}")
     return int(expr)
Ejemplo n.º 4
0
def xlog(y: Basic, x: Symbol, base: Basic = 10):
    "For log plots on the x axis"
    return y.subs(x, 10**x)