# Path: molmod/test/common.py
# class BaseTestCase(unittest.TestCase):
#     def assertArraysEqual(self, a, b):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         assert (a==b).all(), "The array values do not match."
# 
#     def assertArrayConstant(self, arr, const):
#         assert (arr==const).all(), "Some/All array values do not match the constant."
# 
#     def assertArraysAlmostEqual(self, a, b, threshold=1e-6, mean=False, doabs=False):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         if a.shape == (0,):
#             return
#         if mean:
#             abserr = abs(a-b).mean()
#             oom = 0.5*(abs(a).mean()+abs(b).mean())
#         else:
#             abserr = abs(a-b).max()
#             oom = 0.5*(abs(a).max()+abs(b).max())
#         if doabs:
#             assert abserr <= threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, threshold)
#         else:
#             relerr = abserr/oom
#             assert relerr <= threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, threshold)
# 
#     def assertArrayAlmostConstant(self, arr, const, relerr_threshold):
#         error = abs(arr-const).max()
#         oom = const
#         relerr = error/oom
#         assert relerr <= relerr_threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, relerr_threshold)
# 
#     def assertArrayAlmostZero(self, arr, abserr_threshold):
#         abserr = abs(arr).max()
#         assert abserr <= abserr_threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, abserr_threshold)


import numpy as np
import pytest
from molmod.test.common import BaseTestCase
from molmod import *
            assert f_opt - f_dev <= grad_rms*step_rms
        # check if it is really the minimum by computing the eigen values of the
        # hessian
        hessian1 = compute_fd_hessian(fun, x_opt, 1e-4, anagrad=True)
        assert (np.linalg.eigvalsh(hessian1) > 0).all()
        # check if it is really the minimum by computing the eigen values of the
        # hessian
        hessian2 = compute_fd_hessian(fun, x_opt, 1e-4, anagrad=False)
        assert (np.linalg.eigvalsh(hessian2) > 0).all()
        # also compare the two hessians
        assert abs(hessian1 - hessian2).max() < 1e-4

    def test_sd_golden(self):
        x_init = np.zeros(2, float)
        search_direction = SteepestDescent()
        line_search = GoldenLineSearch(qtol=1e-10, qmax=1.0, max_iter=500)
        convergence = ConvergenceCondition(grad_rms=1e-6, step_rms=1e-6, grad_max=3e-6, step_max=3e-6)
        stop_loss = StopLossCondition(max_iter=50, fun_margin=1e-3, grad_margin=1e-3)
        minimizer = Minimizer(
            x_init, fun, search_direction, line_search, convergence, stop_loss,
            anagrad=False, verbose=False,
        )
        self.check_min(minimizer.get_final(), 1e-6, 1e-6)

    def test_cg_golden(self):
        x_init = np.zeros(2, float)
        search_direction = ConjugateGradient()
        line_search = GoldenLineSearch(qtol=1e-10, qmax=1.0, max_iter=500)
        convergence = ConvergenceCondition(grad_rms=1e-6, step_rms=1e-6, grad_max=3e-6, step_max=3e-6)
        stop_loss = StopLossCondition(max_iter=50, fun_margin=1e-3, grad_margin=1e-3)

# Path: molmod/test/common.py
# class BaseTestCase(unittest.TestCase):
#     def assertArraysEqual(self, a, b):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         assert (a==b).all(), "The array values do not match."
# 
#     def assertArrayConstant(self, arr, const):
#         assert (arr==const).all(), "Some/All array values do not match the constant."
# 
#     def assertArraysAlmostEqual(self, a, b, threshold=1e-6, mean=False, doabs=False):
#         self.assertEqual(a.shape, b.shape, "The array shapes do not match.")
#         if a.shape == (0,):
#             return
#         if mean:
#             abserr = abs(a-b).mean()
#             oom = 0.5*(abs(a).mean()+abs(b).mean())
#         else:
#             abserr = abs(a-b).max()
#             oom = 0.5*(abs(a).max()+abs(b).max())
#         if doabs:
#             assert abserr <= threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, threshold)
#         else:
#             relerr = abserr/oom
#             assert relerr <= threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, threshold)
# 
#     def assertArrayAlmostConstant(self, arr, const, relerr_threshold):
#         error = abs(arr-const).max()
#         oom = const
#         relerr = error/oom
#         assert relerr <= relerr_threshold, "The relative error is larger than the given threshold: %5.3e > %5.3e" % (relerr, relerr_threshold)
# 
#     def assertArrayAlmostZero(self, arr, abserr_threshold):
#         abserr = abs(arr).max()
#         assert abserr <= abserr_threshold, "The absolute error is larger than the given threshold: %5.3e > %5.3e" % (abserr, abserr_threshold)


# Path: molmod/test/test_minimizer.py
import numpy as np
import pytest
from molmod.test.common import BaseTestCase
from molmod import *

            assert f_opt - f_dev <= grad_rms*step_rms
        # check if it is really the minimum by computing the eigen values of the
        # hessian
        hessian1 = compute_fd_hessian(fun, x_opt, 1e-4, anagrad=True)
        assert (np.linalg.eigvalsh(hessian1) > 0).all()
        # check if it is really the minimum by computing the eigen values of the
        # hessian
        hessian2 = compute_fd_hessian(fun, x_opt, 1e-4, anagrad=False)
        assert (np.linalg.eigvalsh(hessian2) > 0).all()
        # also compare the two hessians
        assert abs(hessian1 - hessian2).max() < 1e-4

    def test_sd_golden(self):
        x_init = np.zeros(2, float)
        search_direction = SteepestDescent()
        line_search = GoldenLineSearch(qtol=1e-10, qmax=1.0, max_iter=500)
        convergence = ConvergenceCondition(grad_rms=1e-6, step_rms=1e-6, grad_max=3e-6, step_max=3e-6)
        stop_loss = StopLossCondition(max_iter=50, fun_margin=1e-3, grad_margin=1e-3)
        minimizer = Minimizer(
            x_init, fun, search_direction, line_search, convergence, stop_loss,
            anagrad=False, verbose=False,
        )
        self.check_min(minimizer.get_final(), 1e-6, 1e-6)

    def test_cg_golden(self):
        x_init = np.zeros(2, float)
        search_direction = ConjugateGradient()
        line_search = GoldenLineSearch(qtol=1e-10, qmax=1.0, max_iter=500)
        convergence = ConvergenceCondition(grad_rms=1e-6, step_rms=1e-6, grad_max=3e-6, step_max=3e-6)
        stop_loss = StopLossCondition(max_iter=50, fun_margin=1e-3, grad_margin=1e-3)

        minimizer = Minimizer(