Skip to content

Commit 8048ddc

Browse files
add algebraic-range draft
1 parent 8c0bec5 commit 8048ddc

9 files changed

Lines changed: 1312 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: algebraic-range
2+
3+
on:
4+
push:
5+
paths:
6+
- ".github/workflows/algebraic-range.yml"
7+
pull_request:
8+
paths:
9+
- ".github/workflows/algebraic-range.yml"
10+
workflow_dispatch:
11+
12+
defaults:
13+
run:
14+
working-directory: packages/algebraic-range
15+
16+
jobs:
17+
test:
18+
runs-on: ${{ matrix.os }}
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
os: [ubuntu-latest, macos-latest, windows-latest]
23+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
24+
25+
steps:
26+
- uses: actions/checkout@v4
27+
28+
- name: Set up Python ${{ matrix.python-version }}
29+
uses: actions/setup-python@v5
30+
with:
31+
python-version: ${{ matrix.python-version }}
32+
33+
- name: Install dependencies
34+
run: |
35+
python -m pip install --upgrade pip
36+
pip install -e ".[dev]"
37+
38+
- name: Run tests
39+
run: pytest -v

packages/algebraic-range/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Daniele Gregori
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

packages/algebraic-range/README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# algebraic-range
2+
3+
4+
[![Tests](https://github.com/Daniele-Gregori/PyPI-packages/actions/workflows/algebraic-range.yml/badge.svg)](https://github.com/Daniele-Gregori/PyPI-packages/actions/workflows/algebraic-range.yml)
5+
[![PyPI version](https://img.shields.io/pypi/v/algebraic-range.svg)](https://pypi.org/project/algebraic-range/)
6+
[![Python](https://img.shields.io/pypi/pyversions/algebraic-range.svg)](https://pypi.org/project/algebraic-range/)
7+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8+
9+
Generate ranges of algebraic numbers.
10+
11+
Python port of the **Wolfram** [resource function "AlgebraicRange"](https://resources.wolframcloud.com/FunctionRepository/resources/AlgebraicRange/) resource function.
12+
13+
Requires [SymPy](https://www.sympy.org/) ≥ 1.12.
14+
15+
## Overview
16+
17+
`algebraic_range` creates ranges made of [algebraic numbers](https://en.wikipedia.org/wiki/Algebraic_number). This extends the basic concept of `range()` to include, besides rational numbers, also roots — always restricted to the real domain.
18+
19+
The first two arguments represent the bounds of the range (minimum and maximum values), while the optional third and fourth arguments (by default equal to 1 and 0) regulate the upper and lower bounds of the steps (differences between successive elements).
20+
21+
22+
23+
## Usage
24+
25+
```python
26+
algebraic_range(x) # Sqrt[Range[1, x²]] for x ≥ 1
27+
algebraic_range(x, y) # Sqrt[Range[x², y²]] for 0 ≤ x ≤ y
28+
algebraic_range(x, y, s) # step upper bound s, 0 < s ≤ y
29+
algebraic_range(x, y, s, d) # step lower bound d, 0 ≤ d ≤ s
30+
```
31+
32+
### Parameters
33+
34+
| Parameter | Default | Description |
35+
|-----------|---------|-------------|
36+
| `r1` | *(required)* | Start of range (or single argument) |
37+
| `r2` | `None` | End of range |
38+
| `s` | `None` | Step upper bound (negative → descending) |
39+
| `d` | `0` | Step lower bound |
40+
| `root_order` | `2` | `int r` → orders 2..r; `[r]` → only order r; `[r1,r2,…]` → listed orders |
41+
| `step_method` | `"Outer"` | `"Outer"` or `"Root"` |
42+
| `farey_range` | `False` | Use Farey-sequence–based rational multipliers |
43+
| `formula_complexity_threshold` | `inf` | Discard elements above this complexity |
44+
| `algebraics_only` | `True` | Reject transcendental inputs |
45+
46+
### Options
47+
48+
#### `root_order`
49+
50+
```python
51+
# Include square and cubic roots
52+
algebraic_range(2, root_order=3)
53+
54+
# Only cubic roots
55+
algebraic_range(2, root_order=[3])
56+
57+
# Cubic and fifth roots
58+
algebraic_range(1, Rational(3, 2), root_order=[3, 5])
59+
```
60+
61+
#### `step_method`
62+
63+
```python
64+
# "Root" method: Sqrt[Range[x², y², s²]]
65+
algebraic_range(0, 3, Rational(1, 3), step_method="Root")
66+
```
67+
68+
The default `"Outer"` method uses the outer product construction. The `"Root"` method is generally a superset.
69+
70+
#### `farey_range`
71+
72+
```python
73+
algebraic_range(0, 3, Rational(1, 3), farey_range=True)
74+
```
75+
76+
Generalises `FareyRange` by combining algebraic ranges over all Farey-sequence steps.
77+
78+
#### `formula_complexity_threshold`
79+
80+
```python
81+
# Only keep simple expressions
82+
algebraic_range(4, root_order=4, formula_complexity_threshold=8)
83+
```
84+
85+
#### `algebraics_only`
86+
87+
```python
88+
from sympy import sqrt, E
89+
90+
# This raises NotAlgebraicError:
91+
# algebraic_range(0, 5, sqrt(E))
92+
93+
# Allow transcendental step:
94+
algebraic_range(0, 5, sqrt(E), algebraics_only=False)
95+
```
96+
97+
## Properties
98+
99+
- **Extends `range()`**: `set(range(x, y+1))``set(algebraic_range(x, y))`
100+
- **Negative reflection**: `algebraic_range(-y, -x)` = `list(reversed([-v for v in algebraic_range(x, y)]))`
101+
- **All outputs are algebraic** (when `algebraics_only=True`) and real
102+
- **Sorted** in ascending order (or descending for negative step)
103+
- **No duplicates**
104+
105+
106+
## See also
107+
108+
More details and examples can be found in the documentation for the original Wolfram Language resource function [`AlgebraicRange`](https://resources.wolframcloud.com/FunctionRepository/resources/AlgebraicRange/), contributed by the same author and vetted by the Wolfram Review Team.
109+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
[build-system]
2+
requires = ["setuptools>=68.0", "wheel"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "algebraic-range"
7+
version = "0.8.0"
8+
description = "Generate ranges of algebraic numbers — a Python port of the Wolfram Language AlgebraicRange resource function."
9+
readme = "README.md"
10+
license = "MIT"
11+
requires-python = ">=3.9"
12+
authors = [
13+
{ name = "Daniele Gregori", email = "dangregori@gmail.com" },
14+
]
15+
maintainers = [
16+
{ name = "Daniele Gregori", email = "dangregori@gmail.com" },
17+
]
18+
keywords = [
19+
"algebra",
20+
"algebraic-numbers",
21+
"range",
22+
"roots",
23+
"symbolic-computation",
24+
"number-theory",
25+
]
26+
classifiers = [
27+
"Development Status :: 4 - Beta",
28+
"Intended Audience :: Science/Research",
29+
"Intended Audience :: Education",
30+
"Operating System :: OS Independent",
31+
"Programming Language :: Python :: 3",
32+
"Programming Language :: Python :: 3.9",
33+
"Programming Language :: Python :: 3.10",
34+
"Programming Language :: Python :: 3.11",
35+
"Programming Language :: Python :: 3.12",
36+
"Programming Language :: Python :: 3.13",
37+
"Topic :: Scientific/Engineering :: Mathematics",
38+
]
39+
dependencies = [
40+
"sympy>=1.12",
41+
]
42+
43+
[project.optional-dependencies]
44+
dev = [
45+
"pytest>=7.0",
46+
]
47+
48+
[project.urls]
49+
Homepage = "https://github.com/Daniele-Gregori/PyPI-packages/tree/main/packages/algebraic-range"
50+
Documentation = "https://resources.wolframcloud.com/FunctionRepository/resources/AlgebraicRange/"
51+
Repository = "https://github.com/Daniele-Gregori/PyPI-packages/tree/main/packages/algebraic-range"
52+
Issues = "https://github.com/Daniele-Gregori/PyPI-packages/issues"
53+
54+
[tool.setuptools.packages.find]
55+
where = ["src"]
56+
57+
[tool.pytest.ini_options]
58+
testpaths = ["tests"]
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""
2+
algebraic-range — Generate ranges of algebraic numbers.
3+
4+
A Python port of the Wolfram Language ResourceFunction ``AlgebraicRange``.
5+
"""
6+
7+
from algebraic_range.core import (
8+
algebraic_range,
9+
formula_complexity,
10+
AlgebraicRangeError,
11+
NotRealError,
12+
NotAlgebraicError,
13+
StepBoundError,
14+
__version__,
15+
)
16+
17+
__all__ = [
18+
"algebraic_range",
19+
"formula_complexity",
20+
"AlgebraicRangeError",
21+
"NotRealError",
22+
"NotAlgebraicError",
23+
"StepBoundError",
24+
]

0 commit comments

Comments
 (0)