# $Source: /u/maple/research/lib/algcurves/src/RCS/iss94,v $ # $Notify: mvanhoei@daisy.uwaterloo.ca $ macro( iss94=`algcurves/iss94`, function_with_one_pole=`algcurves/f_with_1_p` ): macro( solve=`solve/linear`, homogeneous=`algcurves/homogeneous`, integral_basis=`algcurves/integral_basis`, g_conversion1=`algcurves/g_conversion1`, g_conversion2=`algcurves/g_conversion2`, g_normal=`algcurves/g_normal`, g_expand=`algcurves/g_expand`, g_ext=`algcurves/g_ext`, express_in_p=`algcurves/expr_in_p`, z=`algcurves/z` ): # f is a polynomial in x and y # f must be irreducible over Qbar # If f is reducible this procedure does not work properly. # RootOf syntax. iss94:=proc(f,x,y,t,point) global z; local d,fu; options remember, `Copyright (c) 1996 Waterloo Maple Inc. All rights reserved. Author: M. van Hoeij`; d:=degree(f,{x,y}); if coeff(f,y,d)=0 then if coeff(f,x,d)<>0 then # switch x and y d:=procname(f,y,x,t,[point[2],point[1],point[3]]); return [d[2],d[1]] elif coeff(coeff(f,x,0),y,0)<>0 then # switch z and y d:=procname(subs(y=1,z=y,homogeneous(f,x,y,z, polynom)),x,y,t,[point[1],point[3],point[2]]); return map(evala@Normal,[d[1]/d[2],1/d[2]]) else d:=procname(collect(subs(x=x+y,f),{x,y},'distributed',g_normal) ,x,y,t,[point[1]-point[2],point[2],point[3]]); return [evala(Normal(d[1]+d[2])),d[2]] fi fi; # coeff(f,y,d)<>0, so [0,1,0] is not a point on the curve anymore. # Now we compute a function that has a pole in point. If the # point is finite, this function has no other poles in finite # otherwise it has no other poles in infinity. # It may still have other poles, they will be removed by # the procedure function_with_one_pole if point[3]=0 then fu:=[(homogeneous(evala(Quo(subs({t=0,x=1} ,homogeneous(f,x,y,t,polynom)),y-point[2]/point[1],y)) ,y,t,x,polynom)),infinity]; else fu:=[evala(Quo(evala(Expand(subs(x=point[1]/point[3],f))) ,y-point[2]/point[3],y))/(x-point[1]/point[3]),'finite'] fi; fu:=function_with_one_pole(f,x,y,fu); userinfo(2,'algcurves',`Computed a generator of the function field`); express_in_p(f,x,y,t,numer(fu),denom(fu)) end: # The following procedure computes a parameter. A parameter is a function # that has only 1 pole, with multiplicity 1. Then k(p)=k(x,y), p generates # the function field. The pole will be in point. In fact, as the syntax # is now, point is not a point, but a function with a pole in a certain point. # # point=[function,'finite'] or [function,infinity]. This function must # have one pole in finite or infinity. This function is the start for our # search for a parameter. We add an ansatz to this point. Since this function # is already good in a part of the plane (either 'finite' or infinity) # we will change no poles in that part of the plane, and try to remove the # poles in the other part. # # The point [0,1,0] must not be a point on the curve. The reason is that # we have divided the projective plane in 2 affine parts, a line and # a plane. Doing this, there remains 1 point, and therefore that point must # not be on the curve. # # Note that the way we divide the plane in parts is not really relevant # for the method. The fact that one part is only a line does not give much # asymmetry in the algorithm. The important thing about these parts is that # they are affine, and not projective. We need this to apply integral basis. # # We will compute an integral basis for the finite part of the plane, and a # local integral basis for the line infinity. Using these integral basis # we can find linear equations stating that an ansatz, or an ansatz + a # given function is integral (i.e. no poles) in a part of the plane (the # part 'finite' and infinity. function_with_one_pole:=proc(f,x,y,point) local d,j,f_infty,ib1,ib2,den1,den2,d1,d2,ansatz,a,f1,f2,equations, ext,i,zero,point1,deg_inf,B; global g_conversion1,g_conversion2,`algcurves/residue`,z; option `Copyright (c) 1996 Waterloo Maple Inc. All rights reserved. Author: M. van Hoeij`; d:=degree(f,{x,y}); f_infty:=subs(x=1,homogeneous(f,x,y,z,polynom)); ib1:=integral_basis(f,x,y); ib2:=`algcurves/integral_basis2`(f_infty,z,y,{[z,4]}); den1:=expand(denom(ib1[d])); den2:=expand(denom(ib2[d])); if point[2]=`infinity genus1` then # Syntax for genus1, the function point1 may not be changed # so we only determine the upper bound for the denominators now point1:=point[1]; # den1:=evala(Lcm(den1,denom(point1))) den1:=numer(g_normal(den1*denom(point1) /evala(Gcm(den1,denom(point1))))) elif point[2]=infinity then deg_inf:=degree(den1,x)-degree(point[1],{x,y})+1; point1:=x^deg_inf*point[1]/den1; if deg_inf<0 then den1:=evala(Expand(den1*x^(-deg_inf))) fi else point1:=point[1] fi; # den1 is an upperbound for denominators d1:=degree(den1,x); d2:=ldegree(den2,z); d2:=max(d2,degree(expand(numer(point1)),{x,y}) -degree(expand(denom(point1)),{x,y})); # d2 is an upperbound for the denominators in infinity ansatz:=add(add(a[i,j]*x^i*y^j,i=0..d1+d2-j) ,j=0..d-1)/den1; if point[2]='finite' then f1:=ansatz; f2:=ansatz+point1 else f1:=ansatz+point1; f2:=ansatz fi; # Now we solve the following set of linear equations: # {f1 has no poles in 'finite', and f2 has no poles in infinity} ext:=g_ext([f,f1,f2]); f1:=subs(g_conversion1,g_normal(f1)); den1,f1:=denom(f1),numer(f1); f2:=subs(g_conversion1, g_normal(subs(x=1,homogeneous(f2,x,y,z,'ratfunction')))); den2:=denom(f2); den2:=z^ldegree(den2,z); f2:=numer(f2); ib1:=subs(g_conversion1,[seq(g_normal(i*den1),i=ib1)]); ib2:=subs(g_conversion1,[seq(g_normal(i*den2),i=ib2)]); zero:=f1; B:=evalb(indets([f,point],name) minus {x,y,infinity}<>{}); for i from d-1 by -1 to 0 do while degree(coeff(zero,y,i),x) >=degree(lcoeff(ib1[i+1],y),x) and coeff(zero,y,i)<>0 do zero:=g_expand(zero-ib1[i+1]* g_normal(lcoeff(coeff(zero,y,i),x)/lcoeff(lcoeff(ib1[i+1],y),x)) *x^(degree(coeff(zero,y,i),x)-degree(lcoeff(ib1[i+1],y),x)) ,ext); if B and not type(zero,polynom) then zero:=collect(zero,{x,y},'distributed',g_normal) fi od od; equations:={a[d1,0],coeffs(zero,[x,y])}; # These equations state that f1 is integral. We've added and 1 extra # linear condition, to make the solution unique. We still have to # add the equations for infinity: zero:=f2; for i from d-1 by -1 to 0 do while degree(coeff(zero,y,i),z) >=degree(lcoeff(ib2[i+1],y),z) and coeff(zero,y,i)<>0 do zero:=g_expand(zero-ib2[i+1]* g_normal(lcoeff(coeff(zero,y,i),z)/lcoeff(lcoeff(ib2[i+1],y),z)) *z^(degree(coeff(zero,y,i),z)-degree(lcoeff(ib2[i+1],y),z)) ,ext); if B and not type(zero,polynom) then zero:=collect(zero,{z,y},'distributed',g_normal) fi od od; equations:=subs(g_conversion2,{op(equations),coeffs(zero,[y,z])}); d:=g_normal(subs(solve(equations,indets(equations,name) minus indets(f)),ansatz+point1)); if indets(d,name) minus indets([args]) <> {} then error "can not find parameter %1",f=evala(AFactor(f)) fi; d end: #savelib ('iss94','function_with_one_pole'):