import torch


def neg_log_likelihood(w, X, y, L2_param=None):
    """
    w: dx1
    X: Nxd
    y: Nx1
    L2_param: \lambda>0, will introduce -\lambda/2 ||w||_2^2
    """
    Xw = X.mm(w)
    res = torch.mm(Xw.t(), y) - torch.log(1 + Xw.exp()).sum()
    if L2_param != None and L2_param > 0:
        res += -0.5 * L2_param * torch.mm(w.t(), w)
    return -res