"""Claim 1 verification: GICDM out-of-sample generated-point scaling (Eq. 1, Algorithm 1). Test scenario (Figure 1 of paper): real samples drawn from a 60/40 mixture of two hyperspheres with radii (r1, r2); generated samples from a mixture with swapped radii and proportions. The two sets are disjoint, so all fidelity/coverage metrics should score 0 in the ideal case. Standard metrics fail in high dimension due to hubness; GICDM-corrected metrics should remain ~0. """ import numpy as np import sys, os sys.path.insert(0, os.path.dirname(__file__)) from gicdm_core import (pairwise_sq_dists, icdm_scaling, gicdm, clipped_density, clipped_coverage, hubness_stats) def sample_mixture_spheres(d, n, r1, r2, p1): n1 = int(round(p1 * n)) n2 = n - n1 def sphere(r, m): v = np.random.normal(size=(m, d)) v /= np.linalg.norm(v, axis=1, keepdims=True) return v * r return np.vstack([sphere(r1, n1), sphere(r2, n2)]) def run(d, n, seed=0): np.random.seed(seed) Xr = sample_mixture_spheres(d, n, 3.0, 5.0, 0.6) # swapped radii & proportions Xg = sample_mixture_spheres(d, n, 5.0, 3.0, 0.4) K1, K2 = 5, 50 # K2 = 10*K1 # raw metric cd_raw = clipped_density(Xr, Xg, k=5) cc_raw = clipped_coverage(Xr, Xg, k=5) # GICDM-corrected D_final, keep, Drr_gicdm = gicdm(Xr, Xg, K1, K2) dissim = (D_final, Drr_gicdm) # (generated-to-real, real-to-real) GICDM dissimilarities cd_gicdm = clipped_density(Xr, Xg, k=5, dissim=dissim, keep=keep) cc_gicdm = clipped_coverage(Xr, Xg, k=5, dissim=dissim, keep=keep) # Hubness in raw real-real space h5_raw, A5_raw = hubness_stats(pairwise_sq_dists(Xr), k=5) return dict(d=d, n=n, cd_raw=cd_raw, cc_raw=cc_raw, cd_gicdm=cd_gicdm, cc_gicdm=cc_gicdm, kept=float(keep.mean()), h5_raw=h5_raw, A5_raw=A5_raw) if __name__ == "__main__": import json out = [] for d in [10, 50, 100, 500, 1000]: r = run(d, 1000, seed=42) out.append(r) print(f"d={d:5d} CD raw={r['cd_raw']:.3f} GICDM={r['cd_gicdm']:.3f} | " f"CC raw={r['cc_raw']:.3f} GICDM={r['cc_gicdm']:.3f} | kept={r['kept']:.2f} h5={r['h5_raw']:.2f}") json.dump(out, open("results/claim1_hypersphere.json", "w"))