human
Complete this python program:
def compare(traces, models, ic='WAIC', bootstrap=True, b_samples=1000, alpha=1, seed=None):
assistant
#Here is the Python code you requested.

    """Compare models based on the widely available information criterion (WAIC)
    or leave-one-out (LOO) cross-validation.
    Read more theory here - in a paper by some of the leading authorities on
    Model Selection - dx.doi.org/10.1111/1467-9868.00353
    Parameters
    traces : list of PyMC3 traces
    models : list of PyMC3 models
    in the same order as traces.
    ic : string
    Information Criterion (WAIC or LOO) used to compare models.
    Default WAIC.
    bootstrap : boolean
    If True a Bayesian bootstrap will be used to compute the weights and
    the standard error of the IC estimate (SE).
    b_samples: int
    Number of samples taken by the Bayesian bootstrap estimation
    alpha : float
    The shape parameter in the Dirichlet distribution used for the
    Bayesian bootstrap. When alpha=1 (default), the distribution is uniform
    on the simplex. A smaller alpha will keeps the final weights
    more away from 0 and 1.
    seed : int or np.random.RandomState instance
    If int or RandomState, use it for seeding Bayesian bootstrap.
    Default None the global np.random state is used.
    Returns
    A DataFrame, ordered from lowest to highest IC. The index reflects
    the order in which the models are passed to this function. The columns are:
    IC : Information Criteria (WAIC or LOO).
    Smaller IC indicates higher out-of-sample predictive fit ("better" model).
    Default WAIC.
    pIC : Estimated effective number of parameters.
    dIC : Relative difference between each IC (WAIC or LOO)
    and the lowest IC (WAIC or LOO).
    It\s always 0 for the top-ranked model.
    weight: Akaike-like weights for each model.
    This can be loosely interpreted as the probability of each model
    (among the compared model) given the data. By default the uncertainty
    in the weights estimation is considered using Bayesian bootstrap.
    SE : Standard error of the IC estimate.
    By default these values are estimated using Bayesian bootstrap (best
    option) or, if bootstrap=False, using a..."""
    if (ic == 'WAIC'):
        ic_func = waic
        df_comp = pd.DataFrame(index=np.arange(len(models)), columns=['WAIC', 'pWAIC', 'dWAIC', 'weight', 'SE', 'dSE', 'warning'])
    elif (ic == 'LOO'):
        ic_func = loo
        df_comp = pd.DataFrame(index=np.arange(len(models)), columns=['LOO', 'pLOO', 'dLOO', 'weight', 'SE', 'dSE', 'warning'])
    else:
        raise NotImplementedError('The    information    criterion    {}    is    not    supported.'.format(ic))
    warns = np.zeros(len(models))
    c = 0
    def add_warns(*args):
        warns[c] = 1
    with warnings.catch_warnings():
        warnings.showwarning = add_warns
        warnings.filterwarnings('always')
        ics = []
        for (c, (t, m)) in enumerate(zip(traces, models)):
            ics.append((c, ic_func(t, m, pointwise=True)))
    ics.sort(key=(lambda x: x[1][0]))
    if bootstrap:
        N = len(ics[0][1][3])
        ic_i = np.zeros((len(ics), N))
        for i in range(len(ics)):
            ic_i[i] = (ics[i][1][3] * N)
        b_weighting = dirichlet.rvs(alpha=([alpha] * N), size=b_samples, random_state=seed)
        weights = np.zeros((b_samples, len(ics)))
        z_bs = np.zeros((b_samples, len(ics)))
        for i in range(b_samples):
            z_b = np.dot(ic_i, b_weighting[i])
            u_weights = np.exp(((-0.5) * (z_b - np.min(z_b))))
            z_bs[i] = z_b
            weights[i] = (u_weights / np.sum(u_weights))
        weights_mean = weights.mean(0)
        se = z_bs.std(0)
        for (i, (idx, res)) in enumerate(ics):
            diff = (res[3] - ics[0][1][3])
            d_ic = np.sum(diff)
            d_se = np.sqrt((len(diff) * np.var(diff)))
            df_comp.at[idx] = (res[0], res[2], d_ic, weights_mean[i], se[i], d_se, warns[idx])
    else:
        min_ic = ics[0][1][0]
        Z = np.sum([np.exp(((-0.5) * (x[1][0] - min_ic))) for x in ics])
        for (idx, res) in ics:
            diff = (res[3] - ics[0][1][3])
            d_ic = np.sum(diff)
            d_se = np.sqrt((len(diff) *...