Contributing
Thank you for your interest in contributing to Gradient-Free-Optimizers! This guide will help you get started with development and submit your contributions.
See also
Also see CONTRIBUTING.md in the repository for additional guidelines.
How to Contribute
Contribution Workflow
Fork the repository on GitHub
Clone your fork locally
Create a branch for your changes
Make your changes with tests
Run the test suite to ensure everything works
Submit a pull request for review
Types of Contributions
We welcome many types of contributions:
- Bug Fixes
Fix issues and improve stability. Search existing issues for bugs to work on.
- New Features
Add new optimizers, features, or functionality. Discuss major features in an issue or discussion first.
- Documentation
Improve guides, examples, API docs, or fix typos. Documentation is as important as code!
- Tests
Increase test coverage or add test cases. Good tests prevent regressions.
- Performance
Optimize code for speed or memory. Include benchmarks showing improvements.
- Examples
Add examples from your field of work that incorporate GFO.
Development Setup
Prerequisites
Python 3.10 or higher
Git
pip
Setting Up Your Environment
Fork the repository on GitHub
Clone your fork locally:
git clone https://github.com/YOUR-USERNAME/Gradient-Free-Optimizers.git cd Gradient-Free-Optimizers
Add the upstream repository:
git remote add upstream https://github.com/SimonBlanke/Gradient-Free-Optimizers.git
Create a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
Install in development mode with dependencies:
pip install -e ".[test,docs,progress,sklearn]"
Verify the installation:
python -c "import gradient_free_optimizers as gfo; print(gfo.__version__)" pytest tests/ -v
Making Changes
Create a Branch
Create a branch for your work:
git checkout -b fix/issue-123-memory-leak
# or
git checkout -b feature/add-new-optimizer
Use descriptive branch names:
fix/issue-123-descriptionfor bug fixesfeature/descriptionfor new featuresdocs/descriptionfor documentationrefactor/descriptionfor code refactoring
Write Code
Follow these guidelines:
Keep changes focused: One PR should address one issue/feature
Follow existing code style: Match the surrounding code
Add docstrings: Use NumPy-style docstrings for new functions/classes
Add type hints: Use Python type annotations when possible
Handle edge cases: Consider boundary conditions and errors
Example of good code structure:
def new_function(param1: np.ndarray, param2: int) -> float:
"""Brief description of what this function does.
More detailed explanation if needed.
Parameters
----------
param1 : np.ndarray
Description of param1.
param2 : int
Description of param2.
Returns
-------
float
Description of return value.
Examples
--------
>>> result = new_function(np.array([1, 2, 3]), 5)
>>> print(result)
10.5
"""
# Implementation here
return result
Add Tests
All new code should have tests:
# tests/test_new_feature.py
import numpy as np
from gradient_free_optimizers import NewOptimizer
def test_new_optimizer_basic():
"""Test basic functionality of NewOptimizer."""
search_space = {"x": np.linspace(-5, 5, 20)}
def objective(params):
return -params["x"]**2
opt = NewOptimizer(search_space)
opt.search(objective, n_iter=10)
assert opt.best_score < 0
assert "x" in opt.best_para
def test_new_optimizer_with_constraints():
"""Test NewOptimizer respects constraints."""
# Test implementation
Run Tests
Run tests locally before submitting:
# Run all tests
pytest
# Run with coverage
pytest --cov=gradient_free_optimizers --cov-report=html
# Run specific test file
pytest tests/test_new_feature.py
# Run tests matching a pattern
pytest -k "test_new_optimizer"
# Run with verbose output
pytest -v
Update Documentation
If you’re adding a new feature:
Add docstrings to all public functions/classes
Add examples in the docstrings
Update relevant docs in
docs/source/Add to API reference if it’s a new optimizer
Build docs locally to verify:
cd docs
pip install -r requirements.txt
make html
# Open docs/build/html/index.html in a browser
Submitting Changes
Commit Your Changes
Write clear commit messages:
git add .
git commit -m "[Fix] Resolve memory leak in search data collection
- Clear search_data DataFrame periodically
- Add test for long-running optimizations
- Closes #123"
Commit message guidelines:
Use tags:
[Fix],[Feature],[Refactor],[Docs],[Test]First line: Brief summary (< 72 characters)
Blank line, then detailed explanation if needed
Reference issues with
Closes #123orFixes #123
Push Your Branch
git push origin fix/issue-123-memory-leak
Create a Pull Request
Go to your fork on GitHub
Click “Compare & pull request”
Fill in the PR template:
Title: Use tag prefix (
[Fix],[Feature], etc.)Description: Explain what and why, not just what
Link issues: Reference related issues
Testing: Describe how you tested the changes
Example PR description:
## Description
Fixes memory leak in search data collection for long-running optimizations.
## Changes
- Add periodic clearing of search_data DataFrame
- Implement configurable memory threshold
- Add tests for long-running scenarios
## Motivation
Users reported memory errors after 10,000+ iterations.
## Testing
- Added `test_long_running_optimization` that verifies memory stays bounded
- Ran 50,000 iteration test with memory profiling
- All existing tests pass
Closes #123
PR Review Process
Automated checks run (tests, linting)
Maintainer reviews code and provides feedback
You address any requested changes
Maintainer approves and merges
Tips for faster reviews:
Keep PRs focused and reasonably sized
Respond promptly to feedback
Be open to suggestions
Update your branch if requested
Code Style
Formatting
GFO follows PEP 8 with some flexibility. Key points:
4 spaces for indentation (not tabs)
Maximum line length: 88 characters (Black default)
Use descriptive variable names
Add blank lines to separate logical sections
Naming Conventions
Classes:
PascalCase(e.g.,HillClimbingOptimizer)Functions/methods:
snake_case(e.g.,search)Constants:
UPPER_SNAKE_CASE(e.g.,DEFAULT_N_ITER)Private members:
_leading_underscore(e.g.,_internal_method)
Imports
Organize imports in this order:
# Standard library
import os
import sys
from typing import Dict, List
# Third-party
import numpy as np
import pandas as pd
# Local
from gradient_free_optimizers.base import BaseOptimizer
from gradient_free_optimizers.utils import validate_search_space
Testing Guidelines
What to Test
Happy path: Normal usage scenarios
Edge cases: Boundary conditions, empty inputs
Error cases: Invalid inputs should raise appropriate errors
Integration: Features work together correctly
Test Structure
def test_feature_name():
"""Test description of what is being tested."""
# Arrange: Set up test data
search_space = {"x": np.array([1, 2, 3])}
# Act: Execute the code being tested
opt = Optimizer(search_space)
result = opt.some_method()
# Assert: Verify the results
assert result == expected_value
Running Specific Tests
# Single test
pytest tests/test_file.py::test_specific_function
# Test class
pytest tests/test_file.py::TestClassName
# With debugging output
pytest tests/test_file.py -v -s
Adding a New Optimizer
If you’re contributing a new optimizer:
Inherit from base class:
from gradient_free_optimizers.optimizers.base_optimizer import BaseOptimizer class MyOptimizer(BaseOptimizer): def __init__(self, search_space, **kwargs): super().__init__(search_space, **kwargs) # Your initialization
Implement required methods:
_init_position()- Initialize starting position_iterate()- Single optimization step
Add to exports:
In
src/gradient_free_optimizers/__init__.py:from .optimizers.my_optimizer import MyOptimizer __all__ = [ # ... existing optimizers "MyOptimizer", ]
Write tests in
tests/test_my_optimizer.pyAdd documentation in
docs/source/user_guide/optimizers/category/my_optimizer.rst
Getting Help
If you need help with your contribution:
Ask in the PR: Comment on your pull request
Open a discussion: Use GitHub Discussions for questions
Join the community: See Getting Help
Email maintainer: simon.blanke@yahoo.com for private matters
Code of Conduct
All contributors must follow our Code of Conduct. Be respectful, welcoming, and constructive in all interactions.
License
By contributing, you agree that your contributions will be licensed under the MIT License, the same as the rest of the project.
Thank You!
Thank you for contributing to Gradient-Free-Optimizers! Your efforts help make optimization more accessible to everyone.