"""Real-data (digits) Fig. 5 generator: downstream classification accuracy vs SNR for HIGH/LOW/MIX, parallel to the synthetic Fig. 2. Curves per panel: - OFDMA [division], SFDMA [feature div.], NOMA-SIC (analytical baselines) - UWCA (analytical) : oracle-beta cross-attention (relevance SUPPLIED) -- dotted - UWCA w/o MAML : decoder TRAINED on real digits, no meta-learning (from realdata_train.json) - UWCA w/ MAML : decoder TRAINED on real digits with MAML (proposed) -- hollow circles Trained curves are read from results/realdata_train.json (produced by revision_realdata_train.py); the analytical / baseline curves are recomputed here so they share one Monte-Carlo setting. Saves results/fig_realdata_c.pdf. """ import json, numpy as np import matplotlib; matplotlib.use('Agg') import matplotlib.pyplot as plt from sklearn.datasets import load_digits RNG = np.random.default_rng(7) U, D = 4, 64 DPU = D // U MASKS = np.zeros((U, D)) for u in range(U): MASKS[u, u*DPU:(u+1)*DPU] = 1.0 NOMA_POWER = np.array([0.40, 0.30, 0.20, 0.10]) TAU = 0.45 X, y = load_digits(return_X_y=True) X = X.astype(np.float64); X = X - X.mean(0, keepdims=True) X = X / (np.linalg.norm(X, axis=1, keepdims=True) + 1e-8) by_class = {c: X[y == c] for c in range(10)} PROTO = np.stack([by_class[c].mean(0) for c in range(10)]) PROTO = PROTO / (np.linalg.norm(PROTO, axis=1, keepdims=True) + 1e-8) def _norm(E): return E / (np.linalg.norm(E, axis=-1, keepdims=True) + 1e-8) def se_channel(E, snr): n = E.shape[0]; Ytx = (E * MASKS[None]).sum(1) h = np.sqrt(RNG.standard_normal((n, U, 1))**2 + RNG.standard_normal((n, U, 1))**2)*np.sqrt(0.5) nstd = np.sqrt(float(np.mean(Ytx**2))/(10**(snr/10))) return h*Ytx[:, None, :] + RNG.standard_normal((n, U, D))*nstd def ofdma(Y): return np.stack([_norm(Y[:, u, :]*MASKS[u]) for u in range(U)], 1) def sfdma(E, snr): """Full-band, orthogonal semantic-subspace division (block basis).""" n = E.shape[0] h = np.sqrt(RNG.standard_normal((n, U, 1))**2 + RNG.standard_normal((n, U, 1))**2)*np.sqrt(0.5) X_ = E * MASKS[None] yv = (h * X_).sum(1) yv = yv + RNG.standard_normal((n, D))*np.sqrt(float(np.mean(yv**2))/(10**(snr/10))) return np.stack([_norm((yv * MASKS[u])/(h[:, u, :]+1e-8)) for u in range(U)], 1) def noma_ch(E, snr): n = E.shape[0] h = np.sqrt(RNG.standard_normal((n, U, 1))**2 + RNG.standard_normal((n, U, 1))**2)*np.sqrt(0.5) yv = (E*np.sqrt(NOMA_POWER)[None, :, None]*h).sum(1) yv = yv + RNG.standard_normal((n, D))*np.sqrt(float(np.mean(yv**2))/(10**(snr/10))) return yv, h def noma_sic(yv, h): n = yv.shape[0]; Eh = np.zeros((n, U, D)); res = yv.copy() for u in range(U): Eh[:, u, :] = _norm(res/(h[:, u, :]+1e-8)); res -= h[:, u, :]*np.sqrt(NOMA_POWER[u])*Eh[:, u, :] return Eh def uwca_oracle(Y, bmc): """Analytical UWCA: oracle-beta cross-attention (relevance supplied).""" R = Y[:, :, None, :]*MASKS[None, None] a = bmc.copy(); np.fill_diagonal(a, 1.0); a /= a.sum(1, keepdims=True)+1e-8 ctx = np.einsum('ui,buid->bud', a, R) return np.stack([_norm(ctx[:, u, :]) for u in range(U)], 1) SCEN = {'HIGH': [3, 3, 3, 3], 'LOW': [0, 1, 7, 4], 'MIX': [3, 3, 8, 1]} def sample(n, ca): return np.stack([by_class[ca[u]][RNG.integers(0, len(by_class[ca[u]]), n)] for u in range(U)], 1) def emp_beta(ca, n=4000): E = sample(n, ca); return np.einsum('nud,nvd->uv', E, E)/n def acc(Eh, ca): pred = np.einsum('nud,cd->nuc', _norm(Eh), PROTO).argmax(-1) return (pred == np.array(ca)[None, :]).mean() SNR = np.arange(0, 21, 2) trained = json.load(open('results/realdata_train.json')) # trained UWCA w/ and w/o MAML # --- recompute analytical / baseline accuracy (shared MC) --- ana = {s: {m: [] for m in ['OFDMA', 'SFDMA', 'NOMA-SIC', 'UWCA (analytical)']} for s in SCEN} for s, ca in SCEN.items(): bm = emp_beta(ca); bmc = bm.copy(); np.fill_diagonal(bmc, 0.0); bmc = np.clip(bmc, 0, None) for snr in SNR: ao = asf = an = au = 0.0; nmc = 200 for _ in range(nmc): E = sample(64, ca) ao += acc(ofdma(se_channel(E, snr)), ca) asf += acc(sfdma(E, snr), ca) yv, h = noma_ch(E, snr); an += acc(noma_sic(yv, h), ca) au += acc(uwca_oracle(se_channel(E, snr), bmc), ca) ana[s]['OFDMA'].append(ao/nmc); ana[s]['SFDMA'].append(asf/nmc) ana[s]['NOMA-SIC'].append(an/nmc); ana[s]['UWCA (analytical)'].append(au/nmc) # --- plot: downstream accuracy, 1 row x 3 cols --- COL = {'OFDMA': '#546E7A', 'SFDMA': '#9C27B0', 'NOMA-SIC': '#E65100', 'UWCA (analytical)': '#1565C0', 'UWCA w/o MAML': '#2E7D32', 'UWCA w/ MAML': '#1565C0'} fig, ax = plt.subplots(1, 3, figsize=(11, 3.4)) betas = {s: emp_beta(SCEN[s])[~np.eye(U, dtype=bool)].mean() for s in SCEN} for j, s in enumerate(['HIGH', 'LOW', 'MIX']): a = ax[j] a.plot(SNR, ana[s]['OFDMA'], 's--', color=COL['OFDMA'], lw=2, ms=5, label='OFDMA [division]') a.plot(SNR, ana[s]['SFDMA'], 'v:', color=COL['SFDMA'], lw=2, ms=5, mfc='none', label='SFDMA [feature div.]') a.plot(SNR, ana[s]['NOMA-SIC'], '^-.', color=COL['NOMA-SIC'], lw=2, ms=5, label='NOMA-SIC') a.plot(SNR, ana[s]['UWCA (analytical)'], ':', color=COL['UWCA (analytical)'], lw=2.4, label='UWCA (analytical)') a.plot(SNR, trained[s]['UWCA w/ MAML'], 'o-', color=COL['UWCA w/ MAML'], lw=1.6, ms=6, mfc='none', mew=1.6, label='UWCA (trained)') a.set_ylim(0.1, 1.02); a.set_xlim(0, 20); a.grid(alpha=.3); a.set_box_aspect(0.85) a.set_xlabel('SNR (dB)', fontsize=10) a.text(0.5, -0.34, f"({chr(97+j)}) {s} ($\\hat\\beta_{{u,v}}\\approx{betas[s]:.2f}$)", transform=a.transAxes, ha='center', fontsize=11) if j == 0: a.set_ylabel('Downstream accuracy', fontsize=10) ax[0].legend(fontsize=7.0, loc='upper left', bbox_to_anchor=(0.46, 0.37), bbox_transform=ax[0].transAxes, framealpha=0.9, borderaxespad=0.0) fig.tight_layout() fig.savefig('results/fig_realdata.pdf', bbox_inches='tight') fig.savefig('results/fig_realdata.png', dpi=140, bbox_inches='tight') fig.savefig('results/fig_realdata_c.pdf', bbox_inches='tight') print('saved results/fig_realdata_c.pdf') for s in SCEN: print(f"[{s}] @20dB OFDMA={ana[s]['OFDMA'][-1]:.3f} SFDMA={ana[s]['SFDMA'][-1]:.3f} " f"NOMA={ana[s]['NOMA-SIC'][-1]:.3f} UWCA-ana={ana[s]['UWCA (analytical)'][-1]:.3f} " f"UWCA-MAML(tr)={trained[s]['UWCA w/ MAML'][-1]:.3f}")