<commit_before>""" Unit tests for nonlinear solvers
Author: <NAME>
May 2007
"""
from __future__ import division, print_function, absolute_import

from numpy.testing import assert_, dec, TestCase, run_module_suite

from scipy.lib.six import xrange
from scipy.optimize import nonlin, root
from numpy import matrix, diag, dot
from numpy.linalg import inv
import numpy as np

from test_minpack import pressure_network

SOLVERS = {'anderson': nonlin.anderson, 'diagbroyden': nonlin.diagbroyden,
           'linearmixing': nonlin.linearmixing, 'excitingmixing': nonlin.excitingmixing,
           'broyden1': nonlin.broyden1, 'broyden2': nonlin.broyden2,
           'krylov': nonlin.newton_krylov}
MUST_WORK = {'anderson': nonlin.anderson, 'broyden1': nonlin.broyden1,
             'broyden2': nonlin.broyden2, 'krylov': nonlin.newton_krylov}

#-------------------------------------------------------------------------------
# Test problems
#-------------------------------------------------------------------------------


def F(x):
    x = np.asmatrix(x).T
    d = matrix(diag([3,2,1.5,1,0.5]))
    c = 0.01
    f = -d*x - c*float(x.T*x)*x
    return f
F.xin = [1,1,1,1,1]
F.KNOWN_BAD = {}


def F2(x):
    return x
F2.xin = [1,2,3,4,5,6]
F2.KNOWN_BAD = {'linearmixing': nonlin.linearmixing,
                'excitingmixing': nonlin.excitingmixing}


def F2_lucky(x):
    return x
F2_lucky.xin = [0,0,0,0,0,0]
F2_lucky.KNOWN_BAD = {}


def F3(x):
    A = np.mat('-2 1 0; 1 -2 1; 0 1 -2')
    b = np.mat('1 2 3')
    return np.dot(A, x) - b
F3.xin = [1,2,3]
F3.KNOWN_BAD = {}


def F4_powell(x):
    A = 1e4
    return [A*x[0]*x[1] - 1, np.exp(-x[0]) + np.exp(-x[1]) - (1 + 1/A)]
F4_powell.xin = [-1, -2]
F4_powell.KNOWN_BAD = {'linearmixing': nonlin.linearmixing,
                       'excitingmixing': nonlin.excitingmixing,
                       'diagbroyden': nonlin.diagbroyden}


def F5(x):
    return pressure_network(x, 4, np.array([.5, .5, .5, .5]))
F5.xin = [2., 0, 2, 0]
F5.KNOWN_BAD = {'excitingmixing': nonlin.excitingmixing,
                'linearmixing': nonlin.linearmixing,
                'diagbroyden': nonlin.diagbroyden}


def F6(x):
    x1, x2 = x
    J0 = np.array([[-4.256, 14.7],
                [0.8394989, 0.59964207]])
    v = np.array([(x1 + 3) * (x2**5 - 7) + 3*6,
                  np.sin(x2 * np.exp(x1) - 1)])
    return -np.linalg.solve(J0, v)
F6.xin = [-0.5, 1.4]
F6.KNOWN_BAD = {'excitingmixing': nonlin.excitingmixing,
                'linearmixing': nonlin.linearmixing,
                'diagbroyden': nonlin.diagbroyden}


#-------------------------------------------------------------------------------
# Tests
#-------------------------------------------------------------------------------


