import numpy as np

from . import utils


def brier_score(forecast, observed):
    """
    Calculate Brier score (BS) between two variables.

    Calculates the Brier score (BS), a measure of the mean-square error of
    probability forecasts for a dichotomous (two-category) event, such as
    the occurrence/non-occurrence of precipitation. The score is calculated
    using the formula:

    BS = sum_(n=1)^N (f_n - o_n)^2/N

    where f is the forecast probabilities, o is the observed probabilities
    (0 or 1), and N is the total number of values in f & o. Note that f & o
    must have the same number of values, and those values must be in the
    range [0,1].

    Input:
    FORECAST : forecast probabilities
    OBSERVED : observed probabilities

    Output:
    BS : Brier score

    Reference:
    Glenn W. Brier, 1950: Verification of forecasts expressed in terms
    of probabilities. Mon. We. Rev., 78, 1-23.

    D. S. Wilks, 1995: Statistical Methods in the Atmospheric Sciences.
    Cambridge Press. 547 pp.

    Author: Peter A. Rochford
        Symplectic, LLC
        www.thesymplectic.com
        prochford@thesymplectic.com

    Created on Dec 15, 2016
    """
    # Check that dimensions of forecast and observed fields match
    utils.check_arrays(forecast, observed, pname="forecast", rname="observed")

    # Check for valid values
    index = np.where(np.logical_or(forecast < 0, forecast > 1))
    if np.sum(index) > 0:
        raise ValueError("Forecast has values outside interval [0,1].")
    index = np.where(np.logical_and(observed != 0, observed != 1))
    if np.sum(index) > 0:
        raise ValueError("Observed has values not equal to 0 or 1.")

    return np.sum(np.square(forecast - observed)) / len(forecast)
