Skip to content

Update "matrix Vector"#4162

Open
btotaro wants to merge 2 commits intoMacaulay2:developmentfrom
btotaro:stable
Open

Update "matrix Vector"#4162
btotaro wants to merge 2 commits intoMacaulay2:developmentfrom
btotaro:stable

Conversation

@btotaro
Copy link

@btotaro btotaro commented Mar 15, 2026

I propose to change the definition of "matrix Vector". The matrix (from a free module of rank 1)
is the same as before, but now the domain is not required to have its generator in degree 0,
when things are graded. As a result, the matrix is viewed as being homogeneous of degree 0,
when possible.

This is motivated by its effect on other commands. For example, the command "matrix List"
now has more of a chance to yield a matrix which Macaulay2 recognizes as homogeneous:

R1=QQ[x]; M1=R1^1; f2 = matrix {{xM1_0, x^2M1_0}}; isHomogeneous(f2)

Previously, this gave the answer "false". Now it gives the answer "true", since f2 is viewed
as having domain a free R1-module with generators in degrees 1 and 2; so f2 is a homogeneous map
of degree 0. (Before, the domain of f2 was viewed as the free R1-module with generators of degree 0;
from that point of view, f2 was not homogeneous.)

A related improvement caused by this change appears in Module/List or Module/Sequence:

R1=QQ[x]; M1=R1^1; M2=M1/{xM1_0, x^2M1_0}; isHomogeneous(M2)

Previously, this gave the answer "false", which is essentially a bug. (Even though "isHomogeneous"
does not do much computing, it should recognize that a module with graded generators and relations
is graded.) Now it gives the answer "true", which is what we want.

d-torrance and others added 2 commits February 20, 2026 10:54
It's only marginally useful, and its pull requests create branches in
the main repo beginning with "de", which messages up autocompletion
for "development".

[ci skip]
@pzinn
Copy link
Contributor

pzinn commented Mar 15, 2026

your examples don't run, presumably some formatting issue.

@mahrud
Copy link
Member

mahrud commented Mar 15, 2026

When putting code in markdown environments, wrap it like this:

```m2
your M2 code
```

This way Github won't convert A *B* _D_ to A B D.

@mahrud
Copy link
Member

mahrud commented Mar 15, 2026

But even correcting the formatting issue, I'm getting false in both of your examples when using your changes:

i5 : R1=QQ[x]; M1=R1^1; f2 = matrix {x*M1_0, x^2*M1_0}; isHomogeneous(f2)

              1       2
o7 : Matrix R1  <-- R1

o8 = false

i9 : R1=QQ[x]; M1=R1^1; f2 = matrix {{x*M1_{0}, x^2*M1_{0}}}; isHomogeneous(f2)

               1       2
o11 : Matrix R1  <-- R1

o12 = false

i13 : R1=QQ[x]; M1=R1^1; M2=M1/{x*M1_0, x^2*M1_0}; isHomogeneous(M2)

o16 = false

@d-torrance
Copy link
Member

Here's the failing example (from the MatrixFactorizations package):

i1 : S = ZZ/101[a,b];

i2 : R = S/(a^3+b^3);

i3 : m = ideal vars R

o3 = ideal (a, b)

o3 : Ideal of R

i4 : C = tailMF m

      2      2      2
o4 = S  <-- S  <-- S
                    
     0      1      0

o4 : ZZdFactorization

i5 : D = tailMF (m^2)

      3      3      3
o5 = S  <-- S  <-- S
                    
     0      1      0

o5 : ZZdFactorization

i6 : f = randomFactorizationMap(D,C)

          3                     2
o6 = 0 : S  <----------------- S  : 0
               {3} | 0 24  |
               {3} | 0 -36 |
               {3} | 0 -30 |

          3         2
     1 : S  <----- S  : 1
               0

o6 : ZZdFactorizationMap

i7 : assert isWellDefined f

