Processing math: 100%

First time here? Check out the FAQ!

Ask Your Question
0

change of variables from quartic to weierstrass

asked 7 years ago

Sha gravatar image

Hi. I have been sitting down for the past 1 week trying to get this code to work with no hope. Can someone help me with the change of variables here please. I have the quartic curve v^2 = u^4-2*u^3+5*u^2+8*u+4 which I transform to an elliptic curve of the form y^2 + a1*x*y + a3*y = x^3 + a2*x^2 + a4*x + a6. The code is given by :

var( 'u,v,a,b,c,q,x,y,d' );
f = a*u^4 + b*u^3 + c*u^2 + d*u + q^2
# we want to find an algebraic passage from u, v and the quartic 
# v^2 = f
# to a Weierstass equation in two new variables x, y
x = (2*q*(v+q) + d*u)/u^2
y = ((2*q)^3*(v+q) + (2*q)^2*( d*u + c*u^2 ) - d^2*u^2)/((2*q)*u^3)
# inverse transformation:
u = ((2*q)*(x+c)-d^2/q)/y
v = -q + (u*(u*x-d))/(2*q)
# one can easily define rational functions (u,v) -> (x,y) and (x,y) -> (u,v)
# to be used in the concrete situation
a1 = d/q
a2 = c - ((d/(2*q)))^2
a3 = b*(2*q)
a4 = -a*(2*q)^2
a6 = a2*a4
((y^2 + a1*x*y + a3*y) - (x^3 + a2*x^2 + a4*x + a6)).factor()
def passageQuarticToWeierstrass( a, b, c, d, q, field=QQ ):
    """implement the standard formulas
    """
    a1, a2, a3, a4 = d/q, c - ((d/(2*q)))^2, b*(2*q), -a*(2*q)^2
    a6 = a2 * a4
    print ( a1, a2, a3, a4, a6 )
    return EllipticCurve(field,(a1, a2, a3, a4, a6))
a, b, c, d, q = 1,-2,5,8,2 
E = passageQuarticToWeierstrass( a, b, c, d, q );E

The output yield :

Elliptic Curve defined by E : y^2 + 4*x*y - 8*y = x^3 + x^2 - 16*x - 16 over Rational Field.

Then I transform E into a short Weierstrass equation which should yield : E' : y^2 = x^3 -3267*x +45630 with the corresponding change of variable. This is what I tried, but did not quite worked. (slightly different numerator expression but correct denominators for u and v).

reset('x')
reset('y')
var('x,y,Y')
a, b, c, d, q = 1,-2,5,8,2 #coefficients of quartic v^2
a1, a2, a3, a4, a6 = 4, 1, -8, -16, -16 #coefficients of elliptic curve E
E=y^2 + 4*x*y - 8*y -(x^3 + x^2 - 16*x - 16)
F=E.subs({y:y-(a1*x+a3)/2}) #eliminates xy and y term on the LHS of E
eq2=F.canonicalize_radical()
eq3=eq2.subs({x:x-((a2+1/4*(a1)^2)/3)}) #eliminates the x^2 term from the RHS to give E of the form y^2 = x^3 +Ax +B
eq4=eq3.canonicalize_radical()
eq5=eq4.subs({x:(1/3^2)*x})
eq6=eq5*729;eq6
u=((2*q)*(x+c)-(d^2/q))/y #the inverse transformation from from E to quartic
eq7=u.subs({y:y-(a1*x+a3)/2}).subs({x:x-((a2+1/4*(a1)^2)/3)})
eq8=eq7.subs({x : (x/3^2)}).subs({y:y/(3^3)});eq8
v = -q + (u*(u*x-d))/(2*q) #the inverse transformation from from E to quartic
eq9=v.subs({y:y-(a1*x+a3)/2}).subs({x:x-((a2+1/4*(a1)^2)/3)})
eq10=eq9.subs({x : (x/3^2)}).subs({y:y/(3^3)})
eq11=eq10.simplify_full()
eq12=eq11.subs({y^2:(x^3-3267*x+45630)});eq12

The output yield :

 -x^3 + 729*y^2 + 3267*x - 45630 #wrote this in the form:Y^2 = x^3 - 3267*x +45630  where Y=3^3*y
  u = -12*(x - 42)/(6*x - y - 198) 
  v =  2*(x^3 - 162*x^2 + 6291*x + 108*y - 37962)/(x^3 + 36*x^2 - 12*(x - 33)*y - 5643*x + 84834)

The problem lies in the change of variable for u and v obtained. I tried substituting them back into the curves and they do not satisfy the equations. I suspect the glitch is in eq6 that is giving me the incorrect change of variable for u and v. Can someone help me throw in some suggestions. The reason why I am doing all this step by step is because I need to find the change of variable for u and v.

Preview: (hide)

1 Answer

Sort by » oldest newest most voted
1

answered 7 years ago

dan_fulea gravatar image

This post seems to be related to

https://ask.sagemath.org/question/36637/change-of-variable-from-hyperellictic-curve-to-weierstrass-form/

Please always mention the source, when there is almost a copy+pasted version of existing code.

The following code tries to catch all needed ad-hoc passages in a homogenous structure.

For this, i have introduced the class W, where we can bind all needed coefficients.

First of all the code, than the comments:

class W( object ):
    def __init__( self, a,b,c,d,q, Q, a1,a2,a3,a4,a6, A4,A6 ):
        self.a, self.b, self.c, self.d, self.q = a, b, c, d, q
        self.Q = Q
        self.a1, self.a2, self.a3, self.a4, self.a6 = a1, a2, a3, a4, a6
        self.A4, self.A6 = A4,A6
        self.f = lambda x, y : y^2 - ( a*x^4 + b*x^3 + c*x^2 + d*x + q^2 )
        self.g = lambda x, y : y^2 + a1*x*y + a3*y - ( x^3 + a2*x^2 + a4*x + a6 )
        self.h = lambda x, y : y^2 - ( x^3 + A4*x + A6 )

# var( 'a,b,c,d,q' )
def getData( a,b,c,d,q ):
    Q = 2*q

    a1, a2, a3, a4 = d/q, c - ((d/(2*q)))^2, b*(2*q), -a*(2*q)^2
    a6 = a2 * a4

    A4 = a4 + a1*a3/2 - a1^4/48 - a1^2*a2/6 - a2^2/3
    A6 = a1^6/864 + a1^4*a2/72 + a1^2*a2^2/18 - a1^3*a3/24 + 2/27*a2^3 - a1*a2*a3/6 - a1^2*a4/12 + a3^2/4 - a2*a4/3 + a6

    w = W( a,b,c,d,q, Q, a1,a2,a3,a4,a6, A4,A6 )
    return w

def Passage_uv_to_xy( uv, data ):
    u, v = uv
    c,d, q,Q = data.c, data.d, data.q, data.Q

    x = ( Q*(v+q) + d*u ) / u^2
    y = ( Q^2*(v+q) + Q*( d*u + c*u^2 ) - d^2*u^2/Q ) / u^3
    return x,y

def Passage_xy_to_uv( xy, data ):
    x, y = xy
    c,d, q,Q = data.c, data.d, data.q, data.Q

    U = ( Q*(x+c) - d^2/Q ) / y
    V = -q + U*(U*x-d) / Q
    return U,V

# var( 'a1,a2,a3,a4,a6' )
# use the above to test Y^2 - (X^3+A4*X+A6) == y^2+a1*x*y+a3*y - (x^3+a2*x^2+a4*x+a6) ...
# where var( 'x,y' ); X,Y = Passage_xy_to_XY( (x,y) )
# A4 = a4 + a1*a3/2 - a1^4/48 - a1^2*a2/6 - a2^2/3
# A6 = a1^6/864 + a1^4*a2/72 + a1^2*a2^2/18 - a1^3*a3/24 + 2/27*a2^3 - a1*a2*a3/6 - a1^2*a4/12 + a3^2/4 - a2*a4/3 + a6
# and associate a corresponding data...

def Passage_xy_to_XY( xy, data ):
    x,y = xy
    a1, a2, a3 = data.a1, data.a2, data.a3

    X = x + (a2+a1^2/4)/3
    Y = y + a1*x/2 + a3/2
    return X,Y

def Passage_XY_to_xy( XY, data ):
    X, Y = XY
    a1, a2, a3 = data.a1, data.a2, data.a3

    x = X - (a2+a1^2/4)/3
    y = Y - a1*x/2 - a3/2
    return x,y

# # # =================================================
# # # TESTS AND APPLICATION TO THE GIVEN CASE
var( 'u,v' )
var( 'a,b,c,d,q' )
data = getData( a,b,c,d,q )

u1, v1 = Passage_xy_to_uv( Passage_uv_to_xy( (u,v), data ), data )
print "Is u1=u ? %s" % bool( u1==u )
print "Is v1=v ? %s" % bool( v1==v )
print

var( 'x,y' )
x1, y1 = Passage_XY_to_xy( Passage_xy_to_XY( (x,y), data ), data )
print "Is x1=x ? %s" % bool( x1==x )
print "Is y1=y ? %s" % bool( y1==y )
print

