Metadata-Version: 2.4
Name: complex-range
Version: 1.0.0
Summary: Generate ranges of complex numbers - rectangular grids and linear sequences in the complex plane
Author-email: Daniele Gregori <dangregori@gmail.com>
Maintainer-email: Daniele Gregori <dangregori@gmail.com>
License: MIT
Project-URL: Homepage, https://pypi.org/project/complex-range
Project-URL: Documentation, https://resources.wolframcloud.com/FunctionRepository/resources/ComplexRange/
Project-URL: Repository, https://github.com/Daniele-Gregori/PyPI-packages
Project-URL: Issues, https://github.com/Daniele-Gregori/PyPI-packages/issues
Project-URL: Changelog, https://github.com/Daniele-Gregori/PyPI-packages/blob/main/CHANGELOG.md
Keywords: complex,numbers,range,grid,mathematics,farey,sequence,complex-plane
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Mathematics
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: black>=23.0; extra == "dev"
Requires-Dist: isort>=5.0; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Requires-Dist: flake8>=6.0; extra == "dev"
Provides-Extra: docs
Requires-Dist: sphinx>=6.0; extra == "docs"
Requires-Dist: sphinx-rtd-theme>=1.0; extra == "docs"
Dynamic: license-file

# complex-range

[![PyPI version](https://badge.fury.io/py/complex-range.svg)](https://badge.fury.io/py/complex-range)
[![Python versions](https://img.shields.io/pypi/pyversions/complex-range.svg)](https://pypi.org/project/complex-range/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)


Generate ranges of complex numbers in Python - rectangular grids and linear sequences in the complex plane.


## Installation

```bash
pip install complex-range
```

## Quick Start

```python
from complex_range import complex_range

# Rectangular grid from origin to 2+2j
grid = complex_range(0, 2+2j)
# [0j, 1j, 2j, (1+0j), (1+1j), (1+2j), (2+0j), (2+1j), (2+2j)]

# Linear range along a diagonal
line = complex_range([0, 3+3j])
# [0j, (1+1j), (2+2j), (3+3j)]
```

## Features

- **Rectangular ranges**: Generate 2D grids of complex numbers
- **Linear ranges**: Generate points along a line in the complex plane
- **Flexible step sizes**: Control spacing independently for real and imaginary axes
- **Negative steps**: Support for descending ranges with negative step values
- **Farey sequence subdivision**: Create refined grids using number-theoretic sequences
- **Iteration order control**: Choose whether to iterate real or imaginary component first
- **Pure Python**: No dependencies required

## Usage

### Rectangular Ranges

Generate a grid of complex numbers between two corners:

```python
from complex_range import complex_range

# Basic rectangular range
complex_range(0, 2+2j)
# Returns: [0j, 1j, 2j, (1+0j), (1+1j), (1+2j), (2+0j), (2+1j), (2+2j)]

# Single argument: range from 0 to z
complex_range(2+3j)
# Returns grid from 0 to 2+3j (3×4 = 12 points)

# With custom step size (complex number)
complex_range(0, 2+2j, 0.5+0.5j)
# Real step = 0.5, Imaginary step = 0.5

# With separate real and imaginary steps
complex_range(0, 4+6j, [2, 3])
# Real step = 2, Imaginary step = 3
```

### Linear Ranges

Generate points along a line (diagonal) in the complex plane:

```python
# Linear from 0 to endpoint
complex_range([3+3j])
# Returns: [0j, (1+1j), (2+2j), (3+3j)]

# Linear between two points
complex_range([-1-1j, 2+2j])
# Returns: [(-1-1j), 0j, (1+1j), (2+2j)]

# Linear with custom step
complex_range([0, 4+4j], [2, 2])
# Returns: [0j, (2+2j), (4+4j)]

# Linear with complex step
complex_range([0, 4+4j], 2+2j)
# Returns: [0j, (2+2j), (4+4j)]

# Descending linear range with negative step
complex_range([2+2j, 0], -1-1j)
# Returns: [(2+2j), (1+1j), 0j]
```

### Options

#### `increment_first`

Control the iteration order for rectangular ranges:

```python
# Default: increment imaginary first
complex_range(0, 2+2j, 1+1j, increment_first='im')
# [0j, 1j, 2j, (1+0j), (1+1j), (1+2j), (2+0j), (2+1j), (2+2j)]

# Increment real first
complex_range(0, 2+2j, 1+1j, increment_first='re')
# [0j, (1+0j), (2+0j), 1j, (1+1j), (2+1j), 2j, (1+2j), (2+2j)]
```

#### `farey_range`

Use Farey sequence to create a finer subdivision of the grid:

```python
# Regular grid
regular = complex_range(0, 4+4j, 2+2j)
# Returns 9 points

# Farey subdivision (step must be integer)
farey = complex_range(0, 4+4j, 2+2j, farey_range=True)
# Returns 81 points using Farey sequence F_2

# Farey sequence of order n creates fractions 0, 1/n, ..., 1
from complex_range import farey_sequence
farey_sequence(3)
# [Fraction(0,1), Fraction(1,3), Fraction(1,2), Fraction(2,3), Fraction(1,1)]
```

## API Reference

### `complex_range(z1, z2=None, step=None, *, increment_first='im', farey_range=False)`

Generate a range of complex numbers.

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `z1` | `complex`, `list`, or `tuple` | First corner (rectangular) or endpoint specification (linear) |
| `z2` | `complex`, optional | Second corner for rectangular range |
| `step` | `complex`, `list`, or `tuple`, optional | Step size(s). Default: `1+1j` |
| `increment_first` | `'im'` or `'re'` | Which component to iterate first. Default: `'im'` |
| `farey_range` | `bool` | Use Farey sequence subdivision. Default: `False` |

**Returns:** `List[complex]` - List of complex numbers

**Raises:** `ComplexRangeError` - If `farey_range=True` with non-integer step

### `farey_sequence(n)`

Generate the Farey sequence of order n.

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `n` | `int` | Order of the Farey sequence (must be positive) |

**Returns:** `List[Fraction]` - Sorted list of fractions in [0, 1]

## Understanding the Ranges

### Rectangular Range

A rectangular range generates all points on a 2D grid:

```
Im ↑
 3 │  ·  ·  ·
 2 │  ·  ·  ·
 1 │  ·  ·  ·
 0 │  ·  ·  ·
   └──────────→ Re
      0  1  2
```

With `increment_first='im'` (default), points are generated column by column:
`(0,0), (0,1), (0,2), (0,3), (1,0), (1,1), ...`

### Linear Range

A linear range generates points along a diagonal:

```
Im ↑
 3 │        ·
 2 │     ·
 1 │  ·
 0 │·
   └──────────→ Re
   0  1  2  3
```

Points increment along both axes simultaneously.

## Examples

### Visualizing a Rectangular Grid

```python
import matplotlib.pyplot as plt
from complex_range import complex_range

points = complex_range(0, 3+3j)
x = [p.real for p in points]
y = [p.imag for p in points]

plt.scatter(x, y)
plt.xlabel('Real')
plt.ylabel('Imaginary')
plt.title('Rectangular Complex Range')
plt.grid(True)
plt.show()
```

### Creating a Refined Grid with Farey Sequence

```python
from complex_range import complex_range

# Coarse grid: 3×3 = 9 points
coarse = complex_range(0, 2+2j, 1+1j)

# Refined grid using Farey sequence
refined = complex_range(0, 2+2j, 2+2j, farey_range=True)
print(f"Coarse: {len(coarse)} points, Refined: {len(refined)} points")
```

### Iterating Over Complex Regions

```python
from complex_range import complex_range

# Evaluate a function over a region of the complex plane
def mandelbrot_escape(c, max_iter=100):
    z = 0
    for i in range(max_iter):
        z = z*z + c
        if abs(z) > 2:
            return i
    return max_iter

# Create a grid and evaluate
grid = complex_range(-2-1.5j, 1+1.5j, [0.1, 0.1])
escapes = [mandelbrot_escape(c) for c in grid]
```

## Author

**Daniele Gregori**

- Original [Wolfram Language ComplexRange](https://resources.wolframcloud.com/FunctionRepository/resources/ComplexRange/) function
- Python implementation

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

```bash
# Clone the repository
git clone https://github.com/Daniele-Gregori/PyPI-packages.git
cd PyPI-packages/packages/complex-range

# Install development dependencies
pip install -e ".[dev]"

# Run tests
pytest

# Run type checking
mypy src/complex_range

# Format code
black src tests
isort src tests
```

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## Acknowledgments

Original [Wolfram Language ComplexRange](https://resources.wolframcloud.com/FunctionRepository/resources/ComplexRange/) resource function contributed by Daniele Gregori and reviewed by the Wolfram Review Team.

## Changelog

See [CHANGELOG.md](CHANGELOG.md) for a list of changes.
