예제 #1
0
def symmetrize_periods(Pa, Pb, tol=1e-4):
    r"""Returns symmetric a- and b-periods `Pa_symm` and `Pb_symm`, as well as the
    corresponding symplectic operator `Gamma` such that `Gamma [Pa \\ Pb] =
    [Pa_symm \\ Pb_symm]`.

    Parameters
    ----------
    Pa : complex matrix
    Pb : complex matrix
        The a- and b-periods, respectively, of a genus `g` Riemann surface.
    tol : double
        (Default: 1e-4) Tolerance used to verify integrality of intermediate
        matrices. Dependent on precision of period matrices.

    Returns
    -------
    Gamma : integer matrix
        The symplectic transformation operator.
    Pa : complex matrix
    Pb : complex matrix
        Symmetric a- and b-periods, respectively, of a genus `g` Riemann surface.

    Notes
    -----
    The algorithm described in Kalla, Klein actually operates on the transposes
    of the a- and b-period matrices.
    """
    # coerce from numpy, if necessary
    if isinstance(Pa, numpy.ndarray):
        Pa = Matrix(CDF, numpy.ascontiguousarray(Pa))
    if isinstance(Pb, numpy.ndarray):
        Pb = Matrix(CDF, numpy.ascontiguousarray(Pb))

    # use the transposes of the period matrices and coerce to Sage matrices
    Pa = Pa.T
    Pb = Pb.T

    # use above functions to obtain topological type matrix
    g, g = Pa.dimensions()
    R = involution_matrix(Pa, Pb, tol=tol)
    S = integer_kernel_basis(R)
    N1 = N1_matrix(Pa, Pb, S, tol=tol)
    H, Q = symmetric_block_diagonalize(N1)
    Gamma = symmetric_transformation_matrix(Pa, Pb, S, H, Q, tol=tol)

    # compute the corresponding symmetric periods
    stacked_periods = zero_matrix(CDF, 2 * g, g)
    stacked_periods[:g, :] = Pa
    stacked_periods[g:, :] = Pb
    stacked_symmetric_periods = Gamma * stacked_periods
    Pa_symm = stacked_symmetric_periods[:g, :]
    Pb_symm = stacked_symmetric_periods[g:, :]

    # transpose results back
    Pa_symm = Pa_symm.T
    Pb_symm = Pb_symm.T
    return Pa_symm, Pb_symm
예제 #2
0
def symmetrize_periods(Pa, Pb, tol=1e-4):
    r"""Returns symmetric a- and b-periods `Pa_symm` and `Pb_symm`, as well as the
    corresponding symplectic operator `Gamma` such that `Gamma [Pa \\ Pb] =
    [Pa_symm \\ Pb_symm]`.

    Parameters
    ----------
    Pa : complex matrix
    Pb : complex matrix
        The a- and b-periods, respectively, of a genus `g` Riemann surface.
    tol : double
        (Default: 1e-4) Tolerance used to verify integrality of intermediate
        matrices. Dependent on precision of period matrices.

    Returns
    -------
    Gamma : integer matrix
        The symplectic transformation operator.
    Pa : complex matrix
    Pb : complex matrix
        Symmetric a- and b-periods, respectively, of a genus `g` Riemann surface.

    Notes
    -----
    The algorithm described in Kalla, Klein actually operates on the transposes
    of the a- and b-period matrices.
    """
    # coerce from numpy, if necessary
    if isinstance(Pa, numpy.ndarray):
        Pa = Matrix(CDF, numpy.ascontiguousarray(Pa))
    if isinstance(Pb, numpy.ndarray):
        Pb = Matrix(CDF, numpy.ascontiguousarray(Pb))

    # use the transposes of the period matrices and coerce to Sage matrices
    Pa = Pa.T
    Pb = Pb.T

    # use above functions to obtain topological type matrix
    g,g = Pa.dimensions()
    R = involution_matrix(Pa, Pb, tol=tol)
    S = integer_kernel_basis(R)
    N1 = N1_matrix(Pa, Pb, S, tol=tol)
    H,Q = symmetric_block_diagonalize(N1)
    Gamma = symmetric_transformation_matrix(Pa, Pb, S, H, Q, tol=tol)

    # compute the corresponding symmetric periods
    stacked_periods = zero_matrix(CDF, 2*g, g)
    stacked_periods[:g,:] = Pa
    stacked_periods[g:,:] = Pb
    stacked_symmetric_periods = Gamma*stacked_periods
    Pa_symm = stacked_symmetric_periods[:g,:]
    Pb_symm = stacked_symmetric_periods[g:,:]

    # transpose results back
    Pa_symm = Pa_symm.T
    Pb_symm = Pb_symm.T
    return Pa_symm, Pb_symm
예제 #3
0
파일: mf_pari.py 프로젝트: roed314/CMFs
def coeff_reduce(C, B, SB, Detail=0, debug=False):
    """B is a list of lists of rationals holding an invertible dxd matrix
    C is a list of lists of rationals holding an nxd matrix
    C*B remains invariant
    SB = Sturm bound: the first SB rows of C should span the whole row space over Z

    Computes invertible U and returns (C', B') = (C*U, U^(-1)*B), so
    that the entries of C' are integers and 'small'
    """
    t0 = time.time()
    if Detail > 1:
        print("Before LLL, coefficients:\n{}".format(C))
    # convert to actual matrices:
    d = len(B)
    nan = len(C)
    B = Matrix(B)
    C = Matrix(C)
    if debug:
        print("B has size {}".format(B.dimensions()))
        #print("B={}".format(B))
        print("C has size {}".format(C.dimensions()))
        #print("C={}".format(C))
        CB = C * B
    # Make integral:
    C1, den = C._clear_denom()
    B1 = B / den
    t1 = time.time()
    if Detail:
        print("Cleared denominator = {} in {:0.3f}".format(den, t1 - t0))
    # Make primitive:
    if debug:
        print("C1 is in {}".format(C1.parent()))
        #print("C1 = {}".format(C1))
    C1 = pari(C1)
    # if debug:
    #     print("B1={} in {}".format(B1, B1.parent()))
    B1 = pari(B1)
    V1V2S = C1.matsnf(1)
    t2 = time.time()
    V2 = V1V2S[1]
    S = pari_row_slice(nan - d + 1, nan)(V1V2S[2])
    if Detail:
        print("Computed Smith form in {:0.3f}".format(t2 - t1))
    if debug:
        print("About to invert matrix of size {}".format(V2.matsize()))
    C1 *= V2
    B1 = V2**(-1) * B1
    if debug:
        assert CB == C1 * B1
    scales = [S[i, i] for i in range(d)]
    if not all(s == 1 for s in scales):
        if Detail:
            print("scale factors {}".format(scales))
        C1 *= S**(-1)
        B1 = S * B1
        if debug:
            assert CB == C1 * B1

    # LLL-reduce
    U = C1.qflll()
    t3 = time.time()
    if Detail:
        print("LLL done in {:0.3f}".format(t3 - t2))
    if debug:
        assert U.matdet() in [1, -1]
    C1 *= U
    B1 = U**(-1) * B1
    if debug:
        assert CB == C1 * B1
        print("found Bred, Cred")
    # Convert back to lists of lists
    Cred = [ci.list() for ci in C1.mattranspose()]
    Bred = [bi.list() for bi in B1.mattranspose()]
    if Detail > 1:
        print("After LLL, coefficients:\n{}\nbasis={}".format(Cred, Bred))
    return Cred, Bred