Macaulay2 » Documentation
Packages » Divisor :: reflexify
next | previous | forward | backward | up | index | toc

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

Synopsis

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 |

              1
o17 : Matrix R  <-- M
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.190273 seconds

o23 : Ideal of R
i24 : time reflexify(J*R^1);
     -- used 0.504292 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.0677564 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 5.58669 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 5.42104 seconds
i33 : time reflexify( M, Strategy=>ModuleStrategy );
     -- used 0.329559 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.165077 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.0118199 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.0296578 seconds
i41 : time reflexify( M, Strategy=>ModuleStrategy );
     -- used 0.0426505 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$.

See also

Ways to use reflexify :

For the programmer

The object reflexify is a method function with options.