|
- import numpy as np
- import itertools
- import sys
-
-
- def s_n(n):
- return list(itertools.permutations(range(1,n+1)))
-
- def canon_tab(n):
- return list(range(1,n+1))
-
- def split_rows(part, lst):
- assert(sorted(part, reverse=True) == part)
- n = sum(part)
- xs = lst.copy()
- split = []
- for s in part:
- split.append(xs[0:s])
- xs = xs[s:]
- return split
-
- def is_row_stab(part, perm):
- n = sum(part)
- assert(len(perm) == n)
- return list(map(sorted, split_rows(part, canon_tab(n)))) == list(map(sorted, split_rows(part, list(perm))))
-
- def cycles(perm):
- cycles = []
- xs = list(range(1, len(perm)+1))
- while len(xs) > 0:
- c = [xs[0]]
- k = xs[0]
- while (perm[k-1] not in c):
- k = perm[k-1]
- c.append(k)
- xs = [ x for x in xs if x not in c ]
- cycles.append(c)
- return cycles
-
- def cycle_type(perm):
- cs = cycles(perm)
- types = {}
- for c in cs:
- if len(c) not in types:
- types[len(c)] = 1
- else:
- types[len(c)] += 1
- t = []
- for i in range(1, max(perm)+1):
- t.append(types.get(i, 0))
- return tuple(t)
-
- def conjugacy_classes(n):
- cs = {}
- for perm in s_n(n):
- ct = cycle_type(perm)
- if ct not in cs:
- cs[ct] = [perm]
- else:
- cs[ct].append(perm)
- l = list(cs.items())
- return sorted(l, key=lambda x: x[0], reverse=True)
-
- def partitions(n, conj_classes=None):
- parts = []
- if conj_classes == None:
- conj_classes = conjugacy_classes(n)
- for cycle_type, conj in conj_classes:
- part = []
- for i, c in enumerate(cycle_type):
- for s in range(0, c):
- part.append(i+1)
- parts.append(sorted(part, reverse=True))
- #parts.append([(i+1) * cycle_type[i] for i in range(0, n)])
- return list(sorted(parts, reverse=True))
-
- def psi(n):
- cs = conjugacy_classes(n)
- ps = partitions(n, cs)
- m = np.zeros((len(cs), len(cs)))
- for i, part in enumerate(ps):
- row_stabs = set(filter(lambda sigma: is_row_stab(part, sigma), s_n(n)))
- for j, (cycle_type, conj) in enumerate(cs):
- m[i, j] = len(row_stabs & set(conj)) * np.math.factorial(n) / (len(row_stabs) * len(conj))
- return m
-
- def sigma(n):
- cs = conjugacy_classes(n)
- m = np.zeros((len(cs), len(cs)))
- for i, (cycle_type, conj) in enumerate(cs):
- m[i, i] = len(conj) / np.math.factorial(n)
- return m
-
- if __name__ == '__main__':
- if len(sys.argv) >= 2:
- n = int(sys.argv[1])
- else:
- n = 3
-
- psi = psi(n)
- sigma = sigma(n)
-
- a = np.dot(psi, np.dot(sigma, np.transpose(psi)))
- k = np.linalg.cholesky(a)
- x = np.dot(np.linalg.inv(k), psi)
- print("Character table for S_n where n =", n)
- print("Rows are indexed by partitions and columns by conjugacy classes")
- print(x.round())
|