One Hat Cyber Team
Your IP :
216.73.216.115
Server IP :
194.44.31.54
Server :
Linux zen.imath.kiev.ua 4.18.0-553.77.1.el8_10.x86_64 #1 SMP Fri Oct 3 14:30:23 UTC 2025 x86_64
Server Software :
Apache/2.4.37 (Rocky Linux) OpenSSL/1.1.1k
PHP Version :
5.6.40
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
Macaulay2
/
BernsteinSato
/
View File Name :
Dlocalize.m2
-- Copyright 1999-2002 by Anton Leykin and Harrison Tsai -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -- Takes a cyclic holonomic module D_n/I and returns -- localization D_n/I [1/f] as D_n module -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- Dlocalize = method( Options => {Strategy => OTW}) Dlocalize(Ideal, RingElement) := options -> (I, f) -> Dlocalize(comodule I, f, options) Dlocalize(Module, RingElement) := options -> (M, f) -> ( outputRequest := {LocModule}; outputTable := computeLocalization(M, f, outputRequest, options); outputTable#LocModule ) DlocalizeMap = method( Options => {Strategy => OTW}) DlocalizeMap(Ideal, RingElement) := options -> (I, f) -> DlocalizeMap(comodule I, f, options) DlocalizeMap(Module, RingElement) := options -> (M, f) -> ( outputRequest := {LocMap}; outputTable := computeLocalization(M, f, outputRequest, options); outputTable#LocMap ) DlocalizeAll = method( Options => {Strategy => OTW}) DlocalizeAll(Ideal, RingElement) := options -> (I, f) -> DlocalizeAll(comodule I, f, options) DlocalizeAll(Module, RingElement) := options -> (M, f) -> ( outputRequest := {LocModule, LocMap, Bfunction, IntegrateBfunction, Boperator, GeneratorPower, annFS}; computeLocalization(M, f, outputRequest, options) ) ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ -- -- computeLocalization (Module M, RingElement f, List output) -- -- Computes the localization and returns a hash table of outputs according to the -- request given by "output" -- -- -- Two different strategies are possible: -- -- 1. "Oaku" -- appears in Walther's paper on local cohomology and -- based on Oaku's work -- -- 2. "OTW" -- appears in paper of Oaku-Takayama-Walther on localization -- -- -- Possible output formats: -- -- LocModule, LocMap, Bpolynomial, Boperator -- ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ computeLocalization = (M, f, output, options) -> ( if f == 0 then error "can't localize at 0"; W := ring M; r := numgens target gens M; -- case 1: M is a proper submodule of (D_n)^r/N -- MES: the original version did not use zeroize. ensureQuotientModule(M, "expected input to be a cokernel"); -- case 2: M is a cokernel outputList := {}; pInfo(1, "localize: Computing localization with " | toString options.Strategy | " strategy..."); if (options.Strategy === Oaku) then ( pInfo(1, "localize: Warning: Oaku's strategy requires module to be f-saturated"); if r > 1 then error "non-cyclic modules not yet supported with this strategy"; I := ideal relations M; tInfo := toString first timing (AnnI := AnnIFs2 (I,f);); pInfo(2, "\t\t\t time = " | tInfo | " seconds"); Ws := ring AnnI; ns := numgens Ws; elimWs := (coefficientRing Ws)(monoid [(entries vars Ws)#0, WeylAlgebra => Ws.monoid.Options.WeylAlgebra, MonomialOrder => Eliminate (ns-1)]); ff := substitute(f,elimWs); elimAnnI := substitute(AnnI, elimWs); H := gens elimAnnI | matrix{{ff}}; if member(Boperator, output) then ( pInfo(1, "localize: computing Bpoly and Bop..."); tInfo = toString first timing ( gbH := gb(H, ChangeMatrix => true); bpolys := selectInSubring(1, gens gbH); if bpolys == 0 then error "module not specializable"; if rank source bpolys > 1 then error "ideal principal but not realized as such. Need better implementation"; bpoly := bpolys_(0,0); ind := position((entries gens gbH)#0, i -> (i == bpoly)); C := getChangeMatrix gbH; tempBop := C_(numgens source H - 1, ind); Bop := tempBop; ); pInfo(2, "\t\t\t time = " | tInfo | " seconds"); ) else ( pInfo(1, "localize: computing Bpoly..."); tInfo = toString first timing ( bpoly = (mingens ideal selectInSubring(1, gens gb H))_(0,0); ); pInfo(2, "\t\t\t time = " | tInfo | " seconds"); if bpoly == 0 then error "module not specializable"; ); bpoly = substitute(bpoly, (coefficientRing W)(monoid [Ws_(ns-1)])); bestPower := min (getIntRoots (bpoly)); if bestPower == infinity then bestPower = 0; locIdeal := substitute(substitute(AnnI, {Ws_(ns-1) => bestPower}), W); locModule := W^1/locIdeal; local locMap; if member (LocMap, output) then ( if locModule == 0 then locMap = map(W^0, M, map(W^0,W^1,0)) else ( if bestPower > 0 then ( pInfo(1, "Warning: Still need to add b-operator. Adjusting generator to make localization map simple"); bestPower = 0; locIdeal = substitute(substitute(AnnI, {Ws_(ns-1) => bestPower}), W); locModule = W^1/locIdeal; locMap = map(locModule, M, matrix{{f^(-bestPower)}}) ) else locMap = map(locModule, M, matrix{{f^(-bestPower)}}); ); ); ) else if options.Strategy === OTWcyclic then ( if r > 1 then error "non-cyclic modules not yet supported with this strategy"; N := relations M; nW := numgens W; createDpairs W; n := #W.dpairVars#0; -- create the auxiliary ring D_n<a,Da> a := symbol a; Da := symbol Da; LW := (coefficientRing W)(monoid [(entries vars W)#0, a, Da, WeylAlgebra => append(W.monoid.Options.WeylAlgebra, a=>Da)]); a = LW_a; Da = LW_Da; nLW := numgens LW; WtoLW := map(LW, W, (vars LW)_{0..nW-1}); LWtoW := map(W, LW, (vars W) | matrix{{0_W,0_W}}); -- weight vectors for integration to a = 0 w := append( toList(n:0), -1); wt := join( toList(nW:0), {1,-1} ); -- twist generators of I into generators of twistI; Lf := WtoLW f; twistList := apply( toList(0..nLW-1), i -> LW_i - (LW_i*Lf - Lf*LW_i) * a^2 * Da ); twistMap := map(LW, LW, matrix{twistList}); LN := WtoLW N; twistN := matrix{{1-Lf*a}} | twistMap LN; pInfo (1, "localize: computing Bpoly..."); tInfo = toString first timing ( bpoly = bFunction(ideal twistN, w); ); pInfo(2, "\t\t\t time = " | tInfo | " seconds"); if bpoly == 0 then ( error "Module not specializable. Localization cannot be computed."; ); bpoly = substitute(bpoly, {(ring bpoly)_0 => (ring bpoly)_0 + 1}); intRoots := getIntRoots(bpoly); if #intRoots == 0 then maxRoot := -infinity else maxRoot = max intRoots; -- case 1: no non-negative integer roots if maxRoot < 0 then ( locModule = W^0; locMap = map(W^0, M, transpose compress matrix{{0_W}}); maxRoot = 0; bestPower = -2; ) -- case 2: localization generated by (1/f)^(maxroot+2) else ( bestPower = -maxRoot - 2; pInfo(1, "localize: computing GB..."); tInfo = toString first timing ( G := gbw(twistN, wt, Strategy => homogenize); ); pInfo(2, "\t\t\t time = " | tInfo | " seconds"); i := 0; relationsList := {}; while i < numgens source G do ( gi := G_(0,i); weight := max apply(exponents gi, e -> sum(e, wt, (b,c)->b*c) ); j := 0; while j <= maxRoot - weight do ( tmp := Fourier (a^j * gi); relationsList = append(relationsList, FourierInverse substitute(tmp, {a => 0}) ); j = j+1; ); i = i+1; ); relationsMat := transpose matrix{relationsList}; --tempL := oldCoefficients({nLW-2}, relationsMat); tempL := coefficients(transpose relationsMat, Variables=>{nLW-2}); presMat := tempL#1; srcSize := numgens source presMat; targSize := numgens target presMat; genIndex := position((entries tempL#0)#0, e->(e==a^maxRoot)); permList := apply( targSize, i -> if i == genIndex then targSize-1 else if i == targSize-1 then genIndex else i ); presMat = map(LW^targSize, LW^srcSize, presMat^permList); -- eliminate the first "maxRoot" components to get annihilating ideal -- of "a^(maxRoot)" homVar := symbol homVar; HW := (coefficientRing W)(monoid [homVar, (entries vars W)#0, WeylAlgebra => W.monoid.Options.WeylAlgebra, MonomialOrder => Eliminate 1]); HWtoW := map(W, HW, matrix{{1_W}} | (vars W) ); WtoHW := map(HW, W, (vars HW)_{1..numgens W}); I1 := LWtoW presMat; I2 := WtoHW I1; I3 := transpose ( HW_0 * (transpose I2)_{0..(targSize)-2} | (transpose I2)_{targSize - 1} ); pInfo(1, "localize: computing presentation..."); tInfo = toString first timing ( I4 := gens gb I3; ); pInfo(2, "\t\t\t time = " | tInfo | " seconds"); I5 := map(HW^(numgens target I4), HW^(numgens source I4), I4); testMap := map(HW^targSize, HW^targSize, matrix append( toList(targSize-1 : toList(targSize:0_HW)), append(toList(targSize-1:0_HW), 1_HW) ) ); i = 0; tempList := {}; while i < numgens source I5 do ( if testMap * I5_{i} == I5_{i} then ( tempList = append(tempList, I5_(targSize-1,i)) ); i = i+1; ); if tempList === {} then ( locModule = W^0; locMap = map(W^0, M, transpose compress matrix{{0_W}}); ) else ( locModule = cokernel HWtoW matrix{tempList}; locMap = map(locModule, M, matrix{{f^(-bestPower)}}); ); ); ) else if options.Strategy === OTW then ( N = matrix presentation M; nW = numgens W; createDpairs W; n = #W.dpairVars#0; m :=numColumns(N); -- create the auxiliary ring D_n<a,Da> a = symbol a; Da = symbol Da; LW = (coefficientRing W)(monoid [(entries vars W)#0, a, Da, WeylAlgebra => append(W.monoid.Options.WeylAlgebra, a=>Da)]); a = LW_a; Da = LW_Da; nLW = numgens LW; WtoLW = map(LW, W, (vars LW)_{0..nW-1}); LWtoW = map(W, LW, (vars W) | matrix{{0_W,0_W}}); -- weight vectors for integration to a = 0 w = append( toList(n:0), -1); wt = join( toList(nW:0), {1,-1} ); -- twist generators of I into generators of twistI; Lf = WtoLW f; twistList = apply( toList(0..nLW-1), i -> LW_i - (LW_i*Lf - Lf*LW_i) * a^2 * Da ); twistMap = map(LW, LW, matrix{twistList}); diag := apply( toList(0..r-1), i -> twistList); LN=mutableMatrix(LW,r,m); for i from 0 to r-1 do for j from 0 to m-1 do LN_(i,j)= twistMap(WtoLW N_(i,j)); col := apply( toList(0..r-1), i -> 1-Lf*a); twistN = diagonalMatrix(col) | matrix LN; locIntegrationModule := Dintegration(0,coker twistN,-w); --realize it over the original Weyl Algebra locModule = map(W,ring locIntegrationModule, gens W)**locIntegrationModule; bpoly = value locIntegrationModule.cache.BFunction; bestPower = -max(getIntRoots bpoly | {0}) - 2; locMap = if locModule == 0 then map(W^0, M, map(W^0,W^1,0)) else map(locModule, M, f^(-bestPower)*map(W^r)); ) else error "Only recognizes strategies Oaku, OTWcyclic, and OTW (default)."; if member(LocModule, output) then outputList = append(outputList, LocModule => locModule); if member(LocMap, output) then outputList = append(outputList, LocMap => locMap); if member(GeneratorPower, output) then outputList = append(outputList, GeneratorPower => bestPower); if options.Strategy === OTWcyclic then ( if member(IntegrateBfunction, output) then outputList = append(outputList, IntegrateBfunction => factorBFunction bpoly); ); if options.Strategy === OTW then ( if member(IntegrateBfunction, output) then outputList = append(outputList, IntegrateBfunction => factorBFunction bpoly); ); if options.Strategy === Oaku then ( if member(Bfunction, output) then outputList = append(outputList, Bfunction => factorBFunction bpoly); if member(annFS, output) then outputList = append(outputList, annFS => AnnI); if member(Boperator, output) then outputList = append(outputList, Boperator => Bop); ); hashTable outputList ) AnnIFs2 = method() AnnIFs2(Ideal, RingElement) := (I, f) -> ( pInfo(1, "computing AnnIFs... "); W := ring I; n := numgens W; t := symbol t; dt := symbol dt; WAopts := W.monoid.Options.WeylAlgebra | {t => dt}; WT := (coefficientRing W)(monoid [ t, dt, (entries vars W)#0, WeylAlgebra => WAopts, MonomialOrder => Eliminate 2 ]); u := symbol u; v := symbol v; WTUV := (coefficientRing W)(monoid [ u, v, t, dt, (entries vars W)#0, WeylAlgebra => WAopts, MonomialOrder => Eliminate 2 ]); u = WTUV_symbol u; v = WTUV_symbol v; t = WTUV_symbol t; dt = WTUV_symbol dt; WtoWTUV := map(WTUV, W, (vars WTUV)_{4..n+3}); -- twist generators of I into generators of KI f' := substitute(f,WTUV); twistList := join({u,v,t-f',dt}, apply( toList(4..n+3), i -> WTUV_i + (WTUV_i*f' - f'*WTUV_i)*dt)); twistMap := map(WTUV, WTUV, matrix{twistList}); tempKI := twistMap(ideal (t) + WtoWTUV I); wts := {1,-1,1,-1} | toList(n:0); KI := ideal homogenize(gens tempKI, u, wts); g := (entries gens KI)#0 | { u * v - 1 }; preGens := flatten entries substitute( selectInSubring(1, gens gb ideal g), WT); s := symbol s; WS := (coefficientRing W)(monoid [(entries vars W)#0, s, WeylAlgebra => W.monoid.Options.WeylAlgebra]); s = WS_symbol s; t = WT_symbol t; dt = WT_symbol dt; WTtoWS := g -> ( e := first exponents leadMonomial g; if e#0 > e#1 then g = dt^(e#0-e#1) * g else g = t^(e#1-e#0) * g; g' := 0_WS; while (d := first exponents leadMonomial g; d#0 * d#1 != 0) do( c := leadCoefficient g; g' = g' + c * (-s-1)^(d#1) * WS_(drop(d, 2) | {0}); -- >%-0 g = g - c * (t*dt)^(d#1) * WT_({0,0} | drop(d, 2)); ); g' + substitute(g, WS) ); ideal (preGens / WTtoWS) ) ---------------------------------------- -- TESTS TEST /// -- Test 1: Boundary cases x = symbol x; dx = symbol dx; W = QQ[x,dx,WeylAlgebra=>{x=>dx}]; M = cokernel matrix{{dx}}; assert(Dlocalize(M, 1_W) == M); assert(Dlocalize(M, 1_W, Strategy => Oaku) == M); -- simplest localization assert(target DlocalizeMap(M, x) == Dlocalize(M,x)) assert(target DlocalizeMap(M, x, Strategy => Oaku) == Dlocalize(M, x, Strategy => Oaku)) -- Pure torsion module M = cokernel matrix{{x}}; assert(Dlocalize(M, x) == W^0); assert(DlocalizeMap(M, x) == 0); assert(Dlocalize(M, x, Strategy => Oaku) == M) assert(DlocalizeMap(M, x, Strategy => Oaku) == map(M)) -- Already localized M = cokernel matrix{{x*dx+3/2}}; assert(Dlocalize(M, x) == cokernel matrix{{x*dx+3/2+2}}); assert(Dlocalize(M, x, Strategy => Oaku) == M); assert(DlocalizeMap(M, x, Strategy => Oaku) == map(M)); -- Test 2: from Coutinho "Primer..." u = symbol u; Du = symbol Du; n = 4; W = QQ[u_1..u_n, Du_1..Du_n, WeylAlgebra => apply(toList(1..n), i -> u_i => Du_i)]; M = W^1/ideal(Du_1..Du_n); f = sum(toList(1..n), i -> u_i^2); assert(Dlocalize(M, f) == Dlocalize(M, f, Strategy => Oaku)); assert(DlocalizeMap(M, f) == DlocalizeMap(M, f, Strategy => Oaku)); ///