Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
181 views
unlisted
ubuntu2004
o

��c���@sHdZddlmZddlZddlmZddlmZddlmZddl	m
Z
ddlmZdd	l
mZdd
lmZddlmZddlmZd
dlmZmZmZmZmZd
dlmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'd
dl(m)Z)d
dl*m+Z+m,Z,m-Z-m.Z.d
dl/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7de,fdd�Z8de,fdd�Z9ede,fdd��Z:de,fdd�Z;de,fdd�Z<de,fdd�Z=de,fd d!�Z>de,fd"d#�Z?d$d%�Z@de,fd&d'�ZAd(d)�ZBdhd*d+�ZCd,d-�ZDed.d/��ZEd0d1�ZFed2d3��ZGede,fd4d5��ZHede,fd6d7��ZIed8d9��ZJede,fd:d;��ZKede,fd<d=��ZLede,fd>d?��ZMde,fd@dA�ZNede,fdBdC��ZOdDdE�ZPee,fdFdG��ZQee,fdHdI��ZRedJdK��ZSedLdM��ZTdNdO�ZUede,fdPdQ��ZVde,fdRdS�ZWe,fdTdU�ZXedVdW��ZYdXdY�ZZde,fdZd[�Z[de,fd\d]�Z\ede,fd^d_��Z]d`da�Z^dbdc�Z_ddde�Z`dfdg�ZadS)iz9
Faber-Zagier relations and pairing in tautological ring
�)�copyN)�cached_function)�span)�ZZ)�QQ)�matrix)�floor)�
Partitions)�IntegerVectors)�Permutations�)�multiply�insertion_pullback�kappa_multiple�psi_multiple�	get_marks)�
all_strata�
num_strata�contraction_table�unpurify_map�single_stratum�autom_count�graph_count_automorphisms�R�X�Graph�num_of_stratum�graph_isomorphic��socle_evaluation)�	MODULI_SM�	MODULI_ST�MODULI_SMALL�dim_form)�get_memory_usage�dprint�remove_duplicates�subsequences�A_list�B_list�aut�simplify_sparse�cCsTt|t|�|�}||}t||||�t||||�t||||�t||||�dS�N)r#�lenrrr)�g�r1�markings�moduli_type�r3�r2r,r,�:/home/user/Introduction lectures/admcycles/DR/relations.py�gorenstein_precomputesr6cs�t�t����}||}t�|���}t�|����t�|���}���fdd�t|�D���fdd�t|�D�}t||k�}	t|�D]7}
t��D]0}|	r\|
|kr\|||
||
|<qIt||
||�|����t��fdd�t|�D��||
|<qIqC|S)a$
    Return the pairing matrix for the given genus, degree, markings and
    moduli type.

    EXAMPLES::

        sage: from admcycles.DR import pairing_matrix
        sage: pairing_matrix(1, 1, (1, 1))
        [[1/4, 1/6, 1/12, 2], [1/6, 1/12, 0, 2], [1/12, 0, -1/12, 2], [2, 2, 2, 0]]
    c�g|]	}t|�����qSr,r��.0�i�r/r1r2r,r5�
<listcomp>1�
��z"pairing_matrix.<locals>.<listcomp>csg|]}dd�t��D��qS)cS�g|]}d�qS�rr,�r9�i2r,r,r5r<3�z-pairing_matrix.<locals>.<listcomp>.<listcomp>)�range�r9�i1)�ngens2r,r5r<3sc�g|]
}�|�|�qSr,r,�r9�k��L�socle_evaluationsr,r5r<;���r#r.rrC�boolr
�sum)r/r0r1r2r3r4�ngens1�ngens3�pairings�symrErAr,)rKr/r1r2rFrLr5�pairing_matrix!s*���rUc
s�t�t����}||}t�|���}���fdd�t|�D���fdd�|D�}	t||ko1|�k�}
tt|��D]=}tt���D]4}|
rT||krT|	|||	||<qAt||||�|�|����t��fdd�t|�D��|	||<qAq9|	S)Ncr7r,rr8r;r,r5r<Gr=z%pairing_submatrix.<locals>.<listcomp>csg|]	}dd��D��qS)cSr>r?r,r@r,r,r5r<IrBz0pairing_submatrix.<locals>.<listcomp>.<listcomp>r,rD)�S2r,r5r<IscrGr,r,rHrJr,r5r<QrMrN)
�S1rVr/r0r1r2r3r4rRrSrTrErAr,)rKrVr/r1r2rLr5�pairing_submatrix@s&���rXcCs*t||||�}|��t|d�t|�S)aX
    This function returns the predicted rank of the codimension r grading
    of the tautological ring of the moduli space of stable genus g curves
    with marked points labeled by the multiset marked_points.

    g and r should be nonnegative integers and marked_points should be a
    tuple of positive integers.

    The parameter moduli_type determines which moduli space to use:
    - MODULI_ST: all stable curves (this is the default)
    - MODULI_CT: curves of compact type
    - MODULI_RT: curves with rational tails
    - MODULI_SM: smooth curves

    EXAMPLES::

        sage: from admcycles.DR import betti

    Check rank R^3(bar{M}_2) = 1::

        sage: betti(2, 3)
        1

    Check rank R^2(bar{M}_{2,3}) = 44::

        sage: betti(2, 2, (1,2,3))  # long time
        44

    Check rank R^2(bar{M}_{2,3})^{S_3} = 20::

        sage: betti(2, 2, (1,1,1))  # long time
        20

    Check rank R^2(bar{M}_{2,3})^{S_2} = 32 (S_2 interchanging markings 1 and 2)::

        sage: betti(2, 2, (1,1,2))  # long time
        32

    Check rank R^2(M^c_4) = rank R^3(M^c_4) = 6::

        sage: from admcycles.DR import MODULI_CT, MODULI_RT, MODULI_SM
        sage: betti(4, 2, (), MODULI_CT)
        6
        sage: betti(4, 3, (), MODULI_CT)  # long time
        6

    We can use this to check that rank R^8(M^rt_{17,2})^(S_2)=122 < R^9(M^rt_{17,2})^(S_2) = 123.
    Indeed, betti(17,8,(1,1),MODULI_RT) = 122 and betti(17,9,(1,1),MODULI_RT)=123
    Similarly, we have rank R^9(M_{20,1}) = 75 < rank R^10(M_{20,1}) = 76
    Indeed, betti(20,9,(1,),MODULI_SM) = 75 and betti(20,10,(1,),MODULI_SM) = 76.
    r)�list_all_FZ�reverser.�compute_rank)r/�r�
