Exact limit computation for Python functions. Resolve singularities algebraically.
Project description
composite-resolve
Evaluate Python functions at points where they're undefined.
The library where you pass a plain numeric Python function and get exact limits via algebraic infinitesimal arithmetic, with provenance tracking. To my knowledge, this is the first library that does this directly on plain Python functions.
Eliminates edge-case handling and numerical instability at singularities — just write the function and evaluate it everywhere.
import math
from composite_resolve import safe
@safe
def sinc(x):
return math.sin(x) / x
sinc(0.5) # → 0.9589 (normal computation)
sinc(0) # → 1.0 (singularity resolved)
Uses composite arithmetic to resolve singularities algebraically. Works with any callable that uses standard Python arithmetic and math module functions. No symbolic expressions, no approximation. Pure Python, zero dependencies.
Install
pip install composite-resolve
The @safe Decorator
Write your math as-is. The decorator handles singularities automatically:
import math
from composite_resolve import safe
@safe
def f(x):
return (x**2 - 1) / (x - 1)
f(3) # → 4.0 (normal)
f(1) # → 2.0 (resolved — no ZeroDivisionError)
@safe
def entropy(p):
return -p * math.log(p)
entropy(0.5) # → 0.347 (normal)
entropy(0) # → 0.0 (resolved — no ValueError)
Normal inputs run the original function directly with zero overhead. Only when the function fails (ZeroDivisionError, NaN, Inf) does the resolver kick in.
Direct API
For more control, use resolve, limit, and classify directly:
import math
from composite_resolve import resolve, limit, classify, taylor
# Evaluate at removable singularities
resolve(lambda x: math.sin(x) / x, at=0) # → 1.0
resolve(lambda x: (math.exp(x) - 1) / x, at=0) # → 1.0
resolve(lambda x: (x**2 - 1) / (x - 1), at=1) # → 2.0
# Indeterminate forms
limit(lambda x: x * math.log(x), to=0, dir="+") # → 0.0 (0 * inf)
limit(lambda x: x**x, to=0, dir="+") # → 1.0 (0^0)
limit(lambda x: (1 + x)**(1/x), to=0) # → e (1^inf)
limit(lambda x: 1/x - 1/math.sin(x), to=0) # → 0.0 (inf - inf)
# Limits at infinity
limit(lambda x: (1 + 1/x)**x, to=math.inf) # → e
limit(lambda x: math.sin(x) / x, to=math.inf) # → 0.0
# One-sided limits
limit(lambda x: 1/x, to=0, dir="+") # raises LimitDivergesError (+inf)
limit(lambda x: 1/x, to=0, dir="-") # raises LimitDivergesError (-inf)
limit(lambda x: 1/x, to=0) # raises LimitDoesNotExistError
# Singularity classification
classify(lambda x: math.sin(x)/x, at=0) # → Removable(value=1.0)
classify(lambda x: 1/x, at=0) # → Pole(order=1, residue=1.0)
classify(lambda x: math.exp(x), at=0) # → Regular(value=1.0)
# Taylor coefficients
taylor(lambda x: math.exp(x), at=0, order=4)
# → [1.0, 1.0, 0.5, 0.16667, 0.04167]
How It Works
The library evaluates functions using composite arithmetic. Instead of symbolic manipulation, the library substitutes a concrete algebraic infinitesimal into your function. The result carries enough structure to resolve 0/0, 0×∞, and all other indeterminate forms through ordinary arithmetic.
The function is treated as a black box. No expression tree, no symbolic manipulation.
The function is treated as a black box. No expression tree, no symbolic manipulation.
API
safe(f) -> wrapped function
Decorator. Normal inputs run f directly. Singularities are resolved automatically.
resolve(f, at, dir="both", truncation=20) -> float
Evaluate f at a point where it would normally fail. Returns math.inf or -math.inf for divergent limits.
limit(f, to, dir="both", truncation=20) -> float
Compute the limit of f(x) as x -> to. Raises LimitDivergesError for infinite limits, LimitDoesNotExistError when the limit doesn't exist.
evaluate(f, at) -> float
Strict: only returns a value if the singularity is removable. Raises SingularityError otherwise.
taylor(f, at=0, order=10) -> list[float]
Extract Taylor coefficients [f(a), f'(a)/1!, f''(a)/2!, ...].
classify(f, at=0, dir="both") -> SingularityType
Returns Regular, Removable, Pole, or Essential.
residue(f, at=0) -> float
Residue at a pole.
Examples
# Evaluate a function across its full domain, including singularities
from composite_resolve import resolve
f = lambda x: (x**2 - 1) / (x - 1)
for x in range(-5, 6):
print(f"x={x:>2d} f(x)={resolve(f, at=x):.1f}")
# x=1 gives 2.0 — no special case needed
# Cross-entropy loss at boundary
resolve(lambda p: -(0*math.log(p) + 1*math.log(1-p)), at=0, dir="+") # → 0.0
# Continuous compounding
limit(lambda n: (1 + 0.05/n)**n, to=math.inf) # → 1.05127
Math Library Support
Functions can use math, numpy, or composite_resolve.math — all work transparently:
import math
import numpy as np
from composite_resolve import safe
@safe
def f(x):
return math.sin(x) / x # works
@safe
def g(x):
return np.sin(x) / x # also works
f(0) # → 1.0
g(0) # → 1.0
math functions are patched during resolution. numpy functions dispatch via __array_ufunc__.
Limitations
- Single-variable functions only
- Functions must use
mathornumpytranscendentals (notjax,torch, etc.) - Not thread-safe during
limit()/resolve()/@safecalls - Float-precision evaluation points (e.g.,
math.pi/2is not exactly pi/2)
License
AGPL-3.0. Commercial licensing available: tmilovan@fwd.hr
Author
Toni Milovan — tmilovan@fwd.hr
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
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 composite_resolve-0.1.1.tar.gz.
File metadata
- Download URL: composite_resolve-0.1.1.tar.gz
- Upload date:
- Size: 32.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65396f0c39eb715dfba468ffee3fe0c016236d785ea9997d15082b5eca22d985
|
|
| MD5 |
bdebdd2ca51839ea152339db132c6b34
|
|
| BLAKE2b-256 |
c7d987125f644b0c71d4326f9d6c9523fd0414ff2a494186c186ce80cf731f13
|
File details
Details for the file composite_resolve-0.1.1-py3-none-any.whl.
File metadata
- Download URL: composite_resolve-0.1.1-py3-none-any.whl
- Upload date:
- Size: 42.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
63752d88493033c189c1c120b7ad039007dc4371c40f18111441d698ba76dc2e
|
|
| MD5 |
d91c6e37ac422aebee1663bcd04b61a2
|
|
| BLAKE2b-256 |
b927431a137f1e9370ef1a2619a617c9b541c2932a60c3f73ece470d5a6fa5fd
|