<jupyter_start><jupyter_text>Data generating functions<jupyter_code>def equal(n):
    X = np.random.uniform(.2, .7, size=(n, 1))
    Y = np.random.uniform(.2, .7, size=(n, 1))
    
    return X, Y

def linear(n):
    X = np.random.uniform(.2, .7, size=(n, 1))
    Y = X + 0.1
    
    return X, Y

def nonlinear(n):
    X = np.random.uniform(.2, .7, size=(n, 1))
    b = np.random.beta(.2, .2, size=(n, 1))
    Y = 0.5 * b + 0.2
    
    return X, Y<jupyter_output><empty_output><jupyter_text>Running simulations<jupyter_code>def hypothesis_test(X1, X2):
    tests = [KSample('Dcorr'), KSample('MGC')]
    X1_flipped = SignFlips('median').fit_transform(X1, X2)     
    
    pvals = []
    for test in tests:
        res = test.test(X1_flipped, X2, auto=False)
        pvals.append(res[1])
        
    return pvals

def run(data_func, n):
    X, Y = data_func(n)
    A = rdpg(X)
    B = rdpg(Y)
    
    ase = AdjacencySpectralEmbed(n_components=1, diag_aug=True, check_lcc=False)
    Xhat = ase.fit_transform(A)
    Yhat = ase.fit_transform(B)
    
    pvals = hypothesis_test(Xhat, Yhat)
    return [*pvals, n, data_func.__name__]
ns = np.linspace(20, 150, 14).astype(int)
datasets = [equal, linear, nonlinear]

args = list(product(ns, datasets))
repeats = 1000

reses = []
for arg in tqdm(args):
    n, dataset = arg
    res = Parallel(-1, verbose=0)(delayed(run)(dataset, n) for _ in range(repeats))
    reses.extend(res)
cols = ["DCorr", "MGC", "n", "dataset"]

df = pd.DataFrame(reses, columns=cols)

df.to_csv("./results/figure1.csv", index=False)<jupyter_output><empty_output><jupyter_text>Plotting<jupyter_code># Comment below to use computed instead of precomputed results

df = pd.read_csv("./results/figure1.csv")
sns.set_context("talk", font_scale=1.4)

titles = ["Equal", "Linear", "Nonlinear"]
algo_titles = ["MGC", "DCorr", ]
colors = ["#e41a1c", "#377eb8"]

ns = np.linspace(20, 150, 14).astype(int)

fig, axes = plt.subplots(ncols=3, figsize=(18, 5), constrained_layout=True, sharex=True, sharey=True)

for idx, dataset in enumerate(titles):
    axes[idx].axhline(0.05, ls="--", c="k", alpha=0.6)

    tmp_df = df[df.dataset == dataset.lower()]

    for jdx, algo in enumerate(algo_titles):
        powers = []
        errs = []

        for n in ns:
            power = np.mean(tmp_df[tmp_df.n == n][algo].values <= 0.05)
            err = 1.96 * np.sqrt(power * (1 - power) / 1000) #1000 = num reps

            powers.append(power)
            errs.append(err)

        axes[idx].errorbar(x = ns, y=powers, yerr=errs, label=algo_titles[jdx], c=colors[jdx], alpha=0.85, lw=5)

    axes[idx].set_xticks([50, 100, 150])
    axes[idx].set_xlabel("Number of Vertices")
    axes[idx].set_title(titles[idx])

axes[0].set_xlim(*(13.5, 156.5))

axes[0].legend(loc="upper left")
axes[0].set_ylabel("Type I Error")
axes[1].set_ylabel("Power", labelpad=20)
fig.savefig("./figures/figure1.pdf", dpi=300, bbox_inches="tight")
fig.savefig("./figures/figure1.png", dpi=300, bbox_inches="tight")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17590759075907592, 'fraction_numerical': 0.038943894389438946, 'mean_word_length': 3.537425149700599, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '465916', 'license': 'MIT', 'n_tokens_mistral': 1312, 'n_tokens_neox': 1211, 'n_words': 237, 'path': 'Figure1.ipynb', 'repo_name': 'neurodata/latent-distribution-test', 'size': '3030'}