def test_generate_all_predictions():
    """Spot-check that the predicted free energies are reasonable
    (right shape, finite, RMSE (in kcal/mol) in a reasonable range)"""
    theta = np.ones(2 * n_types)
    from time import time
    print('predicting hydration free energies with theta=ones...')
    t0 = time()
    predictions = generate_all_predictions(theta)
    t1 = time()
    print('that took {:.3f} s'.format(t1 - t0))

    # sanity check that the predictions are finite and that there's the right number of them
    assert (len(predictions) == len(molecules))
    assert (np.isfinite(predictions).all())

    # sanity check that the numerical values of the predictions aren't grossly wrong...
    pred_kcal_mol = unreduce(predictions)
    expt_kcal_mol = unreduce(expt_means)

    rmse = np.sqrt(np.mean((pred_kcal_mol - expt_kcal_mol)**2))
    print('RMSE for theta all ones: {:.3f} kcal/mol'.format(rmse))

    # first time I ran this test, it was ~7.154 kcal/mol
    assert (rmse < 10.)
    assert (rmse > 2.)

    # check that running with mbondi radii and scales gives an RMSE closer to like 2.5 kcal/mol
    theta = pack(radii=mbondi_model.get_radii(),
                 scales=mbondi_model.get_scale_factors())

    print('predicting hydration free energies with theta from mbondi model...')
    t0 = time()
    predictions = generate_all_predictions(theta)
    t1 = time()
    print('that took {:.3f} s'.format(t1 - t0))

    # sanity check that the predictions are finite and that there's the right number of them
    assert (len(predictions) == len(molecules))
    assert (np.isfinite(predictions).all())

    # sanity check that the numerical values of the predictions aren't grossly wrong...
    pred_kcal_mol = unreduce(predictions)
    expt_kcal_mol = unreduce(expt_means)

    rmse = np.sqrt(np.mean((pred_kcal_mol - expt_kcal_mol)**2))
    print('RMSE for mbondi model: {:.3f} kcal/mol'.format(rmse))

    # I think it's around 2.4 kcal/mol, but this test is saying something like 2.628 kcal/mol
    assert (rmse > 2.)
    assert (rmse < 3.)
    assert (np.isfinite(predictions).all())

    # sanity check that the numerical values of the predictions aren't grossly wrong...
    pred_kcal_mol = unreduce(predictions)
    expt_kcal_mol = unreduce(expt_means)

    rmse = np.sqrt(np.mean((pred_kcal_mol - expt_kcal_mol)**2))
    print('RMSE for mbondi model: {:.3f} kcal/mol'.format(rmse))

    # I think it's around 2.4 kcal/mol, but this test is saying something like 2.628 kcal/mol
    assert (rmse > 2.)
    assert (rmse < 3.)


np.random.seed(0)
theta0 = pack(radii=mbondi_model.get_radii(),
              scales=mbondi_model.get_scale_factors())
n_start = 10
x0s = [(np.random.rand(len(theta0)) * 0.05) - 0.025 + theta0
       for _ in range(n_start)]

from collections import namedtuple
Experiment = namedtuple('Experiment', ['x0', 'cv_fold', 'll', 'stepsize'])
gd_stepsize = dict(gaussian=1e-8, student_t=1e-6)
experiments = []
for x0 in x0s:
    for cv_fold in range(N_folds):
        for ll in ll_dict:
            experiments.append(
                Experiment(x0=x0,
                           cv_fold=cv_fold,
    L = log_prior(theta)
    if not (L > -np.inf):
        return L
    else:
        parameterized_list = construct_arrays(theta)
        for i, mol in enumerate(mols):
            radii, scale_factors = parameterized_list[i]
            L += mol.log_prob(radii, scale_factors)
    return L


if __name__ == '__main__':
    n_types = mbondi_model.number_of_nodes
    print('n_types: {}'.format(n_types))

    initial_radii = np.array(mbondi_model.get_radii())
    initial_scales = np.array(mbondi_model.get_scale_factors())
    theta0 = np.hstack((initial_radii, initial_scales))

    print('initial theta', theta0)
    initial_log_prob = log_prob(theta0)

    minimized_theta_fname = os.path.join(
        data_path,
        'elemental_types_l-bfgs-finite-difference_{}.npy'.format(name))

    print('minimizing...')
    from scipy.optimize import minimize

    bounds = [(min_r, max_r)] * n_types + [(min_scale, max_scale)] * n_types