def comp_unrank_grlex_test ( ): #*****************************************************************************80 # ## COMP_UNRANK_GRLEX_TEST tests COMP_UNRANK_GRLEX. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # from i4vec_sum import i4vec_sum kc = 3 print '' print 'COMP_UNRANK_GRLEX_TEST' print ' A COMP is a composition of an integer N into K parts.' print ' Each part is nonnegative. The order matters.' print ' COMP_UNRANK_GRLEX determines the parts' print ' of a COMP from its rank.' print '' print ' Rank: -> NC COMP ' print ' ----: -- ------------ ' for rank in range ( 1, 72 ): xc = comp_unrank_grlex ( kc, rank ) nc = i4vec_sum ( kc, xc ) print ' %3d: ' % ( rank ), print ' %2d = ' % ( nc ), for j in range ( 0, kc - 1 ): print '%2d + ' % ( xc[j] ), print '%2d' % ( xc[kc-1] ) # # When XC(1) == NC, we have completed the compositions associated with # a particular integer, and are about to advance to the next integer. # if ( xc[0] == nc ): print ' ----: -- ------------' # # Terminate. # print '' print 'COMP_UNRANK_GRLEX_TEST:' print ' Normal end of execution.' return
def comp_random_grlex_test(): #*****************************************************************************80 # ## COMP_RANDOM_GRLEX_TEST tests COMP_RANDOM_GRLEX. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # from i4vec_sum import i4vec_sum print '' print 'COMP_RANDOM_GRLEX_TEST' print ' A COMP is a composition of an integer N into K parts.' print ' Each part is nonnegative. The order matters.' print ' COMP_RANDOM_GRLEX selects a random COMP in' print ' graded lexicographic (grlex) order between indices RANK1 and RANK2.' print '' kc = 3 rank1 = 20 rank2 = 60 seed = 123456789 for test in range(0, 5): xc, rank, seed = comp_random_grlex(kc, rank1, rank2, seed) nc = i4vec_sum(kc, xc) print ' %3d: ' % (rank), print ' %2d = ' % (nc), for j in range(0, kc - 1): print '%2d + ' % (xc[j]), print '%2d' % (xc[kc - 1]) # # Terminate. # print '' print 'COMP_RANDOM_GRLEX_TEST:' print ' Normal end of execution.' return
def comp_random_grlex_test ( ): #*****************************************************************************80 # ## COMP_RANDOM_GRLEX_TEST tests COMP_RANDOM_GRLEX. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # from i4vec_sum import i4vec_sum print '' print 'COMP_RANDOM_GRLEX_TEST' print ' A COMP is a composition of an integer N into K parts.' print ' Each part is nonnegative. The order matters.' print ' COMP_RANDOM_GRLEX selects a random COMP in' print ' graded lexicographic (grlex) order between indices RANK1 and RANK2.' print '' kc = 3 rank1 = 20 rank2 = 60 seed = 123456789 for test in range ( 0, 5 ): xc, rank, seed = comp_random_grlex ( kc, rank1, rank2, seed ) nc = i4vec_sum ( kc, xc ) print ' %3d: ' % ( rank ), print ' %2d = ' % ( nc ), for j in range ( 0, kc - 1 ): print '%2d + ' % ( xc[j] ), print '%2d' % ( xc[kc-1] ) # # Terminate. # print '' print 'COMP_RANDOM_GRLEX_TEST:' print ' Normal end of execution.' return
def monomial_counts_test ( ): #*****************************************************************************80 # ## MONOMIAL_COUNTS_TEST tests MONOMIAL_COUNTS. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 25 May 2015 # # Author: # # John Burkardt # from i4vec_sum import i4vec_sum degree_max = 9 print '' print 'MONOMIAL_COUNTS_TEST' print ' MONOMIAL_COUNTS counts the number of monomials of' print ' degrees 0 through DEGREE_MAX in a space of dimension DIM.' for dim in range ( 1, 7 ): counts = monomial_counts ( degree_max, dim ) s = i4vec_sum ( degree_max + 1, counts ) print '' print ' DIM = %d' % ( dim ) print '' for degree in range ( 0, degree_max + 1 ): print ' %8d %8d' % ( degree + 1, counts[degree] ) print '' print ' Total %8d' % ( s ) # # Terminate. # print '' print 'MONOMIAL_COUNTS_TEST:' print ' Normal end of execution.' return
def mono_upto_next_grevlex ( m, n, x ): #*****************************************************************************80 # ## MONO_UPTO_NEXT_GREVLEX: grevlex next monomial, total degree up to N. # # Discussion: # # We consider all monomials in an M-dimensional space, with total # degree N. # # For example: # # M = 3 # N = 3 # # # X(1) X(2) X(3) Degree # +------------------------ # 1 | 0 0 0 0 # | # 2 | 0 0 1 1 # 3 | 0 1 0 1 # 4 | 1 0 0 1 # | # 5 | 0 0 2 2 # 6 | 0 1 1 2 # 7 | 1 0 1 2 # 8 | 0 2 0 2 # 9 | 1 1 0 2 # 10 | 2 0 0 2 # | # 11 | 0 0 3 3 # 12 | 0 1 2 3 # 13 | 1 0 2 3 # 14 | 0 2 1 3 # 15 | 1 1 1 3 # 16 | 2 0 1 3 # 17 | 0 3 0 3 # 18 | 1 2 0 3 # 19 | 2 1 0 3 # 20 | 3 0 0 3 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 24 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # # Input, integer N, the total degree. # 0 <= N. # # Input, integer X[M], the current monomial. # The first element is X = [ 0, 0, ..., 0, 0 ]. # The last is [ N, 0, ..., 0, 0 ]. # # Output, integer X[M], the next monomial. # from i4vec_sum import i4vec_sum from mono_next_grevlex import mono_next_grevlex if ( n < 0 ): print '' print 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' print ' N < 0.' sys.exit ( 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' ) if ( i4vec_sum ( m, x ) < 0 ): print '' print 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' print ' Input X sum is less than 0.' sys.exit ( 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' ) if ( n < i4vec_sum ( m, x ) ): print '' print 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' print ' Input X sum is more than N.' sys.exit ( 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' ) if ( n == 0 ): return x if ( x[0] == n ): x[0] = 0 else: x = mono_next_grevlex ( m, x ) return x
def asm_triangle ( n ): #*****************************************************************************80 # ## ASM_TRIANGLE returns a row of the alternating sign matrix triangle. # # Discussion: # # The first seven rows of the triangle are as follows: # # 1 2 3 4 5 6 7 # # 0 1 # 1 1 1 # 2 2 3 2 # 3 7 14 14 7 # 4 42 105 135 105 42 # 5 429 1287 2002 2002 1287 429 # 6 7436 26026 47320 56784 47320 26026 7436 # # For a given N, the value of A(J) represents entry A(I,J) of # the triangular matrix, and gives the number of alternating sign matrices # of order N in which the (unique) 1 in row 1 occurs in column J. # # Thus, of alternating sign matrices of order 3, there are # 2 with a leading 1 in column 1: # # 1 0 0 1 0 0 # 0 1 0 0 0 1 # 0 0 1 0 1 0 # # 3 with a leading 1 in column 2, and # # 0 1 0 0 1 0 0 1 0 # 1 0 0 0 0 1 1-1 1 # 0 0 1 1 0 0 0 1 0 # # 2 with a leading 1 in column 3: # # 0 0 1 0 0 1 # 1 0 0 0 1 0 # 0 1 0 1 0 0 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 11 June 2004 # # Author: # # John Burkardt # # Parameters: # # Input, integer N, the desired row. # # Output, integer A(N+1), the entries of the row. # import numpy as np from i4vec_sum import i4vec_sum a = np.zeros ( n + 1 ); b = np.zeros ( n + 1 ); c = np.zeros ( n + 1 ); # # Row 1 # a[0] = 1; if ( n + 1 == 1 ): return a # # Row 2 # nn = 2 b[0] = 2 c[0] = nn a[0] = i4vec_sum ( nn - 1, a ) for i in range ( 1, nn ): a[i] = a[i-1] * c[i-1] / b[i-1] if ( n + 1 == 2 ): return a # # Row 3 and on. # for nn in range ( 3, n + 2 ): b[nn-2] = nn for i in range ( nn - 3, 0, -1 ): b[i] = b[i] + b[i-1] b[0] = 2 c[nn-2] = 2 for i in range ( nn - 3, 0, -1 ): c[i] = c[i] + c[i-1] c[0] = nn a[0] = i4vec_sum ( nn - 1, a ) for i in range ( 1, nn ): a[i] = a[i-1] * c[i-1] / b[i-1] return a
def comp_rank_grlex ( kc, xc ): #*****************************************************************************80 # ## COMP_RANK_GRLEX computes the graded lexicographic rank of a composition. # # Discussion: # # The graded lexicographic ordering is used, over all KC-compositions # for NC = 0, 1, 2, ... # # For example, if KC = 3, the ranking begins: # # Rank Sum 1 2 3 # ---- --- -- -- -- # 1 0 0 0 0 # # 2 1 0 0 1 # 3 1 0 1 0 # 4 1 1 0 1 # # 5 2 0 0 2 # 6 2 0 1 1 # 7 2 0 2 0 # 8 2 1 0 1 # 9 2 1 1 0 # 10 2 2 0 0 # # 11 3 0 0 3 # 12 3 0 1 2 # 13 3 0 2 1 # 14 3 0 3 0 # 15 3 1 0 2 # 16 3 1 1 1 # 17 3 1 2 0 # 18 3 2 0 1 # 19 3 2 1 0 # 20 3 3 0 0 # # 21 4 0 0 4 # .. .. .. .. .. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, int KC, the number of parts in the composition. # 1 <= KC. # # Input, int XC[KC], the composition. # For each 1 <= I <= KC, we have 0 <= XC(I). # # Output, int RANK, the rank of the composition. # import numpy as np from i4_choose import i4_choose from i4vec_sum import i4vec_sum from sys import exit # # Ensure that 1 <= KC. # if ( kc < 1 ): print ''; print 'COMP_RANK_GRLEX - Fatal error!' print ' KC < 1' exit ( 'COMP_RANK_GRLEX - Fatal error!' ); # # Ensure that 0 <= XC(I). # for i in range ( 0, kc ): if ( xc[i] < 0 ): print '' print 'COMP_RANK_GRLEX - Fatal error!' print ' XC[I] < 0' exit ( 'COMP_RANK_GRLEX - Fatal error!' ); # # NC = sum ( XC ) # nc = i4vec_sum ( kc, xc ) # # Convert to KSUBSET format. # ns = nc + kc - 1 ks = kc - 1 xs = np.zeros ( ks, dtype = np.int32 ) xs[0] = xc[0] + 1 for i in range ( 2, kc ): xs[i-1] = xs[i-2] + xc[i-1] + 1 # # Compute the rank. # rank = 1; for i in range ( 1, ks + 1 ): if ( i == 1 ): tim1 = 0 else: tim1 = xs[i-2]; if ( tim1 + 1 <= xs[i-1] - 1 ): for j in range ( tim1 + 1, xs[i-1] ): rank = rank + i4_choose ( ns - j, ks - i ) for n in range ( 0, nc ): rank = rank + i4_choose ( n + kc - 1, n ) return rank
def mono_rank_grlex ( m, x ): #*****************************************************************************80 # ## MONO_RANK_GRLEX computes the graded lexicographic rank of a monomial. # # Discussion: # # The graded lexicographic ordering is used, over all monomials in # M dimensions, for total degree = 0, 1, 2, ... # # For example, if M = 3, the ranking begins: # # Rank Sum 1 2 3 # ---- --- -- -- -- # 1 0 0 0 0 # # 2 1 0 0 1 # 3 1 0 1 0 # 4 1 1 0 1 # # 5 2 0 0 2 # 6 2 0 1 1 # 7 2 0 2 0 # 8 2 1 0 1 # 9 2 1 1 0 # 10 2 2 0 0 # # 11 3 0 0 3 # 12 3 0 1 2 # 13 3 0 2 1 # 14 3 0 3 0 # 15 3 1 0 2 # 16 3 1 1 1 # 17 3 1 2 0 # 18 3 2 0 1 # 19 3 2 1 0 # 20 3 3 0 0 # # 21 4 0 0 4 # .. .. .. .. .. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 31 October 2015 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # 1 <= M. # # Input, integer X[M], the composition. # For each 1 <= I <= M, we have 0 <= X(I). # # Output, integer RANK, the rank. # from i4_choose import i4_choose from i4vec_sum import i4vec_sum import numpy as np # # Ensure that 1 <= M. # if ( m < 1 ): print '' print 'MONO_RANK_GRLEX - Fatal error!' print ' M < 1' sys.exit ( 'MONO_RANK_GRLEX - Fatal error!' ) # # Ensure that 0 <= X(I). # for i in range ( 0, m ): if ( x[i] < 0 ): print '' print 'MONO_RANK_GRLEX - Fatal error!' print ' X[I] < 0' sys.exit ( 'MONO_RANK_GRLEX - Fatal error!' ) # # NM = sum ( X ) # nm = i4vec_sum ( m, x ) # # Convert to KSUBSET format. # ns = nm + m - 1 ks = m - 1 if ( 0 < ks ): xs = np.zeros ( ks, dtype = np.int32 ) xs[0] = x[0] + 1 for i in range ( 2, m ): xs[i-1] = xs[i-2] + x[i-1] + 1 # # Compute the rank. # rank = 1 for i in range ( 1, ks + 1 ): if ( i == 1 ): tim1 = 0 else: tim1 = xs[i-2] if ( tim1 + 1 <= xs[i-1] - 1 ): for j in range ( tim1 + 1, xs[i-1] ): rank = rank + i4_choose ( ns - j, ks - i ) for n in range ( 0, nm ): rank = rank + i4_choose ( n + m - 1, n ) return rank
def mono_next_grevlex ( m, x ): #*****************************************************************************80 # ## MONO_NEXT_GREVLEX: grevlex next monomial. # # Discussion: # # Example: # # M = 3 # # # X(1) X(2) X(3) Degree # +------------------------ # 1 | 0 0 0 0 # | # 2 | 0 0 1 1 # 3 | 0 1 0 1 # 4 | 1 0 0 1 # | # 5 | 0 0 2 2 # 6 | 0 1 1 2 # 7 | 1 0 1 2 # 8 | 0 2 0 2 # 9 | 1 1 0 2 # 10 | 2 0 0 2 # | # 11 | 0 0 3 3 # 12 | 0 1 2 3 # 13 | 1 0 2 3 # 14 | 0 2 1 3 # 15 | 1 1 1 3 # 16 | 2 0 1 3 # 17 | 0 3 0 3 # 18 | 1 2 0 3 # 19 | 2 1 0 3 # 20 | 3 0 0 3 # # Thanks to Stefan Klus for pointing out a discrepancy in a previous # version of this code, 05 February 2015. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 05 February 2015 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # # Input, integer X[M], the current monomial. # The first element is X = [ 0, 0, ..., 0, 0 ]. # # Output, integer X[M], the next monomial. # from i4vec_sum import i4vec_sum if ( i4vec_sum ( m, x ) < 0 ): print '' print 'MONO_NEXT_GREVLEX - Fatal error!' print ' Input X sums to less than 0.' sys.exit ( 'MONO_NEXT_GREVLEX - Fatal error!' ) # # Seek the first index 0 < I for which 0 < X(I). # j = 0 for i in range ( 1, m ): if ( 0 < x[i] ): j = i break if ( j == 0 ): t = x[0] x[0] = 0 x[m-1] = t + 1 elif ( j < m - 1 ): x[j] = x[j] - 1 t = x[0] + 1; x[0] = 0; x[j-1] = x[j-1] + t elif ( j == m - 1 ): t = x[0] x[0] = 0 x[j-1] = t + 1 x[j] = x[j] - 1 return x
def mono_upto_next_grevlex(m, n, x): #*****************************************************************************80 # ## MONO_UPTO_NEXT_GREVLEX: grevlex next monomial, total degree up to N. # # Discussion: # # We consider all monomials in an M-dimensional space, with total # degree N. # # For example: # # M = 3 # N = 3 # # # X(1) X(2) X(3) Degree # +------------------------ # 1 | 0 0 0 0 # | # 2 | 0 0 1 1 # 3 | 0 1 0 1 # 4 | 1 0 0 1 # | # 5 | 0 0 2 2 # 6 | 0 1 1 2 # 7 | 1 0 1 2 # 8 | 0 2 0 2 # 9 | 1 1 0 2 # 10 | 2 0 0 2 # | # 11 | 0 0 3 3 # 12 | 0 1 2 3 # 13 | 1 0 2 3 # 14 | 0 2 1 3 # 15 | 1 1 1 3 # 16 | 2 0 1 3 # 17 | 0 3 0 3 # 18 | 1 2 0 3 # 19 | 2 1 0 3 # 20 | 3 0 0 3 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 24 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # # Input, integer N, the total degree. # 0 <= N. # # Input, integer X[M], the current monomial. # The first element is X = [ 0, 0, ..., 0, 0 ]. # The last is [ N, 0, ..., 0, 0 ]. # # Output, integer X[M], the next monomial. # from i4vec_sum import i4vec_sum from mono_next_grevlex import mono_next_grevlex if (n < 0): print '' print 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' print ' N < 0.' sys.exit('MONO_UPTO_NEXT_GREVLEX - Fatal error!') if (i4vec_sum(m, x) < 0): print '' print 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' print ' Input X sum is less than 0.' sys.exit('MONO_UPTO_NEXT_GREVLEX - Fatal error!') if (n < i4vec_sum(m, x)): print '' print 'MONO_UPTO_NEXT_GREVLEX - Fatal error!' print ' Input X sum is more than N.' sys.exit('MONO_UPTO_NEXT_GREVLEX - Fatal error!') if (n == 0): return x if (x[0] == n): x[0] = 0 else: x = mono_next_grevlex(m, x) return x
def comp_next_grlex_test(): #*****************************************************************************80 # ## COMP_NEXT_GRLEX_TEST tests COMP_NEXT_GRLEX. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # from i4vec_sum import i4vec_sum import numpy as np kc = 3 print '' print 'COMP_NEXT_GRLEX_TEST' print ' A COMP is a composition of an integer N into K parts.' print ' Each part is nonnegative. The order matters.' print ' COMP_NEXT_GRLEX determines the next COMP in' print ' graded lexicographic (grlex) order.' xc = np.zeros(kc, dtype=np.int32) print '' print ' Rank: NC COMP' print ' ----: -- ------------' for rank in range(1, 72): if (rank == 1): for j in range(0, kc): xc[j] = 0 else: xc = comp_next_grlex(kc, xc) nc = i4vec_sum(kc, xc) print ' %3d: ' % (rank), print ' %2d = ' % (nc), for j in range(0, kc - 1): print '%2d + ' % (xc[j]), print '%2d' % (xc[kc - 1]) # # When XC(1) == NC, we have completed the compositions associated with # a particular integer, and are about to advance to the next integer. # if (xc[0] == nc): print ' ----: -- ------------' # # Terminate. # print '' print 'COMP_NEXT_GRLEX_TEST:' print ' Normal end of execution.' return
def multinomial_coef1 ( nfactor, factor ): #*****************************************************************************80 # ## MULTINOMIAL_COEF1 computes a multinomial coefficient. # # Discussion: # # The multinomial coefficient is a generalization of the binomial # coefficient. It may be interpreted as the number of combinations of # N objects, where FACTOR(1) objects are indistinguishable of type 1, # ... and FACTOR(NFACTOR) are indistinguishable of type NFACTOR, # and N is the sum of FACTOR(1) through FACTOR(NFACTOR). # # NCOMB = N! / ( FACTOR(1)! FACTOR(2)! ... FACTOR(NFACTOR)! ) # # The log of the gamma function is used, to avoid overflow. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 26 May 2015 # # Author: # # John Burkardt # # Parameters: # # Input, integer NFACTOR, the number of factors. # # Input, integer FACTOR(NFACTOR), contains the factors. # 0 <= FACTOR(I) # # Output, integer NCOMB, the value of the multinomial coefficient. # from math import exp from math import log from r8_gamma import r8_gamma # from math import lgamma from sys import exit from i4vec_sum import i4vec_sum # # Each factor must be nonnegative. # for i in range ( 0, nfactor ): if ( factor[i] < 0 ): print '' print 'MULTINOMIAL_COEF1 - Fatal error!' print ' Factor %d = %d' % ( i, factor[i] ) print ' But this value must be nonnegative.' exit ( 'MULTINOMIAL_COEF1 - Fatal error!' ) # # The factors sum to N. # n = i4vec_sum ( nfactor, factor ) arg = float ( n + 1 ) # # Our obsolete version of Python doesn't have LGAMMA yet! # facn = log ( r8_gamma ( arg ) ) # facn = lgamma ( arg ) for i in range ( 0, nfactor ): arg = float ( factor[i] + 1 ) fack = log ( r8_gamma ( arg ) ) # fack = lgamma ( arg ) facn = facn - fack ncomb = round ( exp ( facn ) ) return ncomb
def asm_triangle(n): #*****************************************************************************80 # ## ASM_TRIANGLE returns a row of the alternating sign matrix triangle. # # Discussion: # # The first seven rows of the triangle are as follows: # # 1 2 3 4 5 6 7 # # 0 1 # 1 1 1 # 2 2 3 2 # 3 7 14 14 7 # 4 42 105 135 105 42 # 5 429 1287 2002 2002 1287 429 # 6 7436 26026 47320 56784 47320 26026 7436 # # For a given N, the value of A(J) represents entry A(I,J) of # the triangular matrix, and gives the number of alternating sign matrices # of order N in which the (unique) 1 in row 1 occurs in column J. # # Thus, of alternating sign matrices of order 3, there are # 2 with a leading 1 in column 1: # # 1 0 0 1 0 0 # 0 1 0 0 0 1 # 0 0 1 0 1 0 # # 3 with a leading 1 in column 2, and # # 0 1 0 0 1 0 0 1 0 # 1 0 0 0 0 1 1-1 1 # 0 0 1 1 0 0 0 1 0 # # 2 with a leading 1 in column 3: # # 0 0 1 0 0 1 # 1 0 0 0 1 0 # 0 1 0 1 0 0 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 11 June 2004 # # Author: # # John Burkardt # # Parameters: # # Input, integer N, the desired row. # # Output, integer A(N+1), the entries of the row. # import numpy as np from i4vec_sum import i4vec_sum a = np.zeros(n + 1) b = np.zeros(n + 1) c = np.zeros(n + 1) # # Row 1 # a[0] = 1 if (n + 1 == 1): return a # # Row 2 # nn = 2 b[0] = 2 c[0] = nn a[0] = i4vec_sum(nn - 1, a) for i in range(1, nn): a[i] = a[i - 1] * c[i - 1] / b[i - 1] if (n + 1 == 2): return a # # Row 3 and on. # for nn in range(3, n + 2): b[nn - 2] = nn for i in range(nn - 3, 0, -1): b[i] = b[i] + b[i - 1] b[0] = 2 c[nn - 2] = 2 for i in range(nn - 3, 0, -1): c[i] = c[i] + c[i - 1] c[0] = nn a[0] = i4vec_sum(nn - 1, a) for i in range(1, nn): a[i] = a[i - 1] * c[i - 1] / b[i - 1] return a
def mono_between_next_grevlex ( m, n1, n2, x ): #*****************************************************************************80 # ## MONO_BETWEEN_NEXT_GREVLEX: grevlex next monomial, degree between N1 and N2. # # Discussion: # # We consider all monomials in an M-dimensional space, with total # degree N between N1 and N2, inclusive. # # For example: # # M = 3 # N1 = 2 # N2 = 3 # # # X(1) X(2) X(3) Degree # +------------------------ # 1 | 0 0 2 2 # 2 | 0 1 1 2 # 3 | 1 0 1 2 # 4 | 0 2 0 2 # 5 | 1 1 0 2 # 6 | 2 0 0 2 # | # 7 | 0 0 3 3 # 8 | 0 1 2 3 # 9 | 1 0 2 3 # 10 | 0 2 1 3 # 11 | 1 1 1 3 # 12 | 2 0 1 3 # 13 | 0 3 0 3 # 14 | 1 2 0 3 # 15 | 2 1 0 3 # 16 | 3 0 0 3 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 24 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # # Input, integer N1, N2, the minimum and maximum degrees. # 0 <= N1 <= N2. # # Input, integer X[M], the current monomial. # The first element is X = [ 0, 0, ..., 0, N1 ]. # The last is [ N2, 0, ..., 0, 0 ]. # # Output, integer X[M], the next monomial. # from i4vec_sum import i4vec_sum from mono_next_grevlex import mono_next_grevlex if ( n1 < 0 ): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' N1 < 0.' sys.exit ( 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' ) if ( n2 < n1 ): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' N2 < N1.' sys.exit ( 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' ) if ( i4vec_sum ( m, x ) < n1 ): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' Input X sums to less than N1.' sys.exit ( 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' ) if ( n2 < i4vec_sum ( m, x ) ): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' Input X sums to more than N2.' sys.exit ( 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' ) if ( n2 == 0 ): return x if ( x[0] == n2 ): x[0] = 0 x[m-1] = n1 else: x = mono_next_grevlex ( m, x ) return x
def comp_rank_grlex(kc, xc): #*****************************************************************************80 # ## COMP_RANK_GRLEX computes the graded lexicographic rank of a composition. # # Discussion: # # The graded lexicographic ordering is used, over all KC-compositions # for NC = 0, 1, 2, ... # # For example, if KC = 3, the ranking begins: # # Rank Sum 1 2 3 # ---- --- -- -- -- # 1 0 0 0 0 # # 2 1 0 0 1 # 3 1 0 1 0 # 4 1 1 0 1 # # 5 2 0 0 2 # 6 2 0 1 1 # 7 2 0 2 0 # 8 2 1 0 1 # 9 2 1 1 0 # 10 2 2 0 0 # # 11 3 0 0 3 # 12 3 0 1 2 # 13 3 0 2 1 # 14 3 0 3 0 # 15 3 1 0 2 # 16 3 1 1 1 # 17 3 1 2 0 # 18 3 2 0 1 # 19 3 2 1 0 # 20 3 3 0 0 # # 21 4 0 0 4 # .. .. .. .. .. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, int KC, the number of parts in the composition. # 1 <= KC. # # Input, int XC[KC], the composition. # For each 1 <= I <= KC, we have 0 <= XC(I). # # Output, int RANK, the rank of the composition. # import numpy as np from i4_choose import i4_choose from i4vec_sum import i4vec_sum from sys import exit # # Ensure that 1 <= KC. # if (kc < 1): print '' print 'COMP_RANK_GRLEX - Fatal error!' print ' KC < 1' exit('COMP_RANK_GRLEX - Fatal error!') # # Ensure that 0 <= XC(I). # for i in range(0, kc): if (xc[i] < 0): print '' print 'COMP_RANK_GRLEX - Fatal error!' print ' XC[I] < 0' exit('COMP_RANK_GRLEX - Fatal error!') # # NC = sum ( XC ) # nc = i4vec_sum(kc, xc) # # Convert to KSUBSET format. # ns = nc + kc - 1 ks = kc - 1 xs = np.zeros(ks, dtype=np.int32) xs[0] = xc[0] + 1 for i in range(2, kc): xs[i - 1] = xs[i - 2] + xc[i - 1] + 1 # # Compute the rank. # rank = 1 for i in range(1, ks + 1): if (i == 1): tim1 = 0 else: tim1 = xs[i - 2] if (tim1 + 1 <= xs[i - 1] - 1): for j in range(tim1 + 1, xs[i - 1]): rank = rank + i4_choose(ns - j, ks - i) for n in range(0, nc): rank = rank + i4_choose(n + kc - 1, n) return rank
def mono_total_next_grevlex ( m, n, x ): #*****************************************************************************80 # ## MONO_TOTAL_NEXT_GREVLEX: grevlex next monomial, total degree equal to N. # # Discussion: # # We consider all monomials in an M-dimensional space, with total # degree N. # # For example: # # M = 3 # N = 3 # # # X(1) X(2) X(3) Degree # +------------------------ # 1 | 0 0 3 3 # 2 | 0 1 2 3 # 3 | 1 0 2 3 # 4 | 0 2 1 3 # 5 | 1 1 1 3 # 6 | 2 0 1 3 # 7 | 0 3 0 3 # 8 | 1 2 0 3 # 9 | 2 1 0 3 # 10 | 3 0 0 3 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 24 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # # Input, integer N, the total degree. # 0 <= N1 <= N2. # # Input, integer X[M], the current monomial. # The first element is X = [ 0, 0, ..., 0, N ]. # The last is [ N, 0, ..., 0, 0 ]. # # Output, integer X[M], the next monomial. # from i4vec_sum import i4vec_sum from mono_next_grevlex import mono_next_grevlex if ( n < 0 ): print '' print 'MONO_TOTAL_NEXT_GREVLEX - Fatal error!' print ' N < 0.' sys.exit ( 'MONO_TOTAL_NEXT_GREVLEX - Fatal error!' ) if ( i4vec_sum ( m, x ) != n ): print '' print 'MONO_TOTAL_NEXT_GREVLEX - Fatal error!' print ' Input X sums is not N.' sys.exit ( 'MONO_TOTAL_NEXT_GREVLEX - Fatal error!' ) if ( n == 0 ): return x if ( x[0] == n ): x[0] = 0 x[m-1] = n else: x = mono_next_grevlex ( m, x ) return x
def mono_rank_grlex(m, x): #*****************************************************************************80 # ## MONO_RANK_GRLEX computes the graded lexicographic rank of a monomial. # # Discussion: # # The graded lexicographic ordering is used, over all monomials in # M dimensions, for total degree = 0, 1, 2, ... # # For example, if M = 3, the ranking begins: # # Rank Sum 1 2 3 # ---- --- -- -- -- # 1 0 0 0 0 # # 2 1 0 0 1 # 3 1 0 1 0 # 4 1 1 0 1 # # 5 2 0 0 2 # 6 2 0 1 1 # 7 2 0 2 0 # 8 2 1 0 1 # 9 2 1 1 0 # 10 2 2 0 0 # # 11 3 0 0 3 # 12 3 0 1 2 # 13 3 0 2 1 # 14 3 0 3 0 # 15 3 1 0 2 # 16 3 1 1 1 # 17 3 1 2 0 # 18 3 2 0 1 # 19 3 2 1 0 # 20 3 3 0 0 # # 21 4 0 0 4 # .. .. .. .. .. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 31 October 2015 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # 1 <= M. # # Input, integer X[M], the composition. # For each 1 <= I <= M, we have 0 <= X(I). # # Output, integer RANK, the rank. # from i4_choose import i4_choose from i4vec_sum import i4vec_sum import numpy as np # # Ensure that 1 <= M. # if (m < 1): print '' print 'MONO_RANK_GRLEX - Fatal error!' print ' M < 1' sys.exit('MONO_RANK_GRLEX - Fatal error!') # # Ensure that 0 <= X(I). # for i in range(0, m): if (x[i] < 0): print '' print 'MONO_RANK_GRLEX - Fatal error!' print ' X[I] < 0' sys.exit('MONO_RANK_GRLEX - Fatal error!') # # NM = sum ( X ) # nm = i4vec_sum(m, x) # # Convert to KSUBSET format. # ns = nm + m - 1 ks = m - 1 if (0 < ks): xs = np.zeros(ks, dtype=np.int32) xs[0] = x[0] + 1 for i in range(2, m): xs[i - 1] = xs[i - 2] + x[i - 1] + 1 # # Compute the rank. # rank = 1 for i in range(1, ks + 1): if (i == 1): tim1 = 0 else: tim1 = xs[i - 2] if (tim1 + 1 <= xs[i - 1] - 1): for j in range(tim1 + 1, xs[i - 1]): rank = rank + i4_choose(ns - j, ks - i) for n in range(0, nm): rank = rank + i4_choose(n + m - 1, n) return rank
def comp_next_grlex_test ( ): #*****************************************************************************80 # ## COMP_NEXT_GRLEX_TEST tests COMP_NEXT_GRLEX. # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 30 October 2014 # # Author: # # John Burkardt # from i4vec_sum import i4vec_sum import numpy as np kc = 3 print '' print 'COMP_NEXT_GRLEX_TEST' print ' A COMP is a composition of an integer N into K parts.' print ' Each part is nonnegative. The order matters.' print ' COMP_NEXT_GRLEX determines the next COMP in' print ' graded lexicographic (grlex) order.' xc = np.zeros ( kc, dtype = np.int32 ) print '' print ' Rank: NC COMP' print ' ----: -- ------------' for rank in range ( 1, 72 ): if ( rank == 1 ): for j in range ( 0, kc ): xc[j] = 0 else: xc = comp_next_grlex ( kc, xc ) nc = i4vec_sum ( kc, xc ) print ' %3d: ' % ( rank ), print ' %2d = ' % ( nc ), for j in range ( 0, kc - 1 ): print '%2d + ' % ( xc[j] ), print '%2d' % ( xc[kc-1] ) # # When XC(1) == NC, we have completed the compositions associated with # a particular integer, and are about to advance to the next integer. # if ( xc[0] == nc ): print ' ----: -- ------------' # # Terminate. # print '' print 'COMP_NEXT_GRLEX_TEST:' print ' Normal end of execution.' return
def mono_between_next_grevlex(m, n1, n2, x): #*****************************************************************************80 # ## MONO_BETWEEN_NEXT_GREVLEX: grevlex next monomial, degree between N1 and N2. # # Discussion: # # We consider all monomials in an M-dimensional space, with total # degree N between N1 and N2, inclusive. # # For example: # # M = 3 # N1 = 2 # N2 = 3 # # # X(1) X(2) X(3) Degree # +------------------------ # 1 | 0 0 2 2 # 2 | 0 1 1 2 # 3 | 1 0 1 2 # 4 | 0 2 0 2 # 5 | 1 1 0 2 # 6 | 2 0 0 2 # | # 7 | 0 0 3 3 # 8 | 0 1 2 3 # 9 | 1 0 2 3 # 10 | 0 2 1 3 # 11 | 1 1 1 3 # 12 | 2 0 1 3 # 13 | 0 3 0 3 # 14 | 1 2 0 3 # 15 | 2 1 0 3 # 16 | 3 0 0 3 # # Licensing: # # This code is distributed under the GNU LGPL license. # # Modified: # # 24 October 2014 # # Author: # # John Burkardt # # Parameters: # # Input, integer M, the spatial dimension. # # Input, integer N1, N2, the minimum and maximum degrees. # 0 <= N1 <= N2. # # Input, integer X[M], the current monomial. # The first element is X = [ 0, 0, ..., 0, N1 ]. # The last is [ N2, 0, ..., 0, 0 ]. # # Output, integer X[M], the next monomial. # from i4vec_sum import i4vec_sum from mono_next_grevlex import mono_next_grevlex if (n1 < 0): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' N1 < 0.' sys.exit('MONO_BETWEEN_NEXT_GREVLEX - Fatal error!') if (n2 < n1): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' N2 < N1.' sys.exit('MONO_BETWEEN_NEXT_GREVLEX - Fatal error!') if (i4vec_sum(m, x) < n1): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' Input X sums to less than N1.' sys.exit('MONO_BETWEEN_NEXT_GREVLEX - Fatal error!') if (n2 < i4vec_sum(m, x)): print '' print 'MONO_BETWEEN_NEXT_GREVLEX - Fatal error!' print ' Input X sums to more than N2.' sys.exit('MONO_BETWEEN_NEXT_GREVLEX - Fatal error!') if (n2 == 0): return x if (x[0] == n2): x[0] = 0 x[m - 1] = n1 else: x = mono_next_grevlex(m, x) return x