def METHOD_NAME(self):
    # Ensure repeatability
    np.random.seed(0)
    def cb(x, A, b):
        fvals.append(0.5*np.dot(x.ravel(), np.ravel(A @ x))
                     - np.dot(b.ravel(), x.ravel()))
    for case in self.spd_cases:
        A = case['A']
        b = case['b']
        x0 = case['x0']
        maxiter = case['maxiter']
        reduction_factor = case['reduction_factor']
        # This function should always decrease
        fvals = []
        callback = partial(cb, A=A, b=b)
        x, _ = steepest_descent(A, b, x0=x0, tol=1e-16,
                                maxiter=maxiter, callback=callback)
        norm1 = norm(np.ravel(b) - np.ravel(A.dot(x.reshape(-1, 1))))
        norm2 = norm(np.ravel(b) - np.ravel(A.dot(x0.reshape(-1, 1))))
        actual_factor = norm1 / norm2
        assert actual_factor < reduction_factor
        if A.dtype != complex:
            for i in range(len(fvals)-1):
                assert fvals[i+1] <= fvals[i]
    # Test preconditioning
    A = pyamg.gallery.poisson((10, 10), format='csr')
    b = np.random.rand(A.shape[0], 1)
    x0 = np.random.rand(A.shape[0], 1)
    fvals = []
    callback = partial(cb, A=A, b=b)
    resvec = []
    sa = pyamg.smoothed_aggregation_solver(A)
    x, _ = steepest_descent(A, b, x0, tol=1e-8, maxiter=20,
                            residuals=resvec, M=sa.aspreconditioner(),
                            callback=callback)
    assert resvec[-1]/resvec[0] < 1e-8
    for i in range(len(fvals)-1):
        assert fvals[i+1] <= fvals[i]