Skip to content
Permalink
Browse files

long-needed update

  • Loading branch information...
cheyneh committed Nov 13, 2015
1 parent fa450b5 commit 688c4c27b564daffeb27ddbadcfd8f3b0a0ef1f0
@@ -1,5 +1,7 @@
*.py[cod]
*.sublime*
.dropbox
.DS_STORE
avoidencegrid.py
OLD_permtools.py
OLD_permtools.py
Icon
No changes.
@@ -0,0 +1,3 @@

from configuration import Configuration
from insertionscheme import InsertionScheme
@@ -0,0 +1,107 @@
from ..permutation import *


class Configuration(tuple):
_basis = set()
_type = ''
_children_computed = False
_children = set()

def __new__(cls, t, basis=set(), childtype='?'):
entries = list(t)
nonzero = [x for x in entries if x != 0]
assert len(set(nonzero)) == len(nonzero), 'Nonzero entries must be distinct.'
for i in range(len(entries)-1):
assert entries[i] != 0 or entries[i+1] != 0, 'Two slots cannot be adjacent.'
standardization = [0]*len(entries)
values = sorted(nonzero)
for i in range(1, len(values)+1):
standardization[entries.index(values[i-1])] = i
return tuple.__new__(cls, standardization)

def __init__(self, t, basis=set(), childtype='?'):
self._basis = basis
self._type = childtype
if childtype == '?':
t = ''
if len(self) == 1:
t = 'f1'
else:
loc = self.index(max(self))
if loc == 0:
if self[1] == 0:
t = 'l1'
else:
t = 'f1'
elif loc == len(self) - 1:
if self[len(self)-2] == 0:
t = 'r'+str(self.num_slots())
else:
t = 'f'+str(self.num_slots()+1)
else:
if self[loc-1] == 0 and self[loc+1] == 0:
t = 'm'+str(len([k for k in self[:loc] if k == 0]))
elif self[loc-1] == 0:
t = 'r'+str(len([k for k in self[:loc] if k == 0]))
elif self[loc+1] == 0:
t = 'l'+str(len([k for k in self[:loc] if k == 0])+1)
else:
t = 'f'+str(len([k for k in self[:loc+1] if k == 0])+1)
self._type = t

def num_slots(self):
return len([x for x in self if x == 0])

def slot_locs(self):
return [i for i in range(len(self)) if self[i] == 0]

def children(self):
if self._children_computed:
return self._children
S = set()
max_entry = len(self)+1
L = list(self)
sl = self.slot_locs()
for i in sl:
S.add(Configuration(L[:i]+[max_entry]+L[i+1:], self._basis, 'f'+str(sl.index(i)+1)))
S.add(Configuration(L[:i+1]+[max_entry]+L[i+1:], self._basis, 'r'+str(sl.index(i)+1)))
S.add(Configuration(L[:i]+[max_entry]+L[i:], self._basis, 'l'+str(sl.index(i)+1)))
S.add(Configuration(L[:i+1]+[max_entry]+L[i:], self._basis, 'm'+str(sl.index(i)+1)))
self._children = S
self._children_computed = True
return self._children

def is_permutation(self):
return self.num_slots() == 0

def to_perm(self):
if self.is_permutation():
return Permutation(self)
else:
return False

def has_valid_filling(self, C=[]):
if self.is_permutation():
return True
if len(C) - 1 >= self.num_slots():
filling_entries = C[self.num_slots()]
else:
filling_entries = Permutation.listall(self.num_slots())
for P in filling_entries:
L = list(self)
slot_locs = self.slot_locs()
for (p,v) in enumerate(P):
L[slot_locs[p]] = v+len(L)
filled_perm = Permutation(L)
if len(C) < len(filled_perm) + 1:
# if len(C) > 2:
# print 'needed length',(len(filled_perm)),'but only had',(len(C)-1),'[for',self,'/',filled_perm,']'
if filled_perm.avoids_set(self._basis):
return True
else:
if filled_perm in C[len(filled_perm)]:
return True
return False

def valid_children(self, C=[]):
return set([c for c in self.children() if c.has_valid_filling(C)])
@@ -0,0 +1,188 @@
from ..permutation import Permutation
from ..avclass import AvClass
from ..permset import PermSet
from configuration import Configuration
import sympy
import random

