Skip to main content

algebraic-range

Tests PyPI version Python License: MIT

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 RootApproximant step): algebraic_range(0.1, 3.1) starts at 1/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 (negative d), 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 GeneralizedRange for extended functionality and syntax.
  • The farey package, 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

algebraic_range-0.9.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

algebraic_range-0.9.0-py3-none-any.whl (16.9 kB view details)

Uploaded Python 3

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

Hashes for algebraic_range-0.9.0.tar.gz
Algorithm Hash digest
SHA256 dbfeb18154589868dcedc20c1db6d4dcd01fbcd6df4a9bcb6e897549128fb5fd
MD5 7a7dec162b814d0d686030923862d905
BLAKE2b-256 db39b7e63b43530e85d29c51588b29e2e144d3bb44dcabeafca10c579bf29938

See more details on using hashes here.

File details

Details for the file algebraic_range-0.9.0-py3-none-any.whl.

File metadata

File hashes

Hashes for algebraic_range-0.9.0-py3-none-any.whl
Algorithm Hash digest
SHA256 bdedb438a5ff6155c9a5bc4e96208ff9463de7094f00127b6a4860a6adf2188b
MD5 943a5b6c2943d2cd42132747e483de4c
BLAKE2b-256 b992ec432369001b1336a2df5e7b194da1eb98c1c9cca091da91f55c194cfc9b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page