-
Notifications
You must be signed in to change notification settings - Fork 5
Add shekel funcfix #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
SimonBlanke
merged 8 commits into
SimonBlanke:main
from
ZohaibHassan16:add-shekel-funcfix
Feb 19, 2026
Merged
Changes from 4 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3503c22
Add shekel func
ZohaibHassan16 feb0d9a
Refactor: Move ShekelFunction from ND to new 4D module
ZohaibHassan16 17cb213
refactor: deletion of ShekelFunction from nd dir
ZohaibHassan16 02f4770
refactor: remove ShekelFunction from ND list
ZohaibHassan16 ea31f19
refactor: 4D shekel logic with explicit unpacking
ZohaibHassan16 89f5f11
test: make spec consistency test dimension-agnostic
ZohaibHassan16 a7e1274
fix: restore .gitignore
ZohaibHassan16 719b80d
test: increment algebraic function count to 29
ZohaibHassan16 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 3 additions & 0 deletions
3
src/surfaces/test_functions/algebraic/standard/test_functions_4d/__init__.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| from .shekel_function import ShekelFunction | ||
|
|
||
| __all__ = ["ShekelFunction"] |
164 changes: 164 additions & 0 deletions
164
src/surfaces/test_functions/algebraic/standard/test_functions_4d/shekel_function.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| from typing import Any, Callable, Dict, List, Optional, Union | ||
|
|
||
| import numpy as np | ||
|
|
||
| from surfaces._array_utils import ArrayLike, get_array_namespace | ||
| from surfaces.modifiers import BaseModifier | ||
|
|
||
| from ..._base_algebraic_function import AlgebraicFunction | ||
|
|
||
|
|
||
| class ShekelFunction(AlgebraicFunction): | ||
| """Shekel 4-dimensional test function. | ||
|
|
||
| A multimodal, non-convex, continuous function fixed at 4 dimensions. | ||
| It is defined as the sum of m inverse quadratic functions. | ||
|
|
||
| The function is defined as: | ||
|
|
||
| .. math:: | ||
|
|
||
| f(\\vec{x}) = - \\sum_{i=1}^{m} \\left( \\sum_{j=1}^{4} (x_j - a_{ij})^2 + c_i \\right)^{-1} | ||
|
|
||
| where :math:`m` is the number of maxima (typically 5, 7, or 10). | ||
|
|
||
| The global minimum is located at :math:`x \\approx (4, 4, 4, 4)` and | ||
| the value depends on :math:`m`. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| m : int, default=10 | ||
| Number of maxima. Standard values are 5, 7, or 10. | ||
| objective : str, default="minimize" | ||
| Either "minimize" or "maximize". | ||
| modifiers : list of BaseModifier, optional | ||
| List of modifiers to apply to function evaluations. | ||
| memory : bool, default=False | ||
| Whether to store function evaluations in memory. | ||
| collect_data : bool, default=True | ||
| Whether to collect data for visualization/history. | ||
| callbacks : list of callable, optional | ||
| Functions to call after evaluation. | ||
| catch_errors : dict, optional | ||
| Dictionary mapping error types to return values. | ||
|
|
||
| Attributes | ||
| ---------- | ||
| n_dim : int | ||
| Number of dimensions (fixed at 4). | ||
| default_bounds : tuple | ||
| Default parameter bounds (0.0, 10.0). | ||
|
|
||
| Examples | ||
| -------- | ||
| >>> from surfaces.test_functions import ShekelFunction | ||
| >>> func = ShekelFunction(m=10) | ||
| >>> result = func({"x0": 4.0, "x1": 4.0, "x2": 4.0, "x3": 4.0}) | ||
| >>> float(result) < -10.0 | ||
| True | ||
| """ | ||
|
|
||
| name = "Shekel Function" | ||
| _name_ = "shekel_function" | ||
| __name__ = "ShekelFunction" | ||
|
|
||
| _spec = { | ||
| "convex": False, | ||
| "unimodal": False, | ||
| "separable": False, | ||
| "scalable": False, | ||
| } | ||
|
|
||
| f_global = -10.536 | ||
| default_bounds = (0.0, 10.0) | ||
|
|
||
| latex_formula = ( | ||
| r"f(\vec{x}) = - \sum_{i=1}^{m} \left( \sum_{j=1}^{4} (x_j - a_{ij})^2 + c_i \right)^{-1}" | ||
| ) | ||
| pgfmath_formula = None | ||
|
|
||
| tagline = "A multimodal function with m sharp peaks (Foxholes). " "Fixed 4-dimensional problem." | ||
| display_bounds = (0.0, 10.0) | ||
|
|
||
| display_projection = {"fixed_values": {"x2": 4.0, "x3": 4.0}} | ||
|
|
||
| reference = "Shekel, J. (1971). Test function for multivariate search problems." | ||
| reference_url = "https://www.sfu.ca/~ssurjano/shekel.html" | ||
|
|
||
| def __init__( | ||
| self, | ||
| m: int = 10, | ||
| objective: str = "minimize", | ||
| modifiers: Optional[List[BaseModifier]] = None, | ||
| memory: bool = False, | ||
| collect_data: bool = True, | ||
| callbacks: Optional[Union[Callable, List[Callable]]] = None, | ||
| catch_errors: Optional[Dict[type, float]] = None, | ||
| ) -> None: | ||
| super().__init__(objective, modifiers, memory, collect_data, callbacks, catch_errors) | ||
|
|
||
| self.n_dim = 4 | ||
| self.m = m | ||
|
|
||
| self.A = np.array( | ||
| [ | ||
| [4.0, 4.0, 4.0, 4.0], | ||
| [1.0, 1.0, 1.0, 1.0], | ||
| [8.0, 8.0, 8.0, 8.0], | ||
| [6.0, 6.0, 6.0, 6.0], | ||
| [3.0, 7.0, 3.0, 7.0], | ||
| [2.0, 9.0, 2.0, 9.0], | ||
| [5.0, 5.0, 3.0, 3.0], | ||
| [8.0, 1.0, 8.0, 1.0], | ||
| [6.0, 2.0, 6.0, 2.0], | ||
| [7.0, 3.6, 7.0, 3.6], | ||
| ] | ||
| ) | ||
|
|
||
| self.c = np.array([0.1, 0.2, 0.2, 0.4, 0.4, 0.6, 0.3, 0.7, 0.5, 0.5]) | ||
|
|
||
| if m < 10: | ||
| self.A = self.A[:m] | ||
| self.c = self.c[:m] | ||
|
|
||
| self.x_global = (4.0, 4.0, 4.0, 4.0) | ||
|
|
||
| def _create_objective_function(self) -> None: | ||
| def shekel_function(params: Dict[str, Any]) -> float: | ||
| x_input = np.array([params[f"x{i}"] for i in range(self.n_dim)]) | ||
|
|
||
| result = 0.0 | ||
| for i in range(self.m): | ||
| diff = x_input - self.A[i] | ||
| sq_sum = np.dot(diff, diff) | ||
| result -= 1.0 / (sq_sum + self.c[i]) | ||
|
|
||
| return result | ||
|
|
||
| self.pure_objective_function = shekel_function | ||
|
|
||
| def _batch_objective(self, X: ArrayLike) -> ArrayLike: | ||
| """Vectorized batch evaluation for Shekel Function.""" | ||
| xp = get_array_namespace(X) | ||
|
|
||
| A = xp.asarray(self.A) | ||
| c = xp.asarray(self.c) | ||
|
|
||
| n_points = X.shape[0] | ||
| result = xp.zeros(n_points) | ||
|
|
||
| for i in range(self.m): | ||
| diff = X - A[i] | ||
| sq_sum = xp.sum(diff**2, axis=1) | ||
| result -= 1.0 / (sq_sum + c[i]) | ||
|
|
||
| return result | ||
|
|
||
| def _search_space( | ||
| self, | ||
| min: float = 0.0, | ||
| max: float = 10.0, | ||
| size: int = 10000, | ||
| value_types: str = "array", | ||
| ) -> Dict[str, Any]: | ||
| return super()._create_n_dim_search_space(min, max, size=size, value_types=value_types) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to change this and the search-space. This part still looks like an n-d test function