#  Orakel is a library providing different regression models.
#  Copyright (C) 2025 culpeo <culpeo@dismail.de>

#  This program is free software: you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or (at your
#  option) any later version.

#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
#  for more details.

#  You should have received a copy of the GNU Lesser General Public License
#  along with this program. If not, see https://www.gnu.org/licenses/.

import numpy as np

def calculate_r2(y_true: np.ndarray, y_pred: np.ndarray):
    """Calculate the coefficient of determination R2."""
    ss_res = np.sum((y_true - y_pred) ** 2)
    ss_tot = np.sum((y_true - y_true.mean()) ** 2)
    return 1 - ss_res / ss_tot if ss_tot != 0 else np.nan

def calculate_aic(y_true: np.ndarray, y_pred: np.ndarray, n_params: int):
    """
    Calculate Akaike information criterion (AIC).

    Assuming Gaussian-distributed errors, the AIC can be simplified using the
    squared sum of the residuals to n * ln(ss_res / n) + 2p.

    Parameters
    ----------
    y_true : array-like with one dimension
        The observed values.
    y_pred : array-like with one dimension
        The predicted values.

    Returns
    -------
    aic : float
        The Akaike information criterion.
    """
    n_points = len(y_true)
    ss_res = np.sum((y_true - y_pred) ** 2)
    return n_points * np.log(ss_res / n_points) + 2 * n_params