i8 : assert not isCommutative f

i9 : g = randomFactorizationMap(D,C, Cycle => true, InternalDegree => 2)

          3                                        2
o9 = 0 : S  <------------------------------------ S  : 0
               {3} | -41a+10b -29a2-10ab-30b2 |
               {3} | -43a+8b  -19a2-19ab+48b2 |
               {3} | -5a+19b  -29a2+11ab+14b2 |

          3                                 2
     1 : S  <----------------------------- S  : 1
               {5} | -41a-14b -29a+19b |
               {5} | 43a-30b  19a-10b  |
               {5} | -5a+48b  -29a-8b  |

o9 : ZZdFactorizationMap

i10 : assert isWellDefined g

i11 : assert isCommutative g

i12 : assert isFactorizationMorphism g

i13 : h = randomFactorizationMap(D,C, Boundary => true)

           3                                     2
o13 = 0 : S  <--------------------------------- S  : 0
                {3} | -38ab-21b2 21a2b-38b3 |
                {3} | -16ab-34b2 34a2b-16b3 |
                {3} | 39ab-19b2  19a2b+39b3 |

           3                                     2
      1 : S  <--------------------------------- S  : 1
                {5} | -38ab-39b2 21ab-19b2  |
                {5} | 16ab-38b2  -34ab+21b2 |
                {5} | 39ab-16b2  19ab+34b2  |

o13 : ZZdFactorizationMap

i14 : assert isWellDefined h

i15 : assert isCommutative h

i16 : assert isFactorizationMorphism h

i17 : p = randomFactorizationMap(D, C, Cycle => true, Degree => 1)

           3         2
o17 = 1 : S  <----- S  : 0
                0

           3         2
      0 : S  <----- S  : 1
                0

o17 : ZZdFactorizationMap

i18 : assert isWellDefined p

i19 : assert isCommutative p

i20 : assert not isFactorizationMorphism p

i21 : assert(degree p === 1)

i22 : q = randomFactorizationMap(D, C, Boundary => true, InternalDegree => 2)

           3                                                       2
o22 = 0 : S  <--------------------------------------------------- S  : 0
                {3} | -13ab3+28b4 -28a2b3-13b5-47a2-18ab-39b2 |
                {3} | -43ab3+47b4 -47a2b3-43b5+39a2-47ab-18b2 |
                {3} | -15ab3-38b4 38a2b3-15b5-18a2-39ab+47b2  |

           3                                               2
      1 : S  <------------------------------------------- S  : 1
                {5} | -13ab3+15b4-47b -28ab3-38b4-47a |
                {5} | 43ab3-13b4-39b  47ab3-28b4-39a  |
                {5} | -15ab3-43b4-18b 38ab3-47b4-18a  |

o22 : ZZdFactorizationMap

i23 : assert all({0,1,2}, i -> degree q_i === {2})
stdio:23:6:(3):[1]: error: assertion failed

@jkyang92
Copy link
Contributor

I think it might be useful to have a function that converts any map into a degree 0 map. This doesn't directly solve the problem you're having, but it makes it easier to work with maps of non-zero degree.

Second, the other issue you are running into is that there's not a good way to combine maps of different degrees and get a well behaved map. I do wonder if we should warn when that is happening. In particular, if you have two different degree maps and put them into matrix then it will just return a degree 0 map. (i.e. degree matrix {{matrix (x*M1_0), matrix (x^2*M1_0)}} == {0} but degree matrix (x*M1_0)=={1} and degree matrix (x^2*M1_0)=={2}).

Finally, for your particular snippet of code, you can avoid some of the weirdness by doing the following

R1=QQ[x]; M1=R1^1; 
M1_{0,0} * diagonalMatrix {x,x^2}

Note however, that x*M1_{0} is still degree 1, and so matrix {{x*M1_{0},x^2*M1_{0}}} still won't do what you want.

@pzinn pzinn mentioned this pull request Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants