|  |  |  | import numpy as np
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RunningStat():
 | 
					
						
							|  |  |  |   # tracks realtime mean and standard deviation without storing any data
 | 
					
						
							|  |  |  |   def __init__(self, priors=None, max_trackable=-1):
 | 
					
						
							|  |  |  |     self.max_trackable = max_trackable
 | 
					
						
							|  |  |  |     if priors is not None:
 | 
					
						
							|  |  |  |       # initialize from history
 | 
					
						
							|  |  |  |       self.M = priors[0]
 | 
					
						
							|  |  |  |       self.S = priors[1]
 | 
					
						
							|  |  |  |       self.n = priors[2]
 | 
					
						
							|  |  |  |       self.M_last = self.M
 | 
					
						
							|  |  |  |       self.S_last = self.S
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else:
 | 
					
						
							|  |  |  |       self.reset()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def reset(self):
 | 
					
						
							|  |  |  |     self.M = 0.
 | 
					
						
							|  |  |  |     self.S = 0.
 | 
					
						
							|  |  |  |     self.M_last = 0.
 | 
					
						
							|  |  |  |     self.S_last = 0.
 | 
					
						
							|  |  |  |     self.n = 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def push_data(self, new_data):
 | 
					
						
							|  |  |  |     # short term memory hack
 | 
					
						
							|  |  |  |     if self.max_trackable < 0 or self.n < self.max_trackable:
 | 
					
						
							|  |  |  |       self.n += 1
 | 
					
						
							|  |  |  |     if self.n == 0:
 | 
					
						
							|  |  |  |       self.M_last = new_data
 | 
					
						
							|  |  |  |       self.M = self.M_last
 | 
					
						
							|  |  |  |       self.S_last = 0.
 | 
					
						
							|  |  |  |     else:
 | 
					
						
							|  |  |  |       self.M = self.M_last + (new_data - self.M_last) / self.n
 | 
					
						
							|  |  |  |       self.S = self.S_last + (new_data - self.M_last) * (new_data - self.M)
 | 
					
						
							|  |  |  |       self.M_last = self.M
 | 
					
						
							|  |  |  |       self.S_last = self.S
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def mean(self):
 | 
					
						
							|  |  |  |     return self.M
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def variance(self):
 | 
					
						
							|  |  |  |     if self.n >= 2:
 | 
					
						
							|  |  |  |       return self.S / (self.n - 1.)
 | 
					
						
							|  |  |  |     else:
 | 
					
						
							|  |  |  |       return 0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def std(self):
 | 
					
						
							|  |  |  |     return np.sqrt(self.variance())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def params_to_save(self):
 | 
					
						
							|  |  |  |     return [self.M, self.S, self.n]
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class RunningStatFilter():
 | 
					
						
							|  |  |  |   def __init__(self, raw_priors=None, filtered_priors=None, max_trackable=-1):
 | 
					
						
							|  |  |  |     self.raw_stat = RunningStat(raw_priors, -1)
 | 
					
						
							|  |  |  |     self.filtered_stat = RunningStat(filtered_priors, max_trackable)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def reset(self):
 | 
					
						
							|  |  |  |     self.raw_stat.reset()
 | 
					
						
							|  |  |  |     self.filtered_stat.reset()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   def push_and_update(self, new_data):
 | 
					
						
							|  |  |  |     _std_last = self.raw_stat.std()
 | 
					
						
							|  |  |  |     self.raw_stat.push_data(new_data)
 | 
					
						
							|  |  |  |     _delta_std = self.raw_stat.std() - _std_last
 | 
					
						
							|  |  |  |     if _delta_std <= 0:
 | 
					
						
							|  |  |  |       self.filtered_stat.push_data(new_data)
 | 
					
						
							|  |  |  |     else:
 | 
					
						
							|  |  |  |       pass
 | 
					
						
							|  |  |  |       # self.filtered_stat.push_data(self.filtered_stat.mean())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # class SequentialBayesian():
 |