# 需要导入模块: from autograd import numpy [as 别名]
# 或者: from autograd.numpy import inf [as 别名]
def coreset_single(N, D, dist, algn):
#sys.stderr.write('n: ' + str(N) + ' d: ' +str(D) + ' dist: ' + str(dist) + ' salgn: ' + str(algn) + '\n')
x, mu0, Sig0, Sig = gendata(N, D, dist)
Sig0inv = np.linalg.inv(Sig0)
Siginv = np.linalg.inv(Sig)
mup, Sigp = weighted_post(mu0, np.linalg.inv(Sig0), np.linalg.inv(Sig), x, np.ones(x.shape[0]))
anm, alg = algn
coreset = alg(x, mu0, Sig0, Sig)
#incremental M tests
prev_err = np.inf
for m in range(1, N+1):
coreset.build(m)
muw, Sigw = weighted_post(mu0, Sig0inv, Siginv, x, coreset.weights())
w = coreset.weights()
#check if coreset for 1 datapoint is immediately optimal
if x.shape[0] == 1:
assert np.fabs(w - np.array([1])) < tol, anm +" failed: coreset not immediately optimal with N = 1. weights: " + str(coreset.weights()) + " mup = " + str(mup) + " Sigp = " + str(Sigp) + " muw = " + str(muw) + " Sigw = " + str(Sigw)
#check if coreset is valid
assert (w > 0.).sum() <= m, anm+" failed: coreset size > m"
assert (w > 0.).sum() == coreset.size(), anm+" failed: sum of coreset.weights()>0 not equal to size(): sum = " + str((coreset.weights()>0).sum()) + " size(): " + str(coreset.size())
assert np.all(w >= 0.), anm+" failed: coreset has negative weights"
#check if actual output error is monotone
err = weighted_post_KL(mu0, Sig0inv, Siginv, x, w, reverse=True if 'Reverse' in anm else False)
assert err - prev_err < tol, anm+" failed: error is not monotone decreasing, err = " + str(err) + " prev_err = " +str(prev_err)
#check if coreset is computing error properly
assert np.fabs(coreset.error() - err) < tol, anm+" failed: error est is not close to true err: est err = " + str(coreset.error()) + ' true err = ' + str(err)
prev_err = err
#save incremental M result
w_inc = coreset.weights()
#check reset
coreset.reset()
err = weighted_post_KL(mu0, Sig0inv, Siginv, x, np.zeros(x.shape[0]), reverse=True if 'Reverse' in anm else False)
assert coreset.M == 0 and np.all(np.fabs(coreset.weights()) == 0.) and np.fabs(coreset.error() - err) < tol and not coreset.reached_numeric_limit, anm+" failed: reset() did not properly reset"
#check build up to N all at once vs incremental
#do this test for all except bin, where symmetries can cause instabilities in the choice of vector / weights
if dist != 'bin':
coreset.build(N)
w = coreset.weights()
err = weighted_post_KL(mu0, Sig0inv, Siginv, x, w, reverse=True if 'Reverse' in anm else False)
err_inc = weighted_post_KL(mu0, Sig0inv, Siginv, x, w_inc, reverse=True if 'Reverse' in anm else False)
assert np.sqrt(((w - w_inc)**2).sum()) < tol, anm+" failed: incremental buid up to N doesn't produce same result as one run at N : \n error = " +str(err) + " error_inc = " + str(err_inc)
#check if coreset with all_data_wts is optimal
coreset._update_weights(coreset.all_data_wts)
assert coreset.error() < tol, anm + " failed: coreset with all_data_wts does not have error 0"