def GI2(n, pi, maxIters=float('inf'), tol=TOL): ''' INPUT: n :: Integer # number of bins pi :: NPArray<Float> # optimal stationary distribution # CAN'T HAVE ANY ZERO ENTRIES! OUTPUT: NPArray<NPArray<Float>> # P^(I) via Gibbs Sampling-inspired Method ''' output = np.zeros([n, n]) # P^(I) for col in xrange(n): output[:, col] = np.transpose(genStat(n)) ev = corrEv(output) indices = range(n) while not listMatch(np.dot(output, ev), pi) and maxIters > 0: # s1, loop # s2, isolate alterRow = np.random.choice(indices, size=[2], replace=False).astype(int) alterCol = np.random.choice(indices, size=[2], replace=False).astype(int) alterRow = np.array([min(alterRow), max(alterRow) ]) # sort in order of lowest to highest alterCol = np.array([min(alterCol), max(alterCol) ]) # sort in order of lowest to highest subpi = np.zeros(2) subpi[0] = pi[alterRow[0]] subpi[1] = pi[alterRow[1]] # s3b, note how much space was formerly taken up resMass_mat = (output[alterRow[0]][alterCol[0]] + output[alterRow[1]][alterCol[0]], \ output[alterRow[0]][alterCol[1]] + output[alterRow[1]][alterCol[1]]) resMass_pi = sum(subpi) # s3, normalize subpi /= sum(subpi) # s4, optimize extracted 2-equation system submat = brS(n, subpi) # !!! Use bS, rS, brS methods. !!! # s5a, denormalize submat[:, 0] *= resMass_mat[0] submat[:, 1] *= resMass_mat[1] subpi *= resMass_pi # s5, substitute in new values renormalized to Q output[alterRow[0]][alterCol[0]] = submat[0][0] output[alterRow[1]][alterCol[0]] = submat[1][0] output[alterRow[0]][alterCol[1]] = submat[0][1] output[alterRow[1]][alterCol[1]] = submat[1][1] ev = corrEv(output) maxIters -= 1 return output
def patch(n): ''' Deterministic patch generator ''' for i in range(n - 1): for j in range(n - 1): yield np.array([[i, i + 1], [j, j + 1]]).astype(int)
def Series(N, n, indMat): ''' INPUT: N :: Integer # number of people n :: Integer # number of bins indMat :: List<List<Float>> # individual matrix OUTPUT: List<List<Float>> # mass matrix according to my generalized series formula (without Java speedup) ''' sl = wc_count(N, n) # side length print 'Progress:' output = np.zeros([sl, sl]) n0s = np.zeros([n, n]) i = 0 # current row index for Ti in weak_compositions(N, n): # rows of mass matrix (s^(2)) j = 0 # current column index for Tj in weak_compositions(N, n): # columns of mass matrix (s^(1)) b1 = 0 # block 1 for scwc in p_wc( np.array(Tj), n, np.array(Ti)): # loop over successively-constrained wcs b2 = 1 # block 2 for d_idx, donor in enumerate(Tj): if donor > 0: b2 *= mn(donor, scwc[d_idx]) for t in xrange(n): # block 3 b2 *= indMat[t][d_idx]**scwc[d_idx][t] b1 += b2 output[i][j] = b1 j += 1 i += 1 print 100.0 * float(i) / float(sl), '%' # progress output return output
def buildVectList(size, mat): ''' INPUT: size :: Integer # n mat :: List<List<Integer>> # individual matrix OUTPUT: List< Tuple< List<Integer>, Float > > # first index is permutation of (n-2)*0,1,-1, next is P[source -> sink] ''' output = [] for perm in iter(permute([1, -1] + [0] * (size - 2))): oneIdx = perm.index(1) negOneIdx = perm.index(-1) output.append((np.array(perm), mat[oneIdx][negOneIdx])) return output
def p_wc(ls, n, initial_maxs, initial_output=[], currIdx=0): ''' INPUT: ls :: NPArray<Integer> n :: Integer # len(ls) initial_maxs :: NPArray<Integer> # should have length len(ls) OUTPUT: generated List<NPArray<Integer>> # a successively bounded wc list as generated ''' n0s = np.zeros(n) if currIdx == n or ls == [] or listMatch(initial_maxs, n0s): yield initial_output else: for bwc in bounded_wcs(ls[currIdx], n, n0s, initial_maxs): next_wc = np.array(bwc).astype(int) i_o = deepcopy(initial_output) i_o.append(next_wc) for x in p_wc(ls, n, initial_maxs - next_wc, i_o, currIdx + 1): yield x
def VSEA(N, n, indMC): # non-unique, identity-less individuals ''' INPUT: N :: Integer # number of people n :: Integer # number of bins indMC :: NPArray<NPArray<Float>> # individual matrix OUTPUT: List<List<Float>> # mass matrix ''' # # Block A # sl = int(comb(N + n - 1, n - 1)) # side length output = np.zeros([sl, sl]) TESTLIST = [] vectList = buildVectList(n, indMC) # lacks 0 vectors zeroVect = np.zeros(n) # # Block B # i = 0 # current row index for Ti in weak_compositions(N, n): # rows of mass matrix print 'Progress:', 100.0 * float(sl * i) / float(sl**2), '%' j = 0 # current column index for Tj in weak_compositions(N, n): # columns of mass matrix # # Block C # diff = np.array(Tj) - np.array( Ti) # Prospective state transition: Tj -> Ti vectList_copy = deepcopy(vectList) # add 0 vectors to vectList max_0s_per_bin = [] for bn in xrange(n): max_0s_per_bin.append(min(Tj[bn], Ti[bn])) if Tj[bn] > 0 and Ti[bn] > 0: vectList_copy.append((np.zeros(n), indMC[bn][bn], bn)) # # Block D # # get every way of allotting N tokens across all vectors in vectList lvlc = len(vectList_copy) transition_prob_terms = [] for wc in weak_compositions( N, lvlc ): # N = number of tokens, lvlc = number of vectors available sum_vect = np.zeros(n) breakIt = False static_in_bin = np.zeros( n) # number of people staying in their bin possibly_correct_vects = [ ] # :: List<Tuple< vector, prob, number_of_times_used, idx0 >> # idx0 if 0 vect, gives corresponding diagonal index of particular 0 vect for vectTup_idx in xrange(lvlc): if wc[vectTup_idx] > 0: #check if vector is used # check if too many of the same zero vector has been invoked if listMatch( vectList_copy[vectTup_idx][0], zeroVect): # when we encounter a zero vector static_in_bin[vectList_copy[vectTup_idx] [2]] += wc[vectTup_idx] if max_0s_per_bin[vectList_copy[vectTup_idx] [2]] < wc[vectTup_idx]: breakIt = True # too many of the same zero vector has been invoked break sum_vect += float( wc[vectTup_idx]) * vectList_copy[vectTup_idx][0] possibly_correct_vects.append( (vectList_copy[vectTup_idx][0], vectList_copy[vectTup_idx][1], wc[vectTup_idx])) if breakIt: # skip to next wc continue # # Block E # if listMatch( diff, sum_vect ): # check if current weak composition wc of vectors equals diff # coefficient determination leaving = np.zeros(n) entering = {} prod = 1 for pre_pvs in possibly_correct_vects: pvs = np.ndarray.tolist(pre_pvs[0]) if not listMatch( pvs, zeroVect ): # when we DON'T encounter a zero vector for bi in xrange(n): if pvs[bi] == -1: leaving[bi] += pre_pvs[2] if bi not in entering: entering[bi] = np.zeros(n) entering[bi][pvs.index(1)] += pre_pvs[2] break # jump to next pre_pvs # check if too many people are leaving a bin <-- REALLY HACKY! >:( for bi in xrange(n): if leaving[bi] + static_in_bin[bi] > Ti[bi]: breakIt = True break if breakIt: # skip to next wc continue # # Block F # prod *= allotCombos(Ti, leaving, entering) # get coefficient # get P^I probabilities that correspond to selected basis vectors # get exponents for all probabilities that correspond to the # quantities of each of their respective basis vector pvstEST = 1 for pvs in possibly_correct_vects: prod *= pvs[1]**pvs[2] pvstEST *= pvs[1]**pvs[2] transition_prob_terms.append( prod ) # this is just one term that contributes to one entry in the mass matrix output[j][i] = sum(transition_prob_terms) j += 1 # add element to mass matrix i += 1 return output
cp[1][0]:(cp[1][1] + 1)] = brS(2, pi[cp[0]] / s) A += Ai output = A / Z return output, L(output), M(output) print '\nRUNNING AVG:\n' errors = [] errors2 = [] b1 = 2 b2 = 11 for i in range(b1, b2): errors.append(AVG(i, genStat(i))[1]) errors2.append(AVG(i, genStat(i))[2]) e = np.array(errors) e2 = np.array(errors2) print e print e2 print sum(e) / float(b2 - b1) print sum(e2) / float(b2 - b1) # errors = [] # errors2 = [] # b = 10 # L = lambda mat, pi: np.linalg.norm(np.dot(mat, pi) - pi) # M = lambda mat, pi: np.linalg.norm(corrEv(mat) - pi) # for _ in range(b): # pi = genStat(2) # errors.append(L(brS(2, pi), pi)) # errors2.append(M(brS(2, pi), pi))