def iterate_distributions(self,indices,k): """ Iterate a number of distributions k steps from their last iteration. This is the core method for iterating distributions to stationarity. It will automatically set the stationary distribution if it is previously unknown and reached during the iteration. indices: list containing indices of distributions to be iterated k: number of iterations to perform """ x = [] for i in indices: x.append(self.get_last_iteration(i)) # invoke the external method performing the iteration y = mkm.iterate_distributions(self.p,numpy.array(x),k) for idx, val in enumerate(indices): self.add_iteration(val,self.last_iteration_time(val)+k,y[idx,:]) # did we find the stationary distribution? # determine this by checking the defintion of stationarity # selecting the number of iterations and the threshold is a numerical task if not(self.stationary_distribution_known()): for i in indices: last = self.get_last_iteration(i) last_iterated = mkm.iterate_distributions(self.p,last,100) # 1e-6 is a good threshold? if mkm.relative_error(last,last_iterated) < 1e-6: self.sd = last
def iterate_distributions(self, indices, k, tv_tol=0.05): """ Iterate a number of distributions k steps from their last iteration. This is the core method for iterating distributions to stationarity. If the number of distributions is >= 3, it will automatically set the stationary distribution, if unknown and found. indices: list containing indices of distributions to be iterated k: number of iterations to perform """ x = [] for i in indices: x.append(self.get_last_iteration(i)) # invoke the external method performing the iteration y = mkm.iterate_distributions(self.p, numpy.array(x), k) for idx, val in enumerate(indices): self.add_iteration(val, self.last_iteration_time(val) + k, y[idx, :]) # check if we found the stationary distribution if len(indices) >= 3: # first check the definition of stationarity for all iterations for i in indices: last = self.get_last_iteration(i) last_iterated = mkm.iterate_distributions(self.p, last, 100) # is 1e-6 a good threshold? (however this can never be trusted -> cutoff) if mkm.relative_error(last, last_iterated) > 1e-6: return # check pairwise distance <= tol for i in indices: d_i = self.get_last_iteration(i) for j in indices: d_j = self.get_last_iteration(j) if mkm.total_variation(d_i, d_j) > tv_tol: return # take the arithmetic mean of all iterations as the stationary distribution stationary_candidate = numpy.zeros(self.n) for i in indices: stationary_candidate = stationary_candidate + self.get_last_iteration( i) stationary_candidate = stationary_candidate / len(indices) self.set_stationary(stationary_candidate)
def iterate_distributions(self,indices,k,tv_tol=0.05): """ Iterate a number of distributions k steps from their last iteration. This is the core method for iterating distributions to stationarity. If the number of distributions is >= 3, it will automatically set the stationary distribution, if unknown and found. indices: list containing indices of distributions to be iterated k: number of iterations to perform """ x = [] for i in indices: x.append(self.get_last_iteration(i)) # invoke the external method performing the iteration y = mkm.iterate_distributions(self.p,numpy.array(x),k) for idx, val in enumerate(indices): self.add_iteration(val,self.last_iteration_time(val)+k,y[idx,:]) # check if we found the stationary distribution if len(indices) >= 3: # first check the definition of stationarity for all iterations for i in indices: last = self.get_last_iteration(i) last_iterated = mkm.iterate_distributions(self.p,last,100) # is 1e-6 a good threshold? (however this can never be trusted -> cutoff) if mkm.relative_error(last,last_iterated) > 1e-6: return # check pairwise distance <= tol for i in indices: d_i = self.get_last_iteration(i) for j in indices: d_j = self.get_last_iteration(j) if mkm.total_variation(d_i, d_j) > tv_tol: return # take the arithmetic mean of all iterations as the stationary distribution stationary_candidate = numpy.zeros(self.n) for i in indices: stationary_candidate = stationary_candidate + self.get_last_iteration(i) stationary_candidate = stationary_candidate / len(indices) self.set_stationary(stationary_candidate)
def tets_distributions(): # not distributions d = numpy.ones((3,3)) assert(mkm.is_distribution(d) == False) d = mkm.delta_distribution(10) d[1] = 1 assert(mkm.is_distribution(d) == False) assert(mkm.is_distribution(mkm.delta_distribution(10),n=11) == False) assert(mkm.is_distribution(mkm.delta_distribution(10),n=10) == True) assert(mkm.relative_error(numpy.array([0.0001,1,1e-16]),numpy.array([0.001,1,1e-16]))>8.0)