LPASeed
|
Initialise a Laurent phenomenon algebra seed. More...
Public Member Functions | |
__init__ (self, data, coefficients=(), base_ring=ZZ) | |
Initialize an LP seed. | |
mutate (self, i, inplace=True) | |
Mutate this seed at the i th index. | |
is_mutation_equivalent (self, other_seed) | |
Return whether this seed and other_seed are mutation equivalent. | |
mutation_class_iter (self, depth=infinity, verbose=False, return_paths=False, algorithm='BFS') | |
Return an iterator for the mutation class of this seed. | |
mutation_class (self, depth=infinity, verbose=False, return_paths=False, algorithm='BFS') | |
Return the mutation class of self with respect to certain constraints. | |
cluster_class_iter (self, depth=infinity, verbose=False, algorithm='BFS') | |
Iterator for the cluster class of self with respect to certain constraints. | |
cluster_class (self, depth=infinity, verbose=False, algorithm='BFS') | |
Return the cluster class of self with respect to certain constraints. | |
variable_class_iter (self, depth=infinity, algorithm='BFS') | |
Return an iterator for all cluster variables in the mutation class of self in seeds at most depth away from self. | |
variable_class (self, depth=infinity) | |
Return all cluster variables in the mutation class of self. | |
is_equivalent (self, other) | |
Return whether self and other are equivalent as LP seeds. | |
exchange_graph (self) | |
Return the exchange graph of self. | |
cluster (self) | |
Return the cluster variables of self. | |
exchange_polys (self) | |
Return the exchange polynomials of self. | |
laurent_polys (self) | |
Return the exchange Laurent polynomials of self. | |
rank (self) | |
Return the rank of self. | |
randomly_mutate (self, depth, inplace=True) | |
Randomly mutates this seed at depth indices. | |
mutation_sequence (self) | |
Return the list of indices we have mutated self at. | |
__eq__ (self, other) | |
Check if self and other are equal. | |
__hash__ (self) | |
Return a hash of self. | |
are_laurent_polys_trivial (self) | |
Return whether this seed has Laurent polynomials with nontrivial denominators. | |
is_mutation_infinite (self, give_reason=True) | |
Perform some heuristic checks on the mutation class of this seed to work out if it is mutation infinite or not. | |
passes_rank_two_check (self) | |
Check that, when restricting to any two variables, that the product of the degrees is strictly less than 4. | |
get_laurent_poly_denominators (self) | |
Return a list containing the denominators of the Laurent polynomials for this seed. |
Static Public Member Functions | |
create_generic_seed (vars, polys) |
Protected Member Functions | |
_check_seed (self) | |
Perform some mathematical checks on this seed. | |
_compute_laurent (self) | |
Compute the exchange Laurent polynomials of self. | |
_mutation_class_iter_bfs (self, depth=infinity, verbose=False, return_paths=False) | |
_mutation_class_iter_dfs (self, depth=infinity, verbose=False, return_paths=False) | |
_copy_ (self) | |
Return a copy of self. | |
_repr_ (self) | |
Return a string representation of self. | |
_latex_ (self) | |
Return a \LaTeX representation of this seed. |
Initialise a Laurent phenomenon algebra seed.
This example initialises a linear Laurent phenomenon algebra in two variables::
sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage S A seed with cluster variables [x1, x2] and exchange polynomials [x2 + 1, x1 + 1]
We add some coefficients to get the generic linear LP algebra in three variables::
sage var('x1,x2,x3,a0,a2,a3,b0,b1,b3,c0,c1,c2') (x1, x2, x3, a0, a2, a3, b0, b1, b3, c0, c1, c2) sage S = LPASeed({x1: a0 + a2*x2 + a3*x3, x2: b0 + b1*x1 + b3*x3, x3: c0 + c1*x1 + c2*x2}, coefficients=[a0,a2,a3,b0,b1,b3,c0,c1,c2],base_ring=ZZ) sage S A seed with cluster variables [x1, x2, x3] and exchange polynomials [x2*a2 + x3*a3 + a0, x1*b1 + x3*b3 + b0, x1*c1 + x2*c2 + c0]
More complicated polynomials are allowed, as long as they are irreducible::
sage var('x1,x2,x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2*x3^2 + 4*x3^3, x2: 2 - x1^2, x3: 4 + x1^3*x2^2 - 3*x1}) sage S A seed with cluster variables [x1, x2, x3] and exchange polynomials [x2*x3^2 + 4*x3^3 + 1, -x1^2 + 2, x1^3*x2^2 - 3*x1 + 4]
Nonirreducible polynomials will raise an exception::
sage var('x1, x2') (x1, x2) sage S = LPASeed({x1: 4 - x2^2, x2: 1 + x1}) Traceback (most recent call last): ... ValueError (LP2) fail: -x2^2 + 4 is not irreducible over Integer Ring
Different base rings are allowed::
sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}, base_ring=QQ) sage S A seed with cluster variables [x1, x2] and exchange polynomials [x2 + 1, x1 + 1]
lp_algebra_seed.LPASeed.__init__ | ( | self, | |
data, | |||
coefficients = (), | |||
base_ring = ZZ ) |
Initialize an LP seed.
EXAMPLES::
sage var('x1, x2, x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}) sage TestSuite(S).run()
lp_algebra_seed.LPASeed.__eq__ | ( | self, | |
other ) |
Check if self and other are equal.
This means checking that they are equivalent.
TESTS::
sage var('x1') x1 sage S = LPASeed({x1:2},base_ring=ZZ) sage T = S.mutate(0, inplace=False) sage T==S False
lp_algebra_seed.LPASeed.__hash__ | ( | self | ) |
Return a hash of self.
We check that two seeds with the same hash are equal:: sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage T = LPASeed(S) sage S.mutate([0,1,0]) A seed with cluster variables [(x1 + 1)/x2, (x1 + x2 + 1)/(x1*x2)] and exchange polynomials [x2 + 1, x1 + 1] sage T.mutate([1,0]) A seed with cluster variables [(x1 + x2 + 1)/(x1*x2), (x1 + 1)/x2] and exchange polynomials [x2 + 1, x1 + 1] sage hash(S) == hash(T) True sage S == T True
|
protected |
Perform some mathematical checks on this seed.
This includes checking that each exchange polynomial does not depend on its corresponding cluster variable, that each exchange polynomial is irreducible, and finally that no cluster variable divides any exchange polynomial. TESTS::
sage var('x1, x2') (x1, x2) sage LPASeed({x1: 1}) Traceback (most recent call last): ... ValueError (LP2) fail: 1 is not irreducible over Integer Ring
sage LPASeed({x1: 0}) Traceback (most recent call last): ... ValueError (LP2) fail: exchange polynomial is zero
sage LPASeed({x1: 1 + 2*x2, x2: 3 + 4*x1}) A seed with cluster variables [x1, x2] and exchange polynomials [2*x2 + 1, 4*x1 + 3]
|
protected |
Compute the exchange Laurent polynomials of self.
This should leave the seed invariant:: sage var('x1, x2, a') (x1, x2, a) sage S = LPASeed({x1: a, x2: a}, coefficients=[a]) sage S._compute_laurent() sage S.laurent_polys() [a/x2, a/x1]
|
protected |
Return a copy of self.
TESTS::
sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage T1 = S._copy_() sage T1.mutate(0, inplace=True) A seed with cluster variables [(x2 + 1)/x1, x2] and exchange polynomials [x2 + 1, x1 + 1] sage T2 = S.mutate(0, inplace=False) sage T1==T2 True
|
protected |
Return a \LaTeX representation of this seed.
TESTS::
sage var('x1, x2') (x1, x2) sage latex(LPASeed({x1: 1 + x2, x2: 1 + x1})) \left(\left(x_{1}, x_{2} + 1\right), \left(x_{2}, x_{1} + 1\right)\right)
|
protected |
Return a string representation of self.
TESTS::
sage var('x1, x2') (x1, x2) sage print(LPASeed({x1: 1 + x2, x2: 1 + x1})) A seed with cluster variables [x1, x2] and exchange polynomials [x2 + 1, x1 + 1]
lp_algebra_seed.LPASeed.cluster | ( | self | ) |
Return the cluster variables of self.
Get the cluster variables after performing a mutation:: sage var('x1, x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage S.mutate(0) A seed with cluster variables [(x2 + 1)/x1, x2] and exchange polynomials [x2 + 1, x1 + 1] sage S.cluster() [(x2 + 1)/x1, x2]
lp_algebra_seed.LPASeed.cluster_class | ( | self, | |
depth = infinity, | |||
verbose = False, | |||
algorithm = 'BFS' ) |
Return the cluster class of self with respect to certain constraints.
.. SEEALSO::
:meth:`mutation_class_iter`
- ``depth`` -- (default: ``infinity``) integer, only clusters with distance at most ``depth`` from ``self`` are returned - ``verbose`` -- (default: ``False``) if ``True``, the actual depth of the mutation is shown - ``return_paths`` -- (default: ``False``) if ``True``, a path of mutation sequences from ``self`` to the given seed is returned as well - ``algorithm`` -- string (default: ``'BFS'``); the search algorithm to find new seeds; currently supported options: * 'BFS' - breadth-first search * 'DFS' - depth-first search .. SEEALSO:: For further examples see :meth:`cluster_class_iter`. TESTS:: sage var('x1, x2, x3') (x1, x2, x3) sage LPASeed({x1: 2},base_ring=ZZ).cluster_class() [[x1], [2/x1]]
lp_algebra_seed.LPASeed.cluster_class_iter | ( | self, | |
depth = infinity, | |||
verbose = False, | |||
algorithm = 'BFS' ) |
Iterator for the cluster class of self with respect to certain constraints.
.. SEEALSO::
:meth:`mutation_class_iter`
- ``depth`` -- (default: ``infinity``) integer, only clusters with distance at most ``depth`` from ``self`` are returned - ``verbose`` -- (default: ``False``) if ``True``, the actual depth of the mutation is shown - ``return_paths`` -- (default: ``False``) if ``True``, a path of mutation sequences from ``self`` to the given seed is returned as well - ``algorithm`` -- string (default: ``'BFS'``); the search algorithm to find new seeds; currently supported options: * 'BFS' - breadth-first search * 'DFS' - depth-first search
We check a classic example:: sage var('a,f,C') (a, f, C) sage S = LPASeed({a: f + C, f: a + C}, coefficients=[C]) sage t = S.cluster_class_iter() sage for cluster in t: print(cluster) [a, f] [(f + C)/a, f] [a, (a + C)/f] [(f + C)/a, (a + f + C)/(a*f)] [(a + f + C)/(a*f), (a + C)/f] .. SEEALSO:: For further examples see :meth:`mutation_class_iter`.
lp_algebra_seed.LPASeed.exchange_graph | ( | self | ) |
Return the exchange graph of self.
We work out the exchange graph for a rank-two example:: sage var('x1, x2') (x1, x2) sage LPASeed({x1: 1 + x2, x2: 1 + x1}).exchange_graph() Graph on 5 vertices .. PLOT:: var('x1, x2') G = LPASeed({x1: 1 + x2, x2: 1 + x1}).exchange_graph() sphinx_plot(G) A rank three example:: sage var('x1, x2, x3') (x1, x2, x3) sage LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}).exchange_graph() Graph on 10 vertices .. PLOT:: var('x1, x2, x3') G = LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}).exchange_graph() sphinx_plot(G)
lp_algebra_seed.LPASeed.exchange_polys | ( | self | ) |
Return the exchange polynomials of self.
Get the exchange polynomials after performing a mutation:: sage var('x1, x2') (x1, x2) sage S = LPASeed({x1: 3 + 4*x2, x2: 5 + 6*x1}) sage S.mutate(0) A seed with cluster variables [(4*x2 + 3)/x1, x2] and exchange polynomials [4*x2 + 3, 5*x1 + 18] sage S.exchange_polys() [4*x2 + 3, 5*x1 + 18]
lp_algebra_seed.LPASeed.is_equivalent | ( | self, | |
other ) |
Return whether self and other are equivalent as LP seeds.
Two seeds are equivalent if and only if there is a permutation of the cluster variables of one seed to get the cluster variables of the other seed, up to unit multipliers. Note we also overload equality to equivalence.
- ``other`` -- ``LPASeed``; the seed which we are comparing ``self`` to
Mutating this rank two example five times yields an equivalent seed:: sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage S.is_equivalent(S.mutate([0,1,0,1,0], inplace=False)) True
lp_algebra_seed.LPASeed.is_mutation_equivalent | ( | self, | |
other_seed ) |
Return whether this seed and other_seed are mutation equivalent.
- ``other_seed`` -- ``LPASeed`` object; the seed we wish to compare to
- ``True`` if the two seeds are mutation equivalent, and ``False`` otherwise
A seed is mutation equivalent to any of its mutations:: sage var('x1,x2,x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}) sage T = S.mutate(0, inplace=False) sage S.is_mutation_equivalent(T) True
lp_algebra_seed.LPASeed.is_mutation_infinite | ( | self, | |
give_reason = True ) |
Perform some heuristic checks on the mutation class of this seed to work out if it is mutation infinite or not.
Completely probabilistic and may false positive; do not use in research setting.
lp_algebra_seed.LPASeed.laurent_polys | ( | self | ) |
Return the exchange Laurent polynomials of self.
This seed has non-trivial exchange Laurent polynomials:: sage var('x1, x2, x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2 + x3, x2: 1 + x3, x3: 1 + x2}) sage S.laurent_polys() [(x2 + x3 + 1)/(x2*x3), x3 + 1, x2 + 1]
lp_algebra_seed.LPASeed.mutate | ( | self, | |
i, | |||
inplace = True ) |
Mutate this seed at the i th index.
- ``i`` -- integer or iterable of integers; the index/indices to mutate ``self`` at, where we index from 0 - ``inplace`` -- boolean (default: ``True``); whether to mutate the current instance of the seed, or return a new ``LPASeed`` object
We mutate a rank-two Laurent phenomenon algebra at the first index:: sage var('x1,x2,a0,a2,b0,b1') (x1, x2, a0, a2, b0, b1) sage S = LPASeed({x1: a0 + a2*x2, x2: b0 + b1*x1}, coefficients=[a0,a2,b0,b1]) sage S A seed with cluster variables [x1, x2] and exchange polynomials [x2*a2 + a0, x1*b1 + b0] sage S.mutate(0, inplace=True) A seed with cluster variables [(x2*a2 + a0)/x1, x2] and exchange polynomials [x2*a2 + a0, x1*b0 + a0*b1] Mutating at the same index is an involution:: sage var('x1,x2,x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2*x3, x2: 1 + x1^2 + x3^2, x3: 1 + x1 + x2}) sage T = S.mutate([2,2], inplace=False) sage T == S True
lp_algebra_seed.LPASeed.mutation_class | ( | self, | |
depth = infinity, | |||
verbose = False, | |||
return_paths = False, | |||
algorithm = 'BFS' ) |
Return the mutation class of self with respect to certain constraints.
.. SEEALSO::
:meth:`mutation_class_iter`
- ``depth`` -- (default: ``infinity``) integer, only seeds with distance at most ``depth`` from ``self`` are returned - ``verbose`` -- (default: ``False``) if ``True``, the actual depth of the mutation is shown - ``return_paths`` -- (default: ``False``) if ``True``, a path of mutation sequences from ``self`` to the given seed is returned as well - ``algorithm`` -- string (default: ``'BFS'``); the search algorithm to find new seeds; currently supported options: * 'BFS' - breadth-first search * 'DFS' - depth-first search
.. SEEALSO:: For further examples see :meth:`mutation_class_iter`. We validate the possible sizes of mutation classes in rank two:: sage var('x1,x2,A,B,C,D,E,F'); (x1, x2, A, B, C, D, E, F) sage S = LPASeed({x1: C, x2: C}, coefficients=[C]) sage len(S.mutation_class()) 3 sage S = LPASeed({x1: A, x2: C + D*x1}, coefficients=[A,C,D]) sage len(S.mutation_class()) 4 sage S = LPASeed({x1: A + B*x2, x2: C + D*x1}, coefficients=[A,B,C,D]) sage len(S.mutation_class()) 5 sage S = LPASeed({x1: A + B*x2 + C*x2^2, x2: D + E*x1}, coefficients=[A,B,C,D,E]) sage len(S.mutation_class()) 6 sage S = LPASeed({x1: A + B*x2 + C*x2^2 + D*x2^3, x2: E + F*x1}, coefficients=[A,B,C,D,E,F]) sage len(S.mutation_class()) 8
lp_algebra_seed.LPASeed.mutation_class_iter | ( | self, | |
depth = infinity, | |||
verbose = False, | |||
return_paths = False, | |||
algorithm = 'BFS' ) |
Return an iterator for the mutation class of this seed.
- ``depth`` -- Integer (default: ``infinity``); only return seeds at most ``depth`` mutations away from the initial seed - ``verbose`` -- Boolean (default: ``False``); if ``True``, the current depth of recursion for the chosen algorithm is shown while computing - ``return_paths`` -- Boolean (default: ``False``); if ``True``, a path of mutations from ``self`` to the given seed is returned as well - ``algorithm`` -- String (default: ``'BFS'``); the search algorithm to find new seeds. Currently supported options:: * 'BFS' - breadth-first search * 'DFS' - depth-first search
We iterate over the mutation class for a rank two seed:: sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage t = S.mutation_class_iter() sage for seed in t: print(seed.cluster()) [x1, x2] [(x2 + 1)/x1, x2] [x1, (x1 + 1)/x2] [(x2 + 1)/x1, (x1 + x2 + 1)/(x1*x2)] [(x1 + x2 + 1)/(x1*x2), (x1 + 1)/x2] Non finite-type works if we specify a fixed depth, but seeds can get big rather quickly:: sage var('x1,x2') (x1, x2) sage S = LPASeed({x1: 1 + x2 + x2^2, x2: 1 + x1 + x1^2}) sage t = S.mutation_class_iter(depth=15,algorithm='DFS') sage for seed in t: print(seed.cluster()[0].denominator()) # long time 1 x1 1 x1*x2^2 x1*x2^2 x1^3*x2^4 x1^3*x2^4 x1^5*x2^6 x1^5*x2^6 x1^7*x2^8 x1^7*x2^8 x1^9*x2^10 x1^9*x2^10 x1^11*x2^12 x1^11*x2^12 x1^13*x2^14 We can print computational statistics when computing examples:: sage var('x1,x2,x3,a0,a2,a3,b0,b1,b3,c0,c1,c2') (x1, x2, x3, a0, a2, a3, b0, b1, b3, c0, c1, c2) sage S = LPASeed({x1: a0 + a2*x2 + a3*x3, x2: b0 + b1*x1 + b3*x3, x3: c0 + c1*x1 + c2*x2}) sage t = S.mutation_class_iter(verbose=True) sage for seed in t: None depth 0 found: 1 depth 1 found: 4 depth 2 found: 10 depth 3 found: 16
lp_algebra_seed.LPASeed.mutation_sequence | ( | self | ) |
Return the list of indices we have mutated self at.
We look at the mutation sequences computed by the mutation class iterator:: sage var('x1, x2, x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}) sage t = S.mutation_class_iter(algorithm='BFS') sage for seed in t: print(seed.mutation_sequence()) [] [0] [1] [2] [0, 1] [0, 2] [1, 0] [1, 2] [2, 0] [2, 1] sage t = S.mutation_class_iter(algorithm='DFS') sage for seed in t: print(seed.mutation_sequence()) [] [0] [1] [2] [2, 0] [2, 1] [2, 1, 2] [2, 1, 2, 0] [2, 1, 2, 0, 2] [2, 1, 2, 0, 2, 0]
lp_algebra_seed.LPASeed.randomly_mutate | ( | self, | |
depth, | |||
inplace = True ) |
Randomly mutates this seed at depth indices.
Useful for working out if a seed produces a finite type LP algebra.
- ``depth`` -- integer, the number of random mutations to perform.
Check that randomly mutating a seed keeps it within the mutation class:: sage var('x1,x2,x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}) sage T = LPASeed(S) sage S.randomly_mutate(5) # random sage S in T.mutation_class() True
lp_algebra_seed.LPASeed.rank | ( | self | ) |
Return the rank of self.
This is the number of cluster variables in self.
The rank is the number of cluster variables in the seed:: sage var('x1,x2,x3,x4') (x1, x2, x3, x4) sage LPASeed({x1: 1 + x2, x2: 1 + x1, x3: 1 + x4, x4: 1 + x1}).rank() 4
lp_algebra_seed.LPASeed.variable_class | ( | self, | |
depth = infinity ) |
Return all cluster variables in the mutation class of self.
These are exactly the generators for the LP algebra generated by this seed.
- ``depth`` -- (default:``infinity``) integer, only seeds with distance at most depth from ``self`` are returned .. SEEALSO:: For further examples see :meth:`variable_class_iter`. We find the generators for various LP algebras:: sage var('x1,x2,x3') (x1, x2, x3) sage S = LPASeed({x1: 1 + x2, x2: 1 + x1}) sage S.variable_class() [(x1 + x2 + 1)/(x1*x2), (x2 + 1)/x1, (x1 + 1)/x2, x2, x1] sage S = LPASeed({x1: 1 + x2 + x3, x2: 1 + x1 + x3, x3: 1 + x1 + x2}) sage S.variable_class() [(x1 + x2 + x3 + 1)/(x1*x2*x3), (x2 + x3 + 1)/x1, (x1 + x3 + 1)/x2, (x1 + x2 + 1)/x3, x3, x2, x1]
lp_algebra_seed.LPASeed.variable_class_iter | ( | self, | |
depth = infinity, | |||
algorithm = 'BFS' ) |
Return an iterator for all cluster variables in the mutation class of self in seeds at most depth away from self.
- ``depth`` -- (default:``infinity``) integer, only seeds with distance at most ``depth`` from ``self`` are returned - ``algorithm`` -- string (default: ``'BFS'``); the search algorithm to find new seeds; currently supported options: * 'BFS' - breadth-first search * 'DFS' - depth-first search
We define a simple iterator for the denominators of seeds in the mutation class:: sage var('x1, x2, x3, a0, a2, a3, b0, b1, b3, c0, c1, c2') (x1, x2, x3, a0, a2, a3, b0, b1, b3, c0, c1, c2) sage S = LPASeed({x1: a0 + a2*x2 + a3*x3, x2: b0 + b1*x1 + b3*x3, x3: c0 + c1*x1 + c2*x2}) sage t = S.variable_class_iter() sage for variable in t: print(variable.denominator()) # long time 1 1 1 x1 x2 x3 x1*x2 x1*x3 x2*x3 x1*x2*x3