Example #1
0
def brS(n, pi, iters=float('inf'), tol=TOL):
    '''
	INPUT:
		n :: Integer
			# number of bins
		pi :: NPArray<Float>
			# optimal stationary distribution
	OUTPUT:
		NPArray<NPArray<Float>>
			# P^(I) via Binary-Random Search Method
			# only works in 2x2 case
			# BECAUSE IT'S 2x2 CASE I CAN USE 2x2 P^(M) SERIES FORMULA
	'''
    output = np.ones([2, 2]) * .5  # P^(I)
    ev = corrEv(output)
    b1 = 0.0 if pi[0] >= pi[1] else 1.0 - (pi[0] / pi[1])
    b2 = 1.0
    output[1][1] = np.average([b1, b2])
    output = resMat(output)
    while not listMatch(np.dot(output, ev), pi,
                        tol=tol) and iters > 0:  # s1, loop
        # look for random number within updated b1, b2
        if ev[1] < pi[1]:
            b1 = np.average([b1, b2])
            output[1][1] += next_term(b1, b2)
        else:
            b2 = np.average([b1, b2])
            output[1][1] -= next_term(b1, b2)
        output[0][0] = p22p1(output[1][1], pi)
        output = resMat(output)
        ev = corrEv(output)
        iters -= 1
    return output
Example #2
0
def GRS(n, pi, maxIters=float('inf'), tol=TOL):
    '''
	INPUT:
		N :: Integer
			# population size
		n :: Integer
			# number of bins
		pi :: NPArray<Float>
			# optimal stationary distribution
	OUTPUT:
		NPArray<NPArray<Float>>
			# P^(I) via Greedy Random Search Method
	'''
    # initialization and normalization
    if maxIters == None:
        maxIters = n * 100000
    output = np.random.random((n, n))
    for col in xrange(n):
        output[:, col] /= sum(output[:, col])
    out = np.linalg.eig(output)
    ev = corrEv(out[1])
    while not listMatch(np.dot(output, pi), pi) and maxIters != 0:  # Step 2
        a = np.random.randint(0, high=n)  # Step 3
        c = 0.45 * float((2 * int(ev[a] < pi[a]) - 1))  # Step 4
        # Step 5
        output[a,a] = output[a,a]*(int((1.0+c)*output[a,a] > 1.0)+int(abs((1.0+c)*output[a,a]) < tol)) \
         + (1.0+c)*output[a,a]*int((1.0+c)*output[a,a] <= 1.0)*int((1.0+c)*output[a,a] > 0.0)
        output[:, a] /= sum(output[:, a])  # Step 6
        out = np.linalg.eig(output)  # preparation for Step 2
        ev = corrEv(out[1])  # preparation for Step 2
        maxIters -= 1  # Step 7
    return output  # Step 8
Example #3
0
def rS(n, pi, iters=float('inf'), tol=TOL):
	'''
	INPUT:
		n :: Integer
			# number of bins
		pi :: NPArray<Float>
			# optimal stationary distribution
	OUTPUT:
		NPArray<NPArray<Float>>
			# P^(I) via Random Search Method
			# only works in 2x2 case
			# BECAUSE IT'S 2x2 CASE I CAN USE 2x2 P^(M) SERIES FORMULA
	'''
	output = np.zeros([2,2]) # P^(I)
	for col in xrange(2):
		output[:,col] = np.transpose(genStat(2))
	ev = corrEv(output)
	b1 = 0.0 if pi[0] >= pi[1] else 1.0-(pi[0]/pi[1])
	b2 = 1.0
	output[1][1] = np.average([b1,b2])
	output = resMat(output)
	while not listMatch(np.dot(output, ev), pi, tol=tol) and iters > 0: # s1, loop
		output[1][1] = (b2-b1)*np.random.random()+b1
		output[0][0] = p22p1(output[1][1], pi) # calculate p_11
		output = resMat(output) # calculate p_12, p_21
		ev = corrEv(output)
		iters -= 1
	return output
Example #4
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
Example #5
0
def NRS(n, pi, iterCols=float('inf'), iterInCol=10000, tol=TOL):
	'''
	INPUT:
		n :: Integer
			# number of bins
		pi :: NPArray<Float>
			# optimal stationary distribution
	OUTPUT:
		NPArray<NPArray<Float>>
			# P^(I) via Naive Random Search Method
	'''
	# initialization and normalization
	if iterCols == None:
		iterCols = n*10000
	output = np.random.random((n,n))
	for col in xrange(n):
		output[:,col] /= sum(output[:,col])
	out = np.linalg.eig(output)
	n0s = np.zeros(n)
	totalIts = iterCols; totalItsIn = iterInCol
	while (not abs(out[0][0] - 1.0) < tol or not listMatch(out[1][:,0], pi)) and iterCols!=0:
		for col in xrange(n):
			p_old = n0s
			iterInCol = totalItsIn
			temp = output
			while not listMatch(output[:,col], p_old) and iterInCol!=0:
				next_try = np.random.random((n,))
				next_try /= sum(next_try) # Line 5 in LaTeX
				temp[:,col] = next_try
				out = np.linalg.eig(temp)
				if np.linalg.norm(out[1][:,0] - pi)**2 < np.linalg.norm(p_old - pi)**2:
					output = temp
					p_old = output[:,col]
				iterInCol -= 1
		out = np.linalg.eig(output)
		iterCols -= 1
	return output
Example #6
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
Example #7
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
Example #8
0
 varis = [[0] * (MAX_PIS - START_CASE) for y in xrange(len(TEST_F) - 1)]
 for f in xrange(len(TEST_F) - 1):
     print '\nFUNCTION:', f
     for case in xrange(START_CASE, MAX_PIS):
         print '\t\tn_VALUE:', case
         TO_AVG = [
         ]  # we will average the values in this array to get the per function per epsilon per test-case average runtime
         for x in xrange(
                 NUM_TIMES):  # we'll average time for each test here
             test_stat = genStat(case)
             start = time()
             print '\t\t\tTRIAL:', x, ', pi_VALUE:', test_stat
             print results
             r = TEST_F[f](case, test_stat)
             print 'RESULT:', r
             print 'Worked?:', listMatch(np.dot(r, test_stat), test_stat)
             TO_AVG.append(time() - start)
         results[f][case - START_CASE] = np.average(TO_AVG)
         varis[f][case - START_CASE] = np.var(TO_AVG)
 results.append(vecexp(range(START_CASE,
                             MAX_PIS)))  # get expected runtime of GI
 varis.append([None])
 print '\n', D
 res = np.array(results)
 v = np.array(varis)
 for f in xrange(len(TEST_F)):
     print '\nRESULTS for FUNCTION', f
     print res[f]
     print 'VARIANCES for FUNCTION', f
     print v[f]
 # only LP