Skip to content

Commit

Permalink
added compatibility functions for 1.24.05
Browse files Browse the repository at this point in the history
  • Loading branch information
mahrud committed May 31, 2024
1 parent b470214 commit 8deef51
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 4 deletions.
5 changes: 4 additions & 1 deletion packages/Varieties.m2
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ importFrom_Core {
"BinaryPowerMethod",
}

-- Backporting changes in the core that didn't make it to M2 v1.24.04
load "./Varieties/backports.m2"

-----------------------------------------------------------------------------
-- Local utilities
-----------------------------------------------------------------------------
Expand Down Expand Up @@ -793,7 +796,7 @@ euler ProjectiveVariety := X -> (
-----------------------------------------------------------------------------

load "Varieties/SheafMaps.m2"
load "Varieties/SheafComplexes.m2"
--load "Varieties/SheafComplexes.m2"

-----------------------------------------------------------------------------
-- Tests
Expand Down
4 changes: 2 additions & 2 deletions packages/Varieties/SheafMaps.m2
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ quotient(SheafMap, SheafMap) := SheafMap => opts -> (f, g) -> (
--assert(homomorphism' f % image Hom(source f, g) == 0)
map(source g, source f, quotient(matrix f, matrix g, opts)))

quotient'(SheafMap, SheafMap) := SheafMap => opts -> (f, g) -> (
quotient'(SheafMap, SheafMap) := SheafMap => (f, g) -> (
-- given f: A-->C and g: A-->B, then find (g\\f): B-->C such that (g\\f) o g = f
--if source f != source g then error "quotient': expected sheaf maps with the same source";
--assert(homomorphism' f % image Hom(g, target f) == 0)
map(target f, target g, quotient'(autotruncate(f, g), opts)))
map(target f, target g, quotient'(autotruncate(f, g))))

-- printing
-- TODO: use abbreviations for source and target
Expand Down
142 changes: 142 additions & 0 deletions packages/Varieties/backports.m2
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
-----------------------------------------------------------------------------
-- Compatibility with M2 v1.24.05
-----------------------------------------------------------------------------

plurals = new MutableHashTable from {
"body" => "bodies",
"dictionary" => "dictionaries",
"matrix" => "matrices",
"sheaf" => "sheaves",
"variety" => "varieties",
}
pluralize = s -> demark_" " append(
drop(ws := separate_" " s, -1),
if plurals#?(last ws)
then plurals#(last ws) else last ws | "s")
pluralsynonym = T -> if T.?synonym then pluralize T.synonym else "objects of class " | toString T

-----------------------------------------------------------------------------

export "isSmooth"
isSmooth = method(TypicalValue => Boolean, Options => true)

-----------------------------------------------------------------------------

applyUniformMethod = (symb, name) -> args -> (
if #args === 0 then error("expected at least one argument for ", name);
type := if uniform args then class args#0 else error("expected uniform objects for ", name);
meth := lookup(symb, type) ?? error("no method for ", name, " of ", pluralsynonym type);
if (Y := youngest args) =!= null and Y.?cache
then Y.cache#(symb, args) ??= meth args else meth args)

pullback List := Module => {} >> o -> applyUniformMethod(symbol pullback, "pullback")
pullback(Matrix, Matrix) := Module => {} >> o -> (f, g) -> pullback {f, g}

Matrix.pullback = args -> (
if not same apply(args, target) then error "expected morphisms with the same target";
h := concatCols args;
P := kernel h;
S := source h;
P.cache.formation = FunctionApplication (pullback, args);
P.cache.pullbackMaps = apply(#args,
i -> map(source args#i, S, S^[i], Degree => - degree args#i) * inducedMap(S, P));
P)

pushout List := Module => applyUniformMethod(symbol pushout, "pushout")
pushout(Matrix, Matrix) := Module => (f, g) -> pushout {f, g}

Matrix.pushout = args -> (
if not same apply(args, source) then error "expected morphisms with the same source";
h := concatRows args;
P := cokernel h;
T := target h;
P.cache.formation = FunctionApplication (pushout, args);
P.cache.pushoutMaps = apply(#args,
i -> inducedMap(P, T) * map(T, target args#i, T_[i], Degree => - degree args#i));
P)


--------------------------------------------------------------------------------
-- factoring of a matrix through another

-- Note: when f and g are endomorphisms, the sources and targets all agree,
-- so we need both functions quotient and quotient' to distinguish them.

-- factor matrices with same targets
Matrix // Matrix := Matrix => (f, g) -> quotient(f, g)
Number // Matrix := RingElement // Matrix := Matrix => (r, g) -> map(source g, target g, map(target g, cover target g, r) // g)
Matrix // Number := Matrix // RingElement := Matrix => (f, r) -> map(target f, source f, f // map(target f, cover target f, r))

-- factor matrices with same sources
Matrix \\ Matrix := Matrix => (g, f) -> quotient'(f, g)
-- commented because they don't seem very meaningful
--Matrix \\ Number := Matrix \\ RingElement := Matrix => (g, r) -> map(source g, target g, g \\ map(cover source g, source g, r))
--Number \\ Matrix := RingElement \\ Matrix := Matrix => (r, f) -> map(target g, source g, map(cover source g, source g, r) \\ f)

quotient(Matrix, Matrix) := Matrix => opts -> (f, g) -> (
-- given f: A-->C and g: B-->C, then find (f//g): A-->B such that g o (f//g) + r = f
if target f != target g then error "quotient: expected maps with the same target";
c := runHooks((quotient, Matrix, Matrix), (opts, f, g), Strategy => opts.Strategy);
if c =!= null then c else error "quotient: no method implemented for this type of input")

addHook((quotient, Matrix, Matrix), Strategy => Default,
-- Note: this strategy only works if the remainder is zero, i.e.:
-- homomorphism' f % image Hom(source f, g) == 0
-- TODO: should we pass MinimalGenerators => false to Hom and homomorphism'?
(opts, f, g) -> map(source g, source f, homomorphism(homomorphism' f // Hom(source f, g))))

-- FIXME: this is still causing unreasonable slow downs, e.g. for (large m) // (scalar)
addHook((quotient, Matrix, Matrix), Strategy => "Reflexive", (opts, f, g) -> if f == 0 or isFreeModule source f then (
L := source f; -- result may not be well-defined if L is not free
M := target f;
N := source g;
if M.?generators then (
M = cokernel presentation M; -- this doesn't change the cover
);
-- now M is a quotient module, without explicit generators
f' := matrix f;
g' := matrix g;
G := (
g.cache#"gb for quotient" ??= (
if M.?relations
then gb(g' | relations M, ChangeMatrix => true, SyzygyRows => rank source g')
else gb(g', ChangeMatrix => true)));
map(N, L, f' // G,
Degree => degree f' - degree g' -- set the degree in the engine instead
)))

addHook((quotient, Matrix, Matrix), Strategy => InexactField, (opts, f, g) ->
if instance(ring target f, InexactField)
-- TODO: c.f. https://github.com/Macaulay2/M2/issues/3252
and numRows g === numColumns g
and isFreeModule source g
and isFreeModule source f
then solve(g, f))

addHook((quotient, Matrix, Matrix), Strategy => ZZ, (opts, f, g) ->
if isQuotientOf(ZZ, ring target f)
and isFreeModule source g
and isFreeModule source f
then solve(g, f))

quotient'(Matrix, Matrix) := Matrix => -* opts -> *- (f, g) -> (
-- given f: A-->C and g: A-->B, then finds (g\\f): B-->C such that (g\\f) o g + r = f
if source f != source g then error "quotient': expected maps with the same source";
c := runHooks((quotient', Matrix, Matrix), (options quotient, f, g));
if c =!= null then c else error "quotient': no method implemented for this type of input")

addHook((quotient', Matrix, Matrix), Strategy => Default,
-- Note: this strategy only works if the remainder is zero, i.e.:
-- homomorphism' f % image Hom(g, target f) == 0
-- TODO: should we pass MinimalGenerators => false to Hom and homomorphism'?
(opts, f, g) -> map(target f, target g, homomorphism(homomorphism' f // Hom(g, target f))))

addHook((quotient', Matrix, Matrix), Strategy => "Reflexive",
(opts, f, g) -> if all({source f, target f, source g, target g}, isFreeModule) then dual quotient(dual f, dual g, opts))


end--
restart
loadPackage("Truncations", Reload => true)
loadPackage("Varieties", Reload => true)
check Varieties
7 changes: 6 additions & 1 deletion tests/testbot.m2
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
-- Uncomment and edit the following line to add your project directories
-- containing Macaulay2 source code files to the load path. Terminate each
-- directory name with a "/".
--path = join( { currentDirectory() | "src/singularities/", ... }, path )
path = join( { currentDirectory() | "packages/" }, path )

-- Uncomment and edit the following lines to preload and check your package or
-- to run a series of examples with every push on GitHub.
Expand All @@ -22,6 +22,11 @@
--load "tests/example.m2"
--capture get "tests/example.m2"

loadPackage("Truncations", FileName => currentDirectory() | "packages/Truncations.m2", Reload => true)
loadPackage("Complexes", FileName => currentDirectory() | "packages/Complexes.m2", Reload => true)
installPackage("Varieties", FileName => currentDirectory() | "packages/Varieties.m2")
check Varieties

-- The following lines automatically run every file in the "tests" directory.
-- If you wish, you can change testDir to any other directory.
testDir = currentDirectory() | "tests/"
Expand Down

0 comments on commit 8deef51

Please sign in to comment.