marked_pointsr2rKr,r,r5�bettiVs4r^c	Csht||||�t|t|�|�}||}t||||�}t||||�}tt|�t|�||||�}t|���S)a�
    This function returns the rank of the codimension r grading of the
    Gorenstein quotient of the tautological ring of the moduli space of genus g
    curves with marked points labeled by the multiset marked_points.

    g and r should be nonnegative integers and marked_points should be a
    tuple of positive integers.

    The parameter moduli_type determines which moduli space to use:
    - MODULI_ST: all stable curves (this is the default)
    - MODULI_CT: curves of compact type
    - MODULI_RT: curves with rational tails

    EXAMPLES::

        sage: from admcycles.DR.relations import gorenstein

    Check rank Gor^3(bar{M}_{3}) = 10::

        sage: gorenstein(3, 3)  # long time
        10

    Check rank Gor^2(bar{M}_{2,2}) = 14::

        sage: gorenstein(2, 2, (1,2))  # long time
        14

    Check rank Gor^2(bar{M}_{2,2})^{S_2} = 11::

        sage: gorenstein(2, 2, (1,1))  # long time
        11

    Check rank Gor^2(M^c_{4}) = 6::

        sage: from admcycles.DR import MODULI_CT, MODULI_RT

        sage: gorenstein(4, 2, (), MODULI_CT)  # long time
        6

    Check rank Gor^4(M^rt_{8,2}) = 22::

        sage: gorenstein(8, 4, (1,2), MODULI_RT)  # long time
        22
    )r6r#r.�good_generator_listrX�tupler�rank)	r/r\r]r2r3r4rWrV�Mr,r,r5�
gorenstein�s-�rccsddlm}m}|d��|�tt���t|���t����kr"dSt��|��}|d|�g}t��t	�d�|��}����fdd�t
�����D�D]}	g}
|	D]}|
�||d|dg�qRt|
�}
|�|
�qLt
���d��D]}	g}
|	D]}|
�||d|dg�qzt|
�}
|�|
�qt|d|t|��|d	��|�tt����tk�r�td��D]�t��|��}|D]�}
t|
d
�}dd�|D�D]�}d
}t|
j���D]}t|
j||fd�|
j||fkr�d}nq�|�r�|
j|dfd�d
���dk�rq�|
�|��t������k�rq�t���ttd�d����}dd�tt|��D�}tt|��D]}t|
j�}|�|||�t|��|��||<�q9�����fdd�t
������D�}|t
����d��7}|D]*}g}|D]}|d}||dk�r�|�|||dg��q|t|�}|�|��qvq�q�q�|d|t|��|d|t|��|d	��|�tt���t|�}t|�}|d||�|d|�d}i}t|�D]\}}|D]
}|d|||df<�q�q�|�rt|||�\}}t|||�}|d||�||S)z�
    EXAMPLES::

        sage: from admcycles.DR.relations import recursive_betti
        sage: recursive_betti(2, 3)  # not tested
        ?
    r)r%�dsavez'Start recursive_betti (%s,%s,%s,%s): %srz%s gensc	s"g|]
}t|��t�d����qSr?��unsymmetrize_vecr�r9�br)r/r2�nr\r,r5r<�s�z#recursive_betti.<locals>.<listcomp>z%s gens, %s rels so farz(Middle recursive_betti (%s,%s,%s,%s): %sTcS�g|]}|d�qSr?r,�r9�orbitr,r,r5r<��F�cSr>������r,�r9�numr,r,r5r<���c	s&g|]}t|���t�d����qSr?rerg)�d�g2r2r\�r0r,r5r<s
�
�rpz%s gens, %s relszsparse-%s-gens-%s-relsz%s gens, %s distinct relszsparse-%s-distinct-relszsparse-answer-%s)�utilsr%rdrr$r.r#r�symmetrize_mapr�choose_basic_rels�appendr+�interior_derived_relsr rCrrrb�ncolsr�degreer`r�replace_vertex_with_graphrr&�	enumerate�choose_orders_sparse�compute_rank_sparse)r/r\r1r2r%rd�ngen�	relationsZpartial_sym_map�rel�rel2�x�strata�G�
vertex_orbitsr:�good�j�strata2�which_gen_listrr�G_copy�rel_list�rel0�relation�nrelsra�DZreli�	row_order�	col_orderr,)rtr/rur2rir\rvr5�recursive_betti�s��

��

$�
�
�

