| """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) |
| |
| Xg = sample_mixture_spheres(d, n, 5.0, 3.0, 0.4) |
| K1, K2 = 5, 50 |
|
|
| |
| cd_raw = clipped_density(Xr, Xg, k=5) |
| cc_raw = clipped_coverage(Xr, Xg, k=5) |
|
|
| |
| D_final, keep, Drr_gicdm = gicdm(Xr, Xg, K1, K2) |
| dissim = (D_final, Drr_gicdm) |
| cd_gicdm = clipped_density(Xr, Xg, k=5, dissim=dissim, keep=keep) |
| cc_gicdm = clipped_coverage(Xr, Xg, k=5, dissim=dissim, keep=keep) |
|
|
| |
| 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")) |
|
|