Fast symbolic differentiation library - Rust-powered Python bindings
Project description
SymbAnaFis: Fast Symbolic Differentiation for Python & Rust
A high-performance symbolic mathematics library written in Rust with Python bindings. SymbAnaFis provides fast symbolic differentiation and simplification.
Installation
Python (Recommended)
pip install symb-anafis
Rust
Add this to your Cargo.toml:
[dependencies]
symb_anafis = "0.2.5"
Quick Start
Python
import symb_anafis
# Differentiation
result = symb_anafis.diff("x^3 + 2*x^2 + x", "x")
print(result) # Output: 3 * x^2 + 4 * x + 1
# Simplification
result = symb_anafis.simplify("sin(x)^2 + cos(x)^2")
print(result) # Output: 1
# With constants
result = symb_anafis.diff("a * x^2", "x", fixed_vars=["a"])
print(result) # Output: 2 * a * x
Rust
use symb_anafis::{diff, simplify};
fn main() {
// Differentiate sin(x) * x with respect to x
let derivative = diff(
"sin(x) * x".to_string(),
"x".to_string(),
None, // No fixed variables
None // No custom functions
).unwrap();
println!("Derivative: {}", derivative);
// Output: cos(x) * x + sin(x)
// Simplify an expression
let simplified = simplify(
"x^2 + 2*x + 1".to_string(),
None, // No fixed variables
None // No custom functions
).unwrap();
println!("Simplified: {}", simplified);
// Output: (x + 1)^2
}
Features
✅ Fast Differentiation
- Supports all standard calculus rules (product, chain, quotient, power)
- Handles trigonometric, exponential, and logarithmic functions
- Support for custom functions and implicit differentiation
✅ Powerful Simplification
- Automatic constant folding
- Trigonometric identities (Pythagorean, double angle, etc.)
- Algebraic simplification (factoring, expanding)
- Fraction cancellation and rationalization
✅ Flexible API
- Fixed variables (constants that aren't differentiated)
- Custom function definitions
- Domain-safety mode to avoid incorrect simplifications (set
SYMB_ANAFIS_DOMAIN_SAFETY=true)
✅ Cross-Language Support
- Native Rust performance with zero-cost abstractions
- Python bindings via PyO3
- Consistent API across languages
Configuration
You can configure safety limits using environment variables:
SYMB_ANAFIS_MAX_DEPTH: Maximum AST depth (default: 100)SYMB_ANAFIS_MAX_NODES: Maximum AST node count (default: 10000)SYMB_ANAFIS_DOMAIN_SAFETY: Enable domain-safe mode (default: false)
export SYMB_ANAFIS_MAX_DEPTH=200
export SYMB_ANAFIS_MAX_NODES=50000
export SYMB_ANAFIS_DOMAIN_SAFETY=true
Domain-Safe Mode
Domain-safe mode prevents mathematically incorrect simplifications by skipping rules that could alter the domain of expressions. For example:
- Without domain safety:
sqrt(x^2)→x(incorrect when x < 0) - With domain safety:
sqrt(x^2)→abs(x)(correct for all real x)
Enable domain-safe mode when you need guaranteed mathematical correctness:
Python
export SYMB_ANAFIS_DOMAIN_SAFETY=true
python -c "import symb_anafis; print(symb_anafis.simplify('sqrt(x^2)'))"
# Output: abs(x)
Rust
use symb_anafis::simplify;
// Set domain safety via environment variable before compilation
// Or use the internal API (not recommended for external use)
fn main() {
let result = simplify(
"sqrt(x^2)".to_string(),
Some(&["x".to_string()]),
None
).unwrap();
println!("Result: {}", result); // With SYMB_ANAFIS_DOMAIN_SAFETY=true: abs(x)
}
Examples
Physics: RC Circuit
Python
# Voltage in RC circuit: V(t) = V₀ * exp(-t/(R*C))
voltage = "V0 * exp(-t / (R * C))"
current = symb_anafis.diff(
voltage,
"t",
fixed_vars=["V0", "R", "C"]
)
print(current) # Current: dV/dt
Rust
use symb_anafis::diff;
fn main() {
let voltage = "V0 * exp(-t / (R * C))".to_string();
let current = diff(
voltage,
"t".to_string(),
Some(&["V0".to_string(), "R".to_string(), "C".to_string()]),
None
).unwrap();
println!("Current: {}", current);
}
Statistics: Normal Distribution
Python
# Normal PDF: f(x) = exp(-(x-μ)²/(2σ²)) / √(2πσ²)
pdf = "exp(-(x - mu)^2 / (2 * sigma^2)) / sqrt(2 * pi * sigma^2)"
derivative = symb_anafis.diff(
pdf,
"x",
fixed_vars=["mu", "sigma"]
)
print(derivative) # Derivative with respect to x
Rust
use symb_anafis::diff;
fn main() {
let pdf = "exp(-(x - mu)^2 / (2 * sigma^2)) / sqrt(2 * pi * sigma^2)".to_string();
let derivative = diff(
pdf,
"x".to_string(),
Some(&["mu".to_string(), "sigma".to_string()]),
None
).unwrap();
println!("Derivative: {}", derivative);
}
Calculus: Chain Rule
Python
# Chain rule: d/dx[sin(cos(tan(x)))]
result = symb_anafis.diff("sin(cos(tan(x)))", "x")
print(result)
Rust
use symb_anafis::diff;
fn main() {
let result = diff(
"sin(cos(tan(x)))".to_string(),
"x".to_string(),
None,
None
).unwrap();
println!("Result: {}", result);
}
API Reference
Python API
diff(formula, var, fixed_vars=None, custom_functions=None) -> str
Differentiate a mathematical expression.
Parameters:
formula(str): Mathematical expression (e.g.,"x^2 + sin(x)")var(str): Variable to differentiate with respect tofixed_vars(list, optional): Variables that are constantscustom_functions(list, optional): User-defined function names
Returns: Simplified derivative as a string
Raises: ValueError if parsing/differentiation fails
Note: Set environment variable SYMB_ANAFIS_DOMAIN_SAFETY=true for domain-safe simplification.
simplify(formula, fixed_vars=None, custom_functions=None) -> str
Simplify a mathematical expression.
Parameters:
formula(str): Expression to simplifyfixed_vars(list, optional): Variables that are constantscustom_functions(list, optional): User-defined function names
Returns: Simplified expression as a string
Note: Set environment variable SYMB_ANAFIS_DOMAIN_SAFETY=true for domain-safe simplification.
parse(formula, fixed_vars=None, custom_functions=None) -> str
Parse and normalize an expression.
Parameters:
formula(str): Expression to parsefixed_vars(list, optional): Variables that are constantscustom_functions(list, optional): User-defined function names
Returns: Normalized expression string
Rust API
diff(formula: String, var: String, fixed_vars: Option<&[String]>, custom_functions: Option<&[String]>) -> Result<String, DiffError>
Differentiate a mathematical expression.
simplify(formula: String, fixed_vars: Option<&[String]>, custom_functions: Option<&[String]>) -> Result<String, DiffError>
Simplify a mathematical expression. Set environment variable SYMB_ANAFIS_DOMAIN_SAFETY=true for domain-safe mode.
parse(formula: String, fixed_vars: Option<&[String]>, custom_functions: Option<&[String]>) -> Result<Expr, DiffError>
Parse and normalize an expression into an AST.
Advanced Usage
Expression Simplification
You can simplify expressions without differentiation:
Python
result = symb_anafis.simplify("sin(x)^2 + cos(x)^2")
print(result) # Output: 1
Rust
use symb_anafis::simplify;
fn main() {
let result = simplify(
"sin(x)^2 + cos(x)^2".to_string(),
None,
None
).unwrap();
println!("Simplified: {}", result); // Output: 1
}
Multi-Character Symbols
For symbols with multiple characters (like "sigma", "alpha", etc.), pass them as fixed variables to ensure they're treated as single symbols:
Python
# This treats "sigma" as one symbol
result = symb_anafis.simplify("(sigma^2)^2", fixed_vars=["sigma"])
print(result) # Output: sigma^4
Rust
use symb_anafis::simplify;
fn main() {
let result = simplify(
"(sigma^2)^2".to_string(),
Some(&["sigma".to_string()]),
None
).unwrap();
println!("Simplified: {}", result); // Output: sigma^4
}
Fixed Variables and Custom Functions
You can define constants (like a, b) and custom functions (like f(x)) that are treated correctly during differentiation.
Python
result = symb_anafis.diff("a * f(x)", "x", fixed_vars=["a"], custom_functions=["f"])
print(result) # Output: a * ∂_f(x)/∂_x
Rust
use symb_anafis::diff;
fn main() {
let result = diff(
"a * f(x)".to_string(),
"x".to_string(),
Some(&["a".to_string()]),
Some(&["f".to_string()])
).unwrap();
println!("Derivative: {}", result); // Output: a * ∂_f(x)/∂_x
}
Domain-Safe Simplification
Domain-safe mode prevents mathematically incorrect simplifications:
Python
export SYMB_ANAFIS_DOMAIN_SAFETY=true
python -c "import symb_anafis; print(symb_anafis.simplify('sqrt(x^2)'))"
# Output: abs(x) (correct for all real x)
Rust
use symb_anafis::simplify;
fn main() {
// Domain safety is controlled by SYMB_ANAFIS_DOMAIN_SAFETY environment variable
let result = simplify(
"sqrt(x^2)".to_string(),
Some(&["x".to_string()]),
None
).unwrap();
println!("Result: {}", result); // abs(x) when domain safety is enabled
}
Supported Functions
- Trigonometric:
sin,cos,tan,cot,sec,csc,asin,acos,atan,acot,asec,acsc - Hyperbolic:
sinh,cosh,tanh,coth,sech,csch,asinh,acosh,atanh,acoth,asech,acsch - Exponential/Logarithmic:
exp,ln,log,log10,log2 - Roots:
sqrt,cbrt - Absolute Value/Sign:
abs,sign - Special:
sinc,erf,erfc,gamma,digamma,trigamma,tetragamma,polygamma,beta,LambertW,besselj,bessely,besseli,besselk
Note: The polygamma(n, x) function provides derivatives for all polygamma functions. Functions with non-elementary derivatives use custom notation.
Expression Syntax
- Variables:
x,y,sigma, etc. - Numbers:
1,3.14,1e-5,2.5e3 - Operations:
+,-,*,/,^(power) - Functions:
sin(),cos(),exp(),ln(),sqrt() - Constants:
pi,e(automatically recognized) - Implicit multiplication:
2x=2*x,(x+1)(x-1)=(x+1)*(x-1)
Comparison with SymPy
| Feature | SymbAnaFis | SymPy |
|---|---|---|
| Speed (diff+simplify) | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Differentiation | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Simplification | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ |
| Python Integration | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| Symbolic solving | ⭐ | ⭐⭐⭐⭐⭐ |
| Maturity | Newer | Established |
When to use SymbAnaFis:
- You need fast differentiation + simplification
- Performance is critical
- You're working with real-world physics/engineering expressions
When to use SymPy:
- You need symbolic equation solving
- You need broader symbolic capabilities
- You prefer pure Python implementation
Building from Source
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Clone repository
git clone https://github.com/CokieMiner/symb_anafis.git
cd symb_anafis
# Build Python bindings
pip install maturin
maturin develop --release
# Build Rust library
cargo build --release
# Run tests
cargo test --release
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Citation
If you use SymbAnaFis in academic work, please cite:
@software{symb_anafis,
author = {CokieMiner},
title = {SymbAnaFis: Fast Symbolic Differentiation Library},
url = {https://github.com/CokieMiner/symb_anafis},
year = {2025}
}
Resources
- GitHub: https://github.com/CokieMiner/symb_anafis
- Crates.io: https://crates.io/crates/symb_anafis
- PyPI: https://pypi.org/project/symb-anafis/
- Documentation: https://docs.rs/symb_anafis
Built with ❤️ in Rust for Python 🚀
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file symb_anafis-0.2.5.tar.gz.
File metadata
- Download URL: symb_anafis-0.2.5.tar.gz
- Upload date:
- Size: 129.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48b6459c865cc63dcdac7681da2b538e7ae856c03e84d3a045df9dc4f126c419
|
|
| MD5 |
015e78d1d97019845f9aa320857c1d27
|
|
| BLAKE2b-256 |
095f1fdd376253ce740cda2d860410a337dd6836a83a1a69ed56091947383927
|
File details
Details for the file symb_anafis-0.2.5-cp314-cp314-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: symb_anafis-0.2.5-cp314-cp314-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 517.1 kB
- Tags: CPython 3.14, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5b825ca795de701de2ad85958e2eb5ff84d278f7b70354e0f3db57d94a18fc85
|
|
| MD5 |
8f40cec03413b23b34cd693b59069043
|
|
| BLAKE2b-256 |
0a58d102f6d89437cd0d1b362621a223416deb092118af8465e5a98d3697003a
|
File details
Details for the file symb_anafis-0.2.5-cp314-cp314-macosx_11_0_arm64.whl.
File metadata
- Download URL: symb_anafis-0.2.5-cp314-cp314-macosx_11_0_arm64.whl
- Upload date:
- Size: 507.4 kB
- Tags: CPython 3.14, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f1eda07c3962d032d6917e89ad2527f5b0921e5786b14e9f69007db9a86d5a32
|
|
| MD5 |
dbdfce70e13007f8244a326f9b3722d9
|
|
| BLAKE2b-256 |
aba40332e709f9904c63276eb1357de9e96001ded1da1bfb7056ed3497fd8523
|
File details
Details for the file symb_anafis-0.2.5-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: symb_anafis-0.2.5-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 582.3 kB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a5cde5e5cad5a0632762a9e0d48bf3b0b95353e3ff2a45b4233feeeee989223
|
|
| MD5 |
e04204ec815f1b95bc0179223b5593d2
|
|
| BLAKE2b-256 |
b962b9b5412e0bb2e2b6ffca372e9ef1dfaca51b30ef87ac68cea362093a8c5d
|
File details
Details for the file symb_anafis-0.2.5-cp39-cp39-win_amd64.whl.
File metadata
- Download URL: symb_anafis-0.2.5-cp39-cp39-win_amd64.whl
- Upload date:
- Size: 437.7 kB
- Tags: CPython 3.9, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.10.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8b1faaf8320022ed45668a17973a484a9e2e7d1a8272b7f18f2f732a083c36e2
|
|
| MD5 |
a07fd13fdfdf99e5ee07a0712633a074
|
|
| BLAKE2b-256 |
1a0873ecb8dcbe243f5d97fba18ca96a2683fe29523a6876842fc44c7f6fff7d
|