var( 'u,v' )
X,Y = Passage_xy_to_XY( Passage_uv_to_xy( (u,v), data ), data )
print "YY - (XXX +A4*X + A6)  is %s" % ( (Y^2 - (X^3+A4*X+A6) ).factor() )
print

var( 'X,Y' )
U,V = Passage_xy_to_uv( Passage_XY_to_xy( (X,Y), data ), data )
print "U = %s" % U
print "V = %s" % V
print

# in the concrete case given:
data = getData( 1,-2,5,8,2 )
var( 'X,Y' )
U,V = Passage_xy_to_uv( Passage_XY_to_xy( (X,Y), data ), data )
print "U = %s" % U
print "V = %s" % V
print "f(U,V) = %s" % ( data.f(U,V).factor() )

This gives:

(u, v)
(a, b, c, d, q)
Is u1=u ? True
Is v1=v ? True

(x, y)
Is x1=x ? True
Is y1=y ? True

(u, v)
YY - (XXX +A4*X + A6)  is (4*c*q^2*u^2 + 8*q^4 + 4*d*q^2*u - d^2*u^2 + 8*q^3*v)*(a*u^4 + b*u^3 + c*u^2 + q^2 + d*u - v^2)/u^6

(X, Y)
U = -(4*(3*X + 2*c)*q - 3*d^2/q)/(6*b*q - 6*Y + (3*X - c)*d/q)
V = -q + 1/6*(4*(3*X + 2*c)*q - 3*d^2/q)*((4*(3*X + 2*c)*q - 3*d^2/q)*(3*X - c)/(6*b*q - 6*Y + (3*X - c)*d/q) + 3*d)/((6*b*q - 6*Y + (3*X - c)*d/q)*q)

(X, Y)
U = -4*(3*X - 2)/(6*X - 3*Y - 22)
V = 4/3*((3*X - 2)*(3*X - 5)/(6*X - 3*Y - 22) + 6)*(3*X - 2)/(6*X - 3*Y - 22) - 2
f(U,V) = 16/9*(27*X^3 - 27*Y^2 - 1089*X + 1690)*(3*X - 2)^3/(6*X - 3*Y - 22)^4

Comments to the above:

  • The equalities u1==u and v1==v shows that the passages Passage_xy_to_uv and Passage_uv_to_xy are inverse to each other.
  • The equalities x1==x and y1==y shows that the passages Passage_xy_to_XY and Passage_XY_to_xy are inverse to each other.
  • The factor (a*u^4 + b*u^3 + c*u^2 + q^2 + d*u - v^2) in YY - (XXX +A4*X + A6) shows that if the pair (u,v) satisfies "the quartic", than (X,Y) satisfies Y2=X3+A4X+A6, with A4,A6 also captured in the instance data.
  • Let now data be the "special data", obtained as data = getData( 1,-2,5,8,2 ). Then if we start with (X,Y) on the curve with the equation

    sage: data.h(X,Y)
    -X^3 + Y^2 + 121/3*X - 1690/27
    sage: data.h(X,Y)*27
    -27*X^3 + 27*Y^2 + 1089*X - 1690
  • then building (U,V) from (X,Y) satisfying h=0, we get the point (U,V) satisfying f(U,V)=0, because of the factor (27*X^3 - 27*Y^2 - 1089*X + 1690).

  • So for (U,V) satisfying the equation of the elliptic curve Y2=X31213X+169027() the corresponding (U,V) point has:

    sage: U.factor()
    -4*(3*X - 2)/(6*X - 3*Y - 22)
    sage: V.factor()
    2/3*(54*X^3 - 54*X^2 - 27*Y^2 - 324*Y - 964)/(6*X - 3*Y - 22)^2

I hope this helps to finally dissolve the puzzle. (In the given situation we have only to rescale X,Y using corresponding powers of 3, i.e. formally multiply () with 36 and group the new variables 33Y and 32X, for the new equation.)

A final note: As in mathematics, it is always simpler to catch the idea when the shape of the text / of the code comes in a pleasant way. Please try to use (for the own sake) a better spacing and a more structural approach. In the posted code it was quite hard to find a Leitfaden, a red line...

Preview: (hide)
link

Comments

@Dan fulea Thank you for your help explaining this to me. This is so useful in my calculation. After scaling, I manage to get the correct change of variable for u and v. And the best part is I see where I made a mistake. Thank you again.

Sha gravatar imageSha ( 7 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 7 years ago

Seen: 438 times

Last updated: Jan 06 '18