S

S

S has 2 variants:

Shared Notes

Create new symbols from names. Symbols can have attributes, such as symmetries. If no attributes are specified and the symbol was previously defined, the attributes are inherited. Once attributes are defined on a symbol, they cannot be redefined later.

S returning Expression

S(
    name: str,
    is_symmetric: bool | None = None,
    is_antisymmetric: bool | None = None,
    is_cyclesymmetric: bool | None = None,
    is_linear: bool | None = None,
    is_scalar: bool | None = None,
    is_real: bool | None = None,
    is_integer: bool | None = None,
    is_positive: bool | None = None,
    tags: Sequence[str] | None = None,
    aliases: Sequence[str] | None = None,
    custom_normalization: Transformer | None = None,
    custom_print: Callable[..., str | None] | None = None,
    custom_derivative: Callable[[Expression, int], Expression] | None = None,
    data: str | int | Expression | bytes | list[Any] | dict[str | int | Expression, Any] | None = None,
) -> Expression

Examples

Define a regular symbol and use it as a variable:

x = S('x')
e = x**2 + 5
print(e)  # x**2 + 5

Define a regular symbol and use it as a function:

f = S('f')
e = f(1,2)
print(e)  # f(1,2)

Define a symmetric function:

f = S('f', is_symmetric=True)
e = f(2,1)
print(e)  # f(1,2)

Define a linear and symmetric function:

p1, p2, p3, p4 = ES('p1', 'p2', 'p3', 'p4')
dot = S('dot', is_symmetric=True, is_linear=True)
e = dot(p2+2*p3,p1+3*p2-p3)
dot(p1,p2)+2*dot(p1,p3)+3*dot(p2,p2)-dot(p2,p3)+6*dot(p2,p3)-2*dot(p3,p3)

Define a custom normalization function:

e = S('real_log', custom_normalization=T().replace(E("x_(exp(x1_))"), E("x1_")))
E("real_log(exp(x)) + real_log(5)")

Define a custom print function:

def print_mu(mu: Expression, mode: PrintMode, **kwargs) -> str | None:
    if mode == PrintMode.Latex:
        if mu.get_type() == AtomType.Fn:
            return "\mu_{" + ",".join(a.format() for a in mu) + "}"
        else:
            return "\mu"
mu = S("mu", custom_print=print_mu)
expr = E("mu + mu(1,2)")
print(expr.to_latex())

If the function returns None, the default print function is used.

Define a custom derivative function:

tag = S('tag', custom_derivative=lambda f, index: f)
x = S('x')
tag(3, x).derivative(x)

Add custom data to a symbol:

x = S('x', data={'my_tag': 'my_value'})
r = x.get_symbol_data('my_tag')

Parameters

  • name (str) The name of the symbol
  • is_symmetric (bool | None) Set to true if the symbol is symmetric.
  • is_antisymmetric (bool | None) Set to true if the symbol is antisymmetric.
  • is_cyclesymmetric (bool | None) Set to true if the symbol is cyclesymmetric.
  • is_linear (bool | None) Set to true if the symbol is linear.
  • is_scalar (bool | None) Set to true if the symbol is a scalar. It will be moved out of linear functions.
  • is_real (bool | None) Set to true if the symbol is a real number.
  • is_integer (bool | None) Set to true if the symbol is an integer.
  • is_positive (bool | None) Set to true if the symbol is a positive number.
  • tags (Sequence[str] | None = None) A list of tags to associate with the symbol.
  • aliases (Sequence[str] | None = None) A list of aliases to associate with the symbol.
  • custom_normalization (Transformer | None) A transformer that is called after every normalization. Note that the symbol name cannot be used in the transformer as this will lead to a definition of the symbol. Use a wildcard with the same attributes instead.
  • custom_print (Callable[…, str | None] | None:) A function that is called when printing the variable/function, which is provided as its first argument. This function should return a string, or None if the default print function should be used. The custom print function takes in keyword arguments that are the same as the arguments of the format function.
  • custom_derivative (Callable[[Expression, int], Expression] | None:) A function that is called when computing the derivative of a function in a given argument.
  • data (str | int | Expression | bytes | list | dict | None = None) Custom user data to associate with the symbol.

S returning Sequence[Expression]

S(
    *names: str,
    is_symmetric: bool | None = None,
    is_antisymmetric: bool | None = None,
    is_cyclesymmetric: bool | None = None,
    is_linear: bool | None = None,
    is_scalar: bool | None = None,
    is_real: bool | None = None,
    is_integer: bool | None = None,
    is_positive: bool | None = None,
    tags: Sequence[str] | None = None,
) -> Sequence[Expression]

Examples

Define two regular symbols:

x, y = S('x', 'y')

Define two symmetric functions:

f, g = S('f', 'g', is_symmetric=True)
e = f(2,1)
print(e)  # f(1,2)

Parameters

  • name (str) The name of the symbol
  • is_symmetric (bool | None) Set to true if the symbol is symmetric.
  • is_antisymmetric (bool | None) Set to true if the symbol is antisymmetric.
  • is_cyclesymmetric (bool | None) Set to true if the symbol is cyclesymmetric.
  • is_linear (bool | None) Set to true if the symbol is multilinear.
  • is_scalar (bool | None) Set to true if the symbol is a scalar. It will be moved out of linear functions.
  • is_real (bool | None) Set to true if the symbol is a real number.
  • is_integer (bool | None) Set to true if the symbol is an integer.
  • is_positive (bool | None) Set to true if the symbol is a positive number.
  • tags (Sequence[str] | None = None) A list of tags to associate with the symbol.