@@ -396,6 +396,7 @@ Matrix \\ Matrix := Matrix => (g, f) -> quotient'(f, g)
396396quotient (Matrix , Matrix ) := Matrix => opts -> (f, g) -> (
397397 -- given f: A-->C and g: B-->C, then find (f//g): A-->B such that g o (f//g) + r = f
398398 if target f != target g then error " quotient: expected maps with the same target" ;
399+ if f == 0 then return map (source g, source f, 0 );
399400 c := runHooks ((quotient , Matrix , Matrix ), (opts, f, g), Strategy => opts.Strategy );
400401 if c =!= null then c else error " quotient: no method implemented for this type of input" )
401402
@@ -408,11 +409,19 @@ addHook((quotient, Matrix, Matrix), Strategy => Default,
408409 MinimalGenerators => opts.MinimalGenerators };
409410 map (source g, source f, homomorphism (homomorphism '(f, opts) // Hom (source f, g, opts)))))
410411
411- -- FIXME: this is still causing unreasonable slow downs, e.g. for (large m) // (scalar)
412- addHook ((quotient , Matrix , Matrix ), Strategy => " Reflexive" , (opts, f, g) -> if f == 0 or isFreeModule source f then (
413- L := source f; -- result may not be well-defined if L is not free
412+ addHook ((quotient , Matrix , Matrix ), Strategy => " Reflexive" , (opts, f, g) -> (
413+ L := source f;
414414 M := target f;
415415 N := source g;
416+ -- TODO: should this be a separate strategy?
417+ if not isFreeModule L then return (
418+ -- result may not be well-defined if L is not free,
419+ -- unless the composition h * syz p is zero
420+ p := coverMap L;
421+ h := quotient (f * p, g, Strategy => " Reflexive" );
422+ -- TODO: does h * gens ker p != 0 suffice?
423+ if h * inducedMap (source p, kernel p) == 0 then map (N, L, h));
424+ --
416425 if M.?generators then (
417426 M = cokernel presentation M; -- this doesn't change the cover
418427 );
0 commit comments