Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
""" Python interface to partition backtrack functions
EXAMPLES::
sage: import sage.groups.perm_gps.partn_ref.refinement_python
This module provides Python frontends to the Cython-based partition backtrack functions. This allows one to write the three input functions (all_children_are_equivalent, refine_and_return_invariant, and compare_structures) in pure Python, and still use the Cython algorithms. Experimentation with specific partition backtrack implementations no longer requires compilation, as the input functions can be dynamically changed at runtime.
NOTE:
This is not intended for production quality implementations of partition refinement, but instead for experimentation, learning, and use of the Python debugger.
"""
#***************************************************************************** # Copyright (C) 2006 - 2011 Robert L. Miller <rlmillster@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #*****************************************************************************
from cysignals.memory cimport sig_malloc, sig_free
from .data_structures cimport * from .automorphism_group_canonical_label cimport ( get_aut_gp_and_can_lab, aut_gp_and_can_lab, allocate_agcl_output, deallocate_agcl_output) from .double_coset cimport double_coset from sage.rings.integer cimport Integer
cdef class PythonPartitionStack: """ Instances of this class wrap a (Cython) PartitionStack. """
def __init__(self, int n): """ Initialize a PartitionStack.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) # implicit doctest
"""
def __dealloc__(self): """ Deallocate the PartitionStack.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: del(P) # implicit doctest
"""
def __repr__(self): """ Returns a string representing the stack.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P # implicit doctest PythonPartitionStack of degree 7 and depth 0.
"""
def display(self): """ Prints a representation of the stack.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.depth(1) 1 sage: P.set_level(2,1) sage: P.display() (0 1 2 3 4 5 6) (0 1 2|3 4 5 6)
"""
def is_discrete(self): """ Returns whether the deepest partition consists only of singleton cells.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.is_discrete() False sage: [P.set_level(i,0) for i in range(7)] [None, None, None, None, None, None, None] sage: P.is_discrete() True
"""
def num_cells(self): """ Returns the number of cells in the deepest partition.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.num_cells() 1
"""
def move_min_to_front(self, int start, int end): """ Makes sure that the first element of the segment of entries i with start <= i <= end is minimal.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.set_entry(1,0) sage: P.set_entry(0,1) sage: P.display() (1 0 2 3 4 5 6) sage: P.move_min_to_front(0,1) sage: P.display() (0 1 2 3 4 5 6)
"""
def __copy__(self): """
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: Q = copy(P) sage: P.display() (0 1 2 3 4 5 6) sage: Q.display() (0 1 2 3 4 5 6)
""" cdef PythonPartitionStack cpy
def clear(self): """ Sets the current partition to the first shallower one, i.e. forgets about boundaries between cells that are new to the current level.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.depth(1) 1 sage: P.set_level(2,1) sage: P.display() (0 1 2 3 4 5 6) (0 1 2|3 4 5 6) sage: P.clear() sage: P.display() (0 1 2 3 4 5 6) (0 1 2 3 4 5 6)
"""
def entries(self): """ Returns the entries array as a Python list of ints.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.entries() [0, 1, 2, 3, 4, 5, 6] sage: P.levels() [7, 7, 7, 7, 7, 7, -1]
""" cdef int i
def set_entry(self, int i, int entry): """ Sets the ith entry of the entries array to entry.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.set_entry(1,0) sage: P.set_entry(0,1) sage: P.display() (1 0 2 3 4 5 6)
"""
def get_entry(self, int i): """ Gets the ith entry of the entries array.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.get_entry(0) 0
"""
def levels(self): """ Return the levels array as a Python list of ints.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.entries() [0, 1, 2, 3, 4, 5, 6] sage: P.levels() [7, 7, 7, 7, 7, 7, -1]
"""
def set_level(self, int i, int level): """ Sets the ith entry of the levels array to entry.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.depth(1) 1 sage: P.set_level(2,1) sage: P.display() (0 1 2 3 4 5 6) (0 1 2|3 4 5 6)
"""
def get_level(self, int i): """ Gets the ith entry of the levels array.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.get_level(0) 7
"""
def depth(self, new=None): """ Returns the depth of the deepest partition in the stack, setting it to new if new is not None.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.depth() 0
"""
def degree(self, new=None): """ Returns the degree of the partition stack, setting it to new if new is not None.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.degree() 7
""" self.c_ps.degree = new
def partition(self, int k): """ Return the partition at level k, as a Python list of lists.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonPartitionStack sage: P = PythonPartitionStack(7) sage: P.depth(1) 1 sage: P.set_level(2,1) sage: P.partition(0) [[0, 1, 2, 3, 4, 5, 6]] sage: P.partition(1) [[0, 1, 2], [3, 4, 5, 6]]
""" cdef int i
""" Instances of this class wrap a Python object and the refinement functions. """ """ Initialize a PythonObjectWrapper.
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonObjectWrapper sage: def acae(a,b): ....: return 0 sage: def rari(a,b,c): ....: return 0 sage: def cs(a,b,c,d,e): ....: return 0 sage: from sage.groups.perm_gps.partn_ref.refinement_python import PythonObjectWrapper sage: P = PythonObjectWrapper(None, acae, rari, cs, 7) # implicit doctest sage: P.obj sage: P.degree 7 sage: P.acae_fn <function acae at ...> sage: P.rari_fn <function rari at ...> sage: P.cs_fn <function cs at ...>
"""
cdef bint all_children_are_equivalent_python(PartitionStack *PS, void *S): """ Python conversion of all_children_are_equivalent function. """
cdef int refine_and_return_invariant_python(PartitionStack *PS, void *S, int *cells_to_refine_by, int ctrb_len): """ Python conversion of refine_and_return_invariant function. """ cdef int i
cdef int compare_structures_python(int *gamma_1, int *gamma_2, void *S1, void *S2, int degree): """ Python conversion of compare_structures function. """ cdef int i
all_children_are_equivalent, refine_and_return_invariant, compare_structures, canonical_label, base, order): """ Calls the automorphism group and canonical label function.
INPUT:
S -- the object to examine partition -- an ordered partition, as a list of lists n -- the degree of the automorphism group to be computed
::
all_children_are_equivalent -- Python function of "signature": bool all_children_are_equivalent(PythonPartitionStack, object) refine_and_return_invariant -- Python function of "signature": int refine_and_return_invariant(PythonPartitionStack, object, list) compare_structures -- Python function of "signature": int compare_structures(list, list, object, object) (see automorphism_group_canonical_label.pyx for more documentation)
::
canonical_label -- boolean; whether to search for a canonical label base -- boolean; whether to return a base for the automorphism group order -- boolean; whether to return the order of the automorphism group
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import aut_gp_and_can_lab_python sage: def acae(a,b): ....: return 0 sage: def rari(a,b,c): ....: return 0 sage: def cs(a,b,c,d,e): ....: return 0 sage: aut_gp_and_can_lab_python(None, [[0,1,2,3],[4,5]], 6, acae, rari, cs, True, True, True) ([[0, 1, 3, 2, 4, 5], [0, 2, 1, 3, 4, 5], [1, 0, 2, 3, 4, 5], [0, 1, 2, 3, 5, 4]], [0, 1, 2, 3, 4, 5], [4, 0, 1, 2], 48) sage: factorial(4)*factorial(2) 48
""" cdef aut_gp_and_can_lab *output cdef int i, j cdef Integer I
raise MemoryError
&all_children_are_equivalent_python, &refine_and_return_invariant_python, &compare_structures_python,
return return_tuple[0] else:
all_children_are_equivalent, refine_and_return_invariant, compare_structures): """ Calls the double coset function.
INPUT:
S1, S2 -- the objects to examine partition1 -- an ordered partition, as a list of lists ordering2 -- represents a partition of the points of S2, as a relabeling of partition1 n -- the degree
::
all_children_are_equivalent -- Python function of "signature": bool all_children_are_equivalent(PythonPartitionStack, object) refine_and_return_invariant -- Python function of "signature": int refine_and_return_invariant(PythonPartitionStack, object, list) compare_structures -- Python function of "signature": int compare_structures(list, list, object, object) (see double_coset.pyx for more documentation)
EXAMPLES::
sage: from sage.groups.perm_gps.partn_ref.refinement_python import double_coset_python sage: def acae(a,b): ....: return 0 sage: def rari(a,b,c): ....: return 0 sage: def cs(a,b,c,d,e): ....: return 0 sage: double_coset_python(None, None, [[0,1,2,3],[4,5]], [2,3,1,5,0,4], 6, acae, rari, cs) [1, 2, 3, 5, 0, 4]
sage: def compare_lists(p1,p2,l1,l2,deg): ....: for i in range(len(l1)): ....: a1 = l1[p1[i]] ....: a2 = l2[p2[i]] ....: if a1 < a2: return -1 ....: if a1 > a2: return 1 ....: return 0
sage: double_coset_python([0,0,1], [1,0,0], [[0,1,2]], [0,1,2], 3, acae, rari, compare_lists) [1, 2, 0]
"""
PS_dealloc(part) sig_free(ordering) sig_free(output) raise MemoryError
&all_children_are_equivalent_python, &refine_and_return_invariant_python, &compare_structures_python, NULL, NULL, output)
else: output_py = False
|