Skip to content

Adjustable function#17

Open
wd7512 wants to merge 19 commits intomainfrom
adjustable_function
Open

Adjustable function#17
wd7512 wants to merge 19 commits intomainfrom
adjustable_function

Conversation

@wd7512
Copy link
Copy Markdown
Contributor

@wd7512 wd7512 commented Jan 8, 2026

Allows for any function to be used in place of the rastrigin function. As long as it maps x, y -> z.

Tests added to ensure rust implementation and python implementation is the same.

Add 1, more simple function, a simple quadratic z = x**2 + y ** 2.

Modularises rust code

Modularises python code

removes unused sa rust algorithm

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @wd7512, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the flexibility of the simulated annealing framework by decoupling the optimization algorithm from specific objective functions. It achieves this by introducing a mechanism to pass any 2D function to the SA solver, alongside a modular restructuring of the rastrigin_2d function into dedicated math modules for both Python and Rust. While the PR description mentions adding a simple quadratic function, its implementation is not present in the provided changes. The PR also lays the groundwork for cross-language function equivalence testing.

Highlights

  • Function Generalization: The simulated annealing algorithms in both Python and Rust have been refactored to accept an arbitrary 2D function as an argument, replacing the previously hardcoded Rastrigin function.
  • Code Modularization: The rastrigin_2d function has been extracted into dedicated math modules for both Python (core/math.py) and Rust (src/math.rs), improving code organization and reusability.
  • Test Infrastructure: New test files (tests/helper.py, tests/test_func_equivalence.py) have been introduced to facilitate future testing of function equivalence between Python and Rust implementations. The test_func_equivalence.py is currently a placeholder.
  • Rust Serial SA Removal: The serial version of the run_sa function in Rust (src/lib.rs) has been removed, leaving only the parallel implementation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@Will-D-AER
Copy link
Copy Markdown
Contributor

@copilot finish this MR

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 8, 2026

@Will-D-AER I've opened a new pull request, #18, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to make the objective function for the simulated annealing algorithm adjustable, which is a valuable enhancement. The code has been modularized in both Python and Rust by moving the rastrigin_2d function into separate math modules, and an unused serial Rust algorithm has been removed. However, there are several critical issues that need to be addressed. The Python implementation is currently broken as the new function parameter is not correctly passed through the call stack, which will lead to runtime errors. The Rust implementation has not been updated to accept a generic function, contrary to the PR's objective. Finally, a new test file has been added but it is incomplete and contains syntax errors. I've left specific comments on the areas that need fixing.

Comment thread core/sa_algorithms/python_serial.py Outdated
Comment thread tests/test_func_equivalence.py Outdated
Copilot AI and others added 2 commits January 8, 2026 14:58
Co-authored-by: Will-D-AER <197624355+Will-D-AER@users.noreply.github.com>
Add pluggable objective functions with quadratic benchmark
@Will-D-AER
Copy link
Copy Markdown
Contributor

@copilot adjust so that we can define which function we want to use in the run_experiment.py file.

this is as simple as adding loss_function as an input to the train_tuner. Also ensure the wording of loss_function is accurately used across the whole codebase. Pick a better more appropriate name than "loss_function"

Copy link
Copy Markdown
Contributor

Copilot AI commented Jan 8, 2026

@Will-D-AER I've opened a new pull request, #19, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 7 commits January 8, 2026 15:21
Co-authored-by: Will-D-AER <197624355+Will-D-AER@users.noreply.github.com>
…sistent defaults

Co-authored-by: Will-D-AER <197624355+Will-D-AER@users.noreply.github.com>
Co-authored-by: Will-D-AER <197624355+Will-D-AER@users.noreply.github.com>
…rameter

Co-authored-by: Will-D-AER <197624355+Will-D-AER@users.noreply.github.com>
Co-authored-by: Will-D-AER <197624355+Will-D-AER@users.noreply.github.com>
Add configurable objective function parameter with full Rust support
@wd7512
Copy link
Copy Markdown
Contributor Author

wd7512 commented Jan 8, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request does a great job of making the objective function adjustable, which significantly increases the flexibility of the optimization framework. The modularization of both Python and Rust code is clean, and the addition of tests to ensure implementation equivalence is an excellent practice. My review includes a few suggestions to further improve code robustness, style, and performance.

Comment on lines +58 to +68
if function is not None:
fn_name = getattr(function, "__name__", None)
if fn_name == "rastrigin_2d":
function_name = "rastrigin"
elif fn_name == "quadratic_2d":
function_name = "quadratic"
else:
raise ValueError(
f"Rust parallel implementation only supports rastrigin_2d and quadratic_2d, "
f"but received '{fn_name}'."
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Relying on __name__ to identify functions can be brittle. For example, if the function is a lambda or has been wrapped by a decorator, its __name__ might not be what you expect. A more robust approach is to check for function identity. This would require importing the functions from core.math. The local import in the suggestion can be moved to the top of the file.

Suggested change
if function is not None:
fn_name = getattr(function, "__name__", None)
if fn_name == "rastrigin_2d":
function_name = "rastrigin"
elif fn_name == "quadratic_2d":
function_name = "quadratic"
else:
raise ValueError(
f"Rust parallel implementation only supports rastrigin_2d and quadratic_2d, "
f"but received '{fn_name}'."
)
if function is not None:
from core.math import rastrigin_2d, quadratic_2d
if function is rastrigin_2d:
function_name = "rastrigin"
elif function is quadratic_2d:
function_name = "quadratic"
else:
fn_name = getattr(function, "__name__", "<unknown>")
raise ValueError(
f"Rust parallel implementation only supports rastrigin_2d and quadratic_2d, "
f"but received '{fn_name}'."
)

Comment thread core/sa_config.py
Returns:
The objective function
"""
from core import math as math_funcs
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

According to PEP 8, imports should generally be at the top of the file. This local import can be moved to the top level as there doesn't appear to be a risk of circular dependencies. This improves readability and maintainability.

Please move from core import math as math_funcs to the top of the file and remove this line.

Comment thread src/math.rs Outdated
Comment on lines +13 to +21
try:
import sa_rust

rust_available = True
except ImportError:
print(
"Warning: sa_rust module not available. Run 'uv run maturin develop --release' first."
)
rust_available = False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For handling optional dependencies in tests, it's more idiomatic to use pytest.importorskip. This will correctly mark tests as 'skipped' in test reports if the module isn't found, which is more informative than printing a warning and having the test pass vacuously.

To implement this, you can:

  1. Add import pytest to the top of the file.
  2. Replace this try...except block with sa_rust = pytest.importorskip("sa_rust").
  3. Remove the if not rust_available: checks from both test_rastrigin_equivalence and test_quadratic_equivalence.

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants