#===============================================================================
#
# Copyright (C) 2011 Martin Raum
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see .
#
#===============================================================================
#===============================================================================
#
# This file concerns the case T = 0 in the proof of Theorem 3 of the paper
# "Kohnen's limit process for real-analytic Siegel modular forms"
# by Kathrin Bringmann, Martin Raum, and Olav K. Richter.
# For detailed definitions see the paper.
# The symmetry arising from GL_2(ZZ) leads to periodicity and
# another symmetry, that we want to express here. It leads to additional
# differential equations for phi.
#
#===============================================================================
# 'x' and 'y' will be as in the paper
P. = QQ[]
## The basic substitution corresponding to [[0,-1],[0,1]] \in \GL{2}(\ZZ)
## leads to new coordinates \tilde x and \tilde y
xtilde = -x * y**-2 * (1 + x**2 * y**-2)**-1
ytilde = (y*(x**2 * y**-2 + 1))**-1
## The function phi satisfies a differential equation
## y^2(phi_xx + phi_yy) + phi = 0
## Hence the function psi(x, y) = phi(xtilde, ytilde) satisfies
## an additional differential equation. Since we assume that phi is \GL{2}(\ZZ)
## symmetric, we have phi = psi. In particular, the differential equation for
## psi also holds for phi.
## The prefix v refers to symbolic variables, distinguishing all variables
## defined here from polynomial expressions, that we will use below. The
## suffixes stand for differentials.
vphi = function('phi', x,y)
vpsi = phi(xtilde, ytilde)
## Later we will use the differentials of psi to
## reduce the differential equation for phi.
vdpsix = diff(vpsi, x)
vdpsixx = diff(vdpsix, x)
vdpsiy = diff(vpsi, y)
vdpsiyy = diff(vdpsiy, y)
vdpsixy = diff(vdpsix, y)
## We insert in \tilde x and \tilde y the differentials phi.
vdphix = diff(vphi, x)(xtilde, ytilde)
vdphixx = diff(vphi, x, x)(xtilde, ytilde)
vdphiy = diff(vphi, y)(xtilde, ytilde)
vdphiyy = diff(vphi, y, y)(xtilde, ytilde)
vdphixy = diff(vphi, x, y)(xtilde, ytilde)
## Rconv is a formal trick to convert the symbolic expressions to polynomials.
## The term order is not necessary and we carry it through for clarification.
Rconv. = PolynomialRing(QQ, order = TermOrder('dp', 2) + TermOrder('dp', 5) + TermOrder('dp', 6))
## We need the following substitutions to express the differentials of psi
## in terms of differentials of phi.
psisubs = {vphi(xtilde, ytilde): psi, vdphix: dphix,
vdphixx: dphixx, vdphixy: dphixy, vdphiy: dphiy,
vdphiyy: dphiyy}
## We will Groebner reduce the following relations. Note that multiplication
## (x**2 + y**2)**4 * y**6 is only done to allow conversion into 'Rconv'.
relations = map( lambda expr, evar: \
(x**2 + y**2)**-4 * y**-6 \
* Rconv( ( (x**2 + y**2)**4 * y**6 * expr.subs(psisubs) ) \
.simplify_rational().factor() )
- evar,
[vdpsix, vdpsixx, vdpsixy, vdpsiy, vdpsiyy],
[dpsix, dpsixx, dpsixy, dpsiy, dpsiyy] )
## We use the fraction field of QQ[x, y] to simplify the computation of
## the substitution terms
RR. = QQ[]
RR = RR.fraction_field()
R. = PolynomialRing(RR, order = TermOrder('dp', 5) + TermOrder('dp', 6))
## We have to separate the numerator and the denominator to allow conversion
## into 'R'.
relations = [R(r.numerator()) / RR(r.denominator()) for r in relations]
## We will reduce the wave equation deq to obtain additional differential
## equations for phi
deq = y**2 * (dphixx + dphiyy) + psi
nI = R.ideal(relations + [deq])
gI = nI.groebner_basis(algorithm = 'toy:buchberger')
## Suppose phi = psi. The first differential equation that phi has
## to satisfy is deq.
deq1 = y**2 * (dpsixx + dpsiyy) + psi
deq2 = gI[-1]
## The assertion checks that we have substituted all occurences of phi
assert set(deq2.monomials()).intersection(set([dphix, dphixx, dphixy, dphiy, dphiyy])) == set()
## The differential equation deq2 contains x. We assume that phi is 1-periodic
## in x and we need only to add shifts of deq2 to the restrictions to show that
## there are no solutions.
deqs = [deq1, deq2] + [R(dict((e, c.numerator().subs(x = x + n)/c.denominator().subs(x = x + n)) for (e,c) in deq2.dict().iteritems())) for n in range(1, 5)]
## We use a new polynomial ring to reduce the number of variables that we have to
## handle and to impose another term order, that is fast in our situation.
RR. = QQ[]
RR = RR.fraction_field()
R. = PolynomialRing(RR, order = TermOrder('lex', 6))
deqs = [R(dict((e[5:], p[e]) for e in p.exponents())) for p in deqs]
dI = R.ideal(deqs)
gb = dI.groebner_basis(algorithm = 'toy:buchberger')
## gb contains psi, showing that there is no solution to the system of
## differential equations above except 0.