def test_expanding_consistency(consistency_data, min_periods):
    x, is_constant, no_nans = consistency_data
    # suppress warnings about empty slices, as we are deliberately testing
    # with empty/0-length Series/DataFrames
    with warnings.catch_warnings():
        warnings.filterwarnings("ignore",
                                message=".*(empty slice|0 for slice).*",
                                category=RuntimeWarning)

        # test consistency between different expanding_* moments
        moments_consistency_mock_mean(
            x=x,
            mean=lambda x: x.expanding(min_periods=min_periods).mean(),
            mock_mean=lambda x: x.expanding(min_periods=min_periods).sum() / x.
            expanding().count(),
        )

        moments_consistency_is_constant(
            x=x,
            is_constant=is_constant,
            min_periods=min_periods,
            count=lambda x: x.expanding().count(),
            mean=lambda x: x.expanding(min_periods=min_periods).mean(),
            corr=lambda x, y: x.expanding(min_periods=min_periods).corr(y),
        )

        moments_consistency_var_debiasing_factors(
            x=x,
            var_unbiased=lambda x: x.expanding(min_periods=min_periods).var(),
            var_biased=lambda x: x.expanding(min_periods=min_periods).var(ddof=
                                                                          0),
            var_debiasing_factors=lambda x:
            (x.expanding().count() /
             (x.expanding().count() - 1.0).replace(0.0, np.nan)),
        )
def test_ewm_consistency(consistency_data, min_periods, adjust, ignore_na):
    def _weights(s, com, adjust, ignore_na):
        if isinstance(s, DataFrame):
            if not len(s.columns):
                return DataFrame(index=s.index, columns=s.columns)
            w = concat(
                [
                    _weights(s.iloc[:, i],
                             com=com,
                             adjust=adjust,
                             ignore_na=ignore_na)
                    for i, _ in enumerate(s.columns)
                ],
                axis=1,
            )
            w.index = s.index
            w.columns = s.columns
            return w

        w = Series(np.nan, index=s.index)
        alpha = 1.0 / (1.0 + com)
        if ignore_na:
            w[s.notna()] = _weights(s[s.notna()],
                                    com=com,
                                    adjust=adjust,
                                    ignore_na=False)
        elif adjust:
            for i in range(len(s)):
                if s.iat[i] == s.iat[i]:
                    w.iat[i] = pow(1.0 / (1.0 - alpha), i)
        else:
            sum_wts = 0.0
            prev_i = -1
            for i in range(len(s)):
                if s.iat[i] == s.iat[i]:
                    if prev_i == -1:
                        w.iat[i] = 1.0
                    else:
                        w.iat[i] = alpha * sum_wts / pow(
                            1.0 - alpha, i - prev_i)
                    sum_wts += w.iat[i]
                    prev_i = i
        return w

    def _variance_debiasing_factors(s, com, adjust, ignore_na):
        weights = _weights(s, com=com, adjust=adjust, ignore_na=ignore_na)
        cum_sum = weights.cumsum().fillna(method="ffill")
        cum_sum_sq = (weights * weights).cumsum().fillna(method="ffill")
        numerator = cum_sum * cum_sum
        denominator = numerator - cum_sum_sq
        denominator[denominator <= 0.0] = np.nan
        return numerator / denominator

    def _ewma(s, com, min_periods, adjust, ignore_na):
        weights = _weights(s, com=com, adjust=adjust, ignore_na=ignore_na)
        result = (s.multiply(weights).cumsum().divide(
            weights.cumsum()).fillna(method="ffill"))
        result[s.expanding().count() < (
            max(min_periods, 1) if min_periods else 1)] = np.nan
        return result

    x, is_constant, no_nans = consistency_data
    com = 3.0
    moments_consistency_mock_mean(
        x=x,
        mean=lambda x: x.ewm(com=com,
                             min_periods=min_periods,
                             adjust=adjust,
                             ignore_na=ignore_na).mean(),
        mock_mean=lambda x: _ewma(x,
                                  com=com,
                                  min_periods=min_periods,
                                  adjust=adjust,
                                  ignore_na=ignore_na),
    )

    moments_consistency_is_constant(
        x=x,
        is_constant=is_constant,
        min_periods=min_periods,
        count=lambda x: x.expanding().count(),
        mean=lambda x: x.ewm(com=com,
                             min_periods=min_periods,
                             adjust=adjust,
                             ignore_na=ignore_na).mean(),
        corr=lambda x, y: x.ewm(com=com,
                                min_periods=min_periods,
                                adjust=adjust,
                                ignore_na=ignore_na).corr(y),
    )

    moments_consistency_var_debiasing_factors(
        x=x,
        var_unbiased=lambda x: (x.ewm(com=com,
                                      min_periods=min_periods,
                                      adjust=adjust,
                                      ignore_na=ignore_na).var(bias=False)),
        var_biased=lambda x: (x.ewm(com=com,
                                    min_periods=min_periods,
                                    adjust=adjust,
                                    ignore_na=ignore_na).var(bias=True)),
        var_debiasing_factors=lambda x: (_variance_debiasing_factors(
            x, com=com, adjust=adjust, ignore_na=ignore_na)),
    )