class TestNonlin(object):
    """
    Check the Broyden methods for a few test problems.

    broyden1, broyden2, and newton_krylov must succeed for
    all functions. Some of the others don't -- tests in KNOWN_BAD are skipped.

    """

    def _check_nonlin_func(self, f, func, f_tol=1e-2):
        x = func(f, f.xin, f_tol=f_tol, maxiter=200, verbose=0)
        assert_(np.absolute(f(x)).max() < f_tol)

    def _check_root(self, f, method, f_tol=1e-2):
        res = root(f, f.xin, method=method,
                   options={'ftol': f_tol, 'maxiter': 200, 'disp': 0})
        assert_(np.absolute(res.fun).max() < f_tol)

    @dec.knownfailureif(True)
    def _check_func_fail(self, *a, **kw):
        pass

    def test_problem_nonlin(self):
        """ Tests for nonlin functions """
        for f in [F, F2, F2_lucky, F3, F4_powell, F5, F6]:
            for func in SOLVERS.values():
                if func in f.KNOWN_BAD.values():
                    if func in MUST_WORK.values():
                        yield self._check_func_fail, f, func
                    continue
                yield self._check_nonlin_func, f, func

    def test_tol_norm_called(self):
        """ Check that supplying tol_norm keyword to nonlin_solve works"""
        self._tol_norm_used = False
        
        def local_norm_func(x):
            self._tol_norm_used = True
            return np.absolute(x).max()

        for f in [F, F2, F2_lucky, F3, F4_powell, F5, F6]:
            for func in SOLVERS.values():
                self._tol_norm_used = False
                if func in f.KNOWN_BAD.values():
                    if func in MUST_WORK.values():
                        continue
                    continue
                func(f, f.xin, f_tol=1e-2, maxiter=200, verbose=0,
                     tol_norm=local_norm_func)
                assert self._tol_norm_used == True

    def test_problem_root(self):
        """ Tests for root """
        for f in [F, F2, F2_lucky, F3, F4_powell, F5, F6]:
            for meth in SOLVERS:
                if meth in f.KNOWN_BAD:
                    if meth in MUST_WORK:
                        yield self._check_func_fail, f, meth
                    continue
                yield self._check_root, f, meth


