Skip to content

Commit 5ed34ab

Browse files
tests updated
1 parent 7f28289 commit 5ed34ab

File tree

1 file changed

+11
-81
lines changed

1 file changed

+11
-81
lines changed

tests/integration/test_classification.py

Lines changed: 11 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,18 @@ def test_classify_using_hessian(self, simulator, dataset):
113113
"Z",
114114
):
115115
assert k in info
116-
assert "hessian_fd" in info and info["hessian_fd"].shape == (2, 2)
117-
assert "eigenvalues" in info and info["eigenvalues"].shape == (2,)
118-
assert "eigenvectors" in info and info["eigenvectors"].shape == (2, 2)
116+
assert info["hessian_fd"].shape == (2, 2)
117+
assert info["eigenvalues"].shape == (2,)
118+
assert info["eigenvectors"].shape == (2, 2)
119119
assert info["x"].shape == (2,)
120-
assert "Z" in info and info["Z"].ndim == 2
120+
assert info["dx"].shape == (2,)
121+
assert len(info["names"]) == 2
122+
assert isinstance(info["best_cost"], float)
123+
assert isinstance(info["span0"], tuple)
124+
assert len(info["span0"]) == 2
125+
assert isinstance(info["span1"], tuple)
126+
assert len(info["span1"]) == 2
127+
assert info["Z"].ndim == 2
121128
assert info["Z"].shape[0] == info["Z"].shape[1] # grid is square
122129

123130
# Hessian may be NaN on some model combinations
@@ -256,80 +263,3 @@ def test_insensitive_classify_using_hessian(self, model, parameter_values):
256263
"Classification cannot proceed due to infinite cost value(s)."
257264
" The result is near the upper bound of R0_a [Ohm]."
258265
)
259-
260-
def test_quadratic_hessian_full_coverage(self):
261-
"""
262-
Construct a tiny deterministic quadratic problem so classify_using_hessian
263-
executes the full finite-difference Hessian calculation, eigen decomposition,
264-
the grid evaluation loop (no exceptions), and the final packing/return.
265-
"""
266-
267-
# Minimal test parameters object used by classify_using_hessian
268-
class TestParameters:
269-
def __init__(self):
270-
self.names = ["p0", "p1"]
271-
272-
def get_bounds(self):
273-
return {"lower": np.array([-10.0, -10.0]), "upper": np.array([10.0, 10.0])}
274-
275-
class TestProblem:
276-
def __init__(self, A, b, c=0.0):
277-
self.parameters = TestParameters()
278-
self.A = np.asarray(A, dtype=float)
279-
self.b = np.asarray(b, dtype=float)
280-
self.c = float(c)
281-
282-
def evaluate(self, x):
283-
x = np.asarray(x, dtype=float)
284-
val = 0.5 * float(x.T @ self.A @ x) + float(self.b.dot(x)) + self.c
285-
return type("R", (), {"values": val})
286-
287-
class TestOptim:
288-
def __init__(self, problem):
289-
self.problem = problem
290-
291-
class TestResult:
292-
pass
293-
294-
A = np.array([[4.0, 0.5], [0.5, 2.0]])
295-
b = np.array([0.1, -0.2])
296-
problem = TestProblem(A, b)
297-
298-
x = np.array([1.23, -0.45], dtype=float)
299-
best_cost = problem.evaluate(x).values
300-
301-
optim = TestOptim(problem=problem)
302-
303-
result = TestResult()
304-
result.x = x
305-
result.best_cost = best_cost
306-
result.optim = optim
307-
result.minimising = True
308-
309-
dx = np.array([1e-3, 1e-3], dtype=float)
310-
311-
message, info = pybop.classify_using_hessian(result, dx=dx, cost_tolerance=1e-8)
312-
313-
assert isinstance(info, dict)
314-
H = info["hessian_fd"]
315-
assert H.shape == (2, 2)
316-
assert np.isfinite(H).all()
317-
assert np.allclose(H, H.T, atol=1e-8)
318-
319-
evals = info["eigenvalues"]
320-
evecs = info["eigenvectors"]
321-
assert evals.shape == (2,)
322-
assert evecs.shape == (2, 2)
323-
assert np.isfinite(evals).all()
324-
assert np.isfinite(evecs).all()
325-
326-
assert "minimum" in message.lower()
327-
328-
assert "param0" in info and "param1" in info and "Z" in info
329-
param0 = info["param0"]
330-
param1 = info["param1"]
331-
Z = info["Z"]
332-
assert Z.shape == (41, 41)
333-
assert np.isfinite(Z).all()
334-
assert param0.min() < x[0] < param0.max()
335-
assert param1.min() < x[1] < param1.max()

0 commit comments

Comments
 (0)