def testIsotypePartition(tensor): """Test that the components of tensor add up to tensor, that projecting them again the same way leaves them unchanged, and that projecting them differently leaves them zero""" #print("---") total = np.zeros_like(tensor, dtype="float64") for pp in partitions(tensor.ndim): p = IntegerPartition(pp).partition t=project(tensor, p) #print (p) #print(";") #print(t) #print(t-project(t,p)) #print(project(t,p)) assert np.allclose(t,project(t,p)) #print(tensor,total,t) total += t for qq in partitions(tensor.ndim): q=IntegerPartition(qq).partition if q!=p: #print(p,q) #print(project(t,q)) assert np.allclose(0,project(t,q)) #print(".") #print(tensor) #print(total) assert np.allclose(tensor,total) print("test ok")
def test_partitions(): assert [p.copy() for p in partitions(6, k=2)] == [ {2: 3}, {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=3)] == [ {3: 2}, {1: 1, 2: 1, 3: 1}, {1: 3, 3: 1}, {2: 3}, {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=2, m=2)] == [] assert [p.copy() for p in partitions(8, k=4, m=3)] == [ {4: 2}, {1: 1, 3: 1, 4: 1}, {2: 2, 4: 1}, {2: 1, 3: 2}] == [ i.copy() for i in partitions(8, k=4, m=3) if all(k <= 4 for k in i) and sum(i.values()) <=3] assert [p.copy() for p in partitions(S(3), m=2)] == [ {3: 1}, {1: 1, 2: 1}] assert [i.copy() for i in partitions(4, k=3)] == [ {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] == [ i.copy() for i in partitions(4) if all(k <= 3 for k in i)] raises(ValueError, lambda: list(partitions(3, 0))) # Consistency check on output of _partitions and RGS_unrank. # This provides a sanity test on both routines. Also verifies that # the total number of partitions is the same in each case. # (from pkrathmann2) for n in range(2, 6): i = 0 for m, q in _set_partitions(n): assert q == RGS_unrank(i, n) i = i+1 assert i == RGS_enum(n)
def test_partitions(): assert [p.copy() for p in partitions(6, k=2)] == [{2: 3}, \ {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=3)] == [{3: 2}, \ {1: 1, 2: 1, 3: 1}, {1: 3, 3: 1}, {2: 3}, {1: 2, 2: 2}, \ {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=2, m=2)] == [] assert [p.copy() for p in partitions(8, k=4, m=3)] == [{4: 2},\ {1: 1, 3: 1, 4: 1}, {2: 2, 4: 1}, {2: 1, 3: 2}]
def test_partitions(): assert [p.copy() for p in partitions(6, k=2)] == [{2: 3}, \ {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=3)] == [{3: 2}, \ {1: 1, 2: 1, 3: 1}, {1: 3, 3: 1}, {2: 3}, {1: 2, 2: 2}, \ {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=2, m=2)] == [] assert [p.copy() for p in partitions(8, k=4, m=3)] == [{4: 2},\ {1: 1, 3: 1, 4: 1}, {2: 2, 4: 1}, {2: 1, 3: 2}] assert [p.copy() for p in partitions(S(3), 2)] == \ [{3: 1}, {1: 1, 2: 1}] raises(ValueError, 'list(partitions(3, 0))')
def test_uniq(): assert list(uniq(p.copy() for p in partitions(4))) == [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] assert list(uniq(x % 2 for x in range(5))) == [0, 1] assert list(uniq("a")) == ["a"] assert list(uniq("ababc")) == list("abc") assert list(uniq([[1], [2, 1], [1]])) == [[1], [2, 1]] assert list(uniq(permutations(i for i in [[1], 2, 2]))) == [([1], 2, 2), (2, [1], 2), (2, 2, [1])] assert list(uniq([2, 3, 2, 4, [2], [1], [2], [3], [1]])) == [2, 3, 4, [2], [1], [3]]
def test_uniq(): assert list(uniq(p.copy() for p in partitions(4))) == \ [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] assert list(uniq(x % 2 for x in range(5))) == [0, 1] assert list(uniq('a')) == ['a'] assert list(uniq('ababc')) == list('abc') assert list(uniq([[1], [2, 1], [1]])) == [[1], [2, 1], [1]] assert list(uniq(permutations(i for i in [[1], 2, 2]))) == \ [([1], 2, 2), (2, [1], 2), (2, 2, [1]), (2, [1], 2), (2, 2, [1])]
def fourth_term(lambdas: tp.Dict[int, int]) -> tp.Any: min_lambda = min(lambdas) if min_lambda < 2: return 0 reduced_lambdas = lambdas.copy() decrease_key(reduced_lambdas, min_lambda) return t / Q * sum( map(lambda mu: subterm(mu, reduced_lambdas, f_1), partitions(min_lambda - 2)))
def first_term(lambdas: tp.Dict[int, int]) -> tp.Any: min_lambda = min(lambdas) if min_lambda == 1: return 0 reduced_lambdas = lambdas.copy() decrease_key(reduced_lambdas, min_lambda) return -t / Q * q ** 2 * (1 - q) * \ sum(map(lambda mu: subterm(mu, reduced_lambdas, f_1), partitions(min_lambda, k=min_lambda-1)))
def rs_partitions(N, n): from sympy.utilities.iterables import multiset_permutations, partitions k = 2 * n for m, p in partitions(N, m=k, size=True): if m >= n: for q in multiset_permutations( sum([[k] * v for k, v in p.items()], []) + [0] * (k - m)): res = [(q[:n][i], q[n:][i]) for i in range(n)] if not (0 in map(lambda x: x[0] or x[1], res)): yield res
def test_nD_derangements(): from sympy.utilities.iterables import (partitions, multiset, multiset_derangements, multiset_permutations) from sympy.functions.combinatorial.numbers import nD got = [] for i in partitions(8, k=4): s = [] it = 0 for k, v in i.items(): for i in range(v): s.extend([it] * k) it += 1 ms = multiset(s) c1 = sum(1 for i in multiset_permutations(s) if all(i != j for i, j in zip(i, s))) assert c1 == nD(ms) == nD(ms, 0) == nD(ms, 1) v = [tuple(i) for i in multiset_derangements(s)] c2 = len(v) assert c2 == len(set(v)) assert c1 == c2 got.append(c1) assert got == [ 1, 4, 6, 12, 24, 24, 61, 126, 315, 780, 297, 772, 2033, 5430, 14833 ] assert nD('1112233456', brute=True) == nD('1112233456') == 16356 assert nD('') == nD([]) == nD({}) == 0 assert nD({1: 0}) == 0 raises(ValueError, lambda: nD({1: -1})) assert nD('112') == 0 assert nD(i='112') == 0 assert [nD(n=i) for i in range(6)] == [0, 0, 1, 2, 9, 44] assert nD((i for i in range(4))) == nD('0123') == 9 assert nD(m=(i for i in range(4))) == 3 assert nD(m={0: 1, 1: 1, 2: 1, 3: 1}) == 3 assert nD(m=[0, 1, 2, 3]) == 3 raises(TypeError, lambda: nD(m=0)) raises(TypeError, lambda: nD(-1)) assert nD({-1: 1, -2: 1}) == 1 assert nD(m={0: 3}) == 0 raises(ValueError, lambda: nD(i='123', n=3)) raises(ValueError, lambda: nD(i='123', m=(1, 2))) raises(ValueError, lambda: nD(n=0, m=(1, 2))) raises(ValueError, lambda: nD({1: -1})) raises(ValueError, lambda: nD(m={-1: 1, 2: 1})) raises(ValueError, lambda: nD(m={1: -1, 2: 1})) raises(ValueError, lambda: nD(m=[-1, 2])) raises(TypeError, lambda: nD({1: x})) raises(TypeError, lambda: nD(m={1: x})) raises(TypeError, lambda: nD(m={x: 1}))
def fifth_term(lambdas: tp.Dict[int, int]) -> tp.Any: min_lambda = min(lambdas) reduced_lambdas = lambdas.copy() decrease_key(reduced_lambdas, min_lambda) answer = 0 for nu, sub_lambda in partition_into_two(reduced_lambdas): if min_lambda + norm(nu) - 2 < 0: continue combinations = 1 for key in nu: combinations *= sm.binomial(reduced_lambdas[key], nu[key]) answer += combinations * map_prod(nu, f_3) * \ sum(map(lambda mu: subterm(mu, sub_lambda, f_2), partitions(min_lambda + norm(nu) - 2))) return q * Q * answer
def test_uniq(): assert list(uniq(p for p in partitions(4))) == \ [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] assert list(uniq(x % 2 for x in range(5))) == [0, 1] assert list(uniq('a')) == ['a'] assert list(uniq('ababc')) == list('abc') assert list(uniq([[1], [2, 1], [1]])) == [[1], [2, 1]] assert list(uniq(permutations(i for i in [[1], 2, 2]))) == \ [([1], 2, 2), (2, [1], 2), (2, 2, [1])] assert list(uniq([2, 3, 2, 4, [2], [1], [2], [3], [1]])) == \ [2, 3, 4, [2], [1], [3]] f = [1] raises(RuntimeError, lambda: [f.remove(i) for i in uniq(f)]) f = [[1]] raises(RuntimeError, lambda: [f.remove(i) for i in uniq(f)])
def test_uniq(): assert list(uniq(p.copy() for p in partitions(4))) == [ {4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}, ] assert list(uniq(x % 2 for x in range(5))) == [0, 1] assert list(uniq("a")) == ["a"] assert list(uniq("ababc")) == list("abc") assert list(uniq([[1], [2, 1], [1]])) == [[1], [2, 1]] assert list(uniq(permutations(i for i in [[1], 2, 2]))) == [ ([1], 2, 2), (2, [1], 2), (2, 2, [1]), ] assert list(uniq([2, 3, 2, 4, [2], [1], [2], [3], [1]])) == [2, 3, 4, [2], [1], [3]]
def test_integer_partition(): # no zeros in partition raises(ValueError, lambda: IntegerPartition(list(range(3)))) # check fails since 1 + 2 != 100 raises(ValueError, lambda: IntegerPartition(100, list(range(1, 3)))) a = IntegerPartition(8, [1, 3, 4]) b = a.next_lex() c = IntegerPartition([1, 3, 4]) d = IntegerPartition(8, {1: 3, 3: 1, 2: 1}) assert a == c assert a.integer == d.integer assert a.conjugate == [3, 2, 2, 1] assert (a == b) is False assert a <= b assert (a > b) is False assert a != b for i in range(1, 11): next = set() prev = set() a = IntegerPartition([i]) ans = set([IntegerPartition(p) for p in partitions(i)]) n = len(ans) for j in range(n): next.add(a) a = a.next_lex() IntegerPartition(i, a.partition) # check it by giving i for j in range(n): prev.add(a) a = a.prev_lex() IntegerPartition(i, a.partition) # check it by giving i assert next == ans assert prev == ans assert IntegerPartition([1, 2, 3]).as_ferrers() == '###\n##\n#' assert IntegerPartition([1, 1, 3]).as_ferrers('o') == 'ooo\no\no' assert str(IntegerPartition([1, 1, 3])) == '[3, 1, 1]' assert IntegerPartition([1, 1, 3]).partition == [3, 1, 1] raises(ValueError, lambda: random_integer_partition(-1)) assert random_integer_partition(1) == [1] assert random_integer_partition(10, seed=[1, 3, 2, 1, 5, 1] ) == [5, 2, 1, 1, 1]
def test_integer_partition(): # no zeros in partition raises(ValueError, lambda: IntegerPartition(list(range(3)))) # check fails since 1 + 2 != 100 raises(ValueError, lambda: IntegerPartition(100, list(range(1, 3)))) a = IntegerPartition(8, [1, 3, 4]) b = a.next_lex() c = IntegerPartition([1, 3, 4]) d = IntegerPartition(8, {1: 3, 3: 1, 2: 1}) assert a == c assert a.integer == d.integer assert a.conjugate == [3, 2, 2, 1] assert (a == b) is False assert a <= b assert (a > b) is False assert a != b for i in range(1, 11): next = set() prev = set() a = IntegerPartition([i]) ans = set([IntegerPartition(p) for p in partitions(i)]) n = len(ans) for j in range(n): next.add(a) a = a.next_lex() IntegerPartition(i, a.partition) # check it by giving i for j in range(n): prev.add(a) a = a.prev_lex() IntegerPartition(i, a.partition) # check it by giving i assert next == ans assert prev == ans assert IntegerPartition([1, 2, 3]).as_ferrers() == '###\n##\n#' assert IntegerPartition([1, 1, 3]).as_ferrers('o') == 'ooo\no\no' assert str(IntegerPartition([1, 1, 3])) == '[3, 1, 1]' assert IntegerPartition([1, 1, 3]).partition == [3, 1, 1] raises(ValueError, lambda: random_integer_partition(-1)) assert random_integer_partition(1) == [1] assert random_integer_partition(10, seed=[1, 3, 2, 1, 5, 1]) == [5, 2, 1, 1, 1]
def calcFaaDiBrunoFromPartitionsFromFunction( baseDerivativeFunction, l, n, x, thresholdForExp=30.0, verbose=True): """ Function to calculate derivatives of iterated base function :param baseDerivativeFunction: Function that returns derivaties of base function :param l: Order of function iteration :param n: Highest order of derivative to be evaluated for iterated function :param x: Point at which derivatives are to be evaluated :param thresholdForExp: Threshold beyond which differences in logarithms will be capped :param verbose: Boolean flag. If true then print messages :return: Dictionary containing logarithms and signs of derivates of iterated base function """ # set up arrays for holding derivatives (on log scale) # of the base function, the current iteration and next iteration evaluationPoint = x baseDerivativesLog = np.zeros( n ) baseDerivativesSign = np.ones( n ) currentDerivativesLog = np.zeros( n ) currentDerivativesSign = np.ones( n ) for k in range( n ): baseDerivativeTmp = baseDerivativeFunction( x, k+1 ) if( np.abs( baseDerivativeTmp ) > 1.0e-12 ): baseDerivativesLog[k] = np.log( np.abs(baseDerivativeTmp) ) baseDerivativesSign[k] = np.sign( baseDerivativeTmp) # get current derivatives currentDerivativesLog[k] = np.log( np.abs( baseDerivativeTmp ) ) currentDerivativesSign[k] = np.sign( baseDerivativeTmp ) else: baseDerivativesLog[k] = float( '-Inf' ) baseDerivativesSign[k] = 1.0 currentDerivativesLog[k] = float( '-Inf' ) currentDerivativesSign[k] = 1.0 nextDerivativesLog = np.zeros( n ) nextDerivativesSign = np.ones( n ) # initialize array for holding derivatives at each iteration iteratedFunctionDerivativesLog = np.zeros( (l, n) ) iteratedFunctionDerivativesSign = np.ones( (l, n) ) # store base derivatives in first row of array iteratedFunctionDerivativesLog[0, :] = baseDerivativesLog iteratedFunctionDerivativesSign[0, :] = baseDerivativesSign # set number of function iterations nIterations = l-1 # if we need to iterate then do so if( nIterations > 0 ): # evaluate approximate number of paritions required log_nPartitions = calcHardyRamanujanApprox( n ) if( verbose==True ): print( "You have requested evaluation up to derivative " + str(n) ) if( log_nPartitions > np.log( 1.0e6 ) ): print( "Warning: There are approximately " + str(int(np.round(np.exp(log_nPartitions)))) + " partitions of " + str(n) ) print( "Warning: Evaluation will be costly both in terms of memory and run-time" ) # store partitions pStore = {} for k in range( n ): # get partition iterator pIterator = partitions(k+1) pStore[k] = [p.copy() for p in pIterator] # loop over function iterations for iteration in range( nIterations ): evaluationPoint = baseDerivativeFunction( evaluationPoint, 0 ) if( verbose==True ): print( "Evaluating derivatives for function iteration " + str(iteration+1) ) for k in range( n ): faaSumLog = float( '-Inf' ) faaSumSign = 1 # get partitions partitionsK = pStore[k] for pidx in range( len(partitionsK) ): p = partitionsK[pidx] sumTmp = 0.0 sumMultiplicty = 0 parityTmp = 1 for i in p.keys(): value = float(i) multiplicity = float( p[i] ) sumMultiplicty += p[i] sumTmp += multiplicity * currentDerivativesLog[i-1] sumTmp -= gammaln( multiplicity + 1.0 ) sumTmp -= multiplicity * gammaln( value + 1.0 ) parityTmp *= np.power( currentDerivativesSign[i-1], multiplicity ) #evaluationPointTmp = np.exp( currentDerivativesLog[0] ) * currentDerivativesSign[0] baseDerivativeTmp = baseDerivativeFunction( evaluationPoint , sumMultiplicty ) if( np.abs( baseDerivativeTmp ) > 1.0e-12 ): sumTmp += np.log( np.abs( baseDerivativeTmp ) ) parityTmp *= np.sign( baseDerivativeTmp ) else: sumTmp = float( '-Inf' ) parityTmp = 1.0 # now update faaSum on log scale if( sumTmp > float( '-Inf' ) ): if( faaSumLog > float( '-Inf' ) ): diffLog = sumTmp - faaSumLog if( np.abs(diffLog) <= thresholdForExp ): if( diffLog >= 0.0 ): faaSumLog = sumTmp faaSumLog += np.log( 1.0 + (float(parityTmp*faaSumSign) * np.exp( -diffLog )) ) faaSumSign = parityTmp else: faaSumLog += np.log( 1.0 + (float(parityTmp*faaSumSign) * np.exp( diffLog )) ) else: if( diffLog > thresholdForExp ): faaSumLog = sumTmp faaSumSign = parityTmp else: faaSumLog = sumTmp faaSumSign = parityTmp nextDerivativesLog[k] = faaSumLog + gammaln( float(k+2) ) nextDerivativesSign[k] = faaSumSign # update accounting for proceeding to next function iteration currentDerivativesLog[0:n] = nextDerivativesLog[0:n] currentDerivativesSign[0:n] = nextDerivativesSign[0:n] iteratedFunctionDerivativesLog[iteration+1, 0:n] = currentDerivativesLog[0:n] iteratedFunctionDerivativesSign[iteration+1, 0:n] = currentDerivativesSign[0:n] return( {'logDerivatives':iteratedFunctionDerivativesLog, 'signDerivatives':iteratedFunctionDerivativesSign} )
def test_uniq(): assert list(uniq(p.copy() for p in partitions(4))) == \ [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] assert list(uniq(x % 2 for x in range(5))) == [0, 1] assert list(uniq('a')) == ['a'] assert list(uniq('ababc')) == list('abc')
def test_nC_nP_nT(): from sympy.utilities.iterables import (multiset_permutations, multiset_combinations, multiset_partitions, partitions, subsets, permutations) from sympy.functions.combinatorial.numbers import (nP, nC, nT, stirling, _multiset_histogram, _AOP_product) from sympy.combinatorics.permutations import Permutation from sympy.core.numbers import oo from random import choice c = string.ascii_lowercase for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(8): check = nP(s, i) tot += check assert len(list(multiset_permutations(s, i))) == check if u: assert nP(len(s), i) == check assert nP(s) == tot except AssertionError: print(s, i, 'failed perm test') raise ValueError() for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(8): check = nC(s, i) tot += check assert len(list(multiset_combinations(s, i))) == check if u: assert nC(len(s), i) == check assert nC(s) == tot if u: assert nC(len(s)) == tot except AssertionError: print(s, i, 'failed combo test') raise ValueError() for i in range(1, 10): tot = 0 for j in range(1, i + 2): check = nT(i, j) tot += check assert sum(1 for p in partitions(i, j, size=True) if p[0] == j) == check assert nT(i) == tot for i in range(1, 10): tot = 0 for j in range(1, i + 2): check = nT(range(i), j) tot += check assert len(list(multiset_partitions(list(range(i)), j))) == check assert nT(range(i)) == tot for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(1, 8): check = nT(s, i) tot += check assert len(list(multiset_partitions(s, i))) == check if u: assert nT(range(len(s)), i) == check if u: assert nT(range(len(s))) == tot assert nT(s) == tot except AssertionError: print(s, i, 'failed partition test') raise ValueError() # tests for Stirling numbers of the first kind that are not tested in the # above assert [stirling(9, i, kind=1) for i in range(11) ] == [0, 40320, 109584, 118124, 67284, 22449, 4536, 546, 36, 1, 0] perms = list(permutations(range(4))) assert [ sum(1 for p in perms if Permutation(p).cycles == i) for i in range(5) ] == [0, 6, 11, 6, 1] == [stirling(4, i, kind=1) for i in range(5)] # http://oeis.org/A008275 assert [ stirling(n, k, signed=1) for n in range(10) for k in range(1, n + 1) ] == [ 1, -1, 1, 2, -3, 1, -6, 11, -6, 1, 24, -50, 35, -10, 1, -120, 274, -225, 85, -15, 1, 720, -1764, 1624, -735, 175, -21, 1, -5040, 13068, -13132, 6769, -1960, 322, -28, 1, 40320, -109584, 118124, -67284, 22449, -4536, 546, -36, 1 ] # https://en.wikipedia.org/wiki/Stirling_numbers_of_the_first_kind assert [stirling(n, k, kind=1) for n in range(10) for k in range(n + 1)] == [ 1, 0, 1, 0, 1, 1, 0, 2, 3, 1, 0, 6, 11, 6, 1, 0, 24, 50, 35, 10, 1, 0, 120, 274, 225, 85, 15, 1, 0, 720, 1764, 1624, 735, 175, 21, 1, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1, 0, 40320, 109584, 118124, 67284, 22449, 4536, 546, 36, 1 ] # https://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind assert [stirling(n, k, kind=2) for n in range(10) for k in range(n + 1)] == [ 1, 0, 1, 0, 1, 1, 0, 1, 3, 1, 0, 1, 7, 6, 1, 0, 1, 15, 25, 10, 1, 0, 1, 31, 90, 65, 15, 1, 0, 1, 63, 301, 350, 140, 21, 1, 0, 1, 127, 966, 1701, 1050, 266, 28, 1, 0, 1, 255, 3025, 7770, 6951, 2646, 462, 36, 1 ] assert stirling(3, 4, kind=1) == stirling(3, 4, kind=1) == 0 raises(ValueError, lambda: stirling(-2, 2)) def delta(p): if len(p) == 1: return oo return min(abs(i[0] - i[1]) for i in subsets(p, 2)) parts = multiset_partitions(range(5), 3) d = 2 assert (sum(1 for p in parts if all(delta(i) >= d for i in p)) == stirling(5, 3, d=d) == 7) # other coverage tests assert nC('abb', 2) == nC('aab', 2) == 2 assert nP(3, 3, replacement=True) == nP('aabc', 3, replacement=True) == 27 assert nP(3, 4) == 0 assert nP('aabc', 5) == 0 assert nC(4, 2, replacement=True) == nC('abcdd', 2, replacement=True) == \ len(list(multiset_combinations('aabbccdd', 2))) == 10 assert nC('abcdd') == sum(nC('abcdd', i) for i in range(6)) == 24 assert nC(list('abcdd'), 4) == 4 assert nT('aaaa') == nT(4) == len(list(partitions(4))) == 5 assert nT('aaab') == len(list(multiset_partitions('aaab'))) == 7 assert nC('aabb' * 3, 3) == 4 # aaa, bbb, abb, baa assert dict(_AOP_product((4, 1, 1, 1))) == { 0: 1, 1: 4, 2: 7, 3: 8, 4: 8, 5: 7, 6: 4, 7: 1 } # the following was the first t that showed a problem in a previous form of # the function, so it's not as random as it may appear t = (3, 9, 4, 6, 6, 5, 5, 2, 10, 4) assert sum(_AOP_product(t)[i] for i in range(55)) == 58212000 raises(ValueError, lambda: _multiset_histogram({1: 'a'}))
def test_partitions(): ans = [[{}], [(0, {})]] for i in range(2): assert list(partitions(0, size=i)) == ans[i] assert list(partitions(1, 0, size=i)) == ans[i] assert list(partitions(6, 2, 2, size=i)) == ans[i] assert list(partitions(6, 2, None, size=i)) != ans[i] assert list(partitions(6, None, 2, size=i)) != ans[i] assert list(partitions(6, 2, 0, size=i)) == ans[i] assert [p for p in partitions(6, k=2)] == [{ 2: 3 }, { 1: 2, 2: 2 }, { 1: 4, 2: 1 }, { 1: 6 }] assert [p for p in partitions(6, k=3)] == [{ 3: 2 }, { 1: 1, 2: 1, 3: 1 }, { 1: 3, 3: 1 }, { 2: 3 }, { 1: 2, 2: 2 }, { 1: 4, 2: 1 }, { 1: 6 }] assert [p for p in partitions(8, k=4, m=3)] == [{ 4: 2 }, { 1: 1, 3: 1, 4: 1 }, { 2: 2, 4: 1 }, { 2: 1, 3: 2 }] == [ i for i in partitions(8, k=4, m=3) if all(k <= 4 for k in i) and sum(i.values()) <= 3 ] assert [p for p in partitions(S(3), m=2)] == [{3: 1}, {1: 1, 2: 1}] assert [i for i in partitions(4, k=3)] == [{ 1: 1, 3: 1 }, { 2: 2 }, { 1: 2, 2: 1 }, { 1: 4 }] == [i for i in partitions(4) if all(k <= 3 for k in i)] # Consistency check on output of _partitions and RGS_unrank. # This provides a sanity test on both routines. Also verifies that # the total number of partitions is the same in each case. # (from pkrathmann2) for n in range(2, 6): i = 0 for m, q in _set_partitions(n): assert q == RGS_unrank(i, n) i += 1 assert i == RGS_enum(n)
def test_uniq(): assert list(uniq(p.copy() for p in partitions(4))) == [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] assert list(uniq(x % 2 for x in range(5))) == [0, 1] assert list(uniq("a")) == ["a"] assert list(uniq("ababc")) == list("abc")
def test_partitions(): ans = [[{}], [(0, {})]] for i in range(2): assert list(partitions(0, size=i)) == ans[i] assert list(partitions(1, 0, size=i)) == ans[i] assert list(partitions(6, 2, 2, size=i)) == ans[i] assert list(partitions(6, 2, None, size=i)) != ans[i] assert list(partitions(6, None, 2, size=i)) != ans[i] assert list(partitions(6, 2, 0, size=i)) == ans[i] assert [p.copy() for p in partitions(6, k=2)] == [ {2: 3}, {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(6, k=3)] == [ {3: 2}, {1: 1, 2: 1, 3: 1}, {1: 3, 3: 1}, {2: 3}, {1: 2, 2: 2}, {1: 4, 2: 1}, {1: 6}] assert [p.copy() for p in partitions(8, k=4, m=3)] == [ {4: 2}, {1: 1, 3: 1, 4: 1}, {2: 2, 4: 1}, {2: 1, 3: 2}] == [ i.copy() for i in partitions(8, k=4, m=3) if all(k <= 4 for k in i) and sum(i.values()) <=3] assert [p.copy() for p in partitions(S(3), m=2)] == [ {3: 1}, {1: 1, 2: 1}] assert [i.copy() for i in partitions(4, k=3)] == [ {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] == [ i.copy() for i in partitions(4) if all(k <= 3 for k in i)] # Consistency check on output of _partitions and RGS_unrank. # This provides a sanity test on both routines. Also verifies that # the total number of partitions is the same in each case. # (from pkrathmann2) for n in range(2, 6): i = 0 for m, q in _set_partitions(n): assert q == RGS_unrank(i, n) i += 1 assert i == RGS_enum(n)
def test_F6(): partTest = [p.copy() for p in partitions(4)] partDesired = [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2: 1}, {1: 4}] assert partTest == partDesired
def test_nC_nP_nT(): from sympy.utilities.iterables import ( multiset_permutations, multiset_combinations, multiset_partitions, partitions, subsets, permutations) from sympy.functions.combinatorial.numbers import ( nP, nC, nT, stirling, _multiset_histogram, _AOP_product) from sympy.combinatorics.permutations import Permutation from sympy.core.numbers import oo from random import choice c = string.ascii_lowercase for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(8): check = nP(s, i) tot += check assert len(list(multiset_permutations(s, i))) == check if u: assert nP(len(s), i) == check assert nP(s) == tot except AssertionError: print(s, i, 'failed perm test') raise ValueError() for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(8): check = nC(s, i) tot += check assert len(list(multiset_combinations(s, i))) == check if u: assert nC(len(s), i) == check assert nC(s) == tot if u: assert nC(len(s)) == tot except AssertionError: print(s, i, 'failed combo test') raise ValueError() for i in range(1, 10): tot = 0 for j in range(1, i + 2): check = nT(i, j) tot += check assert sum(1 for p in partitions(i, j, size=True) if p[0] == j) == check assert nT(i) == tot for i in range(1, 10): tot = 0 for j in range(1, i + 2): check = nT(range(i), j) tot += check assert len(list(multiset_partitions(range(i), j))) == check assert nT(range(i)) == tot for i in range(100): s = ''.join(choice(c) for i in range(7)) u = len(s) == len(set(s)) try: tot = 0 for i in range(1, 8): check = nT(s, i) tot += check assert len(list(multiset_partitions(s, i))) == check if u: assert nT(range(len(s)), i) == check if u: assert nT(range(len(s))) == tot assert nT(s) == tot except AssertionError: print(s, i, 'failed partition test') raise ValueError() # tests for Stirling numbers of the first kind that are not tested in the # above assert [stirling(9, i, kind=1) for i in range(11)] == [ 0, 40320, 109584, 118124, 67284, 22449, 4536, 546, 36, 1, 0] perms = list(permutations(range(4))) assert [sum(1 for p in perms if Permutation(p).cycles == i) for i in range(5)] == [0, 6, 11, 6, 1] == [ stirling(4, i, kind=1) for i in range(5)] # http://oeis.org/A008275 assert [stirling(n, k, signed=1) for n in range(10) for k in range(1, n + 1)] == [ 1, -1, 1, 2, -3, 1, -6, 11, -6, 1, 24, -50, 35, -10, 1, -120, 274, -225, 85, -15, 1, 720, -1764, 1624, -735, 175, -21, 1, -5040, 13068, -13132, 6769, -1960, 322, -28, 1, 40320, -109584, 118124, -67284, 22449, -4536, 546, -36, 1] # http://en.wikipedia.org/wiki/Stirling_numbers_of_the_first_kind assert [stirling(n, k, kind=1) for n in range(10) for k in range(n+1)] == [ 1, 0, 1, 0, 1, 1, 0, 2, 3, 1, 0, 6, 11, 6, 1, 0, 24, 50, 35, 10, 1, 0, 120, 274, 225, 85, 15, 1, 0, 720, 1764, 1624, 735, 175, 21, 1, 0, 5040, 13068, 13132, 6769, 1960, 322, 28, 1, 0, 40320, 109584, 118124, 67284, 22449, 4536, 546, 36, 1] # http://en.wikipedia.org/wiki/Stirling_numbers_of_the_second_kind assert [stirling(n, k, kind=2) for n in range(10) for k in range(n+1)] == [ 1, 0, 1, 0, 1, 1, 0, 1, 3, 1, 0, 1, 7, 6, 1, 0, 1, 15, 25, 10, 1, 0, 1, 31, 90, 65, 15, 1, 0, 1, 63, 301, 350, 140, 21, 1, 0, 1, 127, 966, 1701, 1050, 266, 28, 1, 0, 1, 255, 3025, 7770, 6951, 2646, 462, 36, 1] assert stirling(3, 4, kind=1) == stirling(3, 4, kind=1) == 0 raises(ValueError, lambda: stirling(-2, 2)) def delta(p): if len(p) == 1: return oo return min(abs(i[0] - i[1]) for i in subsets(p, 2)) parts = multiset_partitions(range(5), 3) d = 2 assert (sum(1 for p in parts if all(delta(i) >= d for i in p)) == stirling(5, 3, d=d) == 7) # other coverage tests assert nC('abb', 2) == nC('aab', 2) == 2 assert nP(3, 3, replacement=True) == nP('aabc', 3, replacement=True) == 27 assert nP(3, 4) == 0 assert nP('aabc', 5) == 0 assert nC(4, 2, replacement=True) == nC('abcdd', 2, replacement=True) == \ len(list(multiset_combinations('aabbccdd', 2))) == 10 assert nC('abcdd') == sum(nC('abcdd', i) for i in range(6)) == 24 assert nC(list('abcdd'), 4) == 4 assert nT('aaaa') == nT(4) == len(list(partitions(4))) == 5 assert nT('aaab') == len(list(multiset_partitions('aaab'))) == 7 assert nC('aabb'*3, 3) == 4 # aaa, bbb, abb, baa assert dict(_AOP_product((4,1,1,1))) == { 0: 1, 1: 4, 2: 7, 3: 8, 4: 8, 5: 7, 6: 4, 7: 1} # the following was the first t that showed a problem in a previous form of # the function, so it's not as random as it may appear t = (3, 9, 4, 6, 6, 5, 5, 2, 10, 4) assert sum(_AOP_product(t)[i] for i in range(55)) == 58212000 raises(ValueError, lambda: _multiset_histogram({1:'a'}))
def test_F6(): partTest = [p.copy() for p in partitions(4)] partDesired = [{4: 1}, {1: 1, 3: 1}, {2: 2}, {1: 2, 2:1}, {1: 4}] assert partTest == partDesired
def kbin(l, k, ordered=True): """ Return sequence ``l`` partitioned into ``k`` bins. If ordered is True then the order of the items in the flattened partition will be the same as the order of the items in ``l``; if False, all permutations of the items will be given; if None, only unique permutations for a given partition will be given. Examples ======== >>> from sympy.utilities.iterables import kbin >>> for p in kbin(range(3), 2): ... print p ... [[0], [1, 2]] [[0, 1], [2]] >>> for p in kbin(range(3), 2, ordered=False): ... print p ... [(0,), (1, 2)] [(0,), (2, 1)] [(1,), (0, 2)] [(1,), (2, 0)] [(2,), (0, 1)] [(2,), (1, 0)] [(0, 1), (2,)] [(0, 2), (1,)] [(1, 0), (2,)] [(1, 2), (0,)] [(2, 0), (1,)] [(2, 1), (0,)] >>> for p in kbin(range(3), 2, ordered=None): ... print p ... [[0], [1, 2]] [[1], [2, 0]] [[2], [0, 1]] [[0, 1], [2]] [[1, 2], [0]] [[2, 0], [1]] """ from sympy.utilities.iterables import partitions from itertools import permutations def rotations(seq): for i in range(len(seq)): yield seq seq.append(seq.pop(0)) if ordered is None: func = rotations else: func = permutations for p in partitions(len(l), k): if sum(p.values()) != k: continue for pe in permutations(p.keys()): rv = [] i = 0 for part in pe: for do in range(p[part]): j = i + part rv.append(l[i: j]) i = j if ordered: yield rv else: template = [len(i) for i in rv] for pp in func(l): rvp = [] ii = 0 for t in template: jj = ii + t rvp.append(pp[ii: jj]) ii = jj yield rvp