��������&�
�r�cCstt||||����S)al
    EXAMPLES::

        sage: from admcycles.DR.relations import FZ_rels
        sage: FZ_rels(2, 2)
        [
        (1, 0, 0, 0, 0, 0, -1/20, -1/480),
        (0, 1, 0, 0, 0, 0, -5/24, -1/96),
        (0, 0, 1, 0, 0, 0, -1/24, 0),
        (0, 0, 0, 1, 0, 0, -1/24, 0),
        (0, 0, 0, 0, 1, 0, -1, -1/12),
        (0, 0, 0, 0, 0, 1, -1, -1/24)
        ]
    )r�	FZ_matrix�basis�r/r\r1r2r,r,r5�FZ_rels%sr�cC�tt||||��S)a]
    EXAMPLES::

        sage: from admcycles.DR.relations import FZ_matrix
        sage: from admcycles.DR.moduli import MODULI_SM, MODULI_RT, MODULI_CT, MODULI_ST
        sage: FZ_matrix(2, 2)
        [     60     -60      84       0       6       0       0       0]
        [ 473760 -100512   33984  -10080    6624  -10080    -288     -72]
        [ 115920  -12240   13536   -5040    1584   -5040    -144     -36]
        [      0       0     102     -30       0       0      -3       0]
        [      0       0      30      42       0       0      -3       0]
        [      0       0       0       0      66     -60      -6      -3]
        [      0       0       0       0      15       6     -21    -3/2]

        sage: FZ_matrix(2, 2, (1,), MODULI_CT)
        [     30     -30      30       0      42       0       0       0]
        [ 441000  -78120   61200 -138600   37296   -7920  -42840    1368]
        [ 204120  -27864  -39312   98280   20304    9072  -37800   -3672]
        [      0       0     -30      30       0      42       0       0]
        [  71820   -7020    9720  -41580    9288   -3240  -18900     756]
        [  13860    -900   -2520   16380    2520    3528  -16380   -1764]
        [      0       0       0       0      66     -30     -30      -6]
        [      0       0       0       0      15      21     -15     -21]
        [      0       0       0       0      15     -15      21     -21]

        sage: FZ_matrix(3, 2, (1, 2), MODULI_RT)
        [-251370   27162  -34020  -34020  145530   18900  145530   18036  -69930]
        [ -56700    4860   10584   -7560  -49140   -7560   41580   -8424   34020]
        [ -56700    4860   -7560   10584   41580   -7560  -49140   -8424   34020]
        [  -6930     450    1260    1260   -8190    1764   -8190     900   -6930]
        [  -6930     450    -900    -900    6930     900    6930     900   -6930]

        sage: FZ_matrix(3, 2, (1, 1), MODULI_SM)
        [-125685   13581  -34020  145530    9450]
        [ -56700    4860    3024   -7560   -7560]
        [  -3465     225    1260   -8190     882]
        [  -3465     225    -900    6930     450]
    )rrYr�r,r,r5r�8s'r�cCs<dd�}t|||d|d�}t|||d|d�}||�||�kS)aJ
    Check whether computing the FZ-relations via Pixton's 3-spin formula and
    by using new relations give the same result.

    TESTS::

        sage: import itertools
        sage: from admcycles.DR import FZ_methods_sanity_check, MODULI_SM, MODULI_RT, MODULI_CT, MODULI_ST
        sage: gn = [(0, 5), (1, 1), (1, 2), (1, 3), (2, 2), (3, 0), (4, 1)]
        sage: degrees = [0, 1, 2, 3]
        sage: moduli = [MODULI_SM, MODULI_RT, MODULI_CT, MODULI_ST]
        sage: for (g, n), r, moduli_type in itertools.product(gn, degrees, moduli):  # long time
        ....:     if not FZ_methods_sanity_check(g, r, n, moduli_type):
        ....:         print("ERROR: g={}, r={}, n={}, moduli_type={}".format(g, r, n, moduli_type))

        sage: all(FZ_methods_sanity_check(9, i, 0, MODULI_SM) for i in range(10))  # long time
        True
    cSs<|��t|���D]\}}|��r|�t|��Sq
|Sr-)�
echelonizer�rows�is_zero�matrix_from_rowsrC)rbr:r\r,r,r5�echelon_without_zerosus�z6FZ_methods_sanity_check.<locals>.echelon_without_zerosrTF)�rels_matrix)r/r\rir2r�Zspin3�newrelsr,r,r5�FZ_methods_sanity_checkbsr�cCsZtt||||��}|tkr|t||||�7}|s+t||||�}|�dd�t|�D��|S)NcSr>r?r,r8r,r,r5r<�rBzlist_all_FZ.<locals>.<listcomp>)r�interior_FZr �boundary_FZrrzrC)r/r\r1r2r�r�r,r,r5rY�srYcCs\t|ttd|d���}g}ttd|d�}d|d<td|d�D]}||d|f<q!|D]N}	t|j�}
|d|d<|	dD]}|dt|7<q>td|d�D]}d|	d|dddt|d|f<qRt|�}|
�||�|�	|	|
g�q,g}
g}|D]*}|d�
�d}|D]
}t|d|�r�d}nq�|r�|�	|d�|
�	|d�q�|
S)	Nr�rp)rrr)rrTF)�
FZ_param_listr`rCrrrrbrr~rz�compute_invariantr)r��vr/rtri�paramsZgraph_paramsrbr:�pr�r�ZG_pZparams_reducedZgraphs_seenr�r��GGr,r,r5�reduced_FZ_param_list�s>
*��r�c	sn|dkrgSg}td|�}dd�t|�D�}|D]}||dd7<qg�t|�D]}||dkr?��|d||g�q,t|dd�D]l}t|d|dt���D]\}dd�t|d�D�g}tt���D]&}|�t||d�|d�|dd����d	d�|d
D�|d
<qktj|�D]�|�t	�d�t	��fdd�tt���D��f�q�qWqH|S)z�
    EXAMPLES::

        sage: from admcycles.DR.relations import FZ_param_list
        sage: FZ_param_list(3, ())
        [((3,), ()), ((1, 1, 1), ()), ((1,), ())]
    rr?cSr>r?r,r8r,r,r5r<�rBz!FZ_param_list.<locals>.<listcomp>rr�cSs&g|]}tdd�|D��st|��qS)css�|]	}|ddkVqdS)rnr�Nr,�r9�lr,r,r5�	<genexpr>����+FZ_param_list.<locals>.<listcomp>.<genexpr>)�any�list�r9�sigmar,r,r5r<�s�)�lengthcSs0g|]}tdd�|D��dkrdd�|D��qS)css �|]}|ddkrdVqdS)rnrrNr,r�r,r,r5r��s�r�rcSsg|]}|d�qS�rr,rHr,r,r5r<�rmz,FZ_param_list.<locals>.<listcomp>.<listcomp>)rPr�r,r,r5r<�s�rpcs(g|]}�|dt�|d�f�qS�rr)r`rH��SZ
