symforce.internal.symbolic module#

The (symforce-internal) core symbolic API

This represents the core functions that comprise SymForce’s unified version of the SymPy API, without additional imports that would cause import cycles. This means this module is safe to be imported from those modules within SymForce. Users should instead import symforce.symbolic, which includes the entire SymForce symbolic API.

This combines functions available from various sources:

  • Many functions we expose from the SymPy (and SymEngine) API

  • Additional functions defined here to override those provided by SymPy or SymEngine, or provide a uniform interface between the two. See https://symforce.org/api/symforce.symbolic.html for information on these

  • Logic functions defined in symforce.logic, see the documentation for that module

It typically isn’t necessary to actually access the symbolic API being used internally, but that is available as well as symforce.symbolic.sympy.

create_named_scope(scopes_list)[source]#

Return a context manager that adds to the given list of name scopes. This is used to add scopes to symbol names for namespacing.

Parameters:

scopes_list (List[str]) –

Return type:

Callable

set_scope(scope)[source]#
Parameters:

scope (str) –

Return type:

None

get_scope()[source]#
Return type:

str

scope(scope)#
Parameters:

scope (str) –

Return type:

Iterator[None]

class Symbol(name, commutative=True, real=True, positive=None)[source]#

Bases: Symbol

Parameters:
  • name (str) –

  • commutative (bool) –

  • real (bool) –

  • positive (bool | None) –

epsilon()[source]#

The default epsilon for SymForce

Library functions that require an epsilon argument should use a function signature like:

def foo(x: Scalar, epsilon: Scalar = sf.epsilon()) -> Scalar:
    ...

This makes it easy to configure entire expressions that make extensive use of epsilon to either use no epsilon (i.e. 0), or a symbol, or a numerical value. It also means that by setting the default to a symbol, you can confidently generate code without worrying about having forgotten to pass an epsilon argument to one of these functions.

For more information on how we use epsilon to prevent singularities, see the Epsilon Tutorial in the SymForce docs here: https://symforce.org/tutorials/epsilon_tutorial.html

For purely numerical code that just needs a good default numerical epsilon, see symforce.symbolic.numeric_epsilon.

Returns:
  • The current default epsilon. This is typically some kind of “Scalar”, like a float or a

  • :class:`Symbol <symforce.symbolic.Symbol>`.

Return type:

Any

wrap_angle(x)[source]#

Wrap an angle to the interval [-pi, pi). Commonly used to compute the shortest signed distance between two angles.

See also: angle_diff()

Parameters:

x (float) –

Return type:

float

angle_diff(x, y)[source]#

Return the difference x - y, but wrapped into [-pi, pi); i.e. the angle diff closest to 0 such that x = y + diff (mod 2pi).

See also: wrap_angle()

Parameters:
Return type:

float

sign_no_zero(x)[source]#

Returns -1 if x is negative, 1 if x is positive, and 1 if x is zero.

Parameters:

x (float) –

Return type:

float

copysign_no_zero(x, y)[source]#

Returns a value with the magnitude of x and sign of y. If y is zero, returns positive x.

Parameters:
Return type:

float

argmax_onehot(vals, tolerance=0.0)[source]#

Returns a list l such that l[i] = 1.0 if i is the smallest index such that vals[i] equals Max(*vals). l[i] = 0.0 otherwise.

Precondition:

vals has at least one element

Parameters:
  • tolerance (float) – The selected max will be guaranteed to be within tolerance of the true max. If this is too small (e.g. if this is 0), the returned vector may be all zeros for some inputs.

  • vals (Iterable[float]) –

Return type:

List[float]

argmax(vals)[source]#

Returns i (as a Scalar) such that i is the smallest index such that vals[i] equals Max(*vals).

Precondition:

vals has at least one element

Parameters:

vals (Iterable[float]) –

Return type:

float

atan2(y, x, epsilon=0.0)[source]#
Parameters:
Return type:

float

asin_safe(x, epsilon=0.0)[source]#
Parameters:
Return type:

float

acos_safe(x, epsilon=0.0)[source]#
Parameters:
Return type:

float

clamp(x, min_value, max_value)[source]#

Clamps x between min_value and max_value

Returns:

min_value if x < min_value
x if min_value <= x <= max_value
max_value if x > max_value
Parameters:
  • x (float) – Value to clamp between min_value and max_value

  • min_value (float) – Scalar of same type and units as x; minimum value to return

  • max_value (float) – Scalar of same type and units as x; maximum value to return. Must be greater than min_value.

Return type:

float

set_eval_on_sympify(eval_on_sympy=True)[source]#

When using the symengine backed, set whether we should eval args when converting objects to sympy.

By default, this is enabled since this is the implicit behavior with stock symengine. Disabling eval results in more slightly ops, but greatly speeds up codegen time.

Parameters:

eval_on_sympy (bool) –

Return type:

None

simplify(*args, **kwargs)[source]#
Parameters:
  • args (Any) –

  • kwargs (Any) –

Return type:

float

limit(e, z, z0, dir='+')[source]#
Parameters:
Return type:

float

integrate(*args, meijerg=None, conds='piecewise', risch=None, heurisch=None, manual=None, **kwargs)[source]#
Parameters:
  • args (Any) –

  • meijerg (bool | None) –

  • conds (Literal['piecewise', 'separate', 'none']) –

  • risch (bool | None) –

  • heurisch (Any | None) –

  • manual (bool | None) –

  • kwargs (Any) –

solve(*args, **kwargs)[source]#
Parameters:
  • args (Any) –

  • kwargs (Any) –

Return type:

List[float]