|
| 1 | +-- Tests for different variants |
| 2 | + |
| 3 | +TEST /// -- basics of Algorithm => LinearAlgebra |
| 4 | + I = ideal vars(QQ[x]) |
| 5 | + assert try (elapsedTime gb(I, Algorithm => LinearAlgebra); false) else true |
| 6 | + |
| 7 | + R = ZZ/32003[x] |
| 8 | + I = ideal vars R |
| 9 | + elapsedTime result = gens (G = gb(I, Algorithm => LinearAlgebra)); |
| 10 | + assert(result == vars R) |
| 11 | + |
| 12 | + assert try(getChangeMatrix G; false) else true |
| 13 | + assert try(mingens G; false) else true |
| 14 | + assert try(syz G; false) else true |
| 15 | + assert try(a // G; false) else true |
| 16 | + assert try(a % G; false) else true |
| 17 | + assert try(leadTerm G; false) else true |
| 18 | + leadTerm gens G |
| 19 | + assert(numcols gens G == 1) |
| 20 | +/// |
| 21 | + |
| 22 | +TEST /// -- Algorithm => LinearAlgebra, over finite field. |
| 23 | + kk = ZZ/101; |
| 24 | + R1 = kk[a..f]; |
| 25 | + J1 = ideal(a*b*c-d*e*f, a^2*c-b^2*e, b*e^4 - d*f^4 + e^5) |
| 26 | + elapsedTime gbC = flatten entries gens (G = gb(ideal J1_*, Algorithm => LinearAlgebra)); |
| 27 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 28 | + assert(gbC == gbB) |
| 29 | + |
| 30 | + -- TODO: is it ok to check Msolve while we do this? |
| 31 | + needsPackage "Msolve" |
| 32 | + elapsedTime gbD = flatten entries msolveGB(ideal J1_*, Threads => 8); -- slowest, due to translation, or what? |
| 33 | + assert(gbD == gbB) |
| 34 | + |
| 35 | + assert try(getChangeMatrix G; false) else true |
| 36 | + assert try(mingens G; false) else true |
| 37 | + assert try(syz G; false) else true |
| 38 | + assert try(a // G; false) else true |
| 39 | + assert try(a % G; false) else true |
| 40 | + assert try(leadTerm G; false) else true |
| 41 | + assert(numcols gens G == 7) |
| 42 | +/// |
| 43 | + |
| 44 | +TEST /// -- Algorithm => LinearAlgebra, over finite field. |
| 45 | + kk = ZZ/101; |
| 46 | + R1 = kk[a..g, MonomialSize=>8]; |
| 47 | + setRandomSeed 42 |
| 48 | + J1 = ideal random(R1^1, R1^{-2, -2, -2, -3}); |
| 49 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 50 | + elapsedTime gbC = flatten entries gens (G = gb(ideal J1_*, Algorithm => LinearAlgebra)); |
| 51 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 52 | + assert(gbA == gbB) |
| 53 | + assert(gbA == gbC) |
| 54 | + |
| 55 | + -- TODO: is it ok to check Msolve while we do this? |
| 56 | + needsPackage "Msolve" |
| 57 | + elapsedTime gbD = flatten entries msolveGB(ideal J1_*, Threads => 8); -- slowest, due to translation, or what? |
| 58 | + assert(gbD == gbB) |
| 59 | + |
| 60 | + assert try(getChangeMatrix G; false) else true |
| 61 | + assert try(mingens G; false) else true |
| 62 | + assert try(syz G; false) else true |
| 63 | + assert try(a // G; false) else true |
| 64 | + assert try(a % G; false) else true |
| 65 | + assert try(leadTerm G; false) else true |
| 66 | + assert(numcols gens G == 13) |
| 67 | +/// |
| 68 | + |
| 69 | +TEST /// -- Algorithm => LinearAlgebra, over prime finite field. |
| 70 | + kk = ZZ/101; |
| 71 | + R1 = kk[a..g, MonomialSize=>8]; |
| 72 | + setRandomSeed 42 |
| 73 | + J1 = ideal random(R1^1, R1^{-4,-4,-5,-5}); |
| 74 | + elapsedTime gbC = flatten entries gens (G = gb(ideal J1_*, Algorithm => LinearAlgebra)); |
| 75 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 76 | + assert(gbC == gbB) |
| 77 | + |
| 78 | + -- TODO: is it ok to check Msolve while we do this? |
| 79 | + needsPackage "Msolve" |
| 80 | + elapsedTime gbD = flatten entries msolveGB(ideal J1_*, Threads => 8); -- slowest, due to translation, or what? |
| 81 | + assert(gbD == gbB) |
| 82 | + |
| 83 | + assert try(getChangeMatrix G; false) else true |
| 84 | + assert try(mingens G; false) else true |
| 85 | + assert try(syz G; false) else true |
| 86 | + assert try(a // G; false) else true |
| 87 | + assert try(a % G; false) else true |
| 88 | + assert try(leadTerm G; false) else true |
| 89 | + assert(numcols gens G == 78) |
| 90 | +/// |
| 91 | + |
| 92 | +TEST /// -- Algorithm => LinearAlgebra, over non-prime finite field. |
| 93 | + kk = GF 125; |
| 94 | + R1 = kk[a..g, MonomialSize=>8]; |
| 95 | + setRandomSeed 42 |
| 96 | + J1 = ideal random(R1^1, R1^{-4,-4,-5,-5}); |
| 97 | + |
| 98 | + elapsedTime gbC = flatten entries gens gb(ideal J1_*, DegreeLimit => 10); |
| 99 | + elapsedTime gbB = flatten entries gens (G = gb(ideal J1_*, Algorithm => LinearAlgebra, DegreeLimit => 10)); |
| 100 | + assert(gbC == gbB) |
| 101 | + |
| 102 | + -- the following appears to hang. BUG!! It should say it can't do it. |
| 103 | + --try(groebnerBasis(ideal J1_*, Strategy => "F4"); false) else true -- BUG: this should be disallowed...! |
| 104 | + needsPackage "Msolve" |
| 105 | + elapsedTime try(msolveGB(ideal J1_*, Threads => 8); false) else true -- correctly gives error |
| 106 | +/// |
| 107 | + |
| 108 | +-* |
| 109 | + restart |
| 110 | +*- |
| 111 | +TEST /// -- hilbert driven gb computation, for default, Algorithm => LinearAlgebra |
| 112 | + setRandomSeed 42 |
| 113 | + kk = ZZ/101 |
| 114 | + R1 = kk[a..g, MonomialSize => 8]; |
| 115 | + K1 = ideal (a^4, b^4, c^4, d^4) |
| 116 | + hfJ = poincare K1 |
| 117 | + J1 = ideal random(R1^1, R1^{-4, -4, -4, -4}); |
| 118 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*, Hilbert => hfJ); |
| 119 | + elapsedTime gbB = flatten entries gens gb(ideal J1_*, |
| 120 | + Algorithm => LinearAlgebra, |
| 121 | + Hilbert => hfJ); |
| 122 | + elapsedTime gbB2 = flatten entries gens gb(ideal J1_*, |
| 123 | + Algorithm => LinearAlgebra); |
| 124 | + elapsedTime gbC = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 125 | + assert(gbA == gbB) |
| 126 | + assert(gbA == gbB2) |
| 127 | + assert(gbA == gbC) |
| 128 | + |
| 129 | + needsPackage "Msolve" |
| 130 | + elapsedTime gbD = flatten entries msolveGB(ideal J1_*, Threads => 8); |
| 131 | + assert(gbA == gbD) |
| 132 | +/// |
| 133 | + |
| 134 | + |
| 135 | +-* |
| 136 | + restart |
| 137 | +*- |
| 138 | +TEST /// -- hilbert driven gb computation, quasi-degrees |
| 139 | + setRandomSeed 42 |
| 140 | + kk = ZZ/101 |
| 141 | + R1 = kk[a..g, Degrees => {1,2,3,3,4,4,5}]; |
| 142 | + K1 = ideal (a^8, b^4, e^2, f^2) |
| 143 | + hfJ = poincare K1 |
| 144 | + J1 = ideal random(R1^1, R1^{-8, -8, -8, -8}); |
| 145 | + --elapsedTime gbA = flatten entries gens gb(ideal J1_*, Hilbert => hfJ); |
| 146 | + elapsedTime gbB = flatten entries gens gb(ideal J1_*, |
| 147 | + Algorithm => LinearAlgebra, |
| 148 | + Hilbert => hfJ); |
| 149 | + elapsedTime gbB2 = flatten entries gens gb(ideal J1_*, |
| 150 | + Algorithm => LinearAlgebra); |
| 151 | + elapsedTime gbC = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 152 | + assert(gbB == gbB2) |
| 153 | + assert(gbB == gbC) |
| 154 | +/// |
| 155 | + |
| 156 | +-* |
| 157 | + restart |
| 158 | +*- |
| 159 | +TEST /// -- GB over quotient rings |
| 160 | + setRandomSeed 42 |
| 161 | + kk = ZZ/101 |
| 162 | + R1 = kk[a,b,c,d,e,f]/ideal(a^2 - b*c) |
| 163 | + J1 = ideal random(R1^1, R1^{-2,-2,-3,-3}); |
| 164 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 165 | + assert try(gb(ideal J1_*, Algorithm => LinearAlgebra);false) else true |
| 166 | + elapsedTime gbC = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 167 | + assert(gbA == gbC) -- because it falls back to working version |
| 168 | + |
| 169 | + needsPackage "Msolve" |
| 170 | + assert try(msolveGB(ideal J1_*, Threads => 8); false) else true -- correctly gives error |
| 171 | +/// |
| 172 | + |
| 173 | + |
| 174 | +-* |
| 175 | + restart |
| 176 | +*- |
| 177 | +TEST /// -- exterior algebra |
| 178 | + kk = ZZ/101 |
| 179 | + R1 = kk[a,b,c,d,e,f, SkewCommutative=>true] |
| 180 | + setRandomSeed 42 |
| 181 | + J1 = ideal random(R1^1, R1^{-2,-2,-2,-2}); |
| 182 | + elapsedTime gbA = flatten entries gens gb(J1); |
| 183 | + assert try(gb(ideal J1_*, Algorithm => LinearAlgebra); false) else true; |
| 184 | + elapsedTime gbC = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 185 | + assert(gbA == gbC) |
| 186 | +/// |
| 187 | + |
| 188 | +-* |
| 189 | + restart |
| 190 | +*- |
| 191 | +TEST /// -- nonstandard grading |
| 192 | + kk = ZZ/101; |
| 193 | + R1 = kk[a..f, MonomialOrder => {GRevLex => {1,1,1,1,1,1}}, Degrees => {1,2,3,4,4,4}]; |
| 194 | + setRandomSeed 42 |
| 195 | + |
| 196 | + J1 = ideal random(R1^1, R1^{-5, -5, -5, -5}); |
| 197 | + assert isHomogeneous J1 |
| 198 | + elapsedTime gbA = flatten entries gens gb(J1); |
| 199 | + elapsedTime gbB = flatten entries gens gb(ideal J1_*, Algorithm => LinearAlgebra); |
| 200 | + elapsedTime gbC = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 201 | + needsPackage "Msolve" |
| 202 | + elapsedTime gbD = flatten entries msolveGB(ideal J1_*, Threads => 8); |
| 203 | + assert(gbA == gbB) |
| 204 | + assert(gbA == gbC) |
| 205 | + assert(gbA == gbD) |
| 206 | +/// |
| 207 | + |
| 208 | +-* |
| 209 | + restart |
| 210 | +*- |
| 211 | +TEST /// -- GB's of modules |
| 212 | + -- default order: grevlex, followed by position up |
| 213 | + R1 = ZZ/101[vars(0..7)] |
| 214 | + assert(leadTerm matrix{{a},{a}} == matrix{{0},{a}}) |
| 215 | + |
| 216 | + m1 = genericMatrix(R1, a, 2, 3) |
| 217 | + elapsedTime gbA = gens (gb m1); |
| 218 | + m1 = genericMatrix(R1, a, 2, 3) |
| 219 | + elapsedTime gbB = gens (G = gb(m1, Algorithm => LinearAlgebra)); |
| 220 | + |
| 221 | + assert(gbA == gbB) |
| 222 | + |
| 223 | + m1 = genericMatrix(R1, a, 2, 3) |
| 224 | + elapsedTime gbC = groebnerBasis(m1, Strategy => "F4"); -- BUG: just wrong |
| 225 | + |
| 226 | + m1 = genericMatrix(R1, a, 2, 3) |
| 227 | + elapsedTime gbC = groebnerBasis(m1, Strategy => "MGB"); -- BUG: just wrong |
| 228 | + |
| 229 | + R2 = ZZ/101[vars(0..7), MonomialOrder => {Position => Up}] |
| 230 | + m2 = genericMatrix(R2, a, 2, 3) |
| 231 | + elapsedTime gbC = groebnerBasis(m2, Strategy => "MGB"); -- BUG: just wrong |
| 232 | + |
| 233 | + assert(leadTerm matrix{{a},{a}} == matrix{{0},{a}}) |
| 234 | + |
| 235 | + -- note: msolveGB only works for ideals, doesn't take a matrix or Module, in any case. |
| 236 | +/// |
| 237 | + |
| 238 | +TEST /// -- another module GB test |
| 239 | + R = ZZ/101[a..d] |
| 240 | + M = R^{0,-1,-2,-3} |
| 241 | + setRandomSeed 42 |
| 242 | + mat = random(M,R^{-1,-2,-3,-4}) |
| 243 | + gbA = gens gb mat; |
| 244 | + setRandomSeed 42 |
| 245 | + mat = random(M,R^{-1,-2,-3,-4}) |
| 246 | + gbB = gens gb(mat, Algorithm => LinearAlgebra); |
| 247 | + assert(gbA == gbB) |
| 248 | +/// |
| 249 | + |
| 250 | +TEST /// -- another module GB test |
| 251 | + R = ZZ/101[a..d, MonomialOrder => {Position => Up, GRevLex => 2, GRevLex => 2 }] |
| 252 | + M = R^2 |
| 253 | + setRandomSeed 42 |
| 254 | + mat = matrix{{a,b},{a,c}} |
| 255 | + gbA = gens gb mat; |
| 256 | + -- to clear cache for mat |
| 257 | + mat = matrix{{a,b},{a,c}} |
| 258 | + assert try (gb(mat, Algorithm => LinearAlgebra); false) else true |
| 259 | + |
| 260 | + gens gb(ideal(a,b), Algorithm => LinearAlgebra) |
| 261 | +/// |
| 262 | + |
| 263 | +TEST /// -- another module GB test |
| 264 | + R = ZZ/101[a..f, Degrees => {1,2,3,4,5,6}] |
| 265 | + M = koszul(3,vars R) |
| 266 | + gbA = gens gb M; |
| 267 | + M = koszul(3,vars R) |
| 268 | + gbB = gens gb(M, Algorithm => LinearAlgebra); |
| 269 | + assert(gbA == gbB) |
| 270 | +/// |
| 271 | + |
| 272 | +-* |
| 273 | + restart |
| 274 | +*- |
| 275 | +TEST /// -- inhomgeneity. Algorithm => LinearAlgebra, over finite field. Need to implement still |
| 276 | + kk = ZZ/101; |
| 277 | + R1 = kk[a..g, MonomialSize=>8]; |
| 278 | + setRandomSeed 42 |
| 279 | + J1 = ideal (random(2, R1) + random(3, R1), random(2, R1) - 1) |
| 280 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 281 | + elapsedTime assert try(gb(ideal J1_*, Algorithm => LinearAlgebra); false) else true; |
| 282 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 283 | + assert(gbA == gbB) |
| 284 | + |
| 285 | + -- TODO: is it ok to check Msolve while we do this? |
| 286 | + needsPackage "Msolve" |
| 287 | + elapsedTime gbD = flatten entries msolveGB(ideal J1_*, Threads => 8); -- slowest, due to translation, or what? |
| 288 | + assert(gbD == gbB) |
| 289 | +/// |
| 290 | + |
| 291 | +-* |
| 292 | + restart |
| 293 | +*- |
| 294 | +TEST /// -- different monomial orders |
| 295 | + kk = ZZ/101; |
| 296 | + R1 = kk[a..g, MonomialSize=>8]; |
| 297 | + M = genericSymmetricMatrix(R1, 3) |
| 298 | + J1 = minors(2, M) |
| 299 | + |
| 300 | + -- grevlex |
| 301 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 302 | + elapsedTime gbC = flatten entries gens gb(ideal J1_*, Algorithm => LinearAlgebra); |
| 303 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 304 | + assert(gbA == gbB) |
| 305 | + assert(gbA == gbC) |
| 306 | + LT1 = leadTerm J1 |
| 307 | + |
| 308 | + -- lex |
| 309 | + R1 = kk[a..g, MonomialOrder => Lex]; |
| 310 | + J1 = sub(J1, R1) |
| 311 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 312 | + elapsedTime gbC = flatten entries gens gb(ideal J1_*, Algorithm => LinearAlgebra); |
| 313 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 314 | + assert(gbA == gbB) |
| 315 | + assert(gbA == gbC) |
| 316 | + LT2 = leadTerm J1 |
| 317 | + assert(LT2 != sub(LT1, R1)) |
| 318 | + |
| 319 | + -- product order |
| 320 | + R1 = kk[a..g, MonomialOrder => {3,4}]; |
| 321 | + J1 = sub(J1, R1) |
| 322 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 323 | + elapsedTime gbC = flatten entries gens gb(ideal J1_*, Algorithm => LinearAlgebra); |
| 324 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 325 | + assert(gbA == gbB) |
| 326 | + assert(gbA == gbC) |
| 327 | + LT3 = leadTerm J1 |
| 328 | + assert(LT3 != sub(LT1, R1)) |
| 329 | + |
| 330 | + -- product order |
| 331 | + R1 = kk[a..g, MonomialOrder => {Lex => 3, GRevLex => {1,2,3,4}}]; |
| 332 | + J1 = sub(J1, R1) |
| 333 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 334 | + elapsedTime gbC = flatten entries gens gb(ideal J1_*, Algorithm => LinearAlgebra); |
| 335 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 336 | + assert(gbA == gbB) |
| 337 | + assert(gbA == gbC) |
| 338 | + LT4 = leadTerm J1 |
| 339 | + assert(LT4 != sub(LT1, R1)) |
| 340 | +/// |
| 341 | + |
| 342 | +-* |
| 343 | + restart |
| 344 | +*- |
| 345 | +TEST /// -- Weyl algebras |
| 346 | + R = QQ[x,dx, WeylAlgebra => {x=>dx}] |
| 347 | + I = ideal(x^3, x*dx) |
| 348 | + assert try (gb(I, Algorithm => LinearAlgebra); false) else true |
| 349 | + |
| 350 | + R = ZZ/32003[x,dx,h, WeylAlgebra => {x=>dx,h}] |
| 351 | + I = ideal(x^3, x*dx) |
| 352 | + assert try (gb(I, Algorithm => LinearAlgebra); false) else true -- this should error |
| 353 | +/// |
| 354 | + |
| 355 | + |
| 356 | +-* |
| 357 | + restart |
| 358 | +*- |
| 359 | +TEST /// -- multigradings |
| 360 | + I = Grassmannian(2, 5, CoefficientRing => ZZ/32003) |
| 361 | + R = ring I |
| 362 | + es = entries id_(ZZ^6) |
| 363 | + degs = apply(subsets(0..5, 3), x -> sum apply(x, i -> es_i)) |
| 364 | + S = newRing(R, Degrees => degs) |
| 365 | + J1 = sub(I, S) |
| 366 | + isHomogeneous J1 |
| 367 | + elapsedTime gbA = flatten entries gens gb(ideal J1_*); |
| 368 | + elapsedTime gbC = flatten entries gens gb(ideal J1_*, Algorithm => LinearAlgebra); |
| 369 | + elapsedTime gbB = flatten entries groebnerBasis(ideal J1_*, Strategy => "F4"); |
| 370 | + assert(gbA == gbB) |
| 371 | + assert(gbA == gbC) |
| 372 | +/// |
| 373 | + |
| 374 | +-- todo: |
| 375 | +-- error for quotient rings (for LinearAlgebra) |
| 376 | +-- error for exterior algebra |
| 377 | +-- error for Weyl algebra |
| 378 | +-- error if module order is wrong (only if we are in a non-ideal situation). |
| 379 | +-- check |
| 380 | +-- Hilbert hint with quasi-gradings OK |
| 381 | +-- multi-gradings: OK |
| 382 | +-- check Weyl algebra (homogenized Weyl algebra): Need to error |
0 commit comments