markings_bestr,r5r<�s
�

�)
�maxrCrzr
r.r	r��	itertools�productr`)	rir1Z
final_list�mmmZmarkings_groupedr:r�Zn_vec�S_listr,r�r5r��s:� ��
���
r�cCs4||d}|dkrdS|ddkrt|St|S)Nrnr)r(r))�m�termrir,r,r5�C_coeff�sr�cCsht��}|d}|d|kr2|ddkr(|d|dt||�td||�7}|d7}|d|ks|S)Nr�rnrp�����)r�zeror�)r:r��parity�totalrIr,r,r5�dual_C_coeff�s(�r�cCsD|��}g}td|d�D]}t||�D]}|�|�qq
t|�S)Nr)r}rCrzr`)�Fr��target_partitionr:r�r,r,r5�poly_to_partition�s�r�c		Cst��}tdd�|D��}td|d�D]e}tttt|���t|�|�D]S}t|��|�t|t|�|d��|�t|���}tt|�|�D]}|t	||||||�9}qKtt|��D]}||vrjqc|t	d||�9}qc||7}q%qdt|�t|�|t
t|��}|S)Ncss�|]	}|dkrdVqdS)rNr,r8r,r,r5r��r�zkappa_coeff.<locals>.<genexpr>rrrp)rr�rPrCrr�r.�binomial�	factorialr�r*)	r�Zkappa_0r�r�Znum_onesr:Z	injectionr�r�r,r,r5�kappa_coeff�s."�
� 
��
�r�cCsvt|||||�}g}|��}td|d�D]'}	|�d|j|	dfd|�|	�d|j|	df|j|	dfdf�qg}
g}t|�D]?}	d}t|�D]*}
|	dksi||
|
dksi||
|
dkrw|
|dkrw|dksu||
||krw|
}qM|�|�|
�||�qEtt|
�|�}dd�td|>�D�}|D]}d}t|�D]}	||	dkr�|d||	>7}q�||||<q�|S)Nrr�rrpcSr>r?r,r8r,r,r5r<rBz#FZ_kappa_factor.<locals>.<listcomp>)r�num_verticesrCrzrbr}�FZ_kappa_factor2r`)rrr�r/r\r1r2r�rK�nvr:�LL�tau�minir�Zfactor_dictZ
factor_vecZ
parity_keyr�r,r,r5�FZ_kappa_factors:"��L�
�r�c	Cs�t|||||�}|��}|��}td�|}	g}
|D]}|
�t|d��qtj|
�}dd�t|	�D�}
g}|D]C}|�g�td|d�D]4}|j	d|f|dkrztd|d�D]}|j	||fdkry|d�|d|j	||fdf�nqZqFq8|D]G}d}d}tt
|��D]2}tt
||��D]'}|t||||||d�9}||||td�|||d>N}q�q�|
||7<q~|
S)Nr�rcSr>r?r,r8r,r,r5r<(rBz%FZ_marking_factor.<locals>.<listcomp>rrp)rr��	num_edgesrrzrr�r�rCrbr.r�)rr�marking_vecr/r\r1r2r�r��ne�num_paritiesZPPP_list�marksZPPP�marking_factorsZincident_verticesZ	mark_typerIr:�permsr�Zmarking_factorZmarks_index�countr,r,r5�FZ_marking_factorsJ

$�������r�c	Cs�t|�}td|�}dd�t|�D�}|D]}||dd7<qg}|D]
}|�t||��q&tj|�}i}tjdd�t|�D��D]}	d|t|	�<qD|D]�}
dd�t|�D�}t|�D]}t|�D]}t|
||�D]}
||�|d�qnqdq^d}dd�t|�D�}	t�	�}t|�D]6}|t
||�9}|	|t||�7<|	|td	�;<|tt||�||dt
||d��9}q�|t|	�||7<qO|S)
Nr?cSr>r?r,r8r,r,r5r<CrBz$FZ_kappa_factor2.<locals>.<listcomp>rcSr>)r�r,r8r,r,r5r<KrBrcS�g|]}g�qSr,r,�r9r�r,r,r5r<NrBcSr>r?r,r8r,r,r5r<TrBr�)r.r�rCrzr
r�r�r`r�oner*rPr�r�)rKr�r�r�Z
sigma_groupedr:r�r��
kappa_factorsr��
assignmentZassigned_sigmar�rIZ
sigma_autsZkappa_factorr,r,r5r�?s@
��"�r�c	Cs,t|||||�}|��}td�|}|��}g}	td|d�D]=}
|jd|
fdkr\|	�|
g�td|d�D]$}|j||
fdkrI|	d�|�|j||
fddkr[|	d�|�q7qdd�t|�D�}tjdd�|	D��D]�}
d}tt	|	��D] }|
|dkr�|d|	|dd>N}|d|	|dd>N}qzd}tt	|	��D]g}|	|d|	|dkr�|t
|j|	|d|	|dfd|j|	|d|	|dfd|
|td��9}q�|t
|j|	|d|	|dfd|j|	|d|	|dfd|
|td��9}q�|||7<qp|S)Nr�rrrpcSr>r?r,r8r,r,r5r<orBz#FZ_hedge_factor.<locals>.<listcomp>cSsg|]}ddg�qSr�r,r8r,r,r5r<prm)rr�rr�rCrbrzr�r�r.r�)rrr/r\r1r2r�r�r�r��	edge_listrIr:�
hedge_factorsZ
edge_paritiesr�Zhedge_factorr,r,r5�FZ_hedge_factor`sB��$.�$.�r�cCs�|d}|d}t|||||�}|��}	t|||||�}
td�|��}td�|	}t||||||�}
t||||||�}t|||||�}t��}t	|�D]#}|
|dkrUqLt	|�D]}||
||||||A|j
A7}qYqL|||
}|S)a�
    EXAMPLES::

        sage: from admcycles.DR.graph import num_strata
        sage: from admcycles.DR.moduli import MODULI_ST
        sage: from admcycles.DR.relations import FZ_coeff
        sage: [FZ_coeff(i, ((3,), ()), 2, 2, (), MODULI_ST) for i in range(num_strata(2, 2))]
        [60, -60, 84, 0, 6, 0, 0, 0]
        sage: [FZ_coeff(i, ((1, 1, 1), ()), 2, 2, (), MODULI_ST) for i in range(num_strata(2, 2))]
        [473760, -100512, 33984, -10080, 6624, -10080, -288, -72]
        sage: [FZ_coeff(i, ((1,), ()), 2, 2, (), MODULI_ST) for i in range(num_strata(2, 2))]
        [115920, -12240, 13536, -5040, 1584, -5040, -144, -36]
    rrr�)rr�rr�h1r�r�r�r�rC�
