Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def verify_c2_solution(f_values: np.ndarray, c2_achieved_from_opt: float, n_poin
if f_values.shape != (n_points,):
raise ValueError(f"Expected function values shape {(n_points,)}. Got {f_values.shape}.")

if not np.isfinite(f_values).all():
raise ValueError("Function values must be finite.")

if np.any(f_values < -1e-6): # Allow for small floating point errors
raise ValueError("Function must be non-negative.")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def verify_c3_solution(f_values: np.ndarray, c3_achieved: float, n_points: int):
if f_values.shape != (n_points,):
raise ValueError(f"Expected function values shape {(n_points,)}. Got {f_values.shape}.")

if not np.isfinite(f_values).all() or not np.isfinite(c3_achieved):
raise ValueError("Function values and the reported C3 must be finite.")

# Recompute C3 using NumPy to verify
dx = 0.5 / n_points

Expand Down
80 changes: 80 additions & 0 deletions tests/test_autocorr_evaluators_finite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
"""The second/third autocorrelation example evaluators must reject non-finite inputs and still score valid ones."""

import importlib.util
import os
import tempfile
import unittest

import numpy as np

BASE = os.path.join(os.path.dirname(__file__), "..", "examples", "alphaevolve_math_problems")


def _load(name):
spec = importlib.util.spec_from_file_location("ev_" + name, os.path.join(BASE, name, "evaluator.py"))
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module


def _write_program(directory, name, f_values, claimed, n_points):
path = os.path.join(directory, name + ".py")
with open(path, "w") as handle:
handle.write(
"import numpy as np\n"
"def run():\n"
f" return np.array({[float(x) for x in f_values]!r}), {float(claimed)!r}, 0.0, {int(n_points)}\n"
)
return path


def _c3(f_values):
dx = 0.5 / len(f_values)
return np.max(np.abs(np.convolve(f_values, f_values))) * dx / (np.sum(f_values) * dx) ** 2


class TestAutocorrEvaluatorsFinite(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.second = _load("second_autocorr_ineq")
cls.third = _load("third_autocorr_ineq")

def setUp(self):
self._tmp = tempfile.TemporaryDirectory()
self.addCleanup(self._tmp.cleanup)
self.dir = self._tmp.name

def test_second_rejects_nan_and_inf(self):
for i, bad in enumerate((np.nan, np.inf, -np.inf)):
f = np.ones(10)
f[3] = bad
result = self.second.evaluate(_write_program(self.dir, f"s_bad{i}", f, 0.9, 10))
self.assertIn("error", result)
self.assertEqual(result["combined_score"], 0.0)

def test_second_accepts_valid(self):
result = self.second.evaluate(_write_program(self.dir, "s_ok", np.ones(10), 0.9, 10))
self.assertNotIn("error", result)
self.assertGreater(result["combined_score"], 0.0)
self.assertTrue(np.isfinite(result["c2"]))

def test_third_rejects_nan_inf_and_nonfinite_claim(self):
for i, bad in enumerate((np.nan, np.inf, -np.inf)):
f = np.ones(10)
f[3] = bad
result = self.third.evaluate(_write_program(self.dir, f"t_bad{i}", f, 1.5, 10))
self.assertIn("error", result)
self.assertEqual(result["combined_score"], 0.0)
result = self.third.evaluate(_write_program(self.dir, "t_nanclaim", np.ones(10), np.nan, 10))
self.assertIn("error", result)
self.assertEqual(result["combined_score"], 0.0)

def test_third_accepts_valid(self):
f = np.ones(10)
result = self.third.evaluate(_write_program(self.dir, "t_ok", f, _c3(f), 10))
self.assertNotIn("error", result)
self.assertGreater(result["combined_score"], 0.0)


if __name__ == "__main__":
unittest.main()
Loading