# reflexify -- calculate the double dual of an ideal or module Hom(Hom(M, R), R)

## Synopsis

• Usage:
reflexify( I1 )
reflexify( M1 )
• Inputs:
• Optional inputs:
• Strategy => , default value NoStrategy, specify a strategy for reflexify
• ReturnMap => , default value false, tell reflexify to return a map from the original module to the reflexification
• KnownDomain => , default value true, make reflexify more efficient if the ambient ring is a domain
• Outputs:

## Description

Get the reflexification or double dual (in the case of a normal ring, S2-ification) of an ideal $I$ or module $M$. Recall the double dual is defined to be $Hom(Hom(M, R), R)$.

 i1 : R = QQ[x,y,z]/ideal(x^2-y*z); i2 : m = ideal(x,y,z); o2 : Ideal of R i3 : reflexify(m) o3 = ideal 1 o3 : Ideal of R i4 : I = ideal(x,y); o4 : Ideal of R i5 : reflexify(I) o5 = ideal (y, x) o5 : Ideal of R i6 : reflexify(I^2) o6 = ideal y o6 : Ideal of R i7 : reflexify(I^3) 2 o7 = ideal (y , x*y) o7 : Ideal of R

We also have an example of reflexifying a module.

 i8 : R = QQ[x,y,z]/ideal(x^2-y*z); i9 : m = ideal(x,y,z); o9 : Ideal of R i10 : prune reflexify(m*R^2) 2 o10 = R o10 : R-module, free i11 : I = ideal(x,y); o11 : Ideal of R i12 : prune reflexify(I*R^1) o12 = cokernel {1} | x -y | {1} | -z x | 2 o12 : R-module, quotient of R i13 : prune reflexify(I^2*R^1) 1 o13 = R o13 : R-module, free, degrees {1}

There is a canonical map from a module $M$ to its reflexification, $Hom(Hom(M, R), R)$. If reflexify is passed the option ReturnMap => true, then instead of returning a module, reflexify returns that map. This is not necessary for ideals since an ideal is canonically a subsetset of its reflexification.

 i14 : R = QQ[x,y]; i15 : m = ideal(x,y); o15 : Ideal of R i16 : M = m*R^1; i17 : f = reflexify( M, ReturnMap => true ) o17 = | x y | o17 : Matrix i18 : source f o18 = image | x y | 1 o18 : R-module, submodule of R i19 : target f 1 o19 = R o19 : R-module, free

Generally speaking, it is faster to reflexify ideals as opposed to modules. Consider the following example of a point on an elliptic curve.

 i20 : R = QQ[x,y,z]/ideal(-y^2*z +x^3 + x^2*z + x*z^2+z^3); i21 : I = ideal(x-z,y-2*z); o21 : Ideal of R i22 : J = I^21; o22 : Ideal of R i23 : time reflexify(J); -- used 0.730398 seconds o23 : Ideal of R i24 : time reflexify(J*R^1); -- used 1.34429 seconds

Because of this, there are two strategies for computing a reflexification (at least if the module embeds as an ideal).

IdealStrategy. In the case that $R$ is a domain, and our module is isomorphic to an ideal $I$, then one can compute the reflexification by computing colons.

ModuleStrategy. This computes the reflexification simply by computing $Hom$ twice.

ModuleStrategy is the default strategy for modules, IdealStrategy is the default strategy for ideals. In our experience, IdealStrategy is faster on average. Note that calling ModuleStrategy for ideals or IdealStrategy for modules creates overhead which can slow things down substantially (since we must embed various modules as ideals).

 i25 : R = ZZ/13[x,y,z]/ideal(x^3 + y^3-z^11*x*y); i26 : I = ideal(x-4*y, z); o26 : Ideal of R i27 : J = I^20; o27 : Ideal of R i28 : M = J*R^1; i29 : J1 = time reflexify( J, Strategy=>IdealStrategy ) -- used 0.185467 seconds 2 2 9 9 11 o29 = ideal (x + 5x*y + 3y , x*z - 4y*z , z + x - 4y) o29 : Ideal of R i30 : J2 = time reflexify( J, Strategy=>ModuleStrategy ) -- used 12.5094 seconds 2 2 9 9 11 o30 = ideal (x + 5x*y + 3y , x*z - 4y*z , z + x - 4y) o30 : Ideal of R i31 : J1 == J2 o31 = true i32 : time reflexify( M, Strategy=>IdealStrategy ); -- used 12.9275 seconds i33 : time reflexify( M, Strategy=>ModuleStrategy ); -- used 1.03423 seconds

However, sometimes ModuleStrategy is faster, especially for Monomial ideals.

 i34 : R = QQ[x,y,u,v]/ideal(x*y-u*v); i35 : I = ideal(x,u); o35 : Ideal of R i36 : J = I^20; o36 : Ideal of R i37 : M = I^20*R^1; i38 : time reflexify( J, Strategy=>IdealStrategy ) -- used 0.514363 seconds 20 19 2 18 3 17 4 16 5 15 6 14 7 13 8 12 o38 = ideal (u , x*u , x u , x u , x u , x u , x u , x u , x u , ----------------------------------------------------------------------- 9 11 10 10 11 9 12 8 13 7 14 6 15 5 16 4 17 3 18 2 x u , x u , x u , x u , x u , x u , x u , x u , x u , x u , ----------------------------------------------------------------------- 19 20 x u, x ) o38 : Ideal of R i39 : time reflexify( J, Strategy=>ModuleStrategy ) -- used 0.027704 seconds 20 19 2 18 3 17 4 16 5 15 6 14 7 13 8 12 o39 = ideal (u , x*u , x u , x u , x u , x u , x u , x u , x u , ----------------------------------------------------------------------- 9 11 10 10 11 9 12 8 13 7 14 6 15 5 16 4 17 3 18 2 x u , x u , x u , x u , x u , x u , x u , x u , x u , x u , ----------------------------------------------------------------------- 19 20 x u, x ) o39 : Ideal of R i40 : time reflexify( M, Strategy=>IdealStrategy ); -- used 0.257523 seconds i41 : time reflexify( M, Strategy=>ModuleStrategy ); -- used 0.0110063 seconds

For ideals, if KnownDomain is false (default value is true), then the function will check whether it is a domain. If it is a domain (or assumed to be a domain), it will reflexify using a strategy which can speed up computation, if not it will compute using a sometimes slower method which is essentially reflexifying it as a module.

Consider the following example showing the importance of making the correct assumption about the ring being a domain.

 i42 : R = QQ[x,y]/ideal(x*y); i43 : I = ideal(x,y); o43 : Ideal of R i44 : reflexify(I, KnownDomain=>false) o44 = ideal (y, x) o44 : Ideal of R i45 : reflexify(I, KnownDomain=>true) o45 = ideal 1 o45 : Ideal of R i46 : J = ideal(x-y, x+y); o46 : Ideal of R i47 : reflexify(J, KnownDomain=>false) o47 = ideal (y, x) o47 : Ideal of R i48 : reflexify(I, KnownDomain=>true) o48 = ideal 1 o48 : Ideal of R

In the above, when KnownDomain=>true (an incorrect assumption), this function returns the incorrect answer for $I$.