Skip to content

Commit

Permalink
change complex to a method with Options => true. Add some Complex f…
Browse files Browse the repository at this point in the history
…unctions: status, rank, transpose, nullhomotopy (synonym of nullHomotopy). Allow complex to take a single matrix. Do not compute remainder in one version of nullHomotopy(serious performance degradation). Moved Ext(Module, Module) functionality from the Core to Complexes. Added minimalBetti fixes.
  • Loading branch information
mikestillman committed Aug 22, 2024
1 parent 68d262b commit 87975bc
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 20 deletions.
8 changes: 5 additions & 3 deletions M2/Macaulay2/packages/Complexes.m2
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ export {
"isNullHomotopyOf",
"isShortExactSequence",
"liftMapAlongQuasiIsomorphism",
-- "minimalBetti",
"minimizingMap",
"nullHomotopy",
"nullhomotopy" => "nullHomotopy",
--"nullhomotopy" => "nullHomotopy",
"naiveTruncation",
"randomComplexMap",
-- "res" => "resolution",
Expand Down Expand Up @@ -116,6 +117,7 @@ load "Complexes/ChainComplex.m2"
load "Complexes/FreeResolutions.m2"
load "Complexes/ChainComplexMap.m2"
load "Complexes/Tor.m2"
load "Complexes/Ext.m2"

--------------------------------------------------------------------
-- interface code to legacy types ----------------------------------
Expand All @@ -129,7 +131,7 @@ chainComplex Complex := ChainComplex => (cacheValue symbol ChainComplex) (C -> (
D
))

complex ChainComplex := Complex => opts -> (cacheValue symbol Complex)(D -> (
complex ChainComplex := Complex => {} >> opts -> (cacheValue symbol Complex)(D -> (
(lo,hi) := (min D, max D);
while lo < hi and (D_lo).numgens == 0 do lo = lo+1;
while lo < hi and (D_hi).numgens == 0 do hi = hi-1;
Expand All @@ -150,7 +152,7 @@ chainComplex ComplexMap := ChainComplexMap => f -> (
g
)

complex ChainComplexMap := ComplexMap => opts -> g -> (
complex ChainComplexMap := ComplexMap => {} >> opts -> g -> (
map(complex target g, complex source g, i -> g_i, Degree => degree g)
)
--------------------------------------------------------------------
Expand Down
51 changes: 43 additions & 8 deletions M2/Macaulay2/packages/Complexes/ChainComplex.m2
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ concentration ComplexMap := Sequence => f -> (
max Complex := ZZ => C -> max concentration C
min Complex := ZZ => C -> min concentration C

complex = method(Options => {Base=>0})
complex HashTable := Complex => opts -> maps -> (
complexOptions = {Base => 0}
--complex = method(Options => {Base=>0})
complex = method(Options => true)
complex HashTable := Complex => complexOptions >> opts -> maps -> (
spots := sort keys maps;
if #spots === 0 then
error "expected at least one matrix";
Expand All @@ -80,7 +82,7 @@ complex HashTable := Complex => opts -> maps -> (
C.dd = map(C,C,maps,Degree=>-1);
C
)
complex List := Complex => opts -> L -> (
complex List := Complex => complexOptions >> opts -> L -> (
-- L is a list of matrices or a list of modules
if not instance(opts.Base, ZZ) then
error "expected Base to be an integer";
Expand All @@ -104,7 +106,10 @@ complex List := Complex => opts -> L -> (
);
error "expected a list of matrices or a list of modules";
)
complex Module := Complex => opts -> (M) -> (
complex Matrix := Complex => complexOptions >> opts -> M -> (
complex({M}, opts)
)
complex Module := Complex => complexOptions >> opts -> (M) -> (
if not instance(opts.Base, ZZ) then
error "complex: expected base to be an integer";
if M.cache.?Complex and opts.Base === 0 then return M.cache.Complex;
Expand All @@ -118,9 +123,9 @@ complex Module := Complex => opts -> (M) -> (
C.dd = map(C,C,0,Degree=>-1);
C
)
complex Ring := Complex => opts -> R -> complex(R^1, opts)
complex Ideal := Complex => opts -> I -> complex(module I, opts)
complex Complex := Complex => opts -> C -> (
complex Ring := Complex => complexOptions >> opts -> R -> complex(R^1, opts)
complex Ideal := Complex => complexOptions >> opts -> I -> complex(module I, opts)
complex Complex := Complex => complexOptions >> opts -> C -> (
-- all this does is change the homological degrees
-- so the concentration begins at opts.Base
(lo,hi) := concentration C;
Expand All @@ -133,7 +138,7 @@ complex Complex := Complex => opts -> C -> (
complex(L, Base=>opts.Base)
)
)
complex ComplexMap := Complex => opts -> f -> (
complex ComplexMap := Complex => complexOptions >> opts -> f -> (
if degree f === -1 then (
if source f =!= target f then error "expected a differential";
(lo,hi) := concentration source f;
Expand Down Expand Up @@ -483,6 +488,8 @@ defaultLengthLimit = (R, baselen, len) -> (
len
)

-- MES: note, this list of options is all of the ones from resolution, in the Core,
-- except FastNonminimal is not present (use instead: Strategy => Nonminimal).
freeResolution = method(Options => {
StopBeforeComputation => false,
LengthLimit => infinity, -- (infinity means numgens R)
Expand Down Expand Up @@ -533,6 +540,29 @@ freeResolution Matrix := ComplexMap => opts -> f -> extend(
matrix f
)

-- TODO: reinstate these once we remove all uses of ChainComplex...
-- resolution Module := Complex => opts -> M -> (
-- o := pairs opts;
-- o2 := new OptionTable from select(pairs opts, x -> x#0 =!= FastNonminimal);
-- if opts.FastNonminimal then (
-- o2 = o2 ++ {Strategy => Nonminimal};
-- << "warning: `FastNonminimal => true` is deprecated. Use: res(..., Strategy => Nonminimal) instead" << endl;
-- );
-- freeResolution(M, o2)
-- )
-- resolution Ideal := Complex => opts -> I -> resolution(comodule I, opts)
-- resolution MonomialIdeal := Complex => opts -> I -> resolution(comodule ideal I, opts)
-- resolution Matrix := ComplexMap => opts -> f -> extend(
-- resolution(target f, opts),
-- resolution(source f, opts),
-- matrix f
-- )

complete Complex := C -> C
complete ComplexMap := F -> F
nullhomotopy ComplexMap := F -> nullHomotopy F
status Complex := C -> << "resolution status of a Complex needs to be implemented" << endl;

isHomogeneous Complex := (C) -> isHomogeneous dd^C

-- These next two local functions are lifted from previous code in m2/chaincomplexes.m2
Expand Down Expand Up @@ -592,6 +622,11 @@ poincareN Complex := C -> (
f
)

rank Complex := ZZ => C -> (
(lo, hi) := concentration C;
sum for i from lo to hi list (-1)^i * rank C_i
)

minimalPresentation Complex :=
prune Complex := Complex => opts -> (cacheValue symbol minimalPresentation)(C -> (
-- opts is ignored here
Expand Down
77 changes: 74 additions & 3 deletions M2/Macaulay2/packages/Complexes/ChainComplexDoc.m2
Original file line number Diff line number Diff line change
Expand Up @@ -408,17 +408,18 @@ doc ///

doc ///
Key
complex
(complex, List)
[complex, Base]
complex
(complex, Matrix)
[(complex, List), Base]
Base
Headline
make a chain complex
Usage
complex L
Inputs
L:List
of maps
of maps, or a single matrix.
Base => ZZ
the index of the target of the first map
in the differential.
Expand Down Expand Up @@ -483,6 +484,14 @@ doc ///
HH C
prune HH C
prune HH_1 C
Text
Having the input be a matrix is equivalent to having it be
a singleton list containing this matrix.
Example
C' = complex F1
assert isWellDefined C'
C'' = complex(F1, Base => 3)
assert isWellDefined C''
Caveat
This constructor minimizes computation
and does very little error checking. To verify that a complex
Expand Down Expand Up @@ -4363,6 +4372,66 @@ doc ///
freeResolution
///

doc ///
Key
(Ext,Module,Module)
(Ext,Ideal,Ideal)
(Ext,Ideal,Module)
(Ext,Ideal,Ring)
(Ext,Module,Ideal)
(Ext,Module,Ring)
Headline
total Ext module
Usage
Ext(M, N)
Inputs
M:Module
or ofClass{Ideal,Ring}, that is homogeneous
N:Module
or ofClass{Ideal,Ring} over the same ring as $M$, that is also homogeneous
Outputs
:Module
the $\operatorname{Ext}$ module of $M$ and $N$, as a
multigraded module, with the modules
$\operatorname{Ext}^i(M,N)$ for all values of $i$
appearing simultaneously.
Description
Text
The computation of the total Ext module is possible for modules over the
ring $R$ of a complete intersection, according to the algorithm
of Shamash-Eisenbud-Avramov-Buchweitz. The result is provided as a finitely
presented module over a new ring with one additional variable of degree
$\{-2,-d\}$ for each equation of degree $d$ defining $R$. The
variables in this new ring have degree length $1$ more than the degree length of
the original ring. In other words, it is multigraded with the
degree $d$ part of $\operatorname{Ext}^n(M,N)$ appearing as the degree
$\{-n,d\}$ part of $\operatorname{Ext}(M,N)$.
Text
We illustrate this in the following example.
Example
R = QQ[x,y]/(x^3,y^2);
N = cokernel matrix {{x^2, x*y}}
H = Ext(N,N);
ring H
S = ring H;
H
isHomogeneous H
rank source basis( { -2,-3 }, H)
rank source basis( { -3 }, Ext^2(N,N) )
rank source basis( { -4,-5 }, H)
rank source basis( { -5 }, Ext^4(N,N) )
hilbertSeries H
hilbertSeries(H,Order=>11)
Text
For more information, see the chapter {\it Resolutions and cohomology over complete intersections}
by Luchezar L. Avramov and Daniel R. Grayson, in the book
@HREF("https://macaulay2.com/Book/ComputationsBook/book/book.pdf", "Computatations in Algebraic Geometry with Macaulay2")@.
Text
The result of the computation is cached for future reference.
SeeAlso
"computing with Ext"
///

///
Key
Headline
Expand All @@ -4375,3 +4444,5 @@ doc ///
Caveat
SeeAlso
///


9 changes: 5 additions & 4 deletions M2/Macaulay2/packages/Complexes/ChainComplexMap.m2
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,7 @@ Hom(Matrix, ComplexMap) := ComplexMap => opts -> (f,g) ->
Hom(map(complex target f, complex source f, i -> if i === 0 then f), g, opts)

dual ComplexMap := ComplexMap => {} >> o -> f -> Hom(f, (ring f)^1)
transpose ComplexMap := ComplexMap => f -> dual f

homomorphism ComplexMap := ComplexMap => (h) -> (
-- h should be a homomorphism of complexes from R^1[-i] --> E = Hom(C,D)
Expand Down Expand Up @@ -1116,13 +1117,13 @@ nullHomotopyFreeSource = f -> (
(lo,hi) := concentration f;
for i from lo to hi do (
if hs#?(i-1) then (
rem := (f_i - hs#(i-1) * dd^C_i) % (dd^D_(i+deg));
if rem != 0 then return null; -- error "can't construct homotopy";
--rem := (f_i - hs#(i-1) * dd^C_i) % (dd^D_(i+deg));
--if rem != 0 then return null; -- error "can't construct homotopy";
hs#i = (f_i - hs#(i-1) * dd^C_i) // (dd^D_(i+deg))
)
else (
rem = f_i % dd^D_(i+deg);
if rem != 0 then return null; -- error "can't construct homotopy";
--rem = f_i % dd^D_(i+deg);
--if rem != 0 then return null; -- error "can't construct homotopy";
hs#i = f_i // dd^D_(i+deg)
)
);
Expand Down
7 changes: 7 additions & 0 deletions M2/Macaulay2/packages/Complexes/ChainComplexMapDoc.m2
Original file line number Diff line number Diff line change
Expand Up @@ -1271,6 +1271,7 @@ doc ///
doc ///
Key
(dual, ComplexMap)
(transpose, ComplexMap)
Headline
the dual of a map of complexes
Usage
Expand Down Expand Up @@ -1299,10 +1300,16 @@ doc ///
D' = (freeResolution coker matrix{{a^2,a*b,c^3}})[-1]
f' = randomComplexMap(D', D)
dual(f' * f) == dual f * dual f'
Text
For backwards compatibility, one can also use {\tt transpose}.
Example
h' = transpose f
assert(h == h')
SeeAlso
(Hom, ComplexMap, ComplexMap)
(randomComplexMap, Complex, Complex)
(dual, Matrix)
(transpose, Matrix)
///

doc ///
Expand Down
4 changes: 2 additions & 2 deletions M2/Macaulay2/packages/Complexes/ChainComplexTests.m2
Original file line number Diff line number Diff line change
Expand Up @@ -2280,8 +2280,8 @@ TEST ///
beta = map(E, D, {d,e,f})
isWellDefined alpha
isWellDefined beta
phi = complex chainComplex alpha
psi = complex chainComplex beta
phi = complex alpha
psi = complex beta
prune HH phi
prune HH psi
isNullHomotopic phi
Expand Down
Loading

0 comments on commit 87975bc

Please sign in to comment.