class InsertionScheme():
_tree = {}
_basis = []
_max_basis_length = 0
_automaton = {}
_root = None
_configs_checked = set()
_automaton_ready = False
_has_inssch = False
_reductions = {}
_class = []

def __init__(self, basis, quiet=False):
self._basis = basis
self._max_basis_length = max([len(b) for b in self._basis])
self._class = AvClass(basis, 1)
self._configs_checked = set()
self._automaton_ready = False
self._root = Configuration((0,), self._basis, 'm')
self._perm = Configuration((1,), self._basis, 'f')
self._tree = {self._root: self._root.children()}
self._automaton = {self._root: list(self._root.children())}
self._has_inssch = False
self._reductions = {}
self._automaton_ready = False
if self.has_inssch():
self._has_inssch = True
else:
syms = PermSet(self._basis).all_syms()
for S in syms:
self._basis = S
if self.has_inssch():
self._has_inssch = True
if not quiet:
print 'Av(',basis,') does not have an insertion scheme, but its symmetry Av(',S,') does.'
break
if not self._has_inssch:
if not quiet:
print 'Neither this class nor its symmetries has an insertion scheme.'


def has_inssch(self):
types = [
PermSet([Permutation(321), Permutation(2143), Permutation(2413)]),
PermSet([Permutation(123), Permutation(3142), Permutation(3412)]),
PermSet([Permutation(132), Permutation(312)]),
PermSet([Permutation(213), Permutation(231)])
]
return all([any([all([b.avoids(p) for p in B]) for b in self._basis]) for B in types])

def follow_reduce(self,config):
while config in self._reductions.keys():
config = self._reductions[config]
return config


def build_rules(self, verbose=True, make_class=False, class_bound=100):
configs_to_check = [Configuration((0,), self._basis)]
while len(configs_to_check) > 0:
if verbose:
print '\tstates to check:',len(configs_to_check),', nodes in tree:',len(self._tree.keys()),', states:', len(self._automaton)
configs_to_check.sort(key=len)
current_config = configs_to_check[0]
if verbose:
print '\nChecking:',current_config
self._configs_checked.add(current_config)

if current_config.is_permutation():
if verbose:
print current_config,'is not reducible'
configs_to_check.remove(current_config)
continue

length_to_check = self._max_basis_length + current_config.num_slots() - 2

reducible = False
order_to_check = sorted(range(len(current_config)), key=lambda i : current_config[i], reverse=True)
checked_already = list()
for i in order_to_check:
if current_config[i] == 0 or (i > 0 and i < len(current_config)-1 and current_config[i-1] == 0 and current_config[i+1] == 0):
continue
second_config = Configuration(current_config[:i]+current_config[i+1:], self._basis, '?')
if second_config in checked_already:
continue
checked_already.append(second_config)
if verbose:
print 'Checking isomorphism (depth='+str(length_to_check)+'):',current_config, '<->', second_config
if self.check_isomorphism(current_config, second_config, length_to_check, make_class, class_bound):
self._reductions[current_config] = second_config
if verbose:
print current_config,'is reducible to',second_config
if current_config in self._automaton.keys():
del self._automaton[current_config]
for config in self._automaton.keys():
if current_config in self._automaton[config]:
self._automaton[config].remove(current_config)
self._automaton[config].append(self.follow_reduce(second_config))
configs_to_check.append(second_config)
reducible = True
break
if not reducible:
if verbose:
print current_config,'is not reducible'
if make_class and len(self._class) < len(current_config) + 2 and len(current_config) + 2 <= class_bound:
if verbose:
print '\t\t\tExtending class length from ', (len(self._class) - 1), 'to', (len(current_config) + 2), 'for', current_config, '(!)'
self._class.extend_to_length(len(current_config)+2)
if verbose:
print '\t\t\t\tDone!'

# print '3'
TTT = current_config.valid_children(self._class)
self._automaton[current_config] = list(TTT)
configs_to_check.extend(TTT)

configs_to_check.remove(current_config)
configs_to_check = list(set(configs_to_check).difference(self._configs_checked))

self.standardize_perms()
self._automaton_ready = True

def standardize_perms(self):
for config in self._automaton.keys():
for c in self._automaton[config]:
if c.is_permutation():
self._automaton[config].remove(c)
self._automaton[config].append(self._perm)


