"""Lesson 16 starter: stable binary cross-entropy from scores."""
import numpy as np

X = np.array([
    [1., -1.],
    [1.,  0.],
    [1.,  1.]
])
y = np.array([0., 1., 1.])
w = np.array([0.5, 1.0])

def sigmoid(z):
    return 1 / (1 + np.exp(-z))

def cross_entropy_from_scores(w, X, y):
    scores = X @ w
    # TODO: use np.logaddexp(0, scores) - y*scores
    losses = np.logaddexp(0, scores) - y * scores
    return np.mean(losses)

def grad_cross_entropy(w, X, y):
    scores = X @ w
    p = sigmoid(scores)
    # TODO: implement X.T @ (p-y) / len(y)
    return X.T @ (p - y) / len(y)

print("mean cross-entropy =", cross_entropy_from_scores(w, X, y))
print("gradient =", grad_cross_entropy(w, X, y))
