A hands-on tour of Symbolica 2.0: exact symbolic manipulation, pattern matching, programmable symbols, polynomial arithmetic, and fast numerical evaluation from Python. Run the cells from top to bottom, then substitute one of your own expressions to see how the pieces fit together.
Setup
Install Symbolica and import the Python API. The temporary namespace keeps this notebook friendly to re-runs when we define custom symbols later.
error: externally-managed-environment× This environment is externally managed
╰─> To install Python packages system-wide, try 'pacman -S
python-xyz', where xyz is the package you are trying to
install.
If you wish to install a non-Arch-packaged Python package,
create a virtual environment using 'python -m venv path/to/venv'.
Then use path/to/venv/bin/python and path/to/venv/bin/pip.
If you wish to install a non-Arch packaged Python application,
it may be easiest to use 'pipx install xyz', which will manage a
virtual environment for you. Make sure you have python-pipx
installed via pacman.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
Note: you may need to restart the kernel to use updated packages.
Symbolica symbolica-f52eea6
Trying Symbolica
This notebook is meant to be both a tutorial and a small playground. Each section introduces one idea, shows a compact example, and leaves room for you to change the expression or the operation.
1. Build Expressions
Symbols are the atoms of Symbolica. A symbol can be used as a variable, and calling it turns it into a function.
Symbolica keeps exact rational structure by default. You can expand, collect, format, and inspect expressions without leaving Python. In Jupyter, Symbolica expressions use rich HTML output by default; you can also switch the rendered output to LaTeX from Jupyter’s output display controls, or force LaTeX for a specific display call.
expanded = expr.expand()print("Expanded:")display(expanded)poly_part = E("(x + y)^4 + (x - y)^4").expand()print("\nA polynomial identity:")display(poly_part)print("\nCoefficients as a polynomial in x:")for power, coefficient in poly_part.coefficient_list(x):print(f"{power}: {coefficient}")print("\nNumber of terms:", len(expanded))
Expanded:
1123456+10·x·y+f(x,y)+6·x²+5·y²
A polynomial identity:
12·x²·y²+2·x⁴+2·y⁴
Coefficients as a polynomial in x:
1: 2*y^4
x^2: 12*y^2
x^4: 2
Number of terms: 5
Pretty printing is useful once expressions stop fitting on one line. The rich formatted output wraps long expressions, uses superscripts, and colors brackets and built-in functions in notebooks.
For papers, slides, and documentation, display the same expression as LaTeX. In Jupyter you can also toggle the output renderer to LaTeX from the output’s display options.
Symbolica can reorganize expressions without changing their value. collect groups terms around a chosen symbol, while collect_by_coefficient groups terms that share the same numerical coefficient.
x, y, z = S("x", "y", "z")to_collect = E("2*x + 2*x^2 + x^3 + 3*y + 3*x*y")print("Expression:")display(to_collect)print("\nCollected in x:")display(to_collect.collect(x))print("\nCollected by numerical coefficient:")display(to_collect.collect_by_coefficient())print("\nCoefficient list as a polynomial in x:")for power, coefficient in to_collect.coefficient_list(x):print(f"{power}: {coefficient}")
Expression:
2·x+3·x·y+3·y+2·x²+x³
Collected in x:
x·(2+3·y)+3·y+2·x²+x³
Collected by numerical coefficient:
2·(x+x²)+3·(x·y+y)+x³
Coefficient list as a polynomial in x:
1: 3*y
x: 2+3*y
x^2: 2
x^3: 1
Factoring works directly on expressions. For polynomial-heavy workflows, you can also convert to a polynomial and use the polynomial-specific routines shown later.
Symbolica 2.0 lets users attach hooks to symbols. This toy gamma-like function has a derivative rule and a series rule that regularizes a pole at zero.
set_namespace("playground_hooks_"+ uuid4().hex[:8])x = S("x")def regularize_toy_gamma(args):if args[0].get_coefficient(0) ==0: a = args[0].to_expression()return (1/ a, S("toy_gamma")(a +1))toy_gamma = S("toy_gamma", derivative=lambda f, _index: f * E("digamma")(f[0]), series=regularize_toy_gamma,)display(toy_gamma(x).derivative(x))toy_gamma(x).series(x, 0, 0)
toy_gamma(x)·digamma(x)
toy_gamma(1)·x^-1+toy_gamma(1)·digamma(1)+𝒪(x^1)
Evaluation hooks teach a custom symbol how to become a number. The same symbolic expression can remain exact until you ask for a floating-point approximation.
Float conversion: 1.12762596520638+x
Direct evaluation at x = 3: (4.127625965206381+0j)
7. From Formula To Numerical Kernel
One of Symbolica’s strengths is moving between exact formulas and fast numerical evaluation. You can derive expressions symbolically, then evaluate them many times in optimization, fitting, simulation, or integration loops.
x, y = S("x", "y")objective = E("(sin(x*y) + gamma(x + 1)/(1 + y^2))^2 + (x - y)^2")gradient = [objective.derivative(v) for v in (x, y)]print("Objective:")display(objective)print("\nExact gradient:")for variable, derivative inzip((x, y), gradient):print(f"d/d{variable} = {derivative}")
Optimized evaluators are better when the same expression is evaluated many times. The evaluator builds a compact instruction program and, in Python, will use a JIT-compiled backend by default.
---------------------------------------------------------------------------ImportError Traceback (most recent call last)
File /usr/lib/python3.14/site-packages/numpy/_core/__init__.py:24 23try:
---> 24from.import multiarray
25exceptImportErroras exc:
File /usr/lib/python3.14/site-packages/numpy/_core/multiarray.py:11 9importfunctools---> 11from.import _multiarray_umath, overrides
12from._multiarray_umathimport * # noqa: F403ImportError: /usr/lib/libgomp.so.1: cannot allocate memory in static TLS block
The above exception was the direct cause of the following exception:
ImportError Traceback (most recent call last)
CellIn[30], line 1----> 1import numpy as np
2 3 ev = objective.evaluator([x, y])
4File /usr/lib/python3.14/site-packages/numpy/__init__.py:112 109from.import _distributor_init
111try:
--> 112fromnumpy.__config__import show_config
113exceptImportErroras e:
114ifisinstance(e, ModuleNotFoundError) and e.name == "numpy.__config__":
115# The __config__ module itself was not found, so add this info:File /usr/lib/python3.14/site-packages/numpy/__config__.py:4 1# This file is generated by numpy's build process 2# It contains system_info results at the time of building this package. 3fromenumimport Enum
----> 4fromnumpy._core._multiarray_umathimport (
5 __cpu_features__,
6 __cpu_baseline__,
7 __cpu_dispatch__,
8 )
10 __all__ = ["show_config"]
11 _built_with_meson = TrueFile /usr/lib/python3.14/site-packages/numpy/_core/__init__.py:85 58 major, minor, *_ = sys.version_info
59 msg = f""" 60 61IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE! (...) 82Original error was: {exc} 83"""---> 85raiseImportError(msg) fromexc 86finally:
87for envkey in env_added:
ImportError:
IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!
Importing the numpy C-extensions failed. This error can happen for
many reasons, often due to issues with your setup or how NumPy was
installed.
We have compiled some common reasons and troubleshooting tips at:
https://numpy.org/devdocs/user/troubleshooting-importerror.html
Please note and check the following:
* The Python version is: Python 3.14 from "/bin/python"
* The NumPy version is: "2.4.6"
and make sure that they are the versions you expect.
Please carefully study the information and documentation linked above.
This is unlikely to be a NumPy issue but will be caused by a bad install
or environment on your machine.
Original error was: /usr/lib/libgomp.so.1: cannot allocate memory in static TLS block
For higher precision, pass Decimal inputs and the number of decimal digits you want.
x = S("x")value, _ = ev.evaluate_with_prec([1.2, 0.7], 50)print(value)
thread '<unnamed>' (20650) panicked at /root/.cargo/git/checkouts/symbolica-db3dbb7e8d40efb5/f52eea6/src/evaluate/evaluator.rs:292:21:
External function 'symbolica_gamma' does not have an implementation for numerica::domains::float::multiprecision::Float
---------------------------------------------------------------------------PanicException Traceback (most recent call last)
CellIn[35], line 2 1 x = S("x")
----> 2 value, _ = ev.evaluate_with_prec([1.2, 0.7], 50)
3 4 print(value)
PanicException: External function 'symbolica_gamma' does not have an implementation for numerica::domains::float::multiprecision::Float
8. Polynomials
Symbolica has fast exact polynomial arithmetic. Convert an expression to a polynomial when you want polynomial-specific operations such as factorization, GCDs, Groebner bases, or exact parameter elimination.
You can solve symbolic linear systems with parameters just as naturally as numeric ones.
x, y, c = S("x", "y", "c")Expression.solve_linear_system( [x + y - c, 2*x - y -3], [x, y],)
[1/3·(3+c), 1/3·(-3+2·c)]
9. Stream Terms
When expressions get large, many operations can be applied term by term. A TermStreamer lets Symbolica process those terms without keeping the full intermediate expression in memory.
To keep exploring, replace one expression in this notebook with something from your own work. Try a symbolic preprocessing step, a factorization, a pattern rewrite, or a numerical evaluator, then compare the result with your current approach.
For commercial use, production use, unrestricted cores, or organizational support, see https://symbolica.io/license/.