algebraic-range
Generate ranges of algebraic numbers.
Python port of the Wolfram Language resource function
AlgebraicRange
2.0, by the same author. Requires SymPy ≥ 1.12.
pip install algebraic-range
Overview
algebraic_range creates ranges made of
algebraic numbers:
it extends the basic concept of range() to include, besides rational
numbers, also roots — always restricted to the real domain.
The first two arguments are the bounds of the range, while the optional third and fourth arguments (by default 1 and 0) set the upper and lower bounds of the steps, the differences between successive elements:
algebraic_range(x) # Sqrt[Range[1, x²]], for x ≥ 1
algebraic_range(x, y) # Sqrt[Range[x², y²]], for 0 ≤ x ≤ y
algebraic_range(x, y, s) # steps bounded above by s, 0 < s ≤ y − x
algebraic_range(x, y, s, d) # steps bounded below by d, 0 ≤ d ≤ |s|
If no step is given, the elementary range is the square-root grid anchored
at the bounds — Sqrt[Range[x², y²]] — since among irrationals no constant
step exists. Negative bounds are handled by reflection (real roots are
defined for positive arguments), and a negative s produces a descending
range:
>>> from algebraic_range import algebraic_range
>>> algebraic_range(3)
[1, sqrt(2), sqrt(3), 2, sqrt(5), sqrt(6), sqrt(7), 2*sqrt(2), 3]
>>> algebraic_range(-3, -1)
[-3, -2*sqrt(2), -sqrt(7), -sqrt(6), -sqrt(5), -2, -sqrt(3), -sqrt(2), -1]
With a step upper bound the range is filled by rational multiples of the
elementary roots — conceptually the outer product of
algebraic_range(min(x, x/s), y) with the step-s rational grid,
restricted to [x, y]:
>>> from sympy import Rational
>>> algebraic_range(0, 2, Rational(1, 2))
[0, 1/2, sqrt(2)/2, sqrt(3)/2, 1, sqrt(2), 3/2, sqrt(3), 2]
Taken literally, that outer product scales quadratically; like the Wolfram 2.0 implementation, this port instead selects for each root only the admissible multipliers, by binary search over the sorted factor grid, and effectively scales linearly (see benchmark/BENCHMARK.md).
The fourth argument imposes a minimum absolute difference between successive elements, taming the accumulation of algebraics towards certain points and producing nearly uniform distributions:
>>> algebraic_range(2, 5, Rational(1, 3), Rational(1, 4))
[2, 4*sqrt(3)/3, 2*sqrt(15)/3, 2*sqrt(19)/3, sqrt(10), 2*sqrt(3),
5*sqrt(5)/3, 4, sqrt(19), 8*sqrt(3)/3, 2*sqrt(6)]
Options
| Option | Default | Description |
|---|---|---|
root_order |
2 |
the root orders to be included |
step_method |
"Outer" |
how the step bound is interpreted |
farey_range |
False |
steps given by the Farey sequence |
formula_complexity |
inf |
discard elements above this complexity |
algebraics_only |
True |
accept only algebraic parameters |
working_precision |
machine | precision of internal numerical decisions |
root_order
An integer r includes all roots up to order r; [r] only order r;
[r1, r2, …] all listed orders.
algebraic_range(2, root_order=3) # square and cubic roots
algebraic_range(2, root_order=[3]) # cube roots only:
# [1, 2**(1/3), 3**(1/3), 2**(2/3), 5**(1/3), 6**(1/3), 7**(1/3), 2]
algebraic_range(1, Rational(3, 2), root_order=[3, 5])
step_method
The default "Outer" uses the rational-multiplier construction above;
"Root" steps directly in the power domain,
(Range[x^n, y^n, s^n])^(1/n) — generally a superset:
>>> algebraic_range(0, 2, Rational(2, 3), step_method="Root")
[0, 2/3, 2*sqrt(2)/3, 2*sqrt(3)/3, 4/3, 2*sqrt(5)/3, 2*sqrt(6)/3,
2*sqrt(7)/3, 4*sqrt(2)/3, 2]
farey_range
Generalizes the resource function
FareyRange:
the range combines the algebraic ranges of all steps in the Farey
sequence of the given order (an integer step s means order s; a step
1/n means order n):
>>> algebraic_range(0, 3, Rational(1, 3), farey_range=True) # F₃ steps: 1/3, 1/2, 2/3, 1
equals the union of the plain ranges with steps 1/3, 1/2, 2/3 and 1,
and contains FareyRange[0, 3, 3] as its rational backbone.
formula_complexity
An alternative way to thin a range: discard elements whose symbolic form exceeds a heuristic complexity threshold.
algebraic_range(4, root_order=4, formula_complexity=8)
algebraics_only
By default, transcendental parameters are rejected (NotAlgebraicError);
disable to deliberately allow them:
from sympy import sqrt, E
algebraic_range(0, 5, sqrt(E), algebraics_only=False)
working_precision
With steps below machine resolution, nearby algebraics may collide numerically and be omitted; raising the precision keeps them distinct — it can be pushed arbitrarily high:
algebraic_range(1 - Rational(1, 10**13), 1 + Rational(1, 10**13),
Rational(1, 10**17), working_precision=30)
Behaviour notes
- Approximate inputs are exactified before use (the WL
RootApproximantstep):algebraic_range(0.1, 3.1)starts at1/10. - Results are plain lists of exact SymPy expressions, sorted ascending
(descending for negative
s), without duplicates. - Errors mirror the WL failure modes:
NotRealError,NotAlgebraicError,FareyStepError,LowerBoundError(negatived),StepBoundError(d > |s|).
Performance
The five reference cases of the Wolfram verification suite run in about 1–7 s each (40 000–80 000 elements) — up to ~1.7× faster than the Wolfram Language 2.0 implementation on the stepped cases, and ~40×–100× faster than algebraic-range 0.8. Details and methodology: benchmark/BENCHMARK.md.
Applications
A natural application is the search for closed forms of floating-point
numbers, providing structured search ranges of algebraic candidates.
The sibling package
find-closed-form
(port of the Wolfram resource function
FindClosedForm,
by the same author) accepts these ranges since version 0.5.0 through its
search_range option, searching functions of exact algebraic arguments —
here recovering a formula from its bare machine digits:
from find_closed_form import find_closed_form
find_closed_form(4.1132503787829275, search_range="Algebraic")
# exp(sqrt(2))
Generator options reach algebraic_range through search_range_options
(e.g. {"root_order": 3} to search cube-root arguments), and an explicit
algebraic_range(...) output can be passed as fixed search_arguments.
See also
- Full documentation of the original
AlgebraicRange(contributed by the same author and vetted by the Wolfram Review Team), whose 2.0 verification suite this package transcribes in tests/. - The paclet
GeneralizedRangefor extended functionality and syntax. - The
fareypackage, by the same author, for standalone Farey sequences and ranges. - CHANGELOG.md for the 0.9 rewrite notes.
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 algebraic_range-0.9.0.tar.gz.
File metadata
- Download URL: algebraic_range-0.9.0.tar.gz
- Upload date:
- Size: 25.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbfeb18154589868dcedc20c1db6d4dcd01fbcd6df4a9bcb6e897549128fb5fd
|
|
| MD5 |
7a7dec162b814d0d686030923862d905
|
|
| BLAKE2b-256 |
db39b7e63b43530e85d29c51588b29e2e144d3bb44dcabeafca10c579bf29938
|
File details
Details for the file algebraic_range-0.9.0-py3-none-any.whl.
File metadata
- Download URL: algebraic_range-0.9.0-py3-none-any.whl
- Upload date:
- Size: 16.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bdedb438a5ff6155c9a5bc4e96208ff9463de7094f00127b6a4860a6adf2188b
|
|
| MD5 |
943a5b6c2943d2cd42132747e483de4c
|
|
| BLAKE2b-256 |
b992ec432369001b1336a2df5e7b194da1eb98c1c9cca091da91f55c194cfc9b
|