# -*- coding: utf-8

"""Module for testing helper functions.

This file is part of project TESPy (github.com/oemof/tespy). It's copyrighted
by the contributors recorded in the version control history of the file,
available from its original location
tests/tools_tests/helpers_tests.py

SPDX-License-Identifier: MIT
"""

from nose.tools import eq_

from tespy.tools.helpers import newton


def func(params, x):
    return x ** 2 + x - 20


def deriv(params, x):
    return 2 * x + 1


def test_newton_bounds():
    """
    Test newton algorithm value limit handling.

    Try to calculate a zero crossing of a quadratic function in three
    tries.

    - zero crossing within limits, starting value near 4
    - zero crossing within limits, starting value near -5

    - zero crossing below minimum
    - zero crossing above maximum

    The function is x^2 + x - 20, there crossings are -5 and 4.
    """
    result = newton(func, deriv, [], 0, valmin=-10, valmax=10, val0=0)
    msg = ('The newton algorithm should find the zero crossing at 4.0. ' +
           str(round(result, 1)) + ' was found instead.')
    eq_(4.0, result, msg)

    result = newton(func, deriv, [], 0, valmin=-10, valmax=10, val0=-10)
    msg = ('The newton algorithm should find the zero crossing at -5.0. ' +
           str(round(result, 1)) + ' was found instead.')
    eq_(-5.0, result, msg)

    result = newton(func, deriv, [], 0, valmin=-4, valmax=-2, val0=-3)
    msg = ('The newton algorithm should not be able to find a zero crossing. '
           'The value ' + str(round(result, 1)) + ' was found, but the '
           'algorithm should have found the lower boundary of -4.0.')
    eq_(-4.0, result, msg)

    result = newton(func, deriv, [], 0, valmin=-20, valmax=-10, val0=-10)
    msg = ('The newton algorithm should not be able to find a zero crossing. '
           'The value ' + str(round(result, 1)) + ' was found, but the '
           'algorithm should have found the upper boundary of -10.0.')
    eq_(-10.0, result, msg)

[((41, 13, 41, 70), 'tespy.tools.helpers.newton', 'newton', (), '', False, 'from tespy.tools.helpers import newton\n'), ((44, 4, 44, 25), 'nose.tools.eq_', 'eq_', ({(44, 8, 44, 11): '(4.0)', (44, 13, 44, 19): 'result', (44, 21, 44, 24): 'msg'}, {}), '(4.0, result, msg)', False, 'from nose.tools import eq_\n'), ((46, 13, 46, 72), 'tespy.tools.helpers.newton', 'newton', (), '', False, 'from tespy.tools.helpers import newton\n'), ((49, 4, 49, 26), 'nose.tools.eq_', 'eq_', ({(49, 8, 49, 12): '(-5.0)', (49, 14, 49, 20): 'result', (49, 22, 49, 25): 'msg'}, {}), '(-5.0, result, msg)', False, 'from nose.tools import eq_\n'), ((51, 13, 51, 70), 'tespy.tools.helpers.newton', 'newton', (), '', False, 'from tespy.tools.helpers import newton\n'), ((55, 4, 55, 26), 'nose.tools.eq_', 'eq_', ({(55, 8, 55, 12): '(-4.0)', (55, 14, 55, 20): 'result', (55, 22, 55, 25): 'msg'}, {}), '(-4.0, result, msg)', False, 'from nose.tools import eq_\n'), ((57, 13, 57, 73), 'tespy.tools.helpers.newton', 'newton', (), '', False, 'from tespy.tools.helpers import newton\n'), ((61, 4, 61, 27), 'nose.tools.eq_', 'eq_', ({(61, 8, 61, 13): '(-10.0)', (61, 15, 61, 21): 'result', (61, 23, 61, 26): 'msg'}, {}), '(-10.0, result, msg)', False, 'from nose.tools import eq_\n')]