def eval(self, fast=True, pts=1000): """ Evaluate the true divergence by performing numeric integration on the n^d grid of points. """ if not fast: print "using slow integration" if self.dim == 1: val = numeric_integration(lambda x: np.multiply( np.power(self.p.eval(np.matrix(x)), self.alpha), np.power(self.q.eval(np.matrix(x)), self.beta)), [lb], [ub]) if self.dim == 2: val = numeric_integration(lambda x,y: np.multiply( # np.power(self.p.eval(np.concatenate(np.matrix(x), np.matrix(y))), self.alpha), # np.power(self.q.eval(np.concatenate(np.matrix(x), np.matrix(y))), self.beta)), np.power(self.p.eval(np.concatenate(np.matrix(x), np.matrix(y))), self.alpha), np.power(self.q.eval(np.concatenate(np.matrix(x), np.matrix(y))), self.beta)), [lb, lb], [ub, ub]) if fast: print "using fast integration" if self.dim == 1: val = fast_integration(lambda x: np.multiply( np.power(self.p.eval(np.matrix(x)), self.alpha), np.power(self.q.eval(np.matrix(x)), self.beta)), [lb], [ub], pts=pts) if self.dim == 2: val = fast_integration(lambda x: np.multiply( np.power(self.p.eval(np.matrix(x)), self.alpha), np.power(self.q.eval(np.matrix(x)), self.beta)), [lb,lb], [ub,ub]) return val
def test_bilinear_term_estimator(Dp, Dq, ns, iters=10, fast=True): """ Test the bilinear functional estimator """ ms = [] vs = [] T = fast_integration(lambda x: np.array(Dp.eval(x)) * np.array(Dq.eval(x)), [0], [1]) print "Truth: %f" % (T) for n in ns: sub_scores = [] for i in range(iters): pdata = Dp.sample(n) qdata = Dq.sample(n) Q = estimators.QuadraticEstimator(pdata, pdata, 0.5, 0.5, Dp.s) val = Q.bilinear_term_slow(lambda x: 1, pdata, qdata) val2 = Q.bilinear_term_fast( lambda x: np.matrix(np.ones((x.shape[0], 1))), pdata, qdata) print "truth = %0.3f, slow = %0.3f, fast = %0.3f" % (T, val2, val) sub_scores.append(np.abs(val - T)) sub_scores.sort() sub_scores = sub_scores[int(0.2 * iters):int(0.8 * iters)] ms.append(np.mean(sub_scores)) vs.append(np.std(sub_scores)) print "n = %d, av_er = %0.2f, std_er = %0.4f" % ( n, np.mean(sub_scores), np.std(sub_scores)) return (ns, ms, vs)
def quad_term_fast(self, fn, data): """ Fast routine for estimating the quadratic term fn -- a lambda expression for the function \psi. data1 -- data from the distribution we are trying to estimate Returns the value of the estimator Note: this shouldn't be called externally """ n = data.shape[0] total = 0.0 for k in lattice.lattice(self.dim, self.m): sub1 = np.array(self.comp_exp(k, data)) sub2 = sub1*np.array(fn(data)) total += np.sum((np.sum(sub2) - sub2) * sub1) term2 = 0.0 for k in lattice.lattice(self.dim, self.m): for kp in lattice.lattice(self.dim, self.m): bi = fast_integration(lambda x: np.array(self.comp_exp(k,x))*np.array(self.comp_exp(kp,x))*np.array(fn(x)), [0.0 for t in range(self.dim)], [1.0 for t in range(self.dim)], pts=100) sub1 = np.array(self.comp_exp(k, data)) sub2 = np.array(self.comp_exp(kp, data)) term2 += np.sum(bi* sub1* (np.sum(sub2) - sub2)) # print (np.real(2.0*total/(n*(n-1))), np.real(term2/(n*(n-1)))) return np.real(2.0*total/(n*(n-1))) - np.real(term2/(n*(n-1)))
def quad_term_slow(self, fn, data): """ Deprected Slow routine for estimating the quadratic terms fn -- a lambda expression for the function \psi. data1 -- data from the distribution we are trying to estimate Returns the value of the estimator """ assert False, "Deprecated" n = data.shape[0] total = 0.0 for k in lattice.lattice(self.dim, self.m): for i in range(n): for j in range(n): if j != i: total += self.comp_exp(k, data[i,:])*self.comp_exp(k, data[j,:])*fn(data[j,:]) term2 = 0.0 for k in lattice.lattice(self.dim, self.m): for kp in lattice.lattice(self.dim, self.m): bi = fast_integration(lambda x: np.array(self.comp_exp(k,x))*np.array(self.comp_exp(kp,x))*np.array(fn(x)), [0 for t in range(self.dim)], [1 for t in range(self.dim)]) for i in range(n): for j in range(n): if j != i: term2 += bi*self.comp_exp(k, data[i,:])*self.comp_exp(kp, data[j,:]) return np.real(2.0*total/(n*(n-1)) - 1.0*term2/(n*(n-1)))
def eval(self, fast=True, pts=1000): """ Evaluate the true divergence by performing numeric integration on the n^d grid of points. """ if not fast: print "using slow integration" if self.dim == 1: val = numeric_integration( lambda x: np.multiply( np.power(self.p.eval(np.matrix(x)), self.alpha), np.power(self.q.eval(np.matrix(x)), self.beta)), [lb], [ub]) if self.dim == 2: val = numeric_integration( lambda x, y: np.multiply( # np.power(self.p.eval(np.concatenate(np.matrix(x), np.matrix(y))), self.alpha), # np.power(self.q.eval(np.concatenate(np.matrix(x), np.matrix(y))), self.beta)), np.power( self.p.eval( np.concatenate(np.matrix(x), np.matrix(y))), self.alpha), np.power( self.q.eval( np.concatenate(np.matrix(x), np.matrix(y))), self.beta)), [lb, lb], [ub, ub]) if fast: print "using fast integration" if self.dim == 1: val = fast_integration(lambda x: np.multiply( np.power(self.p.eval(np.matrix(x)), self.alpha), np.power(self.q.eval(np.matrix(x)), self.beta)), [lb], [ub], pts=pts) if self.dim == 2: val = fast_integration( lambda x: np.multiply( np.power(self.p.eval(np.matrix(x)), self.alpha), np.power(self.q.eval(np.matrix(x)), self.beta)), [lb, lb], [ub, ub]) return val
def eval(self, fast=True): """ Evaluate the estimator by performing numeric integration on the n^d grid of points. Currently we ignore the fast parameter -- we are always doing fast numeric integration. """ val = fast_integration(lambda x: np.multiply( np.power(self.Kp.eval(np.matrix(x)), self.alpha), np.power(self.Kq.eval(np.matrix(x)), self.beta)), [lb for i in range(self.dim)], [ub for i in range(self.dim)]) return val
def kde_error(self, true_p, p_norm, fast=True): """ Compute the error of this estimator in ell_p^p norm. """ if fast: integrator = lambda x,y,z: helper.fast_integration(x,y,z) else: integrator = lambda x,y,z: helper.numeric_integration(x,y,z) fn_handle = lambda x: np.power(np.array(np.abs(self.eval(np.matrix(x)) - true_p.eval(np.matrix(x)).reshape(x.shape[0],)))[0,:], p_norm) return integrator(fn_handle, [0.1 for i in range(self.d)], [0.9 for i in range(self.d)])
def eval(self, fast=True): """ Evaluate the estimator by performing numeric integration on the n^d grid of points. Currently we ignore the fast parameter -- we are always doing fast numeric integration. """ val = fast_integration( lambda x: np.multiply( np.power(self.Kp.eval(np.matrix(x)), self.alpha), np.power(self.Kq.eval(np.matrix(x)), self.beta)), [lb for i in range(self.dim)], [ub for i in range(self.dim)]) return val
def kde_error(self, true_p, p_norm, fast=True): """ Compute the error of this estimator in ell_p^p norm. """ if fast: integrator = lambda x, y, z: helper.fast_integration(x, y, z) else: integrator = lambda x, y, z: helper.numeric_integration(x, y, z) fn_handle = lambda x: np.power( np.array( np.abs( self.eval(np.matrix(x)) - true_p.eval(np.matrix(x)). reshape(x.shape[0], )))[0, :], p_norm) return integrator(fn_handle, [0.1 for i in range(self.d)], [0.9 for i in range(self.d)])
def test_quadratic_term_estimator(Dp, ns, iters=10, fast=True): """ Test the quadratic term estimator. """ ms = [] vs = [] T = fast_integration(lambda x: np.array(Dp.eval(x))**2, [0], [1]) print "Truth: %f" % (T) for n in ns: sub_scores = [] for i in range(iters): pdata = Dp.sample(n) Q = estimators.QuadraticEstimator(pdata, pdata, 0.5, 0.5, Dp.s) val = Q.quad_term_slow(lambda x: 1, pdata) val2 = Q.quad_term_fast(lambda x: 1, pdata) print "truth = %0.3f, fast = %0.3f, slow = %0.3f" % (T, val2, val) sub_scores.append(np.abs(val-T)) sub_scores.sort(); sub_scores = sub_scores[int(0.2*iters): int(0.8*iters)]; ms.append(np.mean(sub_scores)) vs.append(np.std(sub_scores)) print "n = %d, av_er = %0.2f, std_er = %0.4f" % (n, np.mean(sub_scores), np.std(sub_scores)) return (ns, ms, vs)
def test_bilinear_term_estimator(Dp, Dq, ns, iters=10, fast=True): """ Test the bilinear functional estimator """ ms = [] vs = [] T = fast_integration(lambda x: np.array(Dp.eval(x))*np.array(Dq.eval(x)), [0], [1]) print "Truth: %f" % (T) for n in ns: sub_scores = [] for i in range(iters): pdata = Dp.sample(n) qdata = Dq.sample(n) Q = estimators.QuadraticEstimator(pdata, pdata, 0.5, 0.5, Dp.s) val = Q.bilinear_term_slow(lambda x: 1, pdata, qdata) val2 = Q.bilinear_term_fast(lambda x: np.matrix(np.ones((x.shape[0], 1))), pdata, qdata) print "truth = %0.3f, slow = %0.3f, fast = %0.3f" % (T, val2, val) sub_scores.append(np.abs(val-T)) sub_scores.sort(); sub_scores = sub_scores[int(0.2*iters): int(0.8*iters)]; ms.append(np.mean(sub_scores)) vs.append(np.std(sub_scores)) print "n = %d, av_er = %0.2f, std_er = %0.4f" % (n, np.mean(sub_scores), np.std(sub_scores)) return (ns, ms, vs)
def test_quadratic_term_estimator(Dp, ns, iters=10, fast=True): """ Test the quadratic term estimator. """ ms = [] vs = [] T = fast_integration(lambda x: np.array(Dp.eval(x))**2, [0], [1]) print "Truth: %f" % (T) for n in ns: sub_scores = [] for i in range(iters): pdata = Dp.sample(n) Q = estimators.QuadraticEstimator(pdata, pdata, 0.5, 0.5, Dp.s) val = Q.quad_term_slow(lambda x: 1, pdata) val2 = Q.quad_term_fast(lambda x: 1, pdata) print "truth = %0.3f, fast = %0.3f, slow = %0.3f" % (T, val2, val) sub_scores.append(np.abs(val - T)) sub_scores.sort() sub_scores = sub_scores[int(0.2 * iters):int(0.8 * iters)] ms.append(np.mean(sub_scores)) vs.append(np.std(sub_scores)) print "n = %d, av_er = %0.2f, std_er = %0.4f" % ( n, np.mean(sub_scores), np.std(sub_scores)) return (ns, ms, vs)
def kde_error(self, true_p, p_norm, pts=1000): """ compute the error of this estimator in ell_p^p norm. """ fn_handle = lambda x: np.power(np.array(np.abs(self.eval(np.matrix(x)) - true_p.eval(np.matrix(x)).reshape(x.shape[0],)))[0,:], p_norm) return helper.fast_integration(fn_handle, [0.0 for i in range(self.d)], [1.0 for i in range(self.d)], pts=pts)