A robust Python toolkit for deterministic peak detection in one-dimensional, two-dimensional, and higher-dimensional numerical data.
Peak Locator provides a collection of peak detection algorithms for numerical data represented as arrays or matrices. It supports multiple algorithmic approaches for one-dimensional and two-dimensional inputs, with a unified interface for higher-dimensional data. The library offers automatic algorithm selection based on input characteristics, while allowing explicit configuration when a specific method or performance profile is required.
- 1D Peak Detection: Multiple algorithms (brute force, binary search, hybrid)
- 2D Peak Detection: Divide-and-conquer approach for matrices
- N-Dimensional Support: Conceptual implementation for higher dimensions
- Peak Counting: Linear and segment tree-based approaches
- Automatic Algorithm Selection: Chooses optimal algorithm based on data properties
- Duplicate Handling: Robust handling of arrays with duplicate values
- Visualization Tools: Built-in plotting utilities for 1D and 2D data
- Production Ready: Full type annotations, comprehensive tests, and documentation
pip install peak-locatorFor visualization support:
pip install peak-locator[viz]git clone https://github.com/yourusername/peak-locator.git
cd peak-locator
# Install dependencies
pip install -r requirements.txt
# Install in editable mode with development tools
pip install -e ".[dev]"from peak_locator import PeakDetector
import numpy as np
# 1D peak detection
arr = np.array([1, 3, 2, 5, 4])
detector = PeakDetector(arr)
peak_idx = detector.find_any_peak()
print(f"Peak found at index: {peak_idx}")
# 2D peak detection
matrix = np.array([[1, 2, 3], [4, 9, 5], [6, 7, 8]])
detector = PeakDetector(matrix)
row, col = detector.find_peak_2d()
print(f"Peak found at ({row}, {col})")arr = np.array([1, 5, 2, 6, 3])
detector = PeakDetector(arr)
all_peaks = detector.find_all_peaks()
print(f"Found {len(all_peaks)} peaks at indices: {all_peaks}")arr = np.array([1, 5, 2, 6, 3, 4, 2])
detector = PeakDetector(arr)
count = detector.count_peaks()
print(f"Total peaks: {count}")- Brute Force (
mode="brute"): Linear scan, O(n) time complexity - Binary Search (
mode="binary"): O(log n) time complexity, best for arrays without duplicates - Hybrid (
mode="hybrid"): Compresses duplicates then uses binary search, handles duplicates robustly - Auto (
mode="auto"): Automatically selects the best algorithm based on data properties
- Divide-and-Conquer: O(n log m) time complexity for n×m matrices
- Linear Scan: O(n) time, suitable for single queries
- Segment Tree: O(n) preprocessing, O(log n) per query, optimal for repeated range queries
Peak Locator is designed with the following principles:
- Simplicity: Clean, intuitive API that hides algorithmic complexity
- Robustness: Handles edge cases, duplicates, and invalid inputs gracefully
- Performance: Automatic algorithm selection optimizes for your use case
- Extensibility: Well-structured codebase allows easy addition of new algorithms
- Documentation: Comprehensive docs and examples for all features
- API Stability: Public APIs follow semantic versioning.
Peak Locator performs strict input validation and raises explicit exceptions for:
- Unsupported data types or shapes
- Invalid dimensionality for a selected algorithm
- Ambiguous peak definitions when strict criteria are required
- Algorithms are deterministic
- No global mutable state is used
PeakDetectorinstances are safe for concurrent read-only use
| Algorithm | Time Complexity | Space Complexity | Best For |
|---|---|---|---|
| Brute Force | O(n) | O(1) | Small arrays, simple cases |
| Binary Search | O(log n) | O(1) | Large arrays without duplicates |
| Hybrid | O(n) worst, O(log n) best | O(n) worst, O(1) best | Arrays with duplicates |
- Time: O(n log m) for n×m matrix
- Space: O(log m) for recursion stack
- Linear: O(n) per query
- Segment Tree: O(n) preprocessing, O(log n) per query
Main interface for peak detection.
detector = PeakDetector(
data, # array-like: Input data
allow_duplicates=True, # bool: Handle duplicate values
mode="auto" # str: Algorithm mode
)find_any_peak(): Find any peak in the datafind_all_peaks(): Find all peaks (1D only)count_peaks(use_segment_tree=False): Count peaks (1D only)find_peak_2d(): Find peak in 2D datafind_peak_nd(): Find peak in N-dimensional data
data: Underlying numpy arrayshape: Shape of the datandim: Number of dimensions
import numpy as np
from peak_locator import PeakDetector
# Simulate a signal with noise
signal = np.sin(np.linspace(0, 4*np.pi, 100)) + np.random.normal(0, 0.1, 100)
detector = PeakDetector(signal)
peaks = detector.find_all_peaks()
print(f"Found {len(peaks)} peaks in signal")import numpy as np
from peak_locator import PeakDetector
# Find peak intensity in an image
image = np.random.rand(100, 100) * 255
detector = PeakDetector(image)
row, col = detector.find_peak_2d()
print(f"Peak intensity at pixel ({row}, {col})")import numpy as np
from peak_locator import PeakDetector
from peak_locator.visualization import plot_1d_peaks
arr = np.array([1, 5, 2, 6, 3, 4, 2])
detector = PeakDetector(arr)
peaks = detector.find_all_peaks()
plot_1d_peaks(arr, peaks=peaks, show_all=True)Comprehensive documentation is available in the docs/ directory:
- Quick Start Guide - Get started in 5 minutes
- 1D Peak Detection Examples - Detailed 1D examples
- 2D Peak Detection Examples - Matrix peak detection
- Peak Counting - Counting peaks efficiently
- Segment Tree Usage - Advanced range queries
- N-Dimensional Concepts - Higher-dimensional peak detection
Run the test suite:
pytestWith coverage:
pytest --cov=peak_locator --cov-report=htmlContributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Ensure all tests pass and code is formatted
- Submit a pull request
git clone https://github.com/yourusername/peak-locator.git
cd peak-locator
pip install -r requirements.txt
pip install -e ".[dev]"This project uses:
blackfor code formattingrufffor lintingmypyfor type checkingpytestfor testing
The project uses automated GitHub Actions workflows for:
- CI: Runs tests, linting, and type checking on every push/PR
- Releases: Automatically publishes to PyPI when a GitHub release is created
MIT License - see LICENSE file for details.
All notable changes are documented in CHANGELOG.md.
This project adheres to Keep a Changelog.
