Skip to content

[BUG]: F172017 and F292017 return NaN at 10D — elliptic_func division by zero when idx1 has 1 element #45

@Ahmedman60

Description

@Ahmedman60

Description of the bug

Environment

Item Details
Library opfunu (CEC2017 benchmark suite)
Functions affected F172017 (F17: Hybrid Function 8), F292017 (F29: Composition Function 10)
Dimension 10D
Python 3.x (Anaconda)
OS Windows 11

Summary
F172017.evaluate() returns NaN at 10D due to a division by zero inside elliptic_func when it receives a 1-element input array. F292017.evaluate() inherits the same NaN because it embeds F172017 as a sub-component (g1). Both functions are listed in dim_supported = [10, 30, 50, 100], so 10D is an officially supported dimension and this constitutes a genuine bug.

Steps To Reproduce

import numpy as np
from opfunu.cec_based.cec2017 import F172017, F292017

np.random.seed(42)
x = np.random.uniform(-100, 100, 10)

F17 at 10D

f17 = F172017(ndim=10)
print(f17.evaluate(x)) # Output: nan ← BUG

F29 at 10D

f29 = F292017(ndim=10)
print(f29.evaluate(x)) # Output: nan ← BUG (propagated from F17)

Additional Information

Diagnostic Output (Full Trace)
The following was produced by a step-by-step diagnostic script:

[3] Shuffle index partitioning (F17, ndim=10)
p=[0.1 0.2 0.2 0.2 0.3]
n1=1
[✅ OK] idx1: shape=(1,), values=[8] ← only 1 element fed to elliptic_func
[✅ OK] idx2: shape=(2,), values=[1 4]
[✅ OK] idx3: shape=(2,), values=[3 9]
[✅ OK] idx4: shape=(2,), values=[7 0]
[✅ OK] idx5: shape=(3,), values=[6 2 5]

[6] Individual operator outputs (F17)
[❌ NaN] elliptic_func(mz[idx1]) = nan ← confirmed failure point
[✅ OK] ackley_func(mz[idx2]) = 21.015
[✅ OK] rastrigin_func(mz[idx3])= 92.948
[✅ OK] hgbat_func(mz[idx4]) = 24613.789
[✅ OK] discus_func(mz[idx5]) = 2400210642.72

[5] F29 sub-function evaluate() calls
[✅ OK] g0.evaluate(x) [F14] = 18772307067.33
[❌ NaN] g1.evaluate(x) [F17] = nan ← NaN source in F29
[✅ OK] g2.evaluate(x) [F18] = 1.063e+18

Suggested Fixes (not sure of it )

def elliptic_func(x):
ndim = len(x)
if ndim == 1:
return x[0] ** 2 # degenerate 1D case: exponent scale = 10^0 = 1
idx = np.arange(ndim)
return np.sum(10 ** (6.0 * idx / (ndim - 1)) * x ** 2)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions