#!/usr/bin/env python3


def f(x):
    """Die Zielfunktion."""
    return 0.25 * x**4 - x**3 - 2 * x**2 + 2


def df(x):
    """Die erste Ableitung (Gefälle) der Zielfunktion."""
    return x**3 - 3 * x**2 - 4 * x


def gradient_descent(start_x, learning_rate, epochs):
    x = start_x
    for i in range(epochs):
        gradient = df(x)
        x = x - learning_rate * gradient

        # Logge jeden 5. Schritt zur Kontrolle
        if i % 5 == 0:
            print(f"Epoche {i:2d} | x = {x:.5f} | f(x) = {f(x):.5f}")

    return x


if __name__ == "__main__":
    # Hyperparameter
    START_X = 6.0
    LEARNING_RATE = 0.01
    EPOCHS = 35

    print(f"Starte Gradientenabstieg bei x = {START_X}\n" + "-" * 40)
    minimum_x = gradient_descent(START_X, LEARNING_RATE, EPOCHS)

    print("-" * 40)
    print(f"Globales Minimum gefunden bei x ≈ {minimum_x:.5f}")
