class Embed(ExpSwitcher): def __init__(self, statistic='y_corr', scale_score=False, **kwargs): # @UnusedVariable ExpSwitcher.__init__(self, **kwargs) self.statistic = statistic self.scale_score = False def init(self, boot_spec): ExpSwitcher.init(self, boot_spec) if len(boot_spec.get_observations().shape()) != 1: raise UnsupportedSpec('I assume 1D signals.') self.y_stats = MeanCovariance() self.y_dot_stats = MeanCovariance() self.y_dot_sgn_stats = MeanCovariance() self.y_dot_abs_stats = MeanCovariance() self.count = 0 self.y_deriv = DerivativeBox() def get_similarity(self, which): if which == 'y_corr': return self.y_stats.get_correlation() if which == 'y_dot_corr': return self.y_dot_stats.get_correlation() if which == 'y_dot_sgn_corr': return self.y_dot_sgn_stats.get_correlation() if which == 'y_dot_abs_corr': return self.y_dot_abs_stats.get_correlation() raise ValueError() # check_contained(statistic, self.statistics, 'statistic') def process_observations(self, obs): y = obs['observations'] dt = obs['dt'].item() self.y_deriv.update(y, dt) if self.y_deriv.ready(): y, y_dot = self.y_deriv.get_value() self.y_stats.update(y, dt) self.y_dot_stats.update(y_dot, dt) self.y_dot_sgn_stats.update(np.sign(y_dot), dt) self.y_dot_abs_stats.update(np.abs(y_dot), dt) self.count += 1 def get_S(self, dimensions=2, pub=None): similarity = self.get_similarity(self.statistic) if pub is not None: pub.array_as_image('similarity', similarity, caption='Similarity statistic') plot_spectrum(pub, 'similarity', similarity) if self.scale_score: R = scale_score(similarity).astype('float32') R = R / R.max() if pub is not None: pub.array_as_image('scale_score', R) else: R = similarity D = 1 - R D = D * np.pi / D.max() np.fill_diagonal(D, 0) if pub is not None: # pub.array_as_image('D', D) P = D * D B = double_center(P) # plot_spectrum(pub, 'D', D) # plot_spectrum(pub, 'P', P) plot_spectrum(pub, 'B', B) S = mds(D, ndim=dimensions) # S = inner_product_embedding(similarity, 3) # S = S[1:3, :] return S def get_S_discrete(self, dimensions=2, pub=None): R = self.y_dot_abs_stats.get_correlation() Dis = discretize(-R, 2) np.fill_diagonal(Dis, 0) R = R * R C = np.maximum(R, 0) if pub is not None: pub.array_as_image('Dis', Dis) pub.array_as_image('R', R) pub.array_as_image('C', C) S = inner_product_embedding(Dis, dimensions) # for i in range(R.shape[0]): # R[i, i] = np.NaN # C[i, i] = np.NaN return S def publish(self, pub): if self.count < 10: pub.text('warning', 'Too early to publish anything.') return pub.text('info', 'Using statistics: %s' % self.statistic) if False: # TODO: make option S = self.get_S_discrete(2, pub=pub.section('computation')) else: S = self.get_S(2, pub=pub.section('computation')) with pub.plot('S') as pylab: style_ieee_halfcol_xy(pylab) pylab.plot(S[0, :], S[1, :], 's') with pub.plot('S_joined') as pylab: style_ieee_halfcol_xy(pylab) pylab.plot(S[0, :], S[1, :], '-') self.y_stats.publish(pub.section('y_stats')) self.y_dot_stats.publish(pub.section('y_dot_stats')) self.y_dot_sgn_stats.publish(pub.section('y_dot_sgn_stats')) self.y_dot_abs_stats.publish(pub.section('y_dot_abs_stats'))
class EstStats(ExpSwitcher): ''' A simple agent that estimates various statistics of the observations. ''' def init(self, boot_spec): ExpSwitcher.init(self, boot_spec) if len(boot_spec.get_observations().shape()) != 1: raise UnsupportedSpec('I assume 1D signals.') self.y_stats = MeanCovariance() def merge(self, other): self.y_stats.merge(other.y_stats) def process_observations(self, obs): y = obs['observations'] dt = obs['dt'].item() self.y_stats.update(y, dt) def get_state(self): return dict(y_stats=self.y_stats) def set_state(self, state): self.y_stats = state['y_stats'] def publish(self, pub): if self.y_stats.get_num_samples() == 0: pub.text('warning', 'Too early to publish anything.') return Py = self.y_stats.get_covariance() Ry = self.y_stats.get_correlation() Py_inv = self.y_stats.get_information() Ey = self.y_stats.get_mean() y_max = self.y_stats.get_maximum() y_min = self.y_stats.get_minimum() Ry0 = Ry.copy() np.fill_diagonal(Ry0, np.NaN) Py0 = Py.copy() np.fill_diagonal(Py0, np.NaN) pub.text('stats', 'Num samples: %s' % self.y_stats.get_num_samples()) with pub.plot('y_bounds') as pylab: style_ieee_fullcol_xy(pylab) pylab.plot(Ey, label='E(y)') pylab.plot(y_max, label='y_max') pylab.plot(y_min, label='y_min') pylab.legend() all_positive = (np.min(Ey) > 0 and np.min(y_max) > 0 and np.min(y_min) > 0) if all_positive: with pub.plot('y_stats_log') as pylab: style_ieee_fullcol_xy(pylab) pylab.semilogy(Ey, label='E(y)') pylab.semilogy(y_max, label='y_max') pylab.semilogy(y_min, label='y_min') pylab.legend() pub.array_as_image('Py', Py, caption='cov(y)') pub.array_as_image('Py0', Py0, caption='cov(y) - no diagonal') pub.array_as_image('Ry', Ry, caption='corr(y)') pub.array_as_image('Ry0', Ry0, caption='corr(y) - no diagonal') pub.array_as_image('Py_inv', Py_inv) pub.array_as_image('Py_inv_n', cov2corr(Py_inv)) with pub.plot('Py_svd') as pylab: # XXX: use spectrum style_ieee_fullcol_xy(pylab) _, s, _ = np.linalg.svd(Py) s /= s[0] pylab.semilogy(s, 'bx-') with pub.subsection('y_stats') as sub: self.y_stats.publish(sub)