target_parity)rr�FZ_paramr/r\r1r2r�r�r�r�Z
graph_autsZ	h1_factorr�r�r�r�r�r:r�r,r,r5�FZ_coeff�s.���r�cs^t�����}g}td��d��}|D]������fdd�t|�D�}|�|�q|S)a
    EXAMPLES::

        sage: from admcycles.DR.relations import interior_FZ
        sage: interior_FZ(2, 2)
        [[60, -60, 84, 0, 6, 0, 0, 0],
         [473760, -100512, 33984, -10080, 6624, -10080, -288, -72],
         [115920, -12240, 13536, -5040, 1584, -5040, -144, -36]]
    rnrc	sg|]}t|�������qSr,)r�r8�r�r/r1r2r\r,r5r<�s�zinterior_FZ.<locals>.<listcomp>)rr�rCrz)r/r\r1r2r�r�ZFZplr�r,r�r5r��s�r�c
Csd||d|}|dkrgStd||||tt���d|}t||||�}g}t|d�D]P}||dr8q/t|�D]B}	tdd�|	D��rHq<|dkrVt|	�d|fff}
nt|	�d	f}
g}t|�D]}t||
||||�}
|
dkrx|�	||
g�qb|�	|�q<q/td
||||tt���|S)NrnrrzStart FZ (%s,%s,%s,%s): %sr�r�css�|]	}|ddkVqdS)rnrNr,r�r,r,r5r��r�z"possibly_new_FZ.<locals>.<genexpr>r,zEnd FZ (%s,%s,%s,%s): %s)
r%rr$rrCr	r�r`r�rz)r/r\rir2r�r1r�r�r:r�r�r�r��coeffr,r,r5�possibly_new_FZ�s<����r�cCs|tkrgSt||||�}t|�}g}td|�D]�}t||||�}|D]�}	t|	d�}
dd�|
D�D]�}d}t|	j���D]}
t|	j||
fd�|	j||
fkrTd}nq<|�r|	j|dfd}d|||dkrlq1|	�|�}t	|||�||kr|q1t|||t
td|d��|�}dd�tt|��D�}tt|��D]}t|	j�}|�|||�t
|||||�||<q�t|	|||d|||d�}d}|D]9}dg|}tt|��D]"}||d	kr�|||t|||||t
td|d��|�7<q�|�|�|d7}q�q1q#q|S)
a
    EXAMPLES::

        sage: from admcycles.DR.relations import boundary_FZ
        sage: boundary_FZ(2, 2)
        [[0, 0, 102, -30, 0, 0, -3, 0],
         [0, 0, 30, 42, 0, 0, -3, 0],
         [0, 0, 0, 0, 66, -60, -6, -3],
         [0, 0, 0, 0, 15, 6, -21, -3/2]]
    rTcSrjr?r,rkr,r,r5r<�rmzboundary_FZ.<locals>.<listcomp>rFrncSr>ror,rqr,r,r5r<rBrp)r rr.rCrrbr|rr}r#r`rr~rr�r�rz)r/r\r1r2�
generatorsr�r�rvr�r�r�r:r�r�rurtr�r�rrr�ZrFZplZcccccr�r�r,r,r5r��sj
$�
�


��
���

