From 4d01f39f3e8738cfade15e15abc9d5b53f2ff007 Mon Sep 17 00:00:00 2001 From: Nicolas Quesada Date: Mon, 8 Dec 2025 10:30:45 -0500 Subject: [PATCH 1/2] passes black -l 100 in all the .py files --- haarpy/__init__.py | 4 +- haarpy/circular_ensembles.py | 16 +- haarpy/orthogonal.py | 25 +- haarpy/partition.py | 19 +- haarpy/permutation.py | 11 +- haarpy/symmetric.py | 52 +--- haarpy/symplectic.py | 53 +--- haarpy/tests/test_circular_ensembles.py | 1 - haarpy/tests/test_orthogonal.py | 310 ++++++++++++++---------- haarpy/tests/test_partition.py | 233 +++++++++--------- haarpy/tests/test_permutation.py | 303 +++++++++++------------ haarpy/tests/test_symmetric.py | 199 +++++++-------- haarpy/tests/test_symplectic.py | 97 ++++++-- haarpy/tests/test_unitary.py | 25 +- haarpy/unitary.py | 19 +- setup.py | 4 +- 16 files changed, 674 insertions(+), 697 deletions(-) diff --git a/haarpy/__init__.py b/haarpy/__init__.py index 8c1ed55..da0818f 100644 --- a/haarpy/__init__.py +++ b/haarpy/__init__.py @@ -204,9 +204,7 @@ def about(): import sympy # a QuTiP-style infobox - print( - "\nHaarpy: a Python library for the symbolic calculation of Weingarten functions." - ) + print("\nHaarpy: a Python library for the symbolic calculation of Weingarten functions.") # print("Copyright 2018-2021 Polyquantique\n") print("Python version: {}.{}.{}".format(*sys.version_info[0:3])) diff --git a/haarpy/circular_ensembles.py b/haarpy/circular_ensembles.py index 08f17af..3c9eee2 100644 --- a/haarpy/circular_ensembles.py +++ b/haarpy/circular_ensembles.py @@ -49,9 +49,7 @@ def weingarten_circular_orthogonal( @lru_cache -def weingarten_circular_symplectic( - permutation: Permutation, cse_dimension: Symbol -) -> Expr: +def weingarten_circular_symplectic(permutation: Permutation, cse_dimension: Symbol) -> Expr: """Returns the circular symplectic ensembles Weingarten functions Args: @@ -112,9 +110,7 @@ def haar_integral_circular_orthogonal( @lru_cache -def haar_integral_circular_symplectic( - sequences: tuple[tuple[Expr]], half_dimension: Expr -) -> Expr: +def haar_integral_circular_symplectic(sequences: tuple[tuple[Expr]], half_dimension: Expr) -> Expr: """Returns integral over circular symplectic ensemble polynomial sampled at random from the Haar measure @@ -151,9 +147,7 @@ def haar_integral_circular_symplectic( raise ValueError("The matrix indices are outside the dimension range") if degree != len(seq_j): return 0 - coefficient = prod( - -1 if i < half_dimension else 1 for i in (seq_i + seq_j)[::2] - ) + coefficient = prod(-1 if i < half_dimension else 1 for i in (seq_i + seq_j)[::2]) shifted_i = [ ( i + half_dimension @@ -189,9 +183,7 @@ def haar_integral_circular_symplectic( raise TypeError if degree != len(seq_j): return 0 - coefficient = prod( - -1 if isinstance(i, int) else 1 for i in (seq_i + seq_j)[::2] - ) + coefficient = prod(-1 if isinstance(i, int) else 1 for i in (seq_i + seq_j)[::2]) shifted_i = [ ( i + half_dimension diff --git a/haarpy/orthogonal.py b/haarpy/orthogonal.py index f1cf3c7..2ac540c 100644 --- a/haarpy/orthogonal.py +++ b/haarpy/orthogonal.py @@ -67,9 +67,7 @@ def zonal_spherical_function(permutation: Permutation, partition: tuple[int]) -> double_partition = tuple(2 * part for part in partition) hyperocta = HyperoctahedralGroup(degree // 2) numerator = sum( - murn_naka_rule( - double_partition, get_conjugacy_class(permutation * zeta, degree) - ) + murn_naka_rule(double_partition, get_conjugacy_class(permutation * zeta, degree)) for zeta in hyperocta.generate() ) return Fraction(numerator, hyperocta.order()) @@ -94,9 +92,7 @@ def weingarten_orthogonal( ValueError: if the degree 2k of the symmetric group S_2k is not a factor of 2 """ if not isinstance(orthogonal_dimension, (Expr, int)): - raise TypeError( - "orthogonal_dimension must be an instance of int or sympy.Symbol" - ) + raise TypeError("orthogonal_dimension must be an instance of int or sympy.Symbol") if isinstance(permutation, (tuple, list)) and all( isinstance(value, int) for value in permutation @@ -112,18 +108,14 @@ def weingarten_orthogonal( half_degree = degree // 2 partition_tuple = tuple( - sum((value * (key,) for key, value in part.items()), ()) - for part in partitions(half_degree) + sum((value * (key,) for key, value in part.items()), ()) for part in partitions(half_degree) ) double_partition_tuple = tuple( tuple(2 * part for part in partition) for partition in partition_tuple ) - irrep_dimension_gen = ( - irrep_dimension(partition) for partition in double_partition_tuple - ) + irrep_dimension_gen = (irrep_dimension(partition) for partition in double_partition_tuple) zonal_spherical_gen = ( - zonal_spherical_function(permutation, partition) - for partition in partition_tuple + zonal_spherical_function(permutation, partition) for partition in partition_tuple ) coefficient_gen = ( prod( @@ -168,9 +160,7 @@ def weingarten_orthogonal( @lru_cache -def haar_integral_orthogonal( - sequences: tuple[tuple[int]], orthogonal_dimension: Symbol -) -> Expr: +def haar_integral_orthogonal(sequences: tuple[tuple[int]], orthogonal_dimension: Symbol) -> Expr: """Returns integral over orthogonal group polynomial sampled at random from the Haar measure Args: @@ -209,8 +199,7 @@ def haar_integral_orthogonal( ) coset_mapping = Counter( - coset_type(cycle_j * ~cycle_i) - for cycle_i, cycle_j in product(permutation_i, permutation_j) + coset_type(cycle_j * ~cycle_i) for cycle_i, cycle_j in product(permutation_i, permutation_j) ) integral = sum( diff --git a/haarpy/partition.py b/haarpy/partition.py index d0e2bd9..6e80829 100644 --- a/haarpy/partition.py +++ b/haarpy/partition.py @@ -78,9 +78,7 @@ def perfect_matchings( @lru_cache -def partial_order( - partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]] -) -> bool: +def partial_order(partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]]) -> bool: """Returns True if parition_1 <= partition_2 in terms of partial order For parition_1 and partition_2, two partitions of the same set, we call @@ -105,9 +103,7 @@ def partial_order( @lru_cache -def meet_operation( - partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]] -) -> tuple[tuple]: +def meet_operation(partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]]) -> tuple[tuple]: """Returns the greatest lower bound of the two input partitions For parition_1 and partition_2, two partitions of the same set, @@ -136,9 +132,7 @@ def meet_operation( @lru_cache -def join_operation( - partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]] -) -> tuple[tuple]: +def join_operation(partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]]) -> tuple[tuple]: """Returns the least upper bound of the two input partitions For parition_1 and partition_2, two partitions of the same set, @@ -155,12 +149,7 @@ def join_operation( tuple[tuple[int]]: Least upper bound """ parent = [ - { - index - for value in block1 - for index, block2 in enumerate(partition_2) - if value in block2 - } + {index for value in block1 for index, block2 in enumerate(partition_2) if value in block2} for block1 in partition_1 ] diff --git a/haarpy/permutation.py b/haarpy/permutation.py index fd45a16..05b711a 100644 --- a/haarpy/permutation.py +++ b/haarpy/permutation.py @@ -24,9 +24,7 @@ @lru_cache -def mobius_function( - partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]] -) -> int: +def mobius_function(partition_1: tuple[tuple[int]], partition_2: tuple[tuple[int]]) -> int: """Return the Möbius function as seen in `Collins and Nagatsu. Weingarten Calculus for Centered Random Permutation Matrices `_ @@ -42,8 +40,7 @@ def mobius_function( partition_set_2 = tuple(set(block) for block in partition_2) partition_intersection = tuple( - sum(1 for block_1 in partition_set_1 if block_1 & block_2) - for block_2 in partition_set_2 + sum(1 for block_1 in partition_set_1 if block_1 & block_2) for block_2 in partition_set_2 ) return prod( @@ -109,9 +106,7 @@ def weingarten_centered_permutation( Symbol : The Weingarten function """ singleton_set_size = sum( - 1 - for block in join_operation(first_partition, second_partition) - if len(block) == 1 + 1 for block in join_operation(first_partition, second_partition) if len(block) == 1 ) disjoint_partition_tuple = tuple( diff --git a/haarpy/symmetric.py b/haarpy/symmetric.py index 0b14c3a..28cfea5 100644 --- a/haarpy/symmetric.py +++ b/haarpy/symmetric.py @@ -53,9 +53,7 @@ def get_conjugacy_class(perm: Permutation, degree: int) -> tuple: "The degree you have provided is too low. It must be an integer greater than 0." ) if not isinstance(perm, Permutation): - raise TypeError( - "Permutation must be of type sympy.combinatorics.permutations.Permutation" - ) + raise TypeError("Permutation must be of type sympy.combinatorics.permutations.Permutation") if perm.size > degree: raise ValueError("Incompatible degree and permutation cycle") @@ -101,8 +99,7 @@ def derivative_tableaux( if not current_row_length: if tableau[index][0] <= increment: yield tuple( - row if i != index + 1 else row + (increment,) - for i, row in enumerate(tableau) + row if i != index + 1 else row + (increment,) for i, row in enumerate(tableau) ) return if ( @@ -110,8 +107,7 @@ def derivative_tableaux( and tableau[index][current_row_length] <= increment ): yield tuple( - row if i != index + 1 else row + (increment,) - for i, row in enumerate(tableau) + row if i != index + 1 else row + (increment,) for i, row in enumerate(tableau) ) @@ -141,9 +137,7 @@ def semi_standard_young_tableaux( @lru_cache -def proper_border_strip( - tableau: tuple[tuple[int]], conjugacy_class: tuple[int] -) -> bool: +def proper_border_strip(tableau: tuple[tuple[int]], conjugacy_class: tuple[int]) -> bool: """Returns True if input Young tableau is a valid border-strip tableau Args: @@ -174,12 +168,7 @@ def proper_border_strip( # 2x2 square condition for i in range(1, len(tableau)): for j in range(1, len(tableau[i])): - if ( - tableau[i][j] - == tableau[i][j - 1] - == tableau[i - 1][j] - == tableau[i - 1][j - 1] - ): + if tableau[i][j] == tableau[i][j - 1] == tableau[i - 1][j] == tableau[i - 1][j - 1]: return False return True @@ -201,15 +190,12 @@ def murn_naka_rule(partition: tuple[int], conjugacy_class: tuple[int]) -> int: return 0 tableaux = semi_standard_young_tableaux(partition, conjugacy_class) - tableaux = ( - tableau for tableau in tableaux if proper_border_strip(tableau, conjugacy_class) - ) + tableaux = (tableau for tableau in tableaux if proper_border_strip(tableau, conjugacy_class)) tableaux_set = ((set(row) for row in tableau) for tableau in tableaux) heights = (tuple(i for row in tableau for i in row) for tableau in tableaux_set) heights = ( - sum(height.count(unit) - 1 for unit in range(len(conjugacy_class))) - for height in heights + sum(height.count(unit) - 1 for unit in range(len(conjugacy_class))) for height in heights ) character = sum((-1) ** height for height in heights) @@ -231,9 +217,7 @@ def irrep_dimension(partition: tuple[int]) -> int: for i, part_i in enumerate(partition) for j, part_j in enumerate(partition[i + 1 :]) ) - denominator = prod( - factorial(part + len(partition) - i - 1) for i, part in enumerate(partition) - ) + denominator = prod(factorial(part + len(partition) - i - 1) for i, part in enumerate(partition)) dimension = Fraction(numerator, denominator) * factorial(sum(partition)) return dimension.numerator @@ -254,9 +238,7 @@ def sorting_permutation(*sequence: tuple[int]) -> Permutation: TypeError: if more than two sequences are passed as arguments """ if len(sequence) == 1: - return Permutation( - sorted(range(len(sequence[0])), key=lambda k: sequence[0][k]) - ) + return Permutation(sorted(range(len(sequence[0])), key=lambda k: sequence[0][k])) if len(sequence) == 2: if sorted(sequence[0]) != sorted(sequence[1]): raise ValueError("Incompatible sequences") @@ -309,9 +291,7 @@ def stabilizer_coset(*sequence: tuple) -> Generator[Permutation, None, None]: young_partition = tuple(sequence[0].count(i) for i in sorted(set(sequence[0]))) return ( - ~sorting_permutation(sequence[1]) - * permutation - * sorting_permutation(sequence[0]) + ~sorting_permutation(sequence[1]) * permutation * sorting_permutation(sequence[0]) for permutation in YoungSubgroup(young_partition).generate() ) @@ -331,9 +311,7 @@ def HyperoctahedralGroup(degree: int) -> PermutationGroup: """ if not isinstance(degree, int): raise TypeError - transpositions = tuple( - Permutation(2 * degree - 1)(2 * i, 2 * i + 1) for i in range(degree) - ) + transpositions = tuple(Permutation(2 * degree - 1)(2 * i, 2 * i + 1) for i in range(degree)) double_transpositions = tuple( Permutation(2 * degree - 1)(2 * i, 2 * j)(2 * i + 1, 2 * j + 1) for i in range(degree) @@ -358,8 +336,7 @@ def hyperoctahedral_transversal(degree: int) -> Generator[Permutation, None, Non if degree == 2: return (Permutation(1),) flatten_pmp = ( - tuple(i for pair in pmp for i in pair) - for pmp in perfect_matchings(tuple(range(degree))) + tuple(i for pair in pmp for i in pair) for pmp in perfect_matchings(tuple(range(degree))) ) return (Permutation(pmp) for pmp in flatten_pmp) @@ -394,10 +371,7 @@ def coset_type(permutation: Permutation) -> tuple[int]: ) return tuple( sorted( - ( - len(block) // 2 - for block in join_operation(base_partition, matching_partition) - ), + (len(block) // 2 for block in join_operation(base_partition, matching_partition)), reverse=True, ) ) diff --git a/haarpy/symplectic.py b/haarpy/symplectic.py index 33c1590..b7f1e64 100644 --- a/haarpy/symplectic.py +++ b/haarpy/symplectic.py @@ -33,9 +33,7 @@ @lru_cache -def twisted_spherical_function( - permutation: Permutation, partition: tuple[int] -) -> float: +def twisted_spherical_function(permutation: Permutation, partition: tuple[int]) -> float: """Returns the twisted spherical function of the Gelfand pair (S_2k, H_k) as seen in Macdonald's "Symmetric Functions and Hall Polynomials" chapter VII @@ -68,9 +66,7 @@ def twisted_spherical_function( duplicate_partition = tuple(part for part in partition for _ in range(2)) hyperocta = HyperoctahedralGroup(degree // 2) numerator = sum( - murn_naka_rule( - duplicate_partition, get_conjugacy_class(~zeta * permutation, degree) - ) + murn_naka_rule(duplicate_partition, get_conjugacy_class(~zeta * permutation, degree)) * zeta.signature() for zeta in hyperocta.generate() ) @@ -97,19 +93,14 @@ def weingarten_symplectic(permutation: Permutation, half_dimension: Symbol) -> E half_degree = degree // 2 partition_tuple = tuple( - sum((value * (key,) for key, value in part.items()), ()) - for part in partitions(half_degree) + sum((value * (key,) for key, value in part.items()), ()) for part in partitions(half_degree) ) duplicate_partition_tuple = tuple( - tuple(part for part in partition for _ in range(2)) - for partition in partition_tuple - ) - irrep_dimension_gen = ( - irrep_dimension(partition) for partition in duplicate_partition_tuple + tuple(part for part in partition for _ in range(2)) for partition in partition_tuple ) + irrep_dimension_gen = (irrep_dimension(partition) for partition in duplicate_partition_tuple) twisted_spherical_gen = ( - twisted_spherical_function(permutation, partition) - for partition in partition_tuple + twisted_spherical_function(permutation, partition) for partition in partition_tuple ) coefficient_gen = ( prod( @@ -195,12 +186,8 @@ def haar_integral_symplectic( return 0 seq_i_position = tuple(0 if i < half_dimension else 1 for i in seq_i) seq_j_position = tuple(0 if j < half_dimension else 1 for j in seq_j) - seq_i_value = tuple( - i if i < half_dimension else i - half_dimension for i in seq_i - ) - seq_j_value = tuple( - j if j < half_dimension else j - half_dimension for j in seq_j - ) + seq_i_value = tuple(i if i < half_dimension else i - half_dimension for i in seq_i) + seq_j_value = tuple(j if j < half_dimension else j - half_dimension for j in seq_j) elif isinstance(half_dimension, Symbol): if not all(isinstance(i, (int, Expr)) for i in seq_i + seq_j): raise TypeError @@ -222,19 +209,11 @@ def haar_integral_symplectic( seq_j_position = tuple(0 if isinstance(j, int) else 1 for j in seq_j) seq_i_value = tuple( - ( - i - if isinstance(i, int) - else 0 if i == half_dimension else i.as_ordered_terms()[1] - ) + (i if isinstance(i, int) else 0 if i == half_dimension else i.as_ordered_terms()[1]) for i in seq_i ) seq_j_value = tuple( - ( - j - if isinstance(j, int) - else 0 if j == half_dimension else j.as_ordered_terms()[1] - ) + (j if isinstance(j, int) else 0 if j == half_dimension else j.as_ordered_terms()[1]) for j in seq_j ) else: @@ -243,12 +222,8 @@ def haar_integral_symplectic( def twisted_delta(seq_value, seq_pos, perm): return ( 0 - if not all( - i1 == i2 for i1, i2 in zip(perm(seq_value)[::2], perm(seq_value)[1::2]) - ) - else prod( - i2 - i1 for i1, i2 in zip(perm(seq_pos)[::2], perm(seq_pos)[1::2]) - ) + if not all(i1 == i2 for i1, i2 in zip(perm(seq_value)[::2], perm(seq_value)[1::2])) + else prod(i2 - i1 for i1, i2 in zip(perm(seq_pos)[::2], perm(seq_pos)[1::2])) ) permutation_i_tuple = tuple( @@ -261,9 +236,7 @@ def twisted_delta(seq_value, seq_pos, perm): ) integral = sum( - perm_i[1] - * perm_j[1] - * weingarten_symplectic(perm_j[0] * ~perm_i[0], half_dimension) + perm_i[1] * perm_j[1] * weingarten_symplectic(perm_j[0] * ~perm_i[0], half_dimension) for perm_i, perm_j in product(permutation_i_tuple, permutation_j_tuple) if perm_i[1] * perm_j[1] ) diff --git a/haarpy/tests/test_circular_ensembles.py b/haarpy/tests/test_circular_ensembles.py index 5f557d5..bca6111 100644 --- a/haarpy/tests/test_circular_ensembles.py +++ b/haarpy/tests/test_circular_ensembles.py @@ -263,7 +263,6 @@ def test_haar_integral_circular_symplectic_monte_carlo_symbolic(seq_i, seq_j, ha assert float(integral) == mc_integral - @pytest.mark.parametrize( "sequences", [ diff --git a/haarpy/tests/test_orthogonal.py b/haarpy/tests/test_orthogonal.py index 245c26b..ac58a56 100644 --- a/haarpy/tests/test_orthogonal.py +++ b/haarpy/tests/test_orthogonal.py @@ -25,27 +25,27 @@ import haarpy as ap seed(137) -d = Symbol('d') +d = Symbol("d") @pytest.mark.parametrize( "permutation, partition1, partition2", [ - (Permutation(3), (1,1), (2,)), - (Permutation(3)(0,1), (1,1), (2,)), - (Permutation(0,1,2,3), (1,1), (2,)), - (Permutation(3)(0,1,2), (1,1), (2,)), - (Permutation(0,1,2,3,4,5), (3,), (2,1)), - (Permutation(5)(0,4), (3,), (1,1,1)), - (Permutation(5)(0,4), (3,), (2,1)), - (Permutation(5)(0,1,2,3,4), (3,), (1,1,1)), - (Permutation(5)(0,1,2,3,4), (1,1,1), (2,1)), - (Permutation(5)(0,1,2,3,4), (3,), (2,1)), - (Permutation(5), (3,), (1,1,1)), - (Permutation(5), (3,), (2,1)), - (Permutation(5), (2,1), (1,1,1)), - (Permutation(7), (2,1,1), (2,2)), - (Permutation(7)(0,1), (2,1,1), (2,2)), + (Permutation(3), (1, 1), (2,)), + (Permutation(3)(0, 1), (1, 1), (2,)), + (Permutation(0, 1, 2, 3), (1, 1), (2,)), + (Permutation(3)(0, 1, 2), (1, 1), (2,)), + (Permutation(0, 1, 2, 3, 4, 5), (3,), (2, 1)), + (Permutation(5)(0, 4), (3,), (1, 1, 1)), + (Permutation(5)(0, 4), (3,), (2, 1)), + (Permutation(5)(0, 1, 2, 3, 4), (3,), (1, 1, 1)), + (Permutation(5)(0, 1, 2, 3, 4), (1, 1, 1), (2, 1)), + (Permutation(5)(0, 1, 2, 3, 4), (3,), (2, 1)), + (Permutation(5), (3,), (1, 1, 1)), + (Permutation(5), (3,), (2, 1)), + (Permutation(5), (2, 1), (1, 1, 1)), + (Permutation(7), (2, 1, 1), (2, 2)), + (Permutation(7)(0, 1), (2, 1, 1), (2, 2)), ], ) def test_zonal_spherical_orthogonality_transversal_zero(permutation, partition1, partition2): @@ -67,21 +67,41 @@ def test_zonal_spherical_orthogonality_transversal_zero(permutation, partition1, @pytest.mark.parametrize( "permutation, partition", [ - (Permutation(3,), (2,)), - (Permutation(3,), (1,1)), - (Permutation(5,)(0,1), (2,1)), - (Permutation(0,1,2,3,4,5), (3,)), - (Permutation(5,)(0,3,4), (3,)), - (Permutation(0,1,2,3,4,5), (1,1,1)), - (Permutation(0,1,2,3,4,5), (2,1)), - (Permutation(0,3,5), (2,1)), - (Permutation(0,3,4,5), (2,1)), - (Permutation(0,2,3,4,5), (2,1)), + ( + Permutation( + 3, + ), + (2,), + ), + ( + Permutation( + 3, + ), + (1, 1), + ), + ( + Permutation( + 5, + )(0, 1), + (2, 1), + ), + (Permutation(0, 1, 2, 3, 4, 5), (3,)), + ( + Permutation( + 5, + )(0, 3, 4), + (3,), + ), + (Permutation(0, 1, 2, 3, 4, 5), (1, 1, 1)), + (Permutation(0, 1, 2, 3, 4, 5), (2, 1)), + (Permutation(0, 3, 5), (2, 1)), + (Permutation(0, 3, 4, 5), (2, 1)), + (Permutation(0, 2, 3, 4, 5), (2, 1)), ], ) def test_zonal_spherical_orthogonality_transversal_none_zero(permutation, partition): """Orthogonality relation for the zonal spherical function - `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: + `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: `_ """ degree = permutation.size @@ -91,9 +111,9 @@ def test_zonal_spherical_orthogonality_transversal_none_zero(permutation, partit * ap.zonal_spherical_function(permutation * ~tau, partition) for tau in ap.hyperoctahedral_transversal(degree) ) - double_partition = tuple(2*i for i in partition) + double_partition = tuple(2 * i for i in partition) orthogonality = ( - Fraction(factorial(degree), 2**half_degree*factorial(half_degree)) + Fraction(factorial(degree), 2**half_degree * factorial(half_degree)) * ap.zonal_spherical_function(permutation, partition) / ap.irrep_dimension(double_partition) ) @@ -103,19 +123,19 @@ def test_zonal_spherical_orthogonality_transversal_none_zero(permutation, partit @pytest.mark.parametrize( "permutation, partition1, partition2", [ - (Permutation(3), (1,1), (2,)), - (Permutation(3)(0,1), (1,1), (2,)), - (Permutation(0,1,2,3), (1,1), (2,)), - (Permutation(3)(0,1,2), (1,1), (2,)), - (Permutation(0,1,2,3,4,5), (3,), (2,1)), - (Permutation(5)(0,4), (3,), (1,1,1)), - (Permutation(5)(0,4), (3,), (2,1)), - (Permutation(5)(0,1,2,3,4), (3,), (1,1,1)), - (Permutation(5)(0,1,2,3,4), (1,1,1), (2,1)), - (Permutation(5)(0,1,2,3,4), (3,), (2,1)), - (Permutation(5), (3,), (1,1,1)), - (Permutation(5), (3,), (2,1)), - (Permutation(5), (2,1), (1,1,1)), + (Permutation(3), (1, 1), (2,)), + (Permutation(3)(0, 1), (1, 1), (2,)), + (Permutation(0, 1, 2, 3), (1, 1), (2,)), + (Permutation(3)(0, 1, 2), (1, 1), (2,)), + (Permutation(0, 1, 2, 3, 4, 5), (3,), (2, 1)), + (Permutation(5)(0, 4), (3,), (1, 1, 1)), + (Permutation(5)(0, 4), (3,), (2, 1)), + (Permutation(5)(0, 1, 2, 3, 4), (3,), (1, 1, 1)), + (Permutation(5)(0, 1, 2, 3, 4), (1, 1, 1), (2, 1)), + (Permutation(5)(0, 1, 2, 3, 4), (3,), (2, 1)), + (Permutation(5), (3,), (1, 1, 1)), + (Permutation(5), (3,), (2, 1)), + (Permutation(5), (2, 1), (1, 1, 1)), ], ) def test_zonal_spherical_orthogonality_symmetric_zero(permutation, partition1, partition2): @@ -137,16 +157,36 @@ def test_zonal_spherical_orthogonality_symmetric_zero(permutation, partition1, p @pytest.mark.parametrize( "permutation, partition", [ - (Permutation(3,), (2,)), - (Permutation(3,), (1,1)), - (Permutation(5,)(0,1), (2,1)), - (Permutation(0,1,2,3,4,5), (3,)), - (Permutation(5,)(0,3,4), (3,)), - (Permutation(0,1,2,3,4,5), (1,1,1)), - (Permutation(0,1,2,3,4,5), (2,1)), - (Permutation(0,3,5), (2,1)), - (Permutation(0,3,4,5), (2,1)), - (Permutation(0,2,3,4,5), (2,1)), + ( + Permutation( + 3, + ), + (2,), + ), + ( + Permutation( + 3, + ), + (1, 1), + ), + ( + Permutation( + 5, + )(0, 1), + (2, 1), + ), + (Permutation(0, 1, 2, 3, 4, 5), (3,)), + ( + Permutation( + 5, + )(0, 3, 4), + (3,), + ), + (Permutation(0, 1, 2, 3, 4, 5), (1, 1, 1)), + (Permutation(0, 1, 2, 3, 4, 5), (2, 1)), + (Permutation(0, 3, 5), (2, 1)), + (Permutation(0, 3, 4, 5), (2, 1)), + (Permutation(0, 2, 3, 4, 5), (2, 1)), ], ) def test_zonal_spherical_orthogonality_symmetric_none_zero(permutation, partition): @@ -161,11 +201,10 @@ def test_zonal_spherical_orthogonality_symmetric_none_zero(permutation, partitio for tau in SymmetricGroup(degree).generate() ) - double_partition = tuple(2*i for i in partition) - orthogonality = ( - Fraction(factorial(degree), ap.irrep_dimension(double_partition)) - * ap.zonal_spherical_function(permutation, partition) - ) + double_partition = tuple(2 * i for i in partition) + orthogonality = Fraction( + factorial(degree), ap.irrep_dimension(double_partition) + ) * ap.zonal_spherical_function(permutation, partition) assert convolution == orthogonality @@ -201,10 +240,10 @@ def test_zonal_spherical_partition_error(cycle_type, partition): @pytest.mark.parametrize( "permutation, partition", [ - (Permutation(3)(0, 1), 'a'), - (Permutation(5)(0, 1, 2), [1,1]), + (Permutation(3)(0, 1), "a"), + (Permutation(5)(0, 1, 2), [1, 1]), ((0, 1), (1,)), - ('a', (1, 1)), + ("a", (1, 1)), ], ) def test_zonal_spherical_type_error(permutation, partition): @@ -217,37 +256,54 @@ def test_zonal_spherical_type_error(permutation, partition): "permutation, num, denum", [ (Permutation(1), 1, d), - (Permutation(3), d+1, d*(d-1)*(d+2)), - (Permutation(0,1,2,3), -1, d*(d-1)*(d+2)), - (Permutation(5), d**2+3*d-2, d*(d-1)*(d-2)*(d+2)*(d+4)), - (Permutation(2,3,4,5), -1, d*(d-1)*(d-2)*(d+4)), - (Permutation(0,1,2,3,4,5), 2, d*(d-1)*(d-2)*(d+2)*(d+4)), - (Permutation(0,1,2,3,4,5,6,7), -5*d-6, d*(d-1)*(d-2)*(d-3)*(d+1)*(d+2)*(d+4)*(d+6)), - (Permutation(0,1,2,3,4,7)(5,6), 2, (d-1)*(d-2)*(d-3)*(d+1)*(d+2)*(d+6)), - (Permutation(0,1,2,3)(4,5,6,7), d**2+5*d+18, d*(d-1)*(d-2)*(d-3)*(d+1)*(d+2)*(d+4)*(d+6)), - (Permutation(4,5,6,7), -d**3-6*d**2-3*d+6, d*(d-1)*(d-2)*(d-3)*(d+1)*(d+2)*(d+4)*(d+6)), - (Permutation(7), (d+3)*(d**2+6*d+1), d*(d-1)*(d-3)*(d+1)*(d+2)*(d+4)*(d+6)), - ] + (Permutation(3), d + 1, d * (d - 1) * (d + 2)), + (Permutation(0, 1, 2, 3), -1, d * (d - 1) * (d + 2)), + (Permutation(5), d**2 + 3 * d - 2, d * (d - 1) * (d - 2) * (d + 2) * (d + 4)), + (Permutation(2, 3, 4, 5), -1, d * (d - 1) * (d - 2) * (d + 4)), + (Permutation(0, 1, 2, 3, 4, 5), 2, d * (d - 1) * (d - 2) * (d + 2) * (d + 4)), + ( + Permutation(0, 1, 2, 3, 4, 5, 6, 7), + -5 * d - 6, + d * (d - 1) * (d - 2) * (d - 3) * (d + 1) * (d + 2) * (d + 4) * (d + 6), + ), + ( + Permutation(0, 1, 2, 3, 4, 7)(5, 6), + 2, + (d - 1) * (d - 2) * (d - 3) * (d + 1) * (d + 2) * (d + 6), + ), + ( + Permutation(0, 1, 2, 3)(4, 5, 6, 7), + d**2 + 5 * d + 18, + d * (d - 1) * (d - 2) * (d - 3) * (d + 1) * (d + 2) * (d + 4) * (d + 6), + ), + ( + Permutation(4, 5, 6, 7), + -(d**3) - 6 * d**2 - 3 * d + 6, + d * (d - 1) * (d - 2) * (d - 3) * (d + 1) * (d + 2) * (d + 4) * (d + 6), + ), + ( + Permutation(7), + (d + 3) * (d**2 + 6 * d + 1), + d * (d - 1) * (d - 3) * (d + 1) * (d + 2) * (d + 4) * (d + 6), + ), + ], ) def test_weingarten_orthogonal_literature(permutation, num, denum): """Symbolic validation of orthogonal Weingarten function against results shown in `Collins et al. Integration with Respect to the Haar Measure on Unitary, Orthogonal and Symplectic Group: `_ """ - assert ap.weingarten_orthogonal(permutation, d) == num/denum + assert ap.weingarten_orthogonal(permutation, d) == num / denum -@pytest.mark.parametrize("degree", range(2,10,2)) +@pytest.mark.parametrize("degree", range(2, 10, 2)) def test_weingarten_orthogonal_coset_type(degree): "Test that the orthogonal function works for both a permutation or its coset-type" sample_size = 10 if degree > 2 else 5 - permutation_sample = ( - Permutation.random(degree) for _ in range(sample_size) - ) + permutation_sample = (Permutation.random(degree) for _ in range(sample_size)) for permutation in permutation_sample: - assert ( - ap.weingarten_orthogonal(permutation, d) - == ap.weingarten_orthogonal(ap.coset_type(permutation), d) + assert ap.weingarten_orthogonal(permutation, d) == ap.weingarten_orthogonal( + ap.coset_type(permutation), d ) @@ -255,7 +311,7 @@ def test_weingarten_orthogonal_coset_type(degree): "coset_type, dimension", [ ((3, 2), 1.0), - ((3, 1, 1), 'a'), + ((3, 1, 1), "a"), ((2, 2, 1), (1, 0)), ((3, 3), (8,)), ], @@ -271,10 +327,10 @@ def test_weingarten_orthogonal_class_dimension_type_error(coset_type, dimension) @pytest.mark.parametrize( "coset", [ - (1,2,"a"), - (3, (1,2), 4), + (1, 2, "a"), + (3, (1, 2), 4), "abc", - ] + ], ) def test_weingarten_orthogonal_coset_type_error(coset): "Test the type error for wrong permutation input" @@ -282,7 +338,7 @@ def test_weingarten_orthogonal_coset_type_error(coset): ap.weingarten_orthogonal(coset, d) -@pytest.mark.parametrize("degree", range(1,10,2)) +@pytest.mark.parametrize("degree", range(1, 10, 2)) def test_weingarten_orthogonal_degree_value_error(degree): "Test value error for odd size permutations" with pytest.raises( @@ -306,20 +362,20 @@ def test_weingarten_orthogonal_degree_value_error(degree): (Permutation(0, 1, 2, 3)(4, 5, 6, 7), 7, 102, 8648640), (Permutation(4, 5, 6, 7), 7, -652, 8648640), (Permutation(7), 7, 920, 1729728), - ] + ], ) def test_weingarten_orthogonal_numeric(permutation, dimension, num, denum): """Numeric validation of orthogonal Weingarten function against results shown in `Collins et al. Integration with Respect to the Haar Measure on Unitary, Orthogonal and Symplectic Group: `_ """ - assert ap.weingarten_orthogonal(permutation, dimension) == Fraction(num,denum) + assert ap.weingarten_orthogonal(permutation, dimension) == Fraction(num, denum) @pytest.mark.parametrize("degree", range(3)) def test_weingarten_orthognal_degree_error(degree): "Value error assertion for symmetric group of odd degree" - for conjugacy_class in SymmetricGroup(2*degree+1).conjugacy_classes(): + for conjugacy_class in SymmetricGroup(2 * degree + 1).conjugacy_classes(): with pytest.raises( ValueError, match=".*The degree of the symmetric group S_2k should be even*" ): @@ -329,85 +385,79 @@ def test_weingarten_orthognal_degree_error(degree): @pytest.mark.parametrize( "power_tuple", [ - (1,1), - (2,2), - (2,1), - (2,3), - (2,4), - (3,3), - (1,1,4), - (1,4), - (2,2,2), - (2,2,4), - ] + (1, 1), + (2, 2), + (2, 1), + (2, 3), + (2, 4), + (3, 3), + (1, 1, 4), + (1, 4), + (2, 2, 2), + (2, 2, 4), + ], ) def test_haar_integral_orthogonal_column_symbolic(power_tuple): "Test based on the column integral of an orthogonal Haar-random matrix (symbolic)" - seq_i = sum(power_tuple)*(1,) + seq_i = sum(power_tuple) * (1,) seq_j = tuple(i for i in range(len(power_tuple)) for _ in range(power_tuple[i])) if any(power % 2 for power in power_tuple): assert not ap.haar_integral_orthogonal((seq_i, seq_j), d) else: assert ap.haar_integral_orthogonal((seq_i, seq_j), d) == ( - prod(factorial2(power-1) for power in power_tuple) - / prod((d+i) for i in range(0,sum(power_tuple), 2)) + prod(factorial2(power - 1) for power in power_tuple) + / prod((d + i) for i in range(0, sum(power_tuple), 2)) ) @pytest.mark.parametrize( "power_tuple", [ - (1,1), - (2,2), - (2,1), - (2,3), - (2,4), - (3,3), - (1,1,4), - (1,4), - ] + (1, 1), + (2, 2), + (2, 1), + (2, 3), + (2, 4), + (3, 3), + (1, 1, 4), + (1, 4), + ], ) def test_haar_integral_orthogonal_column_numeric(power_tuple): "Test based on the column integral of an orthogonal Haar-random matrix (numeric)" - dimension = randint(5,15) - seq_i = sum(power_tuple)*(1,) + dimension = randint(5, 15) + seq_i = sum(power_tuple) * (1,) seq_j = tuple(i for i in range(len(power_tuple)) for _ in range(power_tuple[i])) if any(power % 2 for power in power_tuple): assert not ap.haar_integral_orthogonal((seq_i, seq_j), dimension) else: assert ap.haar_integral_orthogonal((seq_i, seq_j), dimension) == ( - prod(factorial2(power-1) for power in power_tuple) - / prod((dimension+i) for i in range(0,sum(power_tuple), 2)) + prod(factorial2(power - 1) for power in power_tuple) + / prod((dimension + i) for i in range(0, sum(power_tuple), 2)) ) -@pytest.mark.parametrize( - "dimension, half_power", - product(range(2,5), range(1,4)) -) +@pytest.mark.parametrize("dimension, half_power", product(range(2, 5), range(1, 4))) def test_haar_integral_orthogonal_trace(dimension, half_power): "Test based on the integral of the power of the trace" - for half_power in range(1,min(dimension+1, 4)): + for half_power in range(1, min(dimension + 1, 4)): integral = sum( - ap.haar_integral_orthogonal( - (seq_i, seq_i), - dimension - ) - for seq_i in product(range(dimension), repeat=2*half_power) + ap.haar_integral_orthogonal((seq_i, seq_i), dimension) + for seq_i in product(range(dimension), repeat=2 * half_power) ) - assert integral == factorial2(2*half_power - 1) + assert integral == factorial2(2 * half_power - 1) @pytest.mark.parametrize( "sequences", [ ((1,),), - ((1,2,3),), - ((1,2),(3,4),(4,5)), + ((1, 2, 3),), + ((1, 2), (3, 4), (4, 5)), "str", - ((1,2),(3,4,5)), - ((1,2,3),(3,4,5,6)), - ] + ((1, 2), (3, 4, 5)), + ((1, 2, 3), (3, 4, 5, 6)), + ], ) def test_haar_integral_orthogonal_value_error(sequences): "Test haar integral value error" diff --git a/haarpy/tests/test_partition.py b/haarpy/tests/test_partition.py index 0f82709..bc609ba 100644 --- a/haarpy/tests/test_partition.py +++ b/haarpy/tests/test_partition.py @@ -33,74 +33,77 @@ def test_set_partition_size(size): @pytest.mark.parametrize("size", range(1, 7)) def test_set_partition_maximum_partition(size): "Assert that there is a single maximum partition" - assert sum( - 1 for partition in ap.set_partitions(tuple(range(size))) - if len(partition) == 1 - and len(partition[0]) == size - ) == 1 + assert ( + sum( + 1 + for partition in ap.set_partitions(tuple(range(size))) + if len(partition) == 1 and len(partition[0]) == size + ) + == 1 + ) @pytest.mark.parametrize("size", range(1, 7)) def test_set_partition_minimum_partition(size): "Assert that there is a single minimum partition" - assert sum( - 1 for partition in ap.set_partitions(tuple(range(size))) - if len(partition) == size - and all(len(part) == 1 for part in partition) - ) == 1 + assert ( + sum( + 1 + for partition in ap.set_partitions(tuple(range(size))) + if len(partition) == size and all(len(part) == 1 for part in partition) + ) + == 1 + ) @pytest.mark.parametrize("size", range(1, 7)) def test_set_partition_unique(size): "Assert that all partitions are unique" - partition_tuple = tuple( - partition for partition in ap.set_partitions(tuple(range(size))) - ) + partition_tuple = tuple(partition for partition in ap.set_partitions(tuple(range(size)))) assert len(partition_tuple) == len(set(partition_tuple)) @pytest.mark.parametrize( - "collection", - [ - (set()), - (dict()), - (range(7)), - (11), - ([0,1,2,3]), - ] + "collection", + [ + (set()), + (dict()), + (range(7)), + (11), + ([0, 1, 2, 3]), + ], ) def test_set_partition_type_error(collection): "Raise TypeError for wrong type input" with pytest.raises( TypeError, - match = 'collection must be a tuple', + match="collection must be a tuple", ): tuple(ap.set_partitions(collection)) -@pytest.mark.parametrize("size", range(2,14)) +@pytest.mark.parametrize("size", range(2, 14)) def test_perfect_matchings_order(size): "test size of perfect matching partitions" - assert ( - sum(1 for _ in ap.perfect_matchings(tuple(range(size)))) - == (factorial2(size-1) if not size % 2 else 0) + assert sum(1 for _ in ap.perfect_matchings(tuple(range(size)))) == ( + factorial2(size - 1) if not size % 2 else 0 ) @pytest.mark.parametrize( "seed", [ - [1,2], - 'a', + [1, 2], + "a", range(4), 12, - ] + ], ) def test_perfect_matchings_type_error(seed): "test perfect matching type error" with pytest.raises( TypeError, - match = "seed must be a tuple", + match="seed must be a tuple", ): [_ for _ in ap.perfect_matchings(seed)] @@ -119,20 +122,26 @@ def test_partial_order_maximum_partition_in(size): def test_partial_order_maximum_partition_out(size): "The maximal partition is contained within no partition but itself" maximum_partition = (tuple(range(size)),) - assert sum( - ap.partial_order(maximum_partition, partition) - for partition in ap.set_partitions(tuple(range(size))) - ) == 1 + assert ( + sum( + ap.partial_order(maximum_partition, partition) + for partition in ap.set_partitions(tuple(range(size))) + ) + == 1 + ) @pytest.mark.parametrize("size", range(1, 7)) def test_partial_order_minimum_partition_out(size): "No partition but itself is contained within the minimmal partition" minimum_partition = tuple((i,) for i in range(size)) - assert sum( - ap.partial_order(partition, minimum_partition) - for partition in ap.set_partitions(tuple(range(size))) - ) == 1 + assert ( + sum( + ap.partial_order(partition, minimum_partition) + for partition in ap.set_partitions(tuple(range(size))) + ) + == 1 + ) @pytest.mark.parametrize("size", range(1, 7)) @@ -148,11 +157,11 @@ def test_partial_order_minimum_partition_in(size): @pytest.mark.parametrize( "partition1, partition2", [ - (((1,2),(3,4,5)), ((1,2),(3,4,5))), - (((1,),(2,),(3,4,5)), ((1,2),(3,4,5))), - (((1,2),(3,),(4,5)), ((1,2),(3,4,5))), - (((3,2,1),(5,4),(8,),(9,7)), ((4,5,2,3,1,8),(7,9))), - ] + (((1, 2), (3, 4, 5)), ((1, 2), (3, 4, 5))), + (((1,), (2,), (3, 4, 5)), ((1, 2), (3, 4, 5))), + (((1, 2), (3,), (4, 5)), ((1, 2), (3, 4, 5))), + (((3, 2, 1), (5, 4), (8,), (9, 7)), ((4, 5, 2, 3, 1, 8), (7, 9))), + ], ) def test_partial_order_true(partition1, partition2): "Partial orders such that partition1 <= partition2 is True" @@ -162,58 +171,56 @@ def test_partial_order_true(partition1, partition2): @pytest.mark.parametrize( "partition1, partition2", [ - (((1,2,3),(4,5)), ((1,2),(3,4,5))), - (((1,),(2,3),(4,5)), ((1,2),(3,4,5))), - (((1,3),(2,4,5)), ((1,2),(3,4,5))), - (((1,2),(3,4,5)), ((1,2),(3,),(4,5))), - (((3,2,1),(5,4),(8,),(9,7)), ((5,2,3,1,8),(4,),(7,9))), - ] + (((1, 2, 3), (4, 5)), ((1, 2), (3, 4, 5))), + (((1,), (2, 3), (4, 5)), ((1, 2), (3, 4, 5))), + (((1, 3), (2, 4, 5)), ((1, 2), (3, 4, 5))), + (((1, 2), (3, 4, 5)), ((1, 2), (3,), (4, 5))), + (((3, 2, 1), (5, 4), (8,), (9, 7)), ((5, 2, 3, 1, 8), (4,), (7, 9))), + ], ) def test_partial_order_false(partition1, partition2): "Partial orders such that partition1 <= partition2 is False" assert not ap.partial_order(partition1, partition2) -@pytest.mark.parametrize("size" , range(1,7)) +@pytest.mark.parametrize("size", range(1, 7)) def test_meet_operation_minimum_partition(size): "Meet operation with minimum partition returns minimum partition" minimum_partition = tuple((i,) for i in range(size)) minimum_counter = Counter(minimum_partition) for partition in ap.set_partitions(tuple(range(size))): - assert ( - Counter(ap.meet_operation(partition, minimum_partition)) - == minimum_counter - ) + assert Counter(ap.meet_operation(partition, minimum_partition)) == minimum_counter -@pytest.mark.parametrize("size" , range(1,7)) +@pytest.mark.parametrize("size", range(1, 7)) def test_meet_operation_maximum_partition(size): "Meet operation with maximum partition returns the same partition" maximum_partition = (tuple(range(size)),) for partition in ap.set_partitions(tuple(range(size))): - assert ( - ap.meet_operation(partition, maximum_partition) - == partition - ) + assert ap.meet_operation(partition, maximum_partition) == partition @pytest.mark.parametrize( "partition1, partition2, expected_result", [ - (((0,1,3), (2,4,5), (6,)), ((0,1), (2,3,4), (5,6)), ((0,1), (2,4), (3,), (5,), (6,))), - (((0,4,5), (1,3,2), (6,7)), ((2,1,3,4), (0,5,6,7)), ((0,5), (1,2,3), (4,), (6,7))), - ] + ( + ((0, 1, 3), (2, 4, 5), (6,)), + ((0, 1), (2, 3, 4), (5, 6)), + ((0, 1), (2, 4), (3,), (5,), (6,)), + ), + ( + ((0, 4, 5), (1, 3, 2), (6, 7)), + ((2, 1, 3, 4), (0, 5, 6, 7)), + ((0, 5), (1, 2, 3), (4,), (6, 7)), + ), + ], ) def test_meet_operation_additional(partition1, partition2, expected_result): "additional hand calculated tests for the meet operation" meet_partition = Counter( - tuple(sorted(block)) - for block in ap.meet_operation(partition1, partition2) - ) - meet_expected = Counter( - tuple(sorted(block)) - for block in expected_result + tuple(sorted(block)) for block in ap.meet_operation(partition1, partition2) ) + meet_expected = Counter(tuple(sorted(block)) for block in expected_result) assert meet_partition == meet_expected @@ -227,10 +234,7 @@ def test_meet_operation_symmetry(size): sample_partition_2 = (choice(partition_tuple) for _ in range(sample_size)) for party1, party2 in zip(sample_partition_1, sample_partition_2): - assert ( - ap.meet_operation(party1, party2) - == ap.meet_operation(party2, party1) - ) + assert ap.meet_operation(party1, party2) == ap.meet_operation(party2, party1) @pytest.mark.parametrize("size", range(5, 10)) @@ -244,56 +248,47 @@ def test_meet_operation_size(size): for party1, party2 in zip(sample_partition_1, sample_partition_2): flatten_joined_partition = tuple( - value - for block in ap.meet_operation(party1, party2) - for value in block + value for block in ap.meet_operation(party1, party2) for value in block ) - - assert ( - len(flatten_joined_partition) == size - and all(i in flatten_joined_partition for i in range(size)) + + assert len(flatten_joined_partition) == size and all( + i in flatten_joined_partition for i in range(size) ) -@pytest.mark.parametrize("size" , range(1,7)) +@pytest.mark.parametrize("size", range(1, 7)) def test_join_operation_minimum_partition(size): "Join operation with minimum partition returns same partition" minimum_partition = tuple((i,) for i in range(size)) for partition in ap.set_partitions(tuple(range(size))): - assert ( - ap.join_operation(partition, minimum_partition) - == partition - ) + assert ap.join_operation(partition, minimum_partition) == partition -@pytest.mark.parametrize("size" , range(1,7)) +@pytest.mark.parametrize("size", range(1, 7)) def test_join_operation_maximum_partition(size): "Join operation with maximum partition returns maximum partition" maximum_partition = (tuple(range(size)),) for partition in ap.set_partitions(tuple(range(size))): - assert ( - ap.join_operation(partition, maximum_partition) - == maximum_partition - ) + assert ap.join_operation(partition, maximum_partition) == maximum_partition @pytest.mark.parametrize( "partition1, partition2, expected_result", [ - (((0,1), (3,), (2,4), (5,), (6,)), ((0,), (1,5), (2,3), (4,6)), ((0,1,5),(2,3,4,6))), - (((1,2), (0,4,5), (3,)), ((5,), (4,3), (1,2), (0,)), ((0,3,4,5), (1,2))), - ] + ( + ((0, 1), (3,), (2, 4), (5,), (6,)), + ((0,), (1, 5), (2, 3), (4, 6)), + ((0, 1, 5), (2, 3, 4, 6)), + ), + (((1, 2), (0, 4, 5), (3,)), ((5,), (4, 3), (1, 2), (0,)), ((0, 3, 4, 5), (1, 2))), + ], ) def test_join_operation_additional(partition1, partition2, expected_result): "additional hand calculated tests for the join operation" join_partition = Counter( - tuple(sorted(block)) - for block in ap.join_operation(partition1, partition2) - ) - join_expected = Counter( - tuple(sorted(block)) - for block in expected_result + tuple(sorted(block)) for block in ap.join_operation(partition1, partition2) ) + join_expected = Counter(tuple(sorted(block)) for block in expected_result) assert join_partition == join_expected @@ -307,10 +302,7 @@ def test_join_operation_symmetry(size): sample_partition_2 = (choice(partition_tuple) for _ in range(sample_size)) for party1, party2 in zip(sample_partition_1, sample_partition_2): - assert ( - ap.join_operation(party1, party2) - == ap.join_operation(party2, party1) - ) + assert ap.join_operation(party1, party2) == ap.join_operation(party2, party1) @pytest.mark.parametrize("size", range(5, 10)) @@ -324,26 +316,23 @@ def test_join_operation_size(size): for party1, party2 in zip(sample_partition_1, sample_partition_2): flatten_joined_partition = tuple( - value - for block in ap.join_operation(party1, party2) - for value in block + value for block in ap.join_operation(party1, party2) for value in block ) - - assert ( - len(flatten_joined_partition) == size - and all(i in flatten_joined_partition for i in range(size)) + + assert len(flatten_joined_partition) == size and all( + i in flatten_joined_partition for i in range(size) ) @pytest.mark.parametrize( "partition", [ - ((0,4),(1,),(2,),(3,)), - ((0,5),(1,4),(2,3)), - ((0,3),(1,2),(4,7),(5,6)), - ((0,8),(1,2),(3,7),(4,),(5,6)), - ((0,11), (1,2), (3,7,8), (4,6), (5,), (9,10)), - ] + ((0, 4), (1,), (2,), (3,)), + ((0, 5), (1, 4), (2, 3)), + ((0, 3), (1, 2), (4, 7), (5, 6)), + ((0, 8), (1, 2), (3, 7), (4,), (5, 6)), + ((0, 11), (1, 2), (3, 7, 8), (4, 6), (5,), (9, 10)), + ], ) def test_crossing_partition_false(partition): "Non crossing partitions" @@ -353,13 +342,13 @@ def test_crossing_partition_false(partition): @pytest.mark.parametrize( "partition", [ - ((0,4),(1,),(2,5),(3,)), - ((0,3,6),(1,5),(2,4)), - ((0,7,8),(1,2),(3,6),(4,9),(5,)), - ((0,5),(1,2),(3,4),(6,8),(7,9,10)), - ((0,7),(1,),(2,3),(4,),(5,12),(6,),(8,9),(10,11)), - ((0,11,15),(1,2),(3,7),(4,),(5,6),(8,9),(10,12),(13,14)), - ] + ((0, 4), (1,), (2, 5), (3,)), + ((0, 3, 6), (1, 5), (2, 4)), + ((0, 7, 8), (1, 2), (3, 6), (4, 9), (5,)), + ((0, 5), (1, 2), (3, 4), (6, 8), (7, 9, 10)), + ((0, 7), (1,), (2, 3), (4,), (5, 12), (6,), (8, 9), (10, 11)), + ((0, 11, 15), (1, 2), (3, 7), (4,), (5, 6), (8, 9), (10, 12), (13, 14)), + ], ) def test_crossing_partition_true(partition): "Crossing partitions" diff --git a/haarpy/tests/test_permutation.py b/haarpy/tests/test_permutation.py index d161767..21ab657 100644 --- a/haarpy/tests/test_permutation.py +++ b/haarpy/tests/test_permutation.py @@ -21,39 +21,38 @@ from sympy import Symbol, simplify, factor, fraction import haarpy as ap -d = Symbol('d') +d = Symbol("d") hand_calculated_weingarten = { - 21: 1/d**2/(d-1), - 22: -1/d/(d-1), - 23: 1/(d-1), - - 31: 4/d**3/(d-1)/(d-2), - 32: -2/d**2/(d-1)/(d-2), - 33: 2/d/(d-1)/(d-2), - 34: 1/d/(d-1)/(d-2), - 35: -1/(d-1)/(d-2), - 36: d/(d-1)/(d-2), - - 41: factor(3*(d+6))/d**4/(d-1)/(d-2)/(d-3), - 42: -(d+6)/d**3/(d-1)/(d-2)/(d-3), - 43: 1/d/(d-1)/(d-2)/(d-3), - 44: 6/d**2/(d-1)/(d-2)/(d-3), - 45: -6/d/(d-1)/(d-2)/(d-3), - 46: 3/d**2/(d-1)/(d-2)/(d-3), - 47: -1/d/(d-1)/(d-3), - 48: -1/d/(d-1)/(d-2)/(d-3), - 49: -2/d/(d-1)/(d-2)/(d-3), - 410: 2/(d-1)/(d-2)/(d-3), - 411: (d**2-3*d+1)/d/(d-1)/(d-2)/(d-3), - 412: 1/d/(d-2)/(d-3), - 413: -1/(d-2)/(d-3), - 414: (d+1)/d/(d-1)/(d-2)/(d-3), - 415: -(d+1)/(d-1)/(d-2)/(d-3), - 416: d*(d+1)/(d-1)/(d-2)/(d-3), + 21: 1 / d**2 / (d - 1), + 22: -1 / d / (d - 1), + 23: 1 / (d - 1), + 31: 4 / d**3 / (d - 1) / (d - 2), + 32: -2 / d**2 / (d - 1) / (d - 2), + 33: 2 / d / (d - 1) / (d - 2), + 34: 1 / d / (d - 1) / (d - 2), + 35: -1 / (d - 1) / (d - 2), + 36: d / (d - 1) / (d - 2), + 41: factor(3 * (d + 6)) / d**4 / (d - 1) / (d - 2) / (d - 3), + 42: -(d + 6) / d**3 / (d - 1) / (d - 2) / (d - 3), + 43: 1 / d / (d - 1) / (d - 2) / (d - 3), + 44: 6 / d**2 / (d - 1) / (d - 2) / (d - 3), + 45: -6 / d / (d - 1) / (d - 2) / (d - 3), + 46: 3 / d**2 / (d - 1) / (d - 2) / (d - 3), + 47: -1 / d / (d - 1) / (d - 3), + 48: -1 / d / (d - 1) / (d - 2) / (d - 3), + 49: -2 / d / (d - 1) / (d - 2) / (d - 3), + 410: 2 / (d - 1) / (d - 2) / (d - 3), + 411: (d**2 - 3 * d + 1) / d / (d - 1) / (d - 2) / (d - 3), + 412: 1 / d / (d - 2) / (d - 3), + 413: -1 / (d - 2) / (d - 3), + 414: (d + 1) / d / (d - 1) / (d - 2) / (d - 3), + 415: -(d + 1) / (d - 1) / (d - 2) / (d - 3), + 416: d * (d + 1) / (d - 1) / (d - 2) / (d - 3), } -@pytest.mark.parametrize("size", range(1,7)) + +@pytest.mark.parametrize("size", range(1, 7)) def test_mobius_function_trivial(size): """Test the first trivial relation for the Mobius funciton as seen as seen in `Collins and Nagatsu. Weingarten Calculus for Centered Random @@ -61,16 +60,15 @@ def test_mobius_function_trivial(size): """ minimum_partition = tuple((i,) for i in range(size)) maximum_partition = (tuple(range(size)),) - assert ( - ap.mobius_function( - minimum_partition, - maximum_partition, - ) - == (-1)**(size-1) * factorial(size-1) - ) - + assert ap.mobius_function( + minimum_partition, + maximum_partition, + ) == (-1) ** ( + size - 1 + ) * factorial(size - 1) + -@pytest.mark.parametrize("size", range(1,7)) +@pytest.mark.parametrize("size", range(1, 7)) def test_mobius_inversion_formula(size): """Test Mobius inversion formula as seen in `Collins and Nagatsu. Weingarten Calculus for Centered Random @@ -87,69 +85,74 @@ def test_mobius_inversion_formula(size): partition_1, partition_3, ) - * int( - ap.partial_order( - partition_3, - partition_2 - ) - ) + * int(ap.partial_order(partition_3, partition_2)) for partition_3 in ap.set_partitions(collection) if ( ap.partial_order(partition_1, partition_3) and ap.partial_order(partition_3, partition_2) ) ) - + assert convolution == kronecker @pytest.mark.parametrize( - "partition1, partition2, result_key", - [ - (((0,), (1,)), ((0,), (1,)), 21), - (((0,), (1,)), ((0,1),), 22), - (((0,1),), ((0,1),), 23), - - (((0,), (1,), (2,)), ((0,), (1,), (2,)), 31), - (((0,), (1,), (2,)), ((0,2), (1,)), 32), - (((0,), (1,), (2,)), ((0,1,2),), 33), - (((0,1,), (2,)), ((0,2), (1,)), 34), - (((0,1,2),), ((0,1), (2,)), 35), - (((0,1,2),), ((0,1,2),), 36), - - (((0,), (1,), (2,), (3,)), ((0,), (1,), (2,), (3,)), 41), - (((0,), (1,2,), (3,)), ((0,), (1,), (2,), (3,)), 42), - (((0,2), (1,3)), ((0,), (1,), (2,), (3,)), 43), - (((0,1,3), (2,)), ((0,), (1,), (2,), (3,)), 44), - (((0,1,2,3),), ((0,), (1,), (2,), (3,)), 45), - - (((0,1), (2,), (3,)), ((0,), (1,3), (2,)), 46), - (((0,2), (1,), (3,)), ((0,), (1,3), (2,)), 43), - - (((0,3), (1,), (2,)), ((0,2), (1,3)), 48), - (((0,3), (1,), (2,)), ((0,3), (1,2)), 47), - - (((0,), (1,), (2,3)), ((0,2,3), (1,)), 49), - - (((0,), (1,), (2,3)), ((0,1,2,3),), 410), - - (((0,2), (1,3)), ((0,3), (1,2)), 43), - (((0,3), (1,2)), ((0,3), (1,2)), 411), - - (((0,3), (1,2)), ((0,), (1,2,3)), 412), - - (((0,3), (1,2)), ((0,1,2,3),), 413), - - (((0,1,2), (3,)), ((0,1,2), (3,)), 414), - (((0,1,2), (3,)), ((0,1,2,3),), 415), - - (((0,1,2,3),), ((0,1,2,3),), 416), - ] + "partition1, partition2, result_key", + [ + (((0,), (1,)), ((0,), (1,)), 21), + (((0,), (1,)), ((0, 1),), 22), + (((0, 1),), ((0, 1),), 23), + (((0,), (1,), (2,)), ((0,), (1,), (2,)), 31), + (((0,), (1,), (2,)), ((0, 2), (1,)), 32), + (((0,), (1,), (2,)), ((0, 1, 2),), 33), + ( + ( + ( + 0, + 1, + ), + (2,), + ), + ((0, 2), (1,)), + 34, + ), + (((0, 1, 2),), ((0, 1), (2,)), 35), + (((0, 1, 2),), ((0, 1, 2),), 36), + (((0,), (1,), (2,), (3,)), ((0,), (1,), (2,), (3,)), 41), + ( + ( + (0,), + ( + 1, + 2, + ), + (3,), + ), + ((0,), (1,), (2,), (3,)), + 42, + ), + (((0, 2), (1, 3)), ((0,), (1,), (2,), (3,)), 43), + (((0, 1, 3), (2,)), ((0,), (1,), (2,), (3,)), 44), + (((0, 1, 2, 3),), ((0,), (1,), (2,), (3,)), 45), + (((0, 1), (2,), (3,)), ((0,), (1, 3), (2,)), 46), + (((0, 2), (1,), (3,)), ((0,), (1, 3), (2,)), 43), + (((0, 3), (1,), (2,)), ((0, 2), (1, 3)), 48), + (((0, 3), (1,), (2,)), ((0, 3), (1, 2)), 47), + (((0,), (1,), (2, 3)), ((0, 2, 3), (1,)), 49), + (((0,), (1,), (2, 3)), ((0, 1, 2, 3),), 410), + (((0, 2), (1, 3)), ((0, 3), (1, 2)), 43), + (((0, 3), (1, 2)), ((0, 3), (1, 2)), 411), + (((0, 3), (1, 2)), ((0,), (1, 2, 3)), 412), + (((0, 3), (1, 2)), ((0, 1, 2, 3),), 413), + (((0, 1, 2), (3,)), ((0, 1, 2), (3,)), 414), + (((0, 1, 2), (3,)), ((0, 1, 2, 3),), 415), + (((0, 1, 2, 3),), ((0, 1, 2, 3),), 416), + ], ) def test_weingarten_centered_permutation_hand_calculated(partition1, partition2, result_key): "Test Weingarten centered permutation function against hand calculated cases" assert ( - ap.weingarten_centered_permutation(partition1, partition2, d) + ap.weingarten_centered_permutation(partition1, partition2, d) == hand_calculated_weingarten[result_key] ) @@ -157,14 +160,14 @@ def test_weingarten_centered_permutation_hand_calculated(partition1, partition2, @pytest.mark.parametrize( "row_indices, column_indices", [ - ((1,2,3,4),(1,2,3,4)), - ((3,2,2,1),(2,2,1,3)), - ((3,2,2,1),(3,2,2,1)), - ((3,2,2,1,2),(3,2,2,1,2)), - ((3,3,2,2,1,2),(3,3,2,2,1,2)), - ((3,3,2,2,3,2),(3,3,2,2,3,2)), - ((3,3,2,2,3,2),(3,3,2,2,1,2)), - ] + ((1, 2, 3, 4), (1, 2, 3, 4)), + ((3, 2, 2, 1), (2, 2, 1, 3)), + ((3, 2, 2, 1), (3, 2, 2, 1)), + ((3, 2, 2, 1, 2), (3, 2, 2, 1, 2)), + ((3, 3, 2, 2, 1, 2), (3, 3, 2, 2, 1, 2)), + ((3, 3, 2, 2, 3, 2), (3, 3, 2, 2, 3, 2)), + ((3, 3, 2, 2, 3, 2), (3, 3, 2, 2, 1, 2)), + ], ) def test_haar_integral_permutation_weingarten(row_indices, column_indices): """Test haar integral for permutation matrices against the Weingarten @@ -195,20 +198,17 @@ def test_haar_integral_permutation_weingarten(row_indices, column_indices): ) num, denum = fraction(simplify(weingarten_integral)) - weingarten_integral = factor(num)/factor(denum) + weingarten_integral = factor(num) / factor(denum) - assert ( - ap.haar_integral_permutation(row_indices, column_indices, d) - == weingarten_integral - ) + assert ap.haar_integral_permutation(row_indices, column_indices, d) == weingarten_integral @pytest.mark.parametrize( "row_indices, column_indices", [ - ((1,2,3), 12), - ({3,4,5}, (3,4,5)), - ] + ((1, 2, 3), 12), + ({3, 4, 5}, (3, 4, 5)), + ], ) def test_haar_integral_permutation_type_error(row_indices, column_indices): "test haar_integral_permutation_weingarten type error" @@ -219,9 +219,9 @@ def test_haar_integral_permutation_type_error(row_indices, column_indices): @pytest.mark.parametrize( "row_indices, column_indices", [ - ((1,2,3), (1,2,3,4)), - ('abcd', 'abc'), - ] + ((1, 2, 3), (1, 2, 3, 4)), + ("abcd", "abc"), + ], ) def test_haar_integral_permutation_value_error(row_indices, column_indices): "test haar_integral_permutation_weingarten value error" @@ -232,42 +232,44 @@ def test_haar_integral_permutation_value_error(row_indices, column_indices): @pytest.mark.parametrize( "row_indices, column_indices, result_dict", [ - ((1,2),(1,2), {21:1}), - ((1,1),(2,2), {21:1, 22:2, 23:1}), - ((1,1),(1,2), {21:1, 22:1}), - - ((1,2,3), (1,2,3), {31:1}), - ((1,2,3), (1,2,2), {31:1, 32:1}), - ((1,2,3), (1,1,1), {31:1, 32:3, 33:1}), - ((1,2,2), (1,1,1), {31:1, 32:4, 33:1, 34:3, 35:1}), - ((1,2,2), (2,2,1), {31:1, 32:2, 34:1}), - ((1,1,1), (1,1,1), {31:1, 32:6, 33:2, 34:9, 35:6, 36:1}), - - ((1,2,3,4), (1,2,3,4), {41:1}), - ((1,2,3,2), (1,1,1,1), {41:1, 42:7, 43:5, 44:4, 45:1, 46:4, 47:1, 48:2, 49:4, 410:1}), + ((1, 2), (1, 2), {21: 1}), + ((1, 1), (2, 2), {21: 1, 22: 2, 23: 1}), + ((1, 1), (1, 2), {21: 1, 22: 1}), + ((1, 2, 3), (1, 2, 3), {31: 1}), + ((1, 2, 3), (1, 2, 2), {31: 1, 32: 1}), + ((1, 2, 3), (1, 1, 1), {31: 1, 32: 3, 33: 1}), + ((1, 2, 2), (1, 1, 1), {31: 1, 32: 4, 33: 1, 34: 3, 35: 1}), + ((1, 2, 2), (2, 2, 1), {31: 1, 32: 2, 34: 1}), + ((1, 1, 1), (1, 1, 1), {31: 1, 32: 6, 33: 2, 34: 9, 35: 6, 36: 1}), + ((1, 2, 3, 4), (1, 2, 3, 4), {41: 1}), + ( + (1, 2, 3, 2), + (1, 1, 1, 1), + {41: 1, 42: 7, 43: 5, 44: 4, 45: 1, 46: 4, 47: 1, 48: 2, 49: 4, 410: 1}, + ), ( - (1,1,1,1), - (1,1,1,1), + (1, 1, 1, 1), + (1, 1, 1, 1), { - 41:1, - 42:12, - 43:24, - 44:8, - 45:2, - 46:24, - 47:12, - 48:24, - 49:48, - 410:12, - 411:3, - 412:24, - 413:6, - 414:16, - 415:8, - 416:1, - } + 41: 1, + 42: 12, + 43: 24, + 44: 8, + 45: 2, + 46: 24, + 47: 12, + 48: 24, + 49: 48, + 410: 12, + 411: 3, + 412: 24, + 413: 6, + 414: 16, + 415: 8, + 416: 1, + }, ), - ] + ], ) def test_haar_integral_centered_permutation_weingarten(row_indices, column_indices, result_dict): """Test haar integral for centered permutation matrices @@ -275,20 +277,21 @@ def test_haar_integral_centered_permutation_weingarten(row_indices, column_indic and (2.4) of `Collins and Nagatsu. Weingarten Calculus for Centered Random Permutation Matrices `_ """ - result = simplify(sum(value*hand_calculated_weingarten[key] for key, value in result_dict.items())) - num, denum = fraction(result) - assert ( - ap.haar_integral_centered_permutation(row_indices, column_indices, d) - == factor(num)/factor(denum) + result = simplify( + sum(value * hand_calculated_weingarten[key] for key, value in result_dict.items()) ) + num, denum = fraction(result) + assert ap.haar_integral_centered_permutation(row_indices, column_indices, d) == factor( + num + ) / factor(denum) @pytest.mark.parametrize( "row_indices, column_indices", [ - ((1,2,3), 12), - ({3,4,5}, (3,4,5)), - ] + ((1, 2, 3), 12), + ({3, 4, 5}, (3, 4, 5)), + ], ) def test_haar_integral_centered_permutation_type_error(row_indices, column_indices): "test haar_integral_centered_permutation_weingarten type error" @@ -299,9 +302,9 @@ def test_haar_integral_centered_permutation_type_error(row_indices, column_indic @pytest.mark.parametrize( "row_indices, column_indices", [ - ((1,2,3), (1,2,3,4)), - ('abcd', 'abc'), - ] + ((1, 2, 3), (1, 2, 3, 4)), + ("abcd", "abc"), + ], ) def test_haar_integral_centered_permutation_value_error(row_indices, column_indices): "test haar_integral_centered_permutation_weingarten value error" diff --git a/haarpy/tests/test_symmetric.py b/haarpy/tests/test_symmetric.py index c10ad33..bd9de0c 100644 --- a/haarpy/tests/test_symmetric.py +++ b/haarpy/tests/test_symmetric.py @@ -110,7 +110,20 @@ def test_get_conjugacy_class_cycle_value_error(degree, cycle): [ (((), ()), 1, (3, 1), (((1,), ()),)), (((1, 2), (2, 3)), 4, (3, 2), (((1, 2, 4), (2, 3)),)), - (((1, 1, 1, 3), (2,)), 4, (4, 2), (((1, 1, 1, 3), (2, 4,)),)), + ( + ((1, 1, 1, 3), (2,)), + 4, + (4, 2), + ( + ( + (1, 1, 1, 3), + ( + 2, + 4, + ), + ), + ), + ), (((1,), ()), 1, (3, 1), (((1, 1), ()), ((1,), (1,)))), (((1, 2), ()), 2, (3, 2), (((1, 2, 2), ()), ((1, 2), (2,)))), (((), (), ()), 1, (3, 1, 1), (((1,), (), ()),)), @@ -285,7 +298,7 @@ def test_irrep_dimension_murn_naka_rule(partition): assert ap.irrep_dimension(partition) == ap.murn_naka_rule(partition, conjugacy_identity) -@pytest.mark.parametrize("degree", range(1,8)) +@pytest.mark.parametrize("degree", range(1, 8)) def test_sorting_permutation_single_len(degree): "Test that the size of the permutation is the size of the sorted sequence" sample_size = 10 @@ -296,7 +309,7 @@ def test_sorting_permutation_single_len(degree): assert permutation.size == len(shuffled_sequence) -@pytest.mark.parametrize("degree", range(1,8)) +@pytest.mark.parametrize("degree", range(1, 8)) def test_sorting_permutation_single_shuffle(degree): "Test that the sorting permutation properly sorts the shuffled sequence" sample_size = 10 @@ -308,7 +321,7 @@ def test_sorting_permutation_single_shuffle(degree): assert permutation(shuffled_sequence) == sorted_sequence -@pytest.mark.parametrize("degree", range(1,8)) +@pytest.mark.parametrize("degree", range(1, 8)) def test_sorting_permutation_double_shuffle(degree): "Test that the sorting permutation properly sorts the shuffled sequence" sample_size = 10 @@ -325,50 +338,42 @@ def test_sorting_permutation_double_shuffle(degree): assert permutation(first_sequence) == second_sequence -@pytest.mark.parametrize("degree", range(3,8)) +@pytest.mark.parametrize("degree", range(3, 8)) def test_sorting_permutation_type_error(degree): "Type error for more than 2 inputs" sequence = tuple(range(degree)) with pytest.raises(TypeError): - ap.sorting_permutation( - *[tuple(sequence) for _ in range(degree)] - ) + ap.sorting_permutation(*[tuple(sequence) for _ in range(degree)]) @pytest.mark.parametrize( "seq1, seq2", [ - ((1,2,3),(0,1,2)), - ((0,0,0,0), (0,0,0)), - ] + ((1, 2, 3), (0, 1, 2)), + ((0, 0, 0, 0), (0, 0, 0)), + ], ) def test_sorting_permutation_value_error(seq1, seq2): "Value error for different inputs" - with pytest.raises( - ValueError, - match = "Incompatible sequences" - ): + with pytest.raises(ValueError, match="Incompatible sequences"): ap.sorting_permutation(seq1, seq2) -@pytest.mark.parametrize('degree', range(1,8)) +@pytest.mark.parametrize("degree", range(1, 8)) def test_young_subgroup_order(degree): "Test the order of the Young subgroup" for partition in partitions(degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) young = ap.YoungSubgroup(partition) - assert ( - young.order() - == prod(SymmetricGroup(part).order() for part in partition) - ) + assert young.order() == prod(SymmetricGroup(part).order() for part in partition) -@pytest.mark.parametrize('degree', range(2,8)) +@pytest.mark.parametrize("degree", range(2, 8)) def test_young_subgroup_stabilizer(degree): "Test the stabilizer property of the Young subgroup" for partition in partitions(degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) - if partition == degree*(1,): + if partition == degree * (1,): continue sequence = [i for i, j in enumerate(partition) for _ in range(j)] young = ap.YoungSubgroup(partition) @@ -378,12 +383,12 @@ def test_young_subgroup_stabilizer(degree): @pytest.mark.parametrize( "partition", [ - {1,2,3}, - 'abc', - {1:1, 2:2}, - (2,2,0), - (1,-1,2), - (2,2,'a'), + {1, 2, 3}, + "abc", + {1: 1, 2: 2}, + (2, 2, 0), + (1, -1, 2), + (2, 2, "a"), ], ) def test_young_subgroup_type_error(partition): @@ -393,86 +398,74 @@ def test_young_subgroup_type_error(partition): @pytest.mark.parametrize( - "seq1, seq2", - [ - ((0,1),(0,2)), - ((0,0,0), (0,0)), - ((0,1,2,3,4), (0,1,2,3,3)), - ] + "seq1, seq2", + [ + ((0, 1), (0, 2)), + ((0, 0, 0), (0, 0)), + ((0, 1, 2, 3, 4), (0, 1, 2, 3, 3)), + ], ) def test_stabilizer_coset_empty(seq1, seq2): "test cases for which there are no stabilizing permutation" assert not len(tuple(ap.stabilizer_coset(seq1, seq2))) -@pytest.mark.parametrize("degree", range(2,6)) +@pytest.mark.parametrize("degree", range(2, 6)) def test_stabilizer_coset_size(degree): "Test the size of the stabilizer coset" for partition in partitions(degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) - seq1 = [i for i,j in enumerate(partition) for _ in range(j)] + seq1 = [i for i, j in enumerate(partition) for _ in range(j)] seq2 = seq1.copy() shuffle(seq1) shuffle(seq2) order = sum(1 for _ in ap.stabilizer_coset(tuple(seq1), tuple(seq2))) - assert ( - order - == prod(SymmetricGroup(part).order() for part in partition) - ) - + assert order == prod(SymmetricGroup(part).order() for part in partition) + -@pytest.mark.parametrize("degree", range(2,8)) +@pytest.mark.parametrize("degree", range(2, 8)) def test_stabilizer_coset_permutation(degree): "Test the set of permutations" for partition in partitions(degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) - seq1 = [i for i,j in enumerate(partition) for _ in range(j)] + seq1 = [i for i, j in enumerate(partition) for _ in range(j)] seq2 = seq1.copy() shuffle(seq1) shuffle(seq2) - assert all( - perm(seq1) == seq2 - for perm in ap.stabilizer_coset(tuple(seq1), tuple(seq2)) - ) + assert all(perm(seq1) == seq2 for perm in ap.stabilizer_coset(tuple(seq1), tuple(seq2))) -@pytest.mark.parametrize("degree", range(2,6)) +@pytest.mark.parametrize("degree", range(2, 6)) def test_stabilizer_coset_brute_force(degree): "Test the set of permutations against brute force" for partition in partitions(degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) - seq1 = [i for i,j in enumerate(partition) for _ in range(j)] + seq1 = [i for i, j in enumerate(partition) for _ in range(j)] seq2 = seq1.copy() shuffle(seq1) shuffle(seq2) stabilizer = tuple(ap.stabilizer_coset(tuple(seq1), tuple(seq2))) - assert all(perm in stabilizer - for perm in SymmetricGroup(degree).generate() - if perm(seq1) == seq2 - ) + assert all( + perm in stabilizer for perm in SymmetricGroup(degree).generate() if perm(seq1) == seq2 + ) -@pytest.mark.parametrize("degree", range(2,8)) +@pytest.mark.parametrize("degree", range(2, 8)) def test_stabilizer_coset_single(degree): "Test the set of permutations for single input" for partition in partitions(degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) - seq1 = [i for i,j in enumerate(partition) for _ in range(j)] + seq1 = [i for i, j in enumerate(partition) for _ in range(j)] shuffle(seq1) - assert all( - perm(seq1) == seq1 - for perm in ap.stabilizer_coset(tuple(seq1)) - ) + assert all(perm(seq1) == seq1 for perm in ap.stabilizer_coset(tuple(seq1))) -@pytest.mark.parametrize("degree", range(3,8)) +@pytest.mark.parametrize("degree", range(3, 8)) def test_stabilizer_coset_type_error(degree): "Type error for more than 2 inputs" sequence = tuple(range(degree)) with pytest.raises(TypeError): - ap.stabilizer_coset( - *[tuple(sequence) for _ in range(degree)] - ) + ap.stabilizer_coset(*[tuple(sequence) for _ in range(degree)]) @pytest.mark.parametrize("degree", range(1, 8)) @@ -500,7 +493,7 @@ def test_hyperoctahedral_type_error(degree): def test_hyperoctahedral_transversal_size(degree): "Test the size of the hyperoctahedral transversal set" size = sum(1 for _ in ap.hyperoctahedral_transversal(degree)) - assert size == factorial(degree)/2**(degree//2)/factorial(degree//2) + assert size == factorial(degree) / 2 ** (degree // 2) / factorial(degree // 2) @pytest.mark.parametrize("degree", range(2, 12, 2)) @@ -508,9 +501,9 @@ def test_hyperoctahedral_transversal_brute_force(degree): "Compare permutations of the transversal set with brute force method" brute_force_permutations = set() for permutation in permutations(range(degree)): - if not all(permutation[2*i] < permutation[2*i+1] for i in range(degree//2)): + if not all(permutation[2 * i] < permutation[2 * i + 1] for i in range(degree // 2)): continue - if not all(permutation[2*i] < permutation[2*i+2] for i in range(degree//2-1)): + if not all(permutation[2 * i] < permutation[2 * i + 2] for i in range(degree // 2 - 1)): continue brute_force_permutations.add(Permutation(permutation)) @@ -525,27 +518,23 @@ def test_hyperoctahedral_transversal_value_error(degree): ap.hyperoctahedral_transversal(degree) -@pytest.mark.parametrize("half_degree", range(1,10)) +@pytest.mark.parametrize("half_degree", range(1, 10)) def test_coset_type_partition(half_degree): "Test that all coset-types of S_2k are partitions of k" sample_size = 100 if half_degree > 2 else 4 - permutation_sample = ( - Permutation.random(2*half_degree) for _ in range(sample_size) - ) + permutation_sample = (Permutation.random(2 * half_degree) for _ in range(sample_size)) for permutation in permutation_sample: - assert ( - sum(ap.coset_type(permutation)) == half_degree - ) + assert sum(ap.coset_type(permutation)) == half_degree @pytest.mark.parametrize( - "permutation", - [ - [0,1,2], - 12, - 'abc', - (1,1,1), - ] + "permutation", + [ + [0, 1, 2], + 12, + "abc", + (1, 1, 1), + ], ) def test_coset_type_type_error(permutation): "Test TypeError if input is not a Permutation" @@ -553,37 +542,31 @@ def test_coset_type_type_error(permutation): ap.coset_type(permutation) -@pytest.mark.parametrize("degree", range(1,11,2)) +@pytest.mark.parametrize("degree", range(1, 11, 2)) def test_coset_type_value_error(degree): "Test ValueError for odd size permutations" - with pytest.raises( - ValueError, - match = "Coset-type are only defined for even sized permutations" - ): + with pytest.raises(ValueError, match="Coset-type are only defined for even sized permutations"): ap.coset_type(Permutation.random(degree)) -@pytest.mark.parametrize("half_degree", range(1,8)) +@pytest.mark.parametrize("half_degree", range(1, 8)) def test_coset_type_coset_representative(half_degree): - """ Taking all partitions of integer k, finding its coset-type + """Taking all partitions of integer k, finding its coset-type representative and then finding the coset-type of this permutation should yield the initial partition """ for partition in partitions(half_degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) - assert ( - ap.coset_type(ap.coset_type_representative(partition)) - == partition - ) + assert ap.coset_type(ap.coset_type_representative(partition)) == partition @pytest.mark.parametrize( - "partition", - [ - ([1,2,3]), - ("test"), - (13), - ] + "partition", + [ + ([1, 2, 3]), + ("test"), + (13), + ], ) def test_coset_type_representative_type_error(partition): "Test TypeError for invalid permutation and partition" @@ -591,22 +574,22 @@ def test_coset_type_representative_type_error(partition): ap.coset_type_representative(partition) -@pytest.mark.parametrize("half_degree", range(2,7)) +@pytest.mark.parametrize("half_degree", range(2, 7)) def test_coset_type_representative_in_transversal(half_degree): - """assert that all coset-type representative permutations of integer partition are in M_2k as seen in - `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: + """assert that all coset-type representative permutations of integer partition are in M_2k as seen in + `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: `_ """ - transversal = tuple(ap.hyperoctahedral_transversal(2*half_degree)) + transversal = tuple(ap.hyperoctahedral_transversal(2 * half_degree)) for partition in partitions(half_degree): partition = tuple(key for key, value in partition.items() for _ in range(value)) assert ap.coset_type_representative(partition) in transversal -@pytest.mark.parametrize("half_degree", range(2,7)) +@pytest.mark.parametrize("half_degree", range(2, 7)) def test_coset_type_representative_signature(half_degree): - """assert that all coset-type permutations of integer partition have signature of 1 as seen in - `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: + """assert that all coset-type permutations of integer partition have signature of 1 as seen in + `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: `_ """ for partition in partitions(half_degree): @@ -614,10 +597,10 @@ def test_coset_type_representative_signature(half_degree): assert ap.coset_type_representative(partition).signature() == 1 -@pytest.mark.parametrize("half_degree", range(2,10)) +@pytest.mark.parametrize("half_degree", range(2, 10)) def test_coset_type_representative_identity(half_degree): - """ asert that the coset-type permutation of the identity partition is the identity permutation - as seen in `Matsumoto. Weingarten calculus for matrix ensembles associated with compact + """asert that the coset-type permutation of the identity partition is the identity permutation + as seen in `Matsumoto. Weingarten calculus for matrix ensembles associated with compact symmetric spaces: `_ """ - assert ap.coset_type_representative(half_degree * (1,)) == Permutation(2*half_degree - 1) + assert ap.coset_type_representative(half_degree * (1,)) == Permutation(2 * half_degree - 1) diff --git a/haarpy/tests/test_symplectic.py b/haarpy/tests/test_symplectic.py index a55fde1..368184e 100644 --- a/haarpy/tests/test_symplectic.py +++ b/haarpy/tests/test_symplectic.py @@ -113,16 +113,36 @@ def test_twisted_spherical_orthogonality_transversal_zero(permutation, partition @pytest.mark.parametrize( "permutation, partition", [ - (Permutation(3,), (2,)), - (Permutation(3,), (1,1)), - (Permutation(5,)(0,1), (2,1)), - (Permutation(0,1,2,3,4,5), (3,)), - (Permutation(5,)(0,3,4), (3,)), - (Permutation(0,1,2,3,4,5), (1,1,1)), - (Permutation(0,1,2,3,4,5), (2,1)), - (Permutation(0,3,5), (2,1)), - (Permutation(0,3,4,5), (2,1)), - (Permutation(0,2,3,4,5), (2,1)), + ( + Permutation( + 3, + ), + (2,), + ), + ( + Permutation( + 3, + ), + (1, 1), + ), + ( + Permutation( + 5, + )(0, 1), + (2, 1), + ), + (Permutation(0, 1, 2, 3, 4, 5), (3,)), + ( + Permutation( + 5, + )(0, 3, 4), + (3,), + ), + (Permutation(0, 1, 2, 3, 4, 5), (1, 1, 1)), + (Permutation(0, 1, 2, 3, 4, 5), (2, 1)), + (Permutation(0, 3, 5), (2, 1)), + (Permutation(0, 3, 4, 5), (2, 1)), + (Permutation(0, 2, 3, 4, 5), (2, 1)), ], ) def test_twisted_spherical_orthogonality_transversal_none_zero(permutation, partition): @@ -149,12 +169,29 @@ def test_twisted_spherical_orthogonality_transversal_none_zero(permutation, part @pytest.mark.parametrize( "permutation, partition", [ - (Permutation(3,), [2,]), - ((3,1), (1,1)), - (Permutation(5,)(0,1), 'a'), - ('a', (3,)), - (Permutation(5,)(0,3,4), 7), - (7, (1,1,1)), + ( + Permutation( + 3, + ), + [ + 2, + ], + ), + ((3, 1), (1, 1)), + ( + Permutation( + 5, + )(0, 1), + "a", + ), + ("a", (3,)), + ( + Permutation( + 5, + )(0, 3, 4), + 7, + ), + (7, (1, 1, 1)), ], ) def test_twisted_spherical_function_type_error(permutation, partition): @@ -166,10 +203,30 @@ def test_twisted_spherical_function_type_error(permutation, partition): @pytest.mark.parametrize( "permutation, partition", [ - (Permutation(3,), (2,2)), - (Permutation(3,), (1,1,1)), - (Permutation(4,), (2,1)), - (Permutation(4,), (1,1,1)), + ( + Permutation( + 3, + ), + (2, 2), + ), + ( + Permutation( + 3, + ), + (1, 1, 1), + ), + ( + Permutation( + 4, + ), + (2, 1), + ), + ( + Permutation( + 4, + ), + (1, 1, 1), + ), ], ) def test_twisted_spherical_function_degree_value_error(permutation, partition): diff --git a/haarpy/tests/test_unitary.py b/haarpy/tests/test_unitary.py index c9375a8..fdbf62e 100644 --- a/haarpy/tests/test_unitary.py +++ b/haarpy/tests/test_unitary.py @@ -155,7 +155,7 @@ def test_weingarten_reconciliation_symbolic(cycle): "partition, dimension", [ ((3, 2), 1.0), - ((3, 1, 1), 'a'), + ((3, 1, 1), "a"), ((2, 2, 1), (1, 0)), ((3, 3), (8,)), ], @@ -173,7 +173,7 @@ def test_weingarten_unitary_class_dimension_type_error(partition, dimension): "cycle, dimension", [ (Permutation(0, 1, 2), 1.0), - (Permutation(0, 2)(1, 3), 'a'), + (Permutation(0, 2)(1, 3), "a"), (Permutation(2), (0, 1)), (Permutation(4, 1), (8,)), ], @@ -190,37 +190,34 @@ def test_weingarten_unitary_element_dimension_type_error(cycle, dimension): @pytest.mark.parametrize( "cycle", [ - (1,2,"a"), - (3, (1,2), 4), + (1, 2, "a"), + (3, (1, 2), 4), "abc", - ] + ], ) def test_weingarten_unitary_cycle_type_error(cycle): "Test the type error for wrong permutation input" with pytest.raises(TypeError): - ap.weingarten_unitary(cycle, Symbol('d')) + ap.weingarten_unitary(cycle, Symbol("d")) -@pytest.mark.parametrize("n", range(2,5)) +@pytest.mark.parametrize("n", range(2, 5)) def test_gram_orthogonality_elements(n): "Test the orthogonality relation between Weingarten matrix and Graham matrix" d = Symbol("d") orthogonality = sum( d ** (g.cycles) * ap.weingarten_unitary(g, d) for g in SymmetricGroup(n).generate_schreier_sims() - ) + ) assert simplify(orthogonality) == 1 -@pytest.mark.parametrize("n", range(2,10)) +@pytest.mark.parametrize("n", range(2, 10)) def test_gram_orthogonality_classes(n): "Test the orthogonality relation between Weingarten matrix and Graham matrix" d = Symbol("d") - weight = lambda g : d ** (g.cycles) * ap.weingarten_unitary(ap.get_conjugacy_class(g, n), d) - orthogonality = sum( - len(c) * weight(c.pop()) - for c in SymmetricGroup(n).conjugacy_classes() - ) + weight = lambda g: d ** (g.cycles) * ap.weingarten_unitary(ap.get_conjugacy_class(g, n), d) + orthogonality = sum(len(c) * weight(c.pop()) for c in SymmetricGroup(n).conjugacy_classes()) assert simplify(orthogonality) == 1 diff --git a/haarpy/unitary.py b/haarpy/unitary.py index 2c190c7..04fd050 100644 --- a/haarpy/unitary.py +++ b/haarpy/unitary.py @@ -68,9 +68,7 @@ def representation_dimension(partition: tuple[int], unitary_dimension: Symbol) - @lru_cache -def weingarten_unitary( - cycle: Union[Permutation, tuple[int]], unitary_dimension: Symbol -) -> Expr: +def weingarten_unitary(cycle: Union[Permutation, tuple[int]], unitary_dimension: Symbol) -> Expr: """Returns the Weingarten function Args: @@ -90,17 +88,14 @@ def weingarten_unitary( if isinstance(cycle, Permutation): degree = cycle.size conjugacy_class = get_conjugacy_class(cycle, degree) - elif isinstance(cycle, (tuple, list)) and all( - isinstance(value, int) for value in cycle - ): + elif isinstance(cycle, (tuple, list)) and all(isinstance(value, int) for value in cycle): degree = sum(cycle) conjugacy_class = tuple(cycle) else: raise TypeError partition_tuple = tuple( - sum((value * (key,) for key, value in part.items()), ()) - for part in partitions(degree) + sum((value * (key,) for key, value in part.items()), ()) for part in partitions(degree) ) irrep_dimension_tuple = (irrep_dimension(part) for part in partition_tuple) @@ -118,9 +113,7 @@ def weingarten_unitary( irrep_dimension**2 * murn_naka_rule(partition, conjugacy_class) / representation_dimension(partition, unitary_dimension) - for partition, irrep_dimension in zip( - partition_tuple, irrep_dimension_tuple - ) + for partition, irrep_dimension in zip(partition_tuple, irrep_dimension_tuple) ) / factorial(degree) ** 2 ) @@ -131,9 +124,7 @@ def weingarten_unitary( @lru_cache -def haar_integral_unitary( - sequences: tuple[tuple[int]], unitary_dimension: Symbol -) -> Expr: +def haar_integral_unitary(sequences: tuple[tuple[int]], unitary_dimension: Symbol) -> Expr: """Returns integral over unitary group polynomial sampled at random from the Haar measure Args: diff --git a/setup.py b/setup.py index 1016a36..15f40ea 100644 --- a/setup.py +++ b/setup.py @@ -19,9 +19,7 @@ version = f.readlines()[-1].split()[-1].strip("\"'") -requirements = [ - "sympy>=1.12" -] +requirements = ["sympy>=1.12"] classifiers = [ "Development Status :: 4 - Beta", From a8440c66c0b500bcbfd5ca3118a005bc2f53c21c Mon Sep 17 00:00:00 2001 From: yaniccd Date: Wed, 10 Dec 2025 11:15:40 +0900 Subject: [PATCH 2/2] black merged in PR #46 --- haarpy/tests/test_orthogonal.py | 56 ++++------------------ haarpy/tests/test_permutation.py | 25 +--------- haarpy/tests/test_symmetric.py | 15 +----- haarpy/tests/test_symplectic.py | 79 +++++--------------------------- pyproject.toml | 2 + 5 files changed, 24 insertions(+), 153 deletions(-) create mode 100644 pyproject.toml diff --git a/haarpy/tests/test_orthogonal.py b/haarpy/tests/test_orthogonal.py index ac58a56..e56a366 100644 --- a/haarpy/tests/test_orthogonal.py +++ b/haarpy/tests/test_orthogonal.py @@ -67,31 +67,11 @@ def test_zonal_spherical_orthogonality_transversal_zero(permutation, partition1, @pytest.mark.parametrize( "permutation, partition", [ - ( - Permutation( - 3, - ), - (2,), - ), - ( - Permutation( - 3, - ), - (1, 1), - ), - ( - Permutation( - 5, - )(0, 1), - (2, 1), - ), + (Permutation(3), (2,)), + (Permutation(3), (1, 1)), + (Permutation(5)(0, 1), (2, 1)), (Permutation(0, 1, 2, 3, 4, 5), (3,)), - ( - Permutation( - 5, - )(0, 3, 4), - (3,), - ), + (Permutation(5)(0, 3, 4), (3,)), (Permutation(0, 1, 2, 3, 4, 5), (1, 1, 1)), (Permutation(0, 1, 2, 3, 4, 5), (2, 1)), (Permutation(0, 3, 5), (2, 1)), @@ -157,31 +137,11 @@ def test_zonal_spherical_orthogonality_symmetric_zero(permutation, partition1, p @pytest.mark.parametrize( "permutation, partition", [ - ( - Permutation( - 3, - ), - (2,), - ), - ( - Permutation( - 3, - ), - (1, 1), - ), - ( - Permutation( - 5, - )(0, 1), - (2, 1), - ), + (Permutation(3), (2,)), + (Permutation(3), (1, 1)), + (Permutation(5)(0, 1), (2, 1)), (Permutation(0, 1, 2, 3, 4, 5), (3,)), - ( - Permutation( - 5, - )(0, 3, 4), - (3,), - ), + (Permutation(5)(0, 3, 4), (3,)), (Permutation(0, 1, 2, 3, 4, 5), (1, 1, 1)), (Permutation(0, 1, 2, 3, 4, 5), (2, 1)), (Permutation(0, 3, 5), (2, 1)), diff --git a/haarpy/tests/test_permutation.py b/haarpy/tests/test_permutation.py index 21ab657..2efcb05 100644 --- a/haarpy/tests/test_permutation.py +++ b/haarpy/tests/test_permutation.py @@ -105,32 +105,11 @@ def test_mobius_inversion_formula(size): (((0,), (1,), (2,)), ((0,), (1,), (2,)), 31), (((0,), (1,), (2,)), ((0, 2), (1,)), 32), (((0,), (1,), (2,)), ((0, 1, 2),), 33), - ( - ( - ( - 0, - 1, - ), - (2,), - ), - ((0, 2), (1,)), - 34, - ), + (((0, 1), (2,)), ((0, 2), (1,)), 34), (((0, 1, 2),), ((0, 1), (2,)), 35), (((0, 1, 2),), ((0, 1, 2),), 36), (((0,), (1,), (2,), (3,)), ((0,), (1,), (2,), (3,)), 41), - ( - ( - (0,), - ( - 1, - 2, - ), - (3,), - ), - ((0,), (1,), (2,), (3,)), - 42, - ), + (((0,), (1, 2), (3,)), ((0,), (1,), (2,), (3,)), 42), (((0, 2), (1, 3)), ((0,), (1,), (2,), (3,)), 43), (((0, 1, 3), (2,)), ((0,), (1,), (2,), (3,)), 44), (((0, 1, 2, 3),), ((0,), (1,), (2,), (3,)), 45), diff --git a/haarpy/tests/test_symmetric.py b/haarpy/tests/test_symmetric.py index bd9de0c..0f78a25 100644 --- a/haarpy/tests/test_symmetric.py +++ b/haarpy/tests/test_symmetric.py @@ -110,20 +110,7 @@ def test_get_conjugacy_class_cycle_value_error(degree, cycle): [ (((), ()), 1, (3, 1), (((1,), ()),)), (((1, 2), (2, 3)), 4, (3, 2), (((1, 2, 4), (2, 3)),)), - ( - ((1, 1, 1, 3), (2,)), - 4, - (4, 2), - ( - ( - (1, 1, 1, 3), - ( - 2, - 4, - ), - ), - ), - ), + (((1, 1, 1, 3), (2,)), 4, (4, 2), (((1, 1, 1, 3), (2, 4)),)), (((1,), ()), 1, (3, 1), (((1, 1), ()), ((1,), (1,)))), (((1, 2), ()), 2, (3, 2), (((1, 2, 2), ()), ((1, 2), (2,)))), (((), (), ()), 1, (3, 1, 1), (((1,), (), ()),)), diff --git a/haarpy/tests/test_symplectic.py b/haarpy/tests/test_symplectic.py index 368184e..1860017 100644 --- a/haarpy/tests/test_symplectic.py +++ b/haarpy/tests/test_symplectic.py @@ -113,31 +113,11 @@ def test_twisted_spherical_orthogonality_transversal_zero(permutation, partition @pytest.mark.parametrize( "permutation, partition", [ - ( - Permutation( - 3, - ), - (2,), - ), - ( - Permutation( - 3, - ), - (1, 1), - ), - ( - Permutation( - 5, - )(0, 1), - (2, 1), - ), + (Permutation(3), (2,)), + (Permutation(3), (1, 1)), + (Permutation(5)(0, 1), (2, 1)), (Permutation(0, 1, 2, 3, 4, 5), (3,)), - ( - Permutation( - 5, - )(0, 3, 4), - (3,), - ), + (Permutation(5)(0, 3, 4), (3,)), (Permutation(0, 1, 2, 3, 4, 5), (1, 1, 1)), (Permutation(0, 1, 2, 3, 4, 5), (2, 1)), (Permutation(0, 3, 5), (2, 1)), @@ -169,28 +149,11 @@ def test_twisted_spherical_orthogonality_transversal_none_zero(permutation, part @pytest.mark.parametrize( "permutation, partition", [ - ( - Permutation( - 3, - ), - [ - 2, - ], - ), + (Permutation(3), [2]), ((3, 1), (1, 1)), - ( - Permutation( - 5, - )(0, 1), - "a", - ), + (Permutation(5)(0, 1), "a"), ("a", (3,)), - ( - Permutation( - 5, - )(0, 3, 4), - 7, - ), + (Permutation(5)(0, 3, 4), 7), (7, (1, 1, 1)), ], ) @@ -203,30 +166,10 @@ def test_twisted_spherical_function_type_error(permutation, partition): @pytest.mark.parametrize( "permutation, partition", [ - ( - Permutation( - 3, - ), - (2, 2), - ), - ( - Permutation( - 3, - ), - (1, 1, 1), - ), - ( - Permutation( - 4, - ), - (2, 1), - ), - ( - Permutation( - 4, - ), - (1, 1, 1), - ), + (Permutation(3), (2, 2)), + (Permutation(3), (1, 1, 1)), + (Permutation(4), (2, 1)), + (Permutation(4), (1, 1, 1)), ], ) def test_twisted_spherical_function_degree_value_error(permutation, partition): diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..aa4949a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +line-length = 100