# Path: guacamol/score_modifier.py
# class ScoreModifier:
# class ChainedModifier(ScoreModifier):
# class LinearModifier(ScoreModifier):
# class SquaredModifier(ScoreModifier):
# class AbsoluteScoreModifier(ScoreModifier):
# class GaussianModifier(ScoreModifier):
# class MinMaxGaussianModifier(ScoreModifier):
# class ClippedScoreModifier(ScoreModifier):
# class SmoothClippedScoreModifier(ScoreModifier):
# class ThresholdedLinearModifier(ScoreModifier):
#     def __call__(self, x):
#     def __init__(self, modifiers: List[ScoreModifier]) -> None:
#     def __call__(self, x):
#     def __init__(self, slope=1.0):
#     def __call__(self, x):
#     def __init__(self, target_value: float, coefficient=1.0) -> None:
#     def __call__(self, x):
#     def __init__(self, target_value: float) -> None:
#     def __call__(self, x):
#     def __init__(self, mu: float, sigma: float) -> None:
#     def __call__(self, x):
#     def __init__(self, mu: float, sigma: float, minimize=False) -> None:
#     def __call__(self, x):
#     def __init__(self, upper_x: float, lower_x=0.0, high_score=1.0, low_score=0.0) -> None:
#     def __call__(self, x):
#     def __init__(self, upper_x: float, lower_x=0.0, high_score=1.0, low_score=0.0) -> None:
#     def __call__(self, x):
#     def __init__(self, threshold: float) -> None:
#     def __call__(self, x):


from functools import partial
from guacamol.score_modifier import LinearModifier, SquaredModifier, AbsoluteScoreModifier, GaussianModifier, \
    MinGaussianModifier, MaxGaussianModifier, ThresholdedLinearModifier, ClippedScoreModifier, \
    SmoothClippedScoreModifier, ChainedModifier
import numpy as np
import pytest
def test_absolute_function():
    target_value = 5.555
    f = AbsoluteScoreModifier(target_value=target_value)

    expected_scalar = 1.0 - abs(target_value - scalar_value)
    expected_array = 1.0 - np.abs(target_value - value_array)

    assert f(scalar_value) == expected_scalar
    assert np.array_equal(f(value_array), expected_array)


def gaussian(x, mu, sig):
    return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))


def test_gaussian_function():
    mu = -1.223
    sigma = 0.334

    f = GaussianModifier(mu=mu, sigma=sigma)

    assert f(mu) == 1.0
    assert f(scalar_value) == gaussian(scalar_value, mu, sigma)
    assert np.allclose(f(value_array), gaussian(value_array, mu, sigma))


def test_min_gaussian_function():
    mu = -1.223
    sigma = 0.334


# Path: guacamol/score_modifier.py
# class ScoreModifier:
# class ChainedModifier(ScoreModifier):
# class LinearModifier(ScoreModifier):
# class SquaredModifier(ScoreModifier):
# class AbsoluteScoreModifier(ScoreModifier):
# class GaussianModifier(ScoreModifier):
# class MinMaxGaussianModifier(ScoreModifier):
# class ClippedScoreModifier(ScoreModifier):
# class SmoothClippedScoreModifier(ScoreModifier):
# class ThresholdedLinearModifier(ScoreModifier):
#     def __call__(self, x):
#     def __init__(self, modifiers: List[ScoreModifier]) -> None:
#     def __call__(self, x):
#     def __init__(self, slope=1.0):
#     def __call__(self, x):
#     def __init__(self, target_value: float, coefficient=1.0) -> None:
#     def __call__(self, x):
#     def __init__(self, target_value: float) -> None:
#     def __call__(self, x):
#     def __init__(self, mu: float, sigma: float) -> None:
#     def __call__(self, x):
#     def __init__(self, mu: float, sigma: float, minimize=False) -> None:
#     def __call__(self, x):
#     def __init__(self, upper_x: float, lower_x=0.0, high_score=1.0, low_score=0.0) -> None:
#     def __call__(self, x):
#     def __init__(self, upper_x: float, lower_x=0.0, high_score=1.0, low_score=0.0) -> None:
#     def __call__(self, x):
#     def __init__(self, threshold: float) -> None:
#     def __call__(self, x):


# Path: tests/test_score_modifier.py
from functools import partial
from guacamol.score_modifier import LinearModifier, SquaredModifier, AbsoluteScoreModifier, GaussianModifier, \
    MinGaussianModifier, MaxGaussianModifier, ThresholdedLinearModifier, ClippedScoreModifier, \
    SmoothClippedScoreModifier, ChainedModifier
import numpy as np
import pytest

def test_absolute_function():
    target_value = 5.555
    f = AbsoluteScoreModifier(target_value=target_value)

    expected_scalar = 1.0 - abs(target_value - scalar_value)
    expected_array = 1.0 - np.abs(target_value - value_array)

    assert f(scalar_value) == expected_scalar
    assert np.array_equal(f(value_array), expected_array)


def gaussian(x, mu, sig):
    return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.)))


def test_gaussian_function():
    mu = -1.223
    sigma = 0.334

    f = GaussianModifier(mu=mu, sigma=sigma)

    assert f(mu) == 1.0
    assert f(scalar_value) == gaussian(scalar_value, mu, sigma)
    assert np.allclose(f(value_array), gaussian(value_array, mu, sigma))


def test_min_gaussian_function():
    mu = -1.223
    sigma = 0.334


    f = MinGaussianModifier(mu=mu, sigma=sigma)