Macaulay2 / M2

The primary source code repository for Macaulay2, a system for computing in commutative algebra, algebraic geometry and related fields.
https://macaulay2.com
347 stars 232 forks source link

Incorrect kernel computation #2004

Open pzinn opened 3 years ago

pzinn commented 3 years ago

there's definitely something wrong here: (kernel should be generated by x-y)

i1 : F=frac(QQ[x])

o1 = F

o1 : FractionField

i2 : R1=F[]

o2 = R1

o2 : PolynomialRing

i3 : R2=F[y]

o3 = R2

o3 : PolynomialRing

i4 : f=map(R1,R2,{x})

o4 = map (R1, R2, {x, x})

o4 : RingMap R1 <--- R2

i5 : kernel f

o5 = ideal ()

o5 : Ideal of R2

i6 : f (x-y)

o6 = 0

o6 : R1
8d1h commented 3 years ago

kernel uses a 2-block Eliminate monomial order on the graph ring to get elements that are entirely in R2. Here R1 has no variables, so the block containing variables of R2 becomes the first block and gets eliminated... https://github.com/Macaulay2/M2/blob/f0ce581750dfd94336883695d3552671410f32f5/M2/Macaulay2/m2/ringmap.m2#L251 This should be changed to something like

ideal mapback selectInSubring(if numgens F > 0 then 1 else 0,generators G)

Edit. There are still some issues.

i1 : kernel map(QQ,QQ[x],{0})
stdio:1:1:(3): error: no ambient ring present

This is because QQ has no ambient ring, and

i2 : kernel map(QQ[],QQ[x],{0})
stdio:2:1:(3): error: expected Hilbert function hint to be in correct degree ring
DanGrayson commented 3 years ago

Thanks for the explanation. A more uniform and pleasing way to fix it would be to prevent empty blocks from being regarded as absent.

8d1h commented 3 years ago

Thanks for the explanation. A more uniform and pleasing way to fix it would be to prevent empty blocks from being regarded as absent.

Yes. But that would require changing the way that monomial orders are internally represented.

BTW I figured that this gives a neat way to compute the minimal polynomial of an algebraic number.

i4 : F = toField(QQ[a]/(a^3-5));

i5 : kernel map(F, QQ[x], {a^2+a+1})

            3     2
o5 = ideal(x  - 3x  - 12x - 16)

o5 : Ideal of QQ[x]
DanGrayson commented 3 years ago

Thanks for the explanation. A more uniform and pleasing way to fix it would be to prevent empty blocks from being regarded as absent.

Yes. But that would require changing the way that monomial orders are internally represented.

Maybe not. Do you have a reason for saying so? (I don't know how Mike represents them internally.)

8d1h commented 3 years ago

Sorry, I didn't want to sound so sure. I think when there are no variables, Eliminate 0 produces the option Weights=>{} which is the same as default.

Actually, one can tell when there are blocks of size zero.

i2 : R = QQ[x,MonomialOrder=>{0,0,0,1}]

o2 = R

o2 : PolynomialRing

i3 : (options R).MonomialOrder

o3 = {MonomialSize => 32}
     {GRevLex => {}     }
     {GRevLex => {}     }
     {GRevLex => {}     }
     {GRevLex => {1}    }
     {Position => Up    }

o3 : VerticalList

But selectInSubring uses the raw ring, which does not seem to remember these.

i4 : R.RawRing

o4 = QQGMP[x,
       DegreeLength => 1,
       Degrees => {1},
       Heft => {1},
       MonomialOrder => {
         GRevLex => {1},
         Position => Up
         }
       ]

o4 : RawRing
DanGrayson commented 3 years ago

Probably there is some code somewhere, either at top level in the d directory, or in the engine in the e directory, that makes empty blocks disappear needlessly.

8d1h commented 3 years ago

Actually I just saw the following in the document

Note: Weights and Eliminate do not create blocks, they only assign weights to the variables.

So Eliminate 0 literally does not change the monomial order and cannot be distinguished from the default.

DanGrayson commented 3 years ago

Maybe it's done at top level when a polynomial ring with 0 variables is created:


i1 : debug Core

i2 : raw (QQ[x])

o2 = QQGMP[x,
       DegreeLength => 1,
       Degrees => {1},
       Heft => {1},
       MonomialOrder => {
         GRevLex => {1},
         Position => Up
         }
       ]

o2 : RawRing

i3 : raw (QQ[])

o3 = QQGMP[,
       DegreeLength => 1,
       Degrees => {},
       Heft => {0},
       MonomialOrder => {
         Position => Up
         }
       ]

o3 : RawRing
8d1h commented 3 years ago

Probably there is some code somewhere, either at top level in the d directory, or in the engine in the e directory, that makes empty blocks disappear needlessly.

I think this is done here https://github.com/Macaulay2/M2/blob/f0ce581750dfd94336883695d3552671410f32f5/M2/Macaulay2/e/interface/monomial-ordering.cpp#L65-L89 If one removes the line return (p->nvars > 0); then empty blocks are preserved.

i1 : debug Core; raw(monoid[x,MonomialOrder=>{0,0,0,1},Global=>false])

o2 = [x,
       DegreeLength => 1,
       Degrees => {1},
       Heft => {1},
       MonomialOrder => {
         GRevLex => {},
         GRevLex => {},
         GRevLex => {},
         GRevLex => {1},
         Position => Up
         }
       ]

o2 : RawMonoid

But then wacky things will happen so it would need extra work. Also this only concerns block order; Eliminate 0 still won't remember the empty blocks since it does not create blocks at all.

mikestillman commented 3 years ago

I think I could fix this, if I know what you want to be fixed. Empty blocks do not need to be in the internal representation, as long as things like selectInSubring (in the e/ directory) use the empty block information.

8d1h commented 3 years ago

I think I could fix this, if I know what you want to be fixed. Empty blocks do not need to be in the internal representation, as long as things like selectInSubring (in the e/ directory) use the empty block information.

Yeah I guess that's it: make selectInSubring remember the empty block information. Then maybe replace the Eliminate n in graphIdeal by a block order so that we can have empty blocks?