def check_isomorphism(self, c1, c2, depth, make_class=False, class_bound=100):
# print '\t\tCI:',depth,c1,c2,len(self._tree.keys())
if depth == 0 or c1.is_permutation() or c2.is_permutation():
if c1.is_permutation() != c2.is_permutation():
pass
# print c1,c2
return c1.is_permutation() == c2.is_permutation()
if c1 not in self._tree.keys():
if make_class and len(self._class) < len(c1) + 3 and len(c1) + 2 <= class_bound:
print '\t\t\tExtending class length from ', (len(self._class)-1), 'to', (len(c1) + 2), 'for', c1, '(@)'
self._class.extend_to_length(len(c1)+2)
print '\t\t\t\tDone!'
# print '1',c1,len(c1)
self._tree[c1] = c1.valid_children(self._class)
if c2 not in self._tree.keys():
if make_class and len(self._class) < len(c2) + 3 and len(c2) + 2 <= class_bound:
print '\t\t\tExtending class length from ', (len(self._class)-1), 'to', (len(c2) + 2), 'for', c2, '(#)'
self._class.extend_to_length(len(c2)+2)
print '\t\t\t\tDone!'
# print '2'
self._tree[c2] = c2.valid_children(self._class)
c1kids = {c._type : c for c in self._tree[c1]}
c2kids = {c._type : c for c in self._tree[c2]}
if set(c1kids.keys()) != set(c2kids.keys()):
# print c1,c2,c1kids,c2kids
return False
# if random.randint(1,1000) == 535:
# print '\tnum states:',len(self._tree), '\tdepth:',depth
return all([self.check_isomorphism(c1kids[i], c2kids[i], depth-1, make_class, class_bound) for i in c1kids.keys()])

def gf(self, verbose=False, show_series=False):
if not self._automaton_ready:
self.build_rules(verbose=verbose)
states = self._automaton.keys()
states.append(self._perm)

x = sympy.Symbol('x')
transitions = []
for s1 in states:
t = []
for s2 in states:
if s1 in self._automaton.keys() and s2 in self._automaton[s1]:
t.append(self._automaton[s1].count(s2)*x)
else:
t.append(0)
transitions.append(t)
M = (sympy.eye(len(states))-sympy.Matrix(transitions)) ** -1
f = (1+M[states.index(self._root),states.index(self._perm)]).factor()
if show_series:
print f.series(x,0,11)
return f

@@ -0,0 +1,3 @@


from restricted_container import RestrictedContainer
@@ -0,0 +1,56 @@

from ..permutation import *
from ..avclass import *





class RestrictedContainer(object):

def __init__(self, basis_list, input_list, container = [], output_list = []):
self.input_list = (input_list if type(input_list) == list else range(1,input_list+1))
self.output_list = output_list
self.basis_list = [Permutation(b) for b in basis_list]
self.container = container


def push(self, position):
if len(self.input_list) == 0:
return -1
new_container = self.container[:position] + [self.input_list[0]] + self.container[position:]
for basis in self.basis_list:
if basis.involved_in( Permutation(new_container) ):
return -1
else:
return RestrictedContainer(self.basis_list, self.input_list[1:], new_container, self.output_list)

def pop(self):
if len(self.container) == 0:
return -1
popped = self.container[0]
new_output = self.output_list + [popped]
return RestrictedContainer(self.basis_list, self.input_list, self.container[1:], new_output)

def __repr__(self):
return "{} | {} | {}".format(self.output_list,self.container, self.input_list)

def container_size(self):
return len(self.container)

def output_size(self):
return len(self.input_list)

def input_size(self):
return len(self.input_list)

def output(self):
return self.output_list








@@ -1,11 +1,15 @@


from __future__ import print_function
from .permset import PermSet
from .permutation import Permutation
from .pegpermutation import PegPermutation
from .permset import PermSet
from .permclass import PermClass
from .avclass import AvClass
from .pegpermset import PegPermSet
from .geometricgridclass import GeometricGridClass
from .InsertionEncoding import *
import RestrictedContainer

Perm = Permutation
Av = AvClass
Av = AvClass
Oops, something went wrong.

0 comments on commit 688c4c2

Please sign in to comment.
You can’t perform that action at this time.