class EstStatsTh(ExpSwitcher): ''' ''' def init(self, boot_spec): ExpSwitcher.init(self, boot_spec) # TODO: check float if len(boot_spec.get_observations().shape()) != 1: raise UnsupportedSpec('I assume 2D signals.') self.yy = Expectation() self.ylogy = Expectation() self.einvy = Expectation() self.ey = Expectation() self.elogy = Expectation() self.covy = MeanCovariance() self.covfy = MeanCovariance() def merge(self, other): self.yy.merge(other.yy) self.ylogy.merge(other.ylogy) self.einvy.merge(other.einvy) self.ey.merge(other.ey) self.elogy.merge(other.elogy) self.covy.merge(other.covy) self.covfy.merge(other.covfy) def process_observations(self, obs): y = obs['observations'] n = y.size # # XXX # which = np.array(range(y.size)) < 100 # y[which] = (y * y)[which] dt = obs['dt'].item() z = y == 0 y[z] = 0.5 yy = outer(y, y) dt = 1 logy = np.log(y) # TMP logy = y * y # logy[:int(n / 4)] = y[:int(n / 4)] ylogy = outer(logy, y) self.yy.update(yy, dt) self.ylogy.update(ylogy, dt) invy = 1.0 / y self.einvy.update(invy, dt) self.ey.update(y, dt) self.elogy.update(logy, dt) self.covy.update(y, dt) self.covfy.update(logy, dt) def publish(self, pub): # pub.text('warn', 'using y^3') yy = self.yy.get_value() ylogy = self.ylogy.get_value() def symmetrize(x): return 0.5 * (x + x.T) yy = symmetrize(yy) ylogy = symmetrize(ylogy) with pub.subsection('yy') as sub: sub.array_as_image('val', yy) pub_svd_decomp(sub, yy) pub_eig_decomp(sub, yy) with pub.subsection('ylogy') as sub: sub.array_as_image('ylogy', ylogy) pub_svd_decomp(sub, ylogy) pub_eig_decomp(sub, ylogy) f = pub.figure() with f.plot('both') as pylab: pylab.plot(yy.flat, ylogy.flat, '.') pylab.xlabel('yy') pylab.ylabel('ylogy') pylab.axis('equal') D = get_deriv_matrix(yy.shape[0]) inv = np.linalg.inv(yy) x = np.dot(ylogy, inv) f.array_as_image('inv', inv) f.array_as_image('ylogy_times_inverse', x) f.array_as_image('D', D) f.array_as_image('Dlog', np.dot(D, x)) diag = np.diag(x) einvy = self.einvy.get_value() elogy = self.elogy.get_value() ey = self.ey.get_value() f = pub.figure() with f.plot('einvy', caption='E{1/y}') as pylab: pylab.plot(einvy, 's') y_axis_set_min(pylab, 0) with f.plot('elogy', caption='E{logy}') as pylab: pylab.plot(elogy, 's') # y_axis_set_min(pylab, 0) with f.plot('ey', caption='E{y}') as pylab: pylab.plot(ey, 's') y_axis_set_min(pylab, 0) with f.plot('diag', caption='diagonal of x') as pylab: pylab.plot(diag, 's')
class MeanCovariance(object): ''' Computes mean and covariance of a quantity ''' def __init__(self, max_window=None): self.mean_accum = Expectation(max_window) self.covariance_accum = Expectation(max_window) self.minimum = None self.maximum = None # TODO: use class self.num_samples = 0 def merge(self, other): warnings.warn('To test') assert isinstance(other, MeanCovariance) self.mean_accum.merge(other.mean_accum) self.covariance_accum.merge(other.covariance_accum) self.num_samples += other.num_samples warnings.warn('minimum/maximum missing') def get_num_samples(self): return self.num_samples def update(self, value, dt=1.0): self.num_samples += dt n = value.size if self.maximum is None: self.maximum = value.copy() self.minimum = value.copy() self.P_t = np.zeros(shape=(n, n), dtype=value.dtype) else: # TODO: check dimensions if not (value.shape == self.maximum.shape): raise ValueError('Value shape changed: %s -> %s' % (self.maximum.shape, value.shape)) self.maximum = np.maximum(value, self.maximum) self.minimum = np.minimum(value, self.minimum) self.mean_accum.update(value, dt) mean = self.mean_accum.get_value() value_norm = value - mean P = outer(value_norm, value_norm) self.covariance_accum.update(P, dt) self.last_value = value def assert_some_data(self): if self.num_samples == 0: raise Exception('Never updated') def get_mean(self): self.assert_some_data() return self.mean_accum.get_value() def get_maximum(self): self.assert_some_data() return self.maximum def get_minimum(self): self.assert_some_data() return self.minimum def get_covariance(self): self.assert_some_data() return self.covariance_accum.get_value() def get_correlation(self): self.assert_some_data() corr = cov2corr(self.covariance_accum.get_value()) np.fill_diagonal(corr, 1) return corr def get_information(self, rcond=1e-2): self.assert_some_data() try: P = self.get_covariance() return pinv(P, rcond=rcond) except LinAlgError: filename = 'pinv-failure' import pickle with open(filename + '.pickle', 'w') as f: pickle.dump(self, f)