Skip to content

chiraag-kakar/peak-locator

Repository files navigation

Peak Locator

A robust Python toolkit for deterministic peak detection in one-dimensional, two-dimensional, and higher-dimensional numerical data.

Python Version License Code Style Type Checking Linting Testing Semantic Versioning Keep a Changelog Release to PyPI

Overview

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.

Peak Detection Visualization

Visualization showing 1D and 2D peak detection in action

Key Features

  • 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

Installation

From PyPI (when published)

pip install peak-locator

For visualization support:

pip install peak-locator[viz]

From Source / Local Development

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]"

Quick Start

Basic Usage

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})")

Finding All Peaks

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}")

Counting Peaks

arr = np.array([1, 5, 2, 6, 3, 4, 2])
detector = PeakDetector(arr)
count = detector.count_peaks()
print(f"Total peaks: {count}")

Supported Algorithms

1D Peak Detection

  • 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

2D Peak Detection

  • Divide-and-Conquer: O(n log m) time complexity for n×m matrices

Peak Counting

  • Linear Scan: O(n) time, suitable for single queries
  • Segment Tree: O(n) preprocessing, O(log n) per query, optimal for repeated range queries

Design Philosophy

Peak Locator is designed with the following principles:

  1. Simplicity: Clean, intuitive API that hides algorithmic complexity
  2. Robustness: Handles edge cases, duplicates, and invalid inputs gracefully
  3. Performance: Automatic algorithm selection optimizes for your use case
  4. Extensibility: Well-structured codebase allows easy addition of new algorithms
  5. Documentation: Comprehensive docs and examples for all features
  6. API Stability: Public APIs follow semantic versioning.

Error Handling

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

Determinism and Thread Safety

  • Algorithms are deterministic
  • No global mutable state is used
  • PeakDetector instances are safe for concurrent read-only use

Performance Characteristics

1D Peak Detection

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

2D Peak Detection

  • Time: O(n log m) for n×m matrix
  • Space: O(log m) for recursion stack

Peak Counting

  • Linear: O(n) per query
  • Segment Tree: O(n) preprocessing, O(log n) per query

API Reference

PeakDetector

Main interface for peak detection.

detector = PeakDetector(
    data,                    # array-like: Input data
    allow_duplicates=True,     # bool: Handle duplicate values
    mode="auto"              # str: Algorithm mode
)

Methods

  • find_any_peak(): Find any peak in the data
  • find_all_peaks(): Find all peaks (1D only)
  • count_peaks(use_segment_tree=False): Count peaks (1D only)
  • find_peak_2d(): Find peak in 2D data
  • find_peak_nd(): Find peak in N-dimensional data

Properties

  • data: Underlying numpy array
  • shape: Shape of the data
  • ndim: Number of dimensions

Examples

Example 1: Signal Processing

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")

Example 2: Image Analysis

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})")

Example 3: Visualization

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)

Documentation

Comprehensive documentation is available in the docs/ directory:

Testing

Run the test suite:

pytest

With coverage:

pytest --cov=peak_locator --cov-report=html

Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes with tests
  4. Ensure all tests pass and code is formatted
  5. Submit a pull request

Development Setup

git clone https://github.com/yourusername/peak-locator.git
cd peak-locator
pip install -r requirements.txt
pip install -e ".[dev]"

Code Quality

This project uses:

  • black for code formatting
  • ruff for linting
  • mypy for type checking
  • pytest for testing

CI

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

License

MIT License - see LICENSE file for details.


Changelog

All notable changes are documented in CHANGELOG.md.

This project adheres to Keep a Changelog.

About

Deterministic peak detection library for numerical data across 1D, 2D, and N-dimensional spaces.

Topics

Resources

License

Stars

Watchers

Forks

Contributors

Languages