class TestSecant(TestCase):
    """Check that some Jacobian approximations satisfy the secant condition"""

    xs = [np.array([1,2,3,4,5], float),
          np.array([2,3,4,5,1], float),<commit_msg>MAINT: only checking one solver in test_tol_norm_called<commit_after>""" Unit tests for nonlinear solvers
Author: <NAME>
May 2007
"""
from __future__ import division, print_function, absolute_import

from numpy.testing import assert_, dec, TestCase, run_module_suite

from scipy.lib.six import xrange
from scipy.optimize import nonlin, root
from numpy import matrix, diag, dot
from numpy.linalg import inv
import numpy as np

from test_minpack import pressure_network

SOLVERS = {'anderson': nonlin.anderson, 'diagbroyden': nonlin.diagbroyden,
           'linearmixing': nonlin.linearmixing, 'excitingmixing': nonlin.excitingmixing,
           'broyden1': nonlin.broyden1, 'broyden2': nonlin.broyden2,
           'krylov': nonlin.newton_krylov}
MUST_WORK = {'anderson': nonlin.anderson, 'broyden1': nonlin.broyden1,
             'broyden2': nonlin.broyden2, 'krylov': nonlin.newton_krylov}

#-------------------------------------------------------------------------------
# Test problems
#-------------------------------------------------------------------------------


def F(x):
    x = np.asmatrix(x).T
    d = matrix(diag([3,2,1.5,1,0.5]))
    c = 0.01
    f = -d*x - c*float(x.T*x)*x
    return f
F.xin = [1,1,1,1,1]
F.KNOWN_BAD = {}


def F2(x):
    return x
F2.xin = [1,2,3,4,5,6]
F2.KNOWN_BAD = {'linearmixing': nonlin.linearmixing,
                'excitingmixing': nonlin.excitingmixing}


def F2_lucky(x):
    return x
F2_lucky.xin = [0,0,0,0,0,0]
F2_lucky.KNOWN_BAD = {}


def F3(x):
    A = np.mat('-2 1 0; 1 -2 1; 0 1 -2')
    b = np.mat('1 2 3')
    return np.dot(A, x) - b
F3.xin = [1,2,3]
F3.KNOWN_BAD = {}


def F4_powell(x):
    A = 1e4
    return [A*x[0]*x[1] - 1, np.exp(-x[0]) + np.exp(-x[1]) - (1 + 1/A)]
F4_powell.xin = [-1, -2]
F4_powell.KNOWN_BAD = {'linearmixing': nonlin.linearmixing,
                       'excitingmixing': nonlin.excitingmixing,
                       'diagbroyden': nonlin.diagbroyden}


def F5(x):
    return pressure_network(x, 4, np.array([.5, .5, .5, .5]))
F5.xin = [2., 0, 2, 0]
F5.KNOWN_BAD = {'excitingmixing': nonlin.excitingmixing,
                'linearmixing': nonlin.linearmixing,
                'diagbroyden': nonlin.diagbroyden}


def F6(x):
    x1, x2 = x
    J0 = np.array([[-4.256, 14.7],
                [0.8394989, 0.59964207]])
    v = np.array([(x1 + 3) * (x2**5 - 7) + 3*6,
                  np.sin(x2 * np.exp(x1) - 1)])
    return -np.linalg.solve(J0, v)
F6.xin = [-0.5, 1.4]
F6.KNOWN_BAD = {'excitingmixing': nonlin.excitingmixing,
                'linearmixing': nonlin.linearmixing,
                'diagbroyden': nonlin.diagbroyden}


#-------------------------------------------------------------------------------
# Tests
#-------------------------------------------------------------------------------


class TestNonlin(object):
    """
    Check the Broyden methods for a few test problems.

    broyden1, broyden2, and newton_krylov must succeed for
    all functions. Some of the others don't -- tests in KNOWN_BAD are skipped.

    """

    def _check_nonlin_func(self, f, func, f_tol=1e-2):
        x = func(f, f.xin, f_tol=f_tol, maxiter=200, verbose=0)
        assert_(np.absolute(f(x)).max() < f_tol)

    def _check_root(self, f, method, f_tol=1e-2):
        res = root(f, f.xin, method=method,
                   options={'ftol': f_tol, 'maxiter': 200, 'disp': 0})
        assert_(np.absolute(res.fun).max() < f_tol)

    @dec.knownfailureif(True)
    def _check_func_fail(self, *a, **kw):
        pass

    def test_problem_nonlin(self):
        """ Tests for nonlin functions """
        for f in [F, F2, F2_lucky, F3, F4_powell, F5, F6]:
            for func in SOLVERS.values():
                if func in f.KNOWN_BAD.values():
                    if func in MUST_WORK.values():
                        yield self._check_func_fail, f, func
                    continue
                yield self._check_nonlin_func, f, func

    def test_tol_norm_called(self):
        """ Check that supplying tol_norm keyword to nonlin_solve works"""
        self._tol_norm_used = False

        def local_norm_func(x):
            self._tol_norm_used = True
            return np.absolute(x).max()

        nonlin.newton_krylov(F, F.xin, f_tol=1e-2, maxiter=200, verbose=0,
             tol_norm=local_norm_func)
        assert self._tol_norm_used

    def test_problem_root(self):
        """ Tests for root """
        for f in [F, F2, F2_lucky, F3, F4_powell, F5, F6]:
            for meth in SOLVERS:
                if meth in f.KNOWN_BAD:
                    if meth in MUST_WORK:
                        yield self._check_func_fail, f, meth
                    continue
                yield self._check_root, f, meth


class TestSecant(TestCase):
    """Check that some Jacobian approximations satisfy the secant condition"""

    xs = [np.array([1,2,3,4,5], float),
          np.array([2,3,4,5,1], float),
{'fraction_non_alphanumeric': 0.1898244570068432, 'fraction_numerical': 0.035505305960527624, 'mean_word_length': 1.8927137119908204, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5377648', 'n_tokens_mistral': 3766, 'n_tokens_neox': 3531, 'n_words': 810}