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
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
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)
def xlog(y: Basic, x: Symbol, base: Basic = 10): "For log plots on the x axis" return y.subs(x, 10**x)