���"r�cs�|r�dkrtd�dStt��t������}|St������}t�����}��krL�dkr?�����fdd�|D�}n
�����fdd�|D�}||}	t��t�����}
ttt|	�|
dd�}t	|	�D]\}��D]
\}}
|
|||f<qnqh|S)	a�
    Returns a matrix containing all FZ-relations for given ``g``, ``r``, ``n``, ``moduli_type``.
    The relations are invariant under the symmetry action on the first ``symm`` points.
    When ``usespin`` is True the relations are computed using Pixton's 3-spin formula.
    When ``usespin`` is False the relations are computed by deriving old relations and
    combining them with (possibly) new relations.

    TESTS::

      sage: from admcycles.DR import rels_matrix
      sage: sum(rels_matrix(2, 2, 4, 2, 1, False).echelon_form().column(-1))  # long time
      38
      sage: from admcycles.DR import rels_matrix, MODULI_RT, betti
      sage: def betti2(g, n, r):
      ....:     M = rels_matrix(g, r, n, n, MODULI_RT, False)
      ....:     return M.ncols() - M.rank()
      sage: [betti2(5, 2, i) for i in range(6)]  # long time
      [1, 3, 6, 6, 3, 1]
      sage: [betti(5, i, (1, 1), MODULI_RT) for i in range(6)]  # long time
      [1, 3, 6, 6, 3, 1]

    Check for https://gitlab.com/modulispaces/admcycles/-/issues/105::

        sage: from admcycles.DR import MODULI_ST
        sage: rels_matrix(9, 3, 0, 0, MODULI_ST, False).ncols()
        356
    rz'FZ_matrix not implemented with symmetryNc	s"g|]
}t|��t������qSr,re�r9r��r/r2rir\�symmr,r5r<@s
��zrels_matrix.<locals>.<listcomp>c
s*g|]}t|��t���t������qSr,��partial_unsymmetrize_vecrr�r�r,r5r<Cs
�
�T)�sparse)
�printrrYr�derived_relsr�rrr.r)r/r\rir�r2�usespinr�ZdrelsZpnrelsZallrelsr�r:r��cr,r�r5r�s0���r�cCs|dkrgStd||||tt���g}t|�D�]T}t|||�|kr�t||||�}|D]X}t||||�D]M}	t|d�|	�d�}
|
|krVt	|||t
||
�t
||�|�}nt|�}t||�D]}t||	||||||
|d�}|	|dkr{|
d7}
q`|�
t|��q6q,q|tkr�|dkr�|dks�|dkr�|dks�qt|||t�}|t|||�}
|D]�}t||||
d|�D]�}t|d�|�d�}t||
d|
d|�D]�}	t|d�|	�d�}
|
|kr�t	|||t
||
�t
||�t�}nt|�}t|
d�D]}t||	||||||
td�}|	|dk�r|
d7}
q�|}
t||d||||
d|
|d�}|ddk�r7|
d7}
t|||
�D]#}t|||d||||
||
|d�}||ddk�ra|
d7}
�q?|�
t|��q�q�q�qtd||||tt���t|�}|S)z�
    Returns a list of relations that are derived from relations with
    less points by pulling back along the forgetfulmap that forgets a point.
    rz(Start pullback_derived (%s,%s,%s,%s): %srFrnTz&End pullback_derived (%s,%s,%s,%s): %s)r%rr$rCr#ryr'r�r�r�rrrrzr+r!r"r&)r/r\rir�r2�answer�n0Z
basic_relsr��vec�
local_symmr�r:rI�vec2Zlocal_symm2r,r,r5�pullback_derived_relsPs��
�����(
���� ������r�cs�td�|��tt���tt�|�|���}t|�D]��t||�d���|kr7t�|t���t�|���������fdd�t	�����D�}|t������7}|D]w}t|�d�D]l}t
|�D]e}	t|�|���D]W}
t|�}�}t���D]!}
t|
|
�D]}t|t���|
d�|����}|d7}q�q�|	D]}
t
||
�|����}||
7}q��|kr‡fdd�|D�}|�t|��qrqeq_qUqtd�|��tt���t|�}|S)z�
    Returns a list of relations that are derived from relations with
    lower codimension by multlication with psi- and kappa-classes.
    z(Start interior_derived (%s,%s,%s,%s): %src
s*g|]}t|��t���t������qSr,r�)r9r�)r/r�r2rirvr,r5r<�s*z)interior_derived_rels.<locals>.<listcomp>rcs g|]}�|d|dg�qSr�r,)r9�y)�symm_mapr,r5r<�� z&End interior_derived (%s,%s,%s,%s): %s)r%rr$rr�rCr�rxrryr	r
rrrzr+r&)r/r\rir�r2r�Z
pullback_relsr�r:r�r�r��rcurr��mmr,)r/r�r2rirvrr5r{�sP�$�
��
�����r{c	Cs�t||||�}|�d�d}g}|D]<}t|j�}	td|	j���D]!}
|	jd|
fddkrBt||	jd|
fd|�|	jd|
f<q!|�t|	||||��q|S)z�
    Returns the map for symmetrizing a stratum by replacing its ``markings`` with ``symm_markings``.
    Requires ``symm_markings`` to be more symmetrized than ``markings``.
    rr�r)	rr�rrbrCr|rrzr)r/r\r1�
symm_markingsr2�gens�difrr�r�r:r,r,r5rx�s
(�rxcs���d��|�d�}t����|krtd�dS�d|kr7������fdd�t��t��d�|��D�St�����}i}tt|��D]w}||��vrOqFd||<||}	td|	j�	��D]}
|	jd|
fddkrp|
}nq_td|	j�	��D]C}
|	jd|
fddkr�t
|	j�}|jd|
fd7<|jd|fd8<t|�����}
|
|��vr�||
d||
<qyd||
<qyqFt���|��}dd�tt
��|���D�}|��D]}|||�|||g�q�|S)	a|
    Returns map that replaces a stratum with ``markings`` by a linear
    combination of strata with ``symm_markings``.

    This function is an inverse of :func:`symmetrize_map`. The coefficient of
    each stratum in the output is the size of its orbit under the corresponding
    symmetric action.  Requires ``symm_markings`` to be more symmetrized than
    ``markings``.
    rzthis should not be happening?rpcs(g|]}t|���t��d����qSr�r�)r9�us�r/r1r2rir\Ztarget_symmr,r5r<�s(z,partial_unsymmetrize_map.<locals>.<listcomp>rr�cSr�r,r,r8r,r,r5r<�rB)r�r.r��partial_unsymmetrize_maprrrC�keysrbr|rrrxrrz)r/r\r1rr2r�r�orbitsr:r�r�Zpt2r�rrr�resultrIr,rr5r	�sH

2�
��
r	cCs�||kr|St|||||�}g}|D]/}d}	||dD]}
|	|
d7}	q||dD]}
|�|
d|d|
dt|	�g�q+qt|�}|S)z^
    Applies partial_symmetrize_map to a relation to calculate its unsymmetrized version.
    rr)r	rzrr+)r�r/r\r1rr2�	unsym_mapr�r�r*r�r,r,r5r��s(�r�cCsttdd�|D��}t|||tt|�t|��|�}dd�tt||||��D�}tt|��D]}|||�|�q,|S)z|
    Does the same as partial_unsymmetrize_map but is faster.
    Only works for unsymmetrizing from complete symmetry.
    cSr>r�r,r8r,r,r5r<rBz$unsymmetrize_map.<locals>.<listcomp>cSr�r,r,r8r,r,r5r<rB)r`rxrr.rCrrz)r/r\r1r2Z	markings2Zsym_map�mapr:r,r,r5�unsymmetrize_mapsrc
Csdt||||�}g}|D] }t||d�}||dD]}	|�|	|dt|�g�qqt|�}|S)Nrr)rr.rzrr+)
r�r/r\r1r2r
r�r�r*r�r,r,r5rfs�rfc
s�td|�|�tt���t||���krgSt||�}tt|�||���}�tkr+|Std��D�]�t	|�|��}|D�]}t
|d�}	dd�|	D�D]�}
d}t|j���D]}t
|j|
|fd�|j|
|fkrnd}nqV|�r=d�t|j���D]}|j|
|fddkr�|jd|fddkr��d7�q{|j|
dfd�d���dkr�qK|�|
��t������kr�qKt	���t�����}
d	d�tt|
��D�}tt|
��D]}t|j�}|�|
|
|�t||�|��||<qه�����fd
d�t������D�}|t�������7}|D]&}g}|D]\}}||dk�r0|�|||g��qt|�}|�|��qqKq<q0t|�}td|�|�tt���|S)
z�
    Returns a list of relations that are derived from relations with
    lower genus, codimension, and/or number of points.
    This is done by taking a Graph and inserting a relation at a vertex.
    zStart derived (%s,%s,%s,%s): %srTcSrjr?r,rkr,r,r5r<7rmz derived_rels.<locals>.<listcomp>rFrncSr>ror,rqr,r,r5r<Jrsc
s.g|]}t|���t���t������qSr,r�rg�rtruZ	localsymmr2r\rvr,r5r<Qs.rpzEnd derived (%s,%s,%s,%s): %s)r%rr$r#rrr{r rCrrrbr|rr}r.rr~rryrzr+r&)r/r\rir�r2r1r�r�r�r�r:r�r�r�r�rrr�r�r�r��x0�x1r,rr5r�%s|�


$�,�
�
�


�*����%

�r�cCs�d|||dkrgSt||tdd�t|�D��|�}|tkr2|t||t�kr2dd�t|�D�}nt||||�}|s=gStd||||tt	���t
|||||�}t|�}td||�i}t|�D]}	||	D]}
|
d||	|
df<qgqa|dkr�t|||�\}}t
|||�}
td	|
�n
d}
g}tt|��}g}tt|��D]4}||D]}
|
d|||
df<q�|�|�|d7}t
|||�|
kr�|�||�|
d7}
td	|
�q�td
||||tt	���td||||||
�|S)a�
    Return a basis of new relations of the tautological ring invariant under symmetry.

    EXAMPLES::

        sage: from admcycles.DR.moduli import MODULI_SM, MODULI_RT, MODULI_CT, MODULI_ST
        sage: from admcycles.DR.relations import choose_basic_rels
        sage: choose_basic_rels(2, 2, 0, MODULI_ST)
        [[[0, 115920],
          [1, -12240],
          [2, 13536],
          [3, -5040],
          [4, 1584],
          [5, -5040],
          [6, -144],
          [7, -36]]]
    rnrcSr>r�r,r8r,r,r5r<urBz%choose_basic_rels.<locals>.<listcomp>cSsg|]}|dgg�qSr�r,r8r,r,r5r<wsz"Start basic_rels (%s,%s,%s,%s): %sz%s gens, %s oldrelsrzrank %sz End basic_rels (%s,%s,%s,%s): %sz%s,%s,%s,%s: rank %s)rr`rCr"r#r r�r%rr$r�r.r�r�r�rz)r/r\rir2Zsym_ngenZsym_possible_relsZ
previous_relsr�r�r:r�r�r�Z
previous_rankr�r�r,r,r5ry`sV ��
�
�ryc
sDd}t|�}t|�}dd�t|�D�}dd�t|�D��t|�D]}||||<q t|�D]}|�||<q-dd�t|�D�}dd�t|�D�}	|D]}
||
d�|
d�|	|
d�|
d�qJ|D]�}g}||D]}|�|�qm|sxqe|d7}|j�fdd	�d
�|d}g}
|	|D]}||||kr�|
�|�q�|dd�D]]}|||ft|||f�}|
D]J}||f|vr�d|||f<||�|�|	|�|�|||f||||f8<|||fdk�r|�||f�||�|�|	|�|�q�q�|
D]}|�||f�||�|�|	|�|��qqe|S)z�
    Return the rank of the sparse matrix ``D`` given as a dictionary.

    EXAMPLES::

        sage: from admcycles.DR.relations import compute_rank_sparse
        sage: compute_rank_sparse({(0, 1): 1, (1, 0): 2}, [0 ,1], [0, 1])
        2
    rcSr>ror,r8r,r,r5r<�rBz'compute_rank_sparse.<locals>.<listcomp>cSr>ror,r8r,r,r5r<�rBcS�g|]}t��qSr,��setr8r,r,r5r<��cSrr,rr8r,r,r5r<�rrc��|Sr-r,�r��Zcol_order_rankr,r5�<lambda>��z%compute_rank_sparse.<locals>.<lambda>��keyN)r.rC�addrz�sortr�pop�remove)r�r�r�r��nrowsr|Zrow_order_rankr:Zrow_contentsZcol_contentsr�r�r��T�iirI�ratr,rr5r��s`

� ��
�r�cCr�r-)r.ry)r/r\rir2r,r,r5�num_new_rels�sr&c	Cspt||||�t|t|�|�}||}ttt||||���}tt||||��}t||||||�}t|��	��
�S)aG
    Return the kernel of the pairing in degree ``r``.

    EXAMPLES::

        sage: from admcycles.DR.relations import goren_rels
        sage: goren_rels(3, 2)  # long time
        [
        (1, 0, 0, -41/21, 4/35, 0, 0, 0, -5/42, 41/504, 1/105, -11/140, 1/5040),
        (0, 1, 0, -89/7, -11/35, 0, 0, 0, -5/7, 103/168, -1/7, -47/70, -1/140),
        (0, 0, 1, -1, -7/5, 0, 0, 0, 0, 0, -1/10, 0, 0),
        (0, 0, 0, 0, 0, 1, 0, 0, 0, -1/24, 0, 0, 0),
        (0, 0, 0, 0, 0, 0, 1, 0, 0, -1/24, 0, 0, 0),
        (0, 0, 0, 0, 0, 0, 0, 1, -2, 1, -7/5, -7/5, -1/10)
        ]
    )r6r#r.r`rCrr_rXr�kernelr�)	r/r\r1r2r3r4rWrVrbr,r,r5�
goren_rels�sr(cCs,t||||�}g}t|�}t|�D]�}||}d}	td|j���D]j}
|j|
dfd}d}td|d�D]$}|j|
df|dkrLd||krLd}	n|||j|
df|7}q5|	s^n.td|j���D]}
||j|
|
fd7}||j|
|
fd7}qf|dkr�||kr�d}	nq!|	r�|�|�q|S)at
    Return a subset of indices whose corresponding strata generate
    the ``r``-th degree part of the tautological ring.

    EXAMPLES::

        sage: from admcycles.DR.moduli import MODULI_SM, MODULI_RT, MODULI_CT, MODULI_ST
        sage: from admcycles.DR.relations import good_generator_list
        sage: good_generator_list(3, 1, (), MODULI_ST)
        [0, 1, 2]
        sage: good_generator_list(3, 2, (), MODULI_ST)
        [1, 3, 4, 8, 9, 10, 11, 12]
        sage: good_generator_list(3, 3, (), MODULI_ST)
        [9, 22, 30, 31, 32, 35, 36, 37, 38, 39]
        sage: good_generator_list(3, 4, (), MODULI_ST)
        [86, 87, 109, 110, 111, 112, 113, 114, 117, 118, 119, 120]
        sage: good_generator_list(3, 5, (), MODULI_ST)
        [237, 238, 239, 257, 258, 259, 260, 261]
        sage: good_generator_list(3, 6, (), MODULI_ST)
        [373, 374, 375, 376, 377]
    TrrrnFr�)rr.rCrbr"r|rz)r/r\r1r2rZ	good_gens�ngensrrr�r�r:�codimrtr�r,r,r5r_�s6"�
�r_cs�dd�t|�D��dd�t|�D��|D]}�|dd7<�|dd7<qtt|��}tt|��}|j�fdd�d�|j�fd	d�d�||fS)
NcSr>r?r,r8r,r,r5r<1rBz(choose_orders_sparse.<locals>.<listcomp>cSr>r?r,r�r,r,r5r<2rBrrcrr-r,r��row_numsr,r5r8rz&choose_orders_sparse.<locals>.<lambda>rcrr-r,r��col_numsr,r5r9r)rCr�r)r�r"r|rr�r�r,�r.r,r5r�0sr�cs�t|�}|dkrggfSt|d�}dd�t|�D��dd�t|�D��t|�D]!}t|�D]}|||dkrH�|d7<�|d7<q.q(tt|��}tt|��}|j�fdd�d�|j�fd	d�d�||fS)
NrcSr>r?r,r8r,r,r5r<BrBz!choose_orders.<locals>.<listcomp>cSr>r?r,r�r,r,r5r<CrBrcrr-r,rr+r,r5rKrzchoose_orders.<locals>.<lambda>rcrr-r,rr-r,r5rLr)r.rCr�r)rKr��colsr:r�r�r�r,r/r5�
choose_orders=s$��r1c	s�d}tt���D]j���fdd�tt�d��D�}|sq|d7}|d���fdd�t�dt���D�}|dd�D]#}��|���}|D]}�|||�|�8<qLq<t�dt���D]}d�|�<qiq|S)a;
    Return the rank of the matrix ``L`` given as a list of lists.

    EXAMPLES::

        sage: from admcycles.DR.relations import compute_rank
        sage: compute_rank([[1, 2], [3, 4]])
        2
        sage: compute_rank([[1, 2], [2, 4]])
        1
        sage: compute_rank([[0, 0], [0, 0]])
        0
    rc� g|]}��|dkr|�qSr?r,r��rKr:r,r5r<brz compute_rank.<locals>.<listcomp>rc� g|]}�|�dkr|�qSr?r,�r9r$�rKr�r,r5r<g�
�N�rCr.)rKr�r�r#rIr%r$r,�rKr:r�r5r[Rs" ""��r[c
	s�d}tt|��D]`}||���fdd�|D�}|sq|d7}|d���fdd�||dd�D�}|dd�D]#}��|���}|D]}	�|	||�|	�8<qIq9|D]}	d�|	�<q_q|S)Nrcr2r?r,r�r3r,r5r<vrz!compute_rank2.<locals>.<listcomp>rcr4r?r,r5r6r,r5r<{r7r8)
rKr�r�r��irowr�r#rIr%r$r,r9r5�
compute_rank2rs$ "��r;)r,)b�__doc__rr��sage.misc.cachefuncr�sage.modules.free_moduler�sage.rings.integer_ringr�sage.rings.rational_fieldr�sage.matrix.constructorr�sage.functions.otherr�sage.combinat.partitionr	�sage.combinat.integer_vectorr
�sage.combinat.permutationr�algebrar
rrrr�graphrrrrrrrrrrrr�
evaluationr�modulir r!r"r#rwr$r%r&r'r(r)r*r+r6rUrXr^rcr�r�r�r�rYr�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r{rxr	r�rrfr�ryr�r&r(r_r�r1r[r;r,r,r,r5�<module>s�8(	97_*

 $


	
 
 !' 79@&

.
;
E:1