예제 #1
0
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
예제 #2
0
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)
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
           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))