From 9a314cc233593170a57a18640a5bf8fa2416f984 Mon Sep 17 00:00:00 2001 From: Mike Stillman Date: Tue, 29 Jul 2025 21:24:41 -0400 Subject: [PATCH 1/2] fixing Hilbert hint code, so it does not crash if given a bad Hilbert function --- M2/BUILD/mike/Makefile | 465 ++---------------- M2/Macaulay2/e/hilb.cpp | 17 +- M2/Macaulay2/m2/exports.m2 | 1 + M2/Macaulay2/m2/gb.m2 | 35 +- M2/Macaulay2/m2/ringmap.m2 | 2 +- .../packages/Macaulay2Doc/functions.m2 | 1 + .../functions/canUseHilbertHint-doc.m2 | 61 +++ .../packages/Macaulay2Doc/functions/gb-doc.m2 | 1 + .../packages/MinimalPrimes/splitIdeals.m2 | 4 +- M2/Macaulay2/tests/normal/gb-hilbert.m2 | 27 + 10 files changed, 163 insertions(+), 451 deletions(-) create mode 100644 M2/Macaulay2/packages/Macaulay2Doc/functions/canUseHilbertHint-doc.m2 create mode 100644 M2/Macaulay2/tests/normal/gb-hilbert.m2 diff --git a/M2/BUILD/mike/Makefile b/M2/BUILD/mike/Makefile index 8168d5a9f9e..1bcf3e186a1 100644 --- a/M2/BUILD/mike/Makefile +++ b/M2/BUILD/mike/Makefile @@ -1,21 +1,16 @@ .PHONY: always always: -BRANCH := $(shell git branch --contains | grep '^\* ' | sed -e s=^..== -e s=/=.=g ) +#BRANCH := $(shell git branch --contains | grep '^\* ' | sed -e s=^..== -e s=/=.=g ) BREWPREFIX := `brew --prefix` -####################### -## cmake build files ## -####################### - cmake-appleclang: - echo "git branch is " $(BRANCH) mkdir -p builds.tmp/cmake-appleclang cd builds.tmp/cmake-appleclang; cmake \ -GNinja \ -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_PREFIX_PATH="`brew --prefix libffi`" \ + -DCMAKE_PREFIX_PATH="/opt/homebrew/opt/mpi;/opt/homebrew/opt/bdw-gc;/opt/homebrew/opt/boost;/opt/homebrew/opt/cohomcalg;/opt/homebrew/opt/csdp;/opt/homebrew/opt/eigen;/opt/homebrew/opt/factory;/opt/homebrew/opt/fflas-ffpack;/opt/homebrew/opt/flint;/opt/homebrew/opt/fourtitwo;/opt/homebrew/opt/frobby;/opt/homebrew/opt/gdbm;/opt/homebrew/opt/gfan;/opt/homebrew/opt/givaro;/opt/homebrew/opt/gmp;/opt/homebrew/opt/libffi;/opt/homebrew/opt/libomp;/opt/homebrew/opt/lrs;/opt/homebrew/opt/mpfi;/opt/homebrew/opt/mpfr;/opt/homebrew/opt/mpsolve;/opt/homebrew/opt/msolve;/opt/homebrew/opt/nauty;/opt/homebrew/opt/node;/opt/homebrew/opt/normaliz;/opt/homebrew/opt/ntl;/opt/homebrew/opt/python;/opt/homebrew/opt/readline;/opt/homebrew/opt/tbb;/opt/homebrew/opt/topcom;/opt/homebrew/opt/" \ -DBUILD_NATIVE=off \ -DCMAKE_INSTALL_PREFIX=`pwd`/installed \ -DBUILD_TESTING=on \ @@ -23,437 +18,59 @@ cmake-appleclang: -DCMAKE_EXPORT_COMPILE_COMMANDS=true \ ../../../.. -cmake-clang: - echo "git branch is " $(BRANCH) - mkdir -p builds.tmp/cmake-clang - cd builds.tmp/cmake-clang; cmake \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DCMAKE_C_COMPILER="`brew --prefix llvm`/bin/clang" \ - -DCMAKE_CXX_COMPILER="`brew --prefix llvm`/bin/clang++" \ - -DBUILD_DOCS=on \ - -DBUILD_NATIVE=off \ - -DCMAKE_EXPORT_COMPILE_COMMANDS=true \ - ../../../.. - -cmake-gcc14: - mkdir -p builds.tmp/cmake-gcc14 - cd builds.tmp/cmake-gcc14; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=/opt/homebrew/opt/gcc/bin/gcc-14 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/opt/homebrew/opt/gcc/bin/g++-14 \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -## clean up or remove all below here -## grab debug builds, autotools builds, profile builds (on linux at leasst) - - -cmake-make-appleclang: - echo "git branch is " $(BRANCH) - mkdir -p builds.tmp/cmake-make-appleclang-$(BRANCH) - cd builds.tmp/cmake-make-appleclang-$(BRANCH); cmake \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_INSTALL_PREFIX=`pwd`/installed \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -# -DLINTING=on - -cmake-tbb2020-appleclang: - echo "git branch is " $(BRANCH) - mkdir -p builds.tmp/cmake-tbb2020-appleclang - cd builds.tmp/cmake-tbb2020-appleclang; cmake \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_PREFIX_PATH="`brew --prefix tbb@2020`;`brew --prefix`" \ - -DBUILD_NATIVE=off \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -cmake-no-tbb-appleclang: - echo "git branch is " $(BRANCH) - mkdir -p builds.tmp/cmake-no-tbb-appleclang - cd builds.tmp/cmake-no-tbb-appleclang; cmake \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_PREFIX_PATH=`brew --prefix` \ - -DWITH_TBB=off \ - -DBUILD_NATIVE=off \ - -DBUILD_TESTING=off \ - -DBUILD_DOCS=on \ - ../../../.. - -cmake-appleclang: - echo "git branch is " $(BRANCH) - mkdir -p builds.tmp/cmake-appleclang - cd builds.tmp/cmake-appleclang; cmake \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_PREFIX_PATH="`brew --prefix libffi`" \ - -DBUILD_NATIVE=off \ - -DCMAKE_INSTALL_PREFIX=`pwd`/installed \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - cmake-debug-appleclang: + echo "git branch is " $(BRANCH) mkdir -p builds.tmp/cmake-debug-appleclang cd builds.tmp/cmake-debug-appleclang; cmake \ -GNinja \ -DCMAKE_BUILD_TYPE=Debug \ - -DCMAKE_PREFIX_PATH="`brew --prefix tbb@2021`;`brew --prefix libffi`;`brew --prefix`" \ + -DCMAKE_PREFIX_PATH="/opt/homebrew/opt/mpi;/opt/homebrew/opt/bdw-gc;/opt/homebrew/opt/boost;/opt/homebrew/opt/cohomcalg;/opt/homebrew/opt/csdp;/opt/homebrew/opt/eigen;/opt/homebrew/opt/factory;/opt/homebrew/opt/fflas-ffpack;/opt/homebrew/opt/flint;/opt/homebrew/opt/fourtitwo;/opt/homebrew/opt/frobby;/opt/homebrew/opt/gdbm;/opt/homebrew/opt/gfan;/opt/homebrew/opt/givaro;/opt/homebrew/opt/gmp;/opt/homebrew/opt/libffi;/opt/homebrew/opt/libomp;/opt/homebrew/opt/lrs;/opt/homebrew/opt/mpfi;/opt/homebrew/opt/mpfr;/opt/homebrew/opt/mpsolve;/opt/homebrew/opt/msolve;/opt/homebrew/opt/nauty;/opt/homebrew/opt/node;/opt/homebrew/opt/normaliz;/opt/homebrew/opt/ntl;/opt/homebrew/opt/python;/opt/homebrew/opt/readline;/opt/homebrew/opt/tbb;/opt/homebrew/opt/topcom;/opt/homebrew/opt/" \ -DBUILD_NATIVE=off \ + -DCMAKE_INSTALL_PREFIX=`pwd`/installed \ -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -cmake-profile-appleclang: - echo "git branch is " $(BRANCH) - mkdir -p builds.tmp/cmake-profile-appleclang - cd builds.tmp/cmake-profile-appleclang; cmake \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DPROFILING=on \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. -# -DLINTING=on - -cmake-profile-appleclang: - mkdir -p builds.tmp/cmake-profile-appleclang - cd builds.tmp/cmake-profile-appleclang; cmake \ - -GNinja \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DCMAKE_PREFIX_PATH="`brew --prefix tbb@2020`;`brew --prefix`" \ - -DCMAKE_INSTALL_PREFIX=`pwd`/installed-profile \ - -DBUILD_NATIVE=on \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. -# -DLINTING=on - -# this one still needs to be modified for M1 -cmake-latestclang: - mkdir -p builds.tmp/cmake-latestclang - cd builds.tmp/cmake-latestclang; LIBRARY_PATH=`/usr/local/opt/llvm/bin/llvm-config --libdir` cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/local/opt/llvm/bin/clang \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/local/opt/llvm/bin/clang++ \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -# this one still needs to be modified for M1 -cmake-debug-latestclang: - mkdir -p builds.tmp/cmake-debug-latestclang - cd builds.tmp/cmake-debug-latestclang; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/local/opt/llvm/bin/clang \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/local/opt/llvm/bin/clang++ \ - -DCMAKE_BUILD_TYPE=Debug \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -# this one still needs to be modified for M1, tbb -cmake-gcc9: - mkdir -p builds.tmp/cmake-gcc9 - cd builds.tmp/cmake-gcc9; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/local/bin/gcc-9 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/local/bin/g++-9 \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -# this one still needs to be modified for M1, tbb -ubuntu-cmake-gcc: - mkdir -p builds.tmp/ubuntu-cmake-gcc - cd builds.tmp/ubuntu-cmake-gcc; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=gcc \ - -DCMAKE_CXX_COMPILER:FILEPATH=g++ \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -ubuntu-arm64-cmake-gcc: - mkdir -p builds.tmp/ubuntu-arm64-cmake-gcc - cd builds.tmp/ubuntu-arm64-cmake-gcc; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=gcc \ - -DCMAKE_CXX_COMPILER:FILEPATH=g++ \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -ubuntu-amd64-cmake-gcc: - mkdir -p builds.tmp/ubuntu-amd64-cmake-gcc - cd builds.tmp/ubuntu-amd64-cmake-gcc; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=gcc \ - -DCMAKE_CXX_COMPILER:FILEPATH=g++ \ - -DCMAKE_BUILD_TYPE=RelWithDebInfo \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - - -# running cmake-gcc9 now: 30 May 2020. -# build-libraries (with testing off): 22m36s -# build-programs (with testing off): 12m19s -# cmake -DBUILD_TESTING=on . -# M2-core: 2m51s -# install-packages: (running) -# M2-unit-tests -# check-packages -# ctest - -# this one still needs to be modified for M1, tbb -cmake-debug-gcc9: - mkdir -p builds.tmp/cmake-debug-gcc9 - cd builds.tmp/cmake-debug-gcc9; cmake \ - -GNinja \ - -DCMAKE_C_COMPILER:FILEPATH=/usr/local/bin/gcc-9 \ - -DCMAKE_CXX_COMPILER:FILEPATH=/usr/local/bin/g++-9 \ - -DCMAKE_BUILD_TYPE=Debug \ - -DBUILD_TESTING=on \ - -DBUILD_DOCS=on \ - ../../../.. - -# does this even work? -xcode: - mkdir -p builds.tmp/xcode - cd builds.tmp/xcode; cmake \ - -GXcode \ + -DBUILD_DOCS=off \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=true \ ../../../.. -########################### -## configure build files ## -########################### - -########### -## MacOS ## -########### -# Some possibly useful configure options -# --build=x86_64-apple-darwin -# --enable-build-libraries="flint ntl" - arm64-appleclang : always mkdir -p builds.tmp/arm64-appleclang cd builds.tmp/arm64-appleclang; ../../../../configure \ - CPPFLAGS="-I`brew --prefix tbb@2021`/include -I`brew --prefix`/include" \ - LDFLAGS="-L`brew --prefix tbb@2021`/lib -L`brew --prefix`/lib" \ - --with-boost-regex=boost_regex \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download + --enable-dmg \ + --enable-download --with-system-gc \ + --with-system-memtailor --with-system-mathic \ + --with-system-mathicgb \ + LDFLAGS="-L`brew --prefix`/lib \ + -L`brew --prefix factory`/lib \ + -L`brew --prefix libomp`/lib \ + -L`brew --prefix readline`/lib \ + -L`brew --prefix python`/Frameworks/Python.framework/Versions/3.13/lib" \ + CPPFLAGS="-I`brew --prefix`/include \ + -I`brew --prefix`/include/cddlib \ + -I`brew --prefix factory`/include \ + -I`brew --prefix libomp`/include \ + -I`brew --prefix readline`/include" \ + F77="gfortran-14" \ + PKG_CONFIG_PATH="`brew --prefix factory`/lib/pkgconfig" debug-arm64-appleclang : always mkdir -p builds.tmp/debug-arm64-appleclang cd builds.tmp/debug-arm64-appleclang; ../../../../configure \ - CPPFLAGS="-I`brew --prefix tbb@2021`/include -I`brew --prefix`/include" \ - LDFLAGS="-L`brew --prefix tbb@2021`/lib -L`brew --prefix`/lib" \ - --with-boost-regex=boost_regex \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-debug \ - --enable-memdebug \ - --disable-optimize \ - --enable-download - -arm64-tbb2020-appleclang : always - mkdir -p builds.tmp/arm64-tbb2020-appleclang - cd builds.tmp/arm64-tbb2020-appleclang; ../../../../configure \ - CPPFLAGS="-I`brew --prefix tbb@2020`/include -I`brew --prefix`/include" \ - LDFLAGS="-L`brew --prefix tbb@2020`/lib -L`brew --prefix`/lib" \ - --with-boost-regex=boost_regex \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -arm64-no-tbb-appleclang : always - mkdir -p builds.tmp/arm64-no-tbb-appleclang - cd builds.tmp/arm64-no-tbb-appleclang; ../../../../configure \ - CPPFLAGS="-I`brew --prefix tbb@2021`/include -I`brew --prefix`/include" \ - LDFLAGS="-L`brew --prefix tbb@2021`/lib -L`brew --prefix`/lib" \ - --disable-tbb \ - --with-boost-regex=boost_regex \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -darwin64-appleclang : always - mkdir -p builds.tmp/darwin64-appleclang - cd builds.tmp/darwin64-appleclang; ../../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download -# --enable-build-libraries="cohomcalg" - -darwin64-latestclang : always - mkdir -p builds.tmp/darwin64-latestclang - cd builds.tmp/darwin64-latestclang; ../../../../configure \ - CC="/usr/local/opt/llvm/bin/clang" \ - CXX="/usr/local/opt/llvm/bin/clang++" \ - LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" \ - CPPFLAGS="-I/usr/local/opt/llvm/include" \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -darwin64-gcc9 : always - mkdir -p builds.tmp/darwin64-gcc9 - cd builds.tmp/darwin64-gcc9; ../../../../configure \ - CC=gcc-9 CXX=g++-9 \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -darwin64-gcc10 : always - mkdir -p builds.tmp/darwin64-gcc9 - cd builds.tmp/darwin64-gcc9; ../../../../configure \ - CC=gcc-10 CXX=g++-10 \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -debug64-latestclang : always - mkdir -p builds.tmp/debug64-latestclang - cd builds.tmp/debug64-latestclang; ../../../../configure \ - CC="/usr/local/opt/llvm/bin/clang" \ - CXX="/usr/local/opt/llvm/bin/clang++" \ - LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" \ - CPPFLAGS="-I/usr/local/opt/llvm/include" \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download \ - --enable-debug \ - --disable-optimize - -debug64-appleclang : always - mkdir -p builds.tmp/debug64-appleclang - cd builds.tmp/debug64-appleclang; ../../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download \ - --enable-debug \ - --enable-memdebug \ - --disable-optimize - -debug64-gcc9 : always - mkdir -p builds.tmp/debug64-gcc9 - cd builds.tmp/debug64-gcc9; ../../../../configure \ - CC=gcc-9 CXX=g++-9 \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download \ - --enable-debug \ - --disable-optimize - -profile64-latestclang : always - mkdir -p builds.tmp/profile64-latestclang - cd builds.tmp/profile64-latestclang; ../../../../configure \ - CC="/usr/local/opt/llvm/bin/clang" \ - CXX="/usr/local/opt/llvm/bin/clang++" \ - LDFLAGS="-L/usr/local/opt/llvm/lib -Wl,-rpath,/usr/local/opt/llvm/lib" \ - CPPFLAGS="-I/usr/local/opt/llvm/include" \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download \ - --enable-profile - -profile64-appleclang : always - mkdir -p builds.tmp/profile64-appleclang - cd builds.tmp/profile64-appleclang; ../../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download \ - --enable-profile - -profile64-gcc9 : always - mkdir -p builds.tmp/profile64-gcc9 - cd builds.tmp/profile64-gcc9; ../../../../configure \ - CC=gcc-9 CXX=g++-9 \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download \ - --enable-profile - -################### -## linux ########## -################### - -linux-opt64-gcc8 : always - mkdir -p builds.tmp/opt64-gcc8 - cd builds.tmp/opt64-gcc8; ../../../../configure \ - CC=gcc-8 CXX=g++-8 \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -linux-opt64 : always - mkdir -p builds.tmp/opt64 - cd builds.tmp/opt64; ../../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -linux-debug64 : always - mkdir -p builds.tmp/debug64 - cd builds.tmp/debug64; ../../../../configure \ - --prefix="`pwd`/installed" \ - CPPFLAGS="-DENGINE_DEBUG_" \ - CXXFLAGS=" -U__GNUC_STDC_INLINE__" \ - --enable-debug \ - --disable-optimize \ - --enable-download - -linux-profile64 : always - mkdir -p builds.tmp/profile64 - cd builds.tmp/profile64; ../../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-profile \ - --enable-download - -######## below this line is older ###################### -opt : always - mkdir -p opt - cd opt; ../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-download - -debug : always - mkdir -p debug - cd debug; ../../../configure \ - --prefix="`pwd`/installed" \ - --enable-debug \ - --disable-strip \ - --disable-optimize \ - --enable-download - -profile : always - mkdir -p profile - cd profile; ../../../configure \ - --prefix="`pwd`/installed" \ - --disable-strip \ - --enable-profile \ - --enable-download \ - -# the following is no longer possible for me. -# TODO: work with Dan to fix that. -upload : always - scp darwin64/*.dmg u00.math.uiuc.edu:/home/html/www/Macaulay2/Uploads + --enable-debug \ + --disable-optimize \ + --disable-strip \ + --enable-download --with-system-gc \ + --with-system-memtailor --with-system-mathic \ + --with-system-mathicgb \ + LDFLAGS="-L`brew --prefix`/lib \ + -L`brew --prefix factory`/lib \ + -L`brew --prefix libomp`/lib \ + -L`brew --prefix readline`/lib \ + -L`brew --prefix python`/Frameworks/Python.framework/Versions/3.13/lib" \ + CPPFLAGS="-I`brew --prefix`/include \ + -I`brew --prefix`/include/cddlib \ + -I`brew --prefix factory`/include \ + -I`brew --prefix libomp`/include \ + -I`brew --prefix readline`/include" \ + F77="gfortran-14" \ + PKG_CONFIG_PATH="`brew --prefix factory`/lib/pkgconfig" diff --git a/M2/Macaulay2/e/hilb.cpp b/M2/Macaulay2/e/hilb.cpp index 5245a273a61..878d14d9418 100644 --- a/M2/Macaulay2/e/hilb.cpp +++ b/M2/Macaulay2/e/hilb.cpp @@ -709,33 +709,26 @@ int hilb_comp::coeff_of(const RingElement *h, int deg) // exp[0]=deg. const PolynomialRing *P = h->get_ring()->cast_to_PolynomialRing(); - exponents_t exp = newarray_atomic(int, P->n_vars()); + exponents_t exp = new int[P->n_vars()]; int result = 0; for (Nterm& f : h->get_value()) { P->getMonoid()->to_expvector(f.monom, exp); if (exp[0] < deg) { - ERROR("incorrect Hilbert function given"); - fprintf( - stderr, - "internal error: incorrect Hilbert function given, aborting\n"); - fprintf( - stderr, - "exp[0]: %d deg: %d\n", exp[0], deg); - abort(); + throw exc::engine_error("incorrect Hilbert function given"); } else if (exp[0] == deg) { std::pair res = P->getCoefficientRing()->coerceToLongInteger(f.coeff); - assert(res.first && - std::abs(res.second) < std::numeric_limits::max()); + if (not res.first or std::abs(res.second) > std::numeric_limits::max()) + throw exc::engine_error("Hilbert function value too large to use with Groebner basis computation"); int n = static_cast(res.second); result += n; } } - freemem(exp); + delete [] exp; return result; } diff --git a/M2/Macaulay2/m2/exports.m2 b/M2/Macaulay2/m2/exports.m2 index 8cf832a6b12..56693325689 100644 --- a/M2/Macaulay2/m2/exports.m2 +++ b/M2/Macaulay2/m2/exports.m2 @@ -529,6 +529,7 @@ export { "cache", "cacheValue", "cancelTask", + "canUseHilbertHint", "capture", "catch", "ceiling", diff --git a/M2/Macaulay2/m2/gb.m2 b/M2/Macaulay2/m2/gb.m2 index e5cb5e49b7b..d111240f802 100644 --- a/M2/Macaulay2/m2/gb.m2 +++ b/M2/Macaulay2/m2/gb.m2 @@ -257,32 +257,43 @@ gbGetPartialComputation := (m, type) -> ( null)) -- handle the Hilbert numerator later, which might be here: -checkHilbertHint = m -> ( - R := ring m; - -- Needed for using Hilbert functions to aid in Groebner basis computation: - -- Ring is poly ring over a field (or skew commutative, or quotient ring of such, or both) - -- Ring is singly graded, every variable is positive - -- Ring is homogeneous in this grading - -- Matrix is homogeneous in this grading - isHomogeneous m - and degreeLength R === 1 +canUseHilbertHint = method() + +canUseHilbertHint Ring := Boolean => R -> ( + degreeLength R === 1 and (instance(R, PolynomialRing) or isQuotientOf(PolynomialRing, R)) and isField coefficientRing R and (isCommutative R or isSkewCommutative R) - and all(degree \ generators(R, CoefficientRing => ZZ), deg -> deg#0 > 0) + and all(degree \ generators R, deg -> deg#0 > 0) ) +canUseHilbertHint Ideal := +canUseHilbertHint Module := +canUseHilbertHint Matrix := Boolean => m -> canUseHilbertHint ring m and isHomogeneous m + +-- checkHilbertHint = m -> ( +-- -- Needed for using Hilbert functions to aid in Groebner basis computation: +-- -- Ring is poly ring over a field (or skew commutative, or quotient ring of such, or both) +-- -- Ring is singly graded, every variable is positive +-- -- Ring is homogeneous in this grading +-- -- Matrix is homogeneous in this grading +-- isHomogeneous m and canUseHilbertHint ring m +-- ) gbGetHilbertHint := (m, opts) -> ( if opts.Hilbert =!= null then ( + if not canUseHilbertHint m then ( + << "warning: Hilbert hint given, but is being ignored" << endl; + return null; + ); if ring opts.Hilbert === degreesRing ring m then opts.Hilbert else error "expected Hilbert option to be in the degrees ring of the ring of the matrix") else if m.cache.?cokernel and m.cache.cokernel.cache.?poincare - and checkHilbertHint m then m.cache.cokernel.cache.poincare + and canUseHilbertHint m then m.cache.cokernel.cache.poincare else if m.?generators then ( g := m.generators; if g.cache.?image then ( M := g.cache.image; - if M.cache.?poincare and checkHilbertHint m + if M.cache.?poincare and canUseHilbertHint m then poincare target g - poincare M))) checkArgGB := m -> ( diff --git a/M2/Macaulay2/m2/ringmap.m2 b/M2/Macaulay2/m2/ringmap.m2 index f46eacdf66d..948165f430e 100644 --- a/M2/Macaulay2/m2/ringmap.m2 +++ b/M2/Macaulay2/m2/ringmap.m2 @@ -304,7 +304,7 @@ algorithms#(kernel, RingMap) = new MutableHashTable from { graph := generators graphIdeal f; assert( not isHomogeneous f or isHomogeneous graph ); SS := ring graph; - chh := checkHilbertHint graph; + chh := canUseHilbertHint graph; if chh then ( -- compare with pushNonLinear hf := poincare module target f; diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions.m2 index 7f760685903..fef06cc79e2 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions.m2 @@ -21,6 +21,7 @@ load "./functions/Beta-doc.m2" load "./functions/betti-doc.m2" load "./functions/between-doc.m2" load "./functions/binomial-doc.m2" +load "./functions/canUseHilbertHint-doc.m2" load "./functions/ceiling-doc.m2" load "./functions/changeBase-doc.m2" load "./functions/char-doc.m2" diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/canUseHilbertHint-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/canUseHilbertHint-doc.m2 new file mode 100644 index 00000000000..245d88915ea --- /dev/null +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/canUseHilbertHint-doc.m2 @@ -0,0 +1,61 @@ +doc /// + Key + canUseHilbertHint + (canUseHilbertHint, Ring) + (canUseHilbertHint, Ideal) + (canUseHilbertHint, Module) + (canUseHilbertHint, Matrix) + Headline + whether certain Groebner computations can make use of the Hilbert function + Usage + canUseHilbertHint m + Inputs + m:{Ring,Ideal,Module,Matrix} + Outputs + :Boolean + Description + Text + Certain Groebner basis computations, when given homogeneous input, can run faster if + the Hilbert function is know: the algorithm can use this information to bypass + computing zero reductions in many cases. + + In order to be able to use a Hilbert function hint, currently the object must be + in a singly graded polynomial ring (or quotient of such), over a field, + with all generators of positive degree, and it must be either commutative, or skew-commutative. + + Given a ring, this function returns whether this holds for the ring. For + a module, matrix or ideal, this function additionally checks whether the input is + homogeneous. + Example + R1 = ZZ/101[x,y,z, Degrees => {1,2,3}]; + assert canUseHilbertHint R1 + R2 = ZZ[x,y,z]; + assert not canUseHilbertHint R2 + R3 = (GF 8)[x,y,z] + assert canUseHilbertHint R3 + use R1 + R4 = R1[u,v, Join => false]/(x*u+y*v) + R5 = first flattenRing R4 + canUseHilbertHint R4 + canUseHilbertHint R5 + Text + Here is one way to use Hilbert hints. If one knows the Hilbert function, one can use it. + If one computes a Hilbert function (via poincare), one can use that in a ring + which is identical, except the monomial order is more computationally intensive (e.g. Lex). + Example + R = ZZ/101[x,y,z,w] + I = ideal random(R^1, R^{-5,-5,-5}) + hf = poincare I + codim I == 3 -- a complete intersection + Rlex = newRing(R, MonomialOrder => Lex) + Ilex = sub(I, Rlex) + elapsedTime g1 = gens gb Ilex; + Ilex = ideal(Ilex_*) -- clear out the previous Groebner basis + elapsedTime g2 = gens gb(Ilex, Hilbert => hf); + g1 == g2 + Caveat + One cannot currently use Hilbert hints for multigraded input + SeeAlso + poincare + newRing +/// diff --git a/M2/Macaulay2/packages/Macaulay2Doc/functions/gb-doc.m2 b/M2/Macaulay2/packages/Macaulay2Doc/functions/gb-doc.m2 index 611810d134e..31fd2da6b39 100644 --- a/M2/Macaulay2/packages/Macaulay2Doc/functions/gb-doc.m2 +++ b/M2/Macaulay2/packages/Macaulay2Doc/functions/gb-doc.m2 @@ -111,6 +111,7 @@ document { TO gbRemove, TO "gbTrace", TO LongPolynomial, + TO canUseHilbertHint } } diff --git a/M2/Macaulay2/packages/MinimalPrimes/splitIdeals.m2 b/M2/Macaulay2/packages/MinimalPrimes/splitIdeals.m2 index f28f449fb90..208111e7157 100644 --- a/M2/Macaulay2/packages/MinimalPrimes/splitIdeals.m2 +++ b/M2/Macaulay2/packages/MinimalPrimes/splitIdeals.m2 @@ -521,7 +521,7 @@ splitFunction#IndependentSet = (I,opts) -> ( J := I.Ideal; if J == 1 then error "Internal error: Input should not be unit ideal."; R := ring J; - hf := if isHomogeneous J then poincare J else null; + hf := if canUseHilbertHint J then poincare J else null; indeps := independentSets(J, Limit=>1); basevars := support first indeps; if opts.Verbosity >= 3 then @@ -540,7 +540,7 @@ splitFunction#IndependentSet = (I,opts) -> ( -- otherwise compute over the fraction field. -- in the next test, I am pretty sure that whenever J is homogeneous, so is J (and hf is then defined). -- But I'm keeping the test here anyway - if isHomogeneous JS and hf =!= null then gb(JS, Hilbert=>hf) else gb JS; + if hf =!= null and canUseHilbertHint JS then gb(JS, Hilbert=>hf) else gb JS; (JSF, coeffs) := minimalizeOverFrac(JS, SF); if coeffs == {} then ( I.IndependentSet = (basevars,S,SF); diff --git a/M2/Macaulay2/tests/normal/gb-hilbert.m2 b/M2/Macaulay2/tests/normal/gb-hilbert.m2 new file mode 100644 index 00000000000..a521216d62d --- /dev/null +++ b/M2/Macaulay2/tests/normal/gb-hilbert.m2 @@ -0,0 +1,27 @@ +-- test of canUseHilbertHint, Hilbert hint code with M2. +restart +R1 = ZZ/101[x,y,z, Degrees => {1,2,3}]; +assert canUseHilbertHint R1 +R2 = ZZ[x,y,z]; +assert not canUseHilbertHint R2 +R3 = (GF 8)[x,y,z] +assert canUseHilbertHint R3 +use R1 +R4 = R1[u,v, Join => false]/(x*u+y*v) +R5 = first flattenRing R4 +assert not canUseHilbertHint R4 -- we might want to change this behavior +assert canUseHilbertHint R5 + +-- test in presence of multi-degrees +R = ZZ/101[a,b,c,d, Degrees => {2:{1,0}, 2:{0,1}}] +I = ideal for i from 1 to 3 list random({2,3}, R) +hf = poincare I +assert not canUseHilbertHint R +assert not canUseHilbertHint I + +Rlex = ZZ/101[a,b,c,d, Degrees => {2:{1,0}, 2:{0,1}}, MonomialOrder => Lex] +Ilex = sub(I, Rlex) +gblex = gens gb(Ilex, Hilbert => hf) -- gives warning, but no error +assert(numgens ideal gblex == 37) -- happens with given random seed, at least.... + + From 09060c9a40bdbbe7d0598b5aa061a2d010090c4d Mon Sep 17 00:00:00 2001 From: Mike Stillman Date: Tue, 29 Jul 2025 21:31:57 -0400 Subject: [PATCH 2/2] Remove warning message that Hilbert hint is not being used --- M2/Macaulay2/m2/gb.m2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/M2/Macaulay2/m2/gb.m2 b/M2/Macaulay2/m2/gb.m2 index d111240f802..9bd9a3655e8 100644 --- a/M2/Macaulay2/m2/gb.m2 +++ b/M2/Macaulay2/m2/gb.m2 @@ -282,7 +282,7 @@ canUseHilbertHint Matrix := Boolean => m -> canUseHilbertHint ring m and isHomog gbGetHilbertHint := (m, opts) -> ( if opts.Hilbert =!= null then ( if not canUseHilbertHint m then ( - << "warning: Hilbert hint given, but is being ignored" << endl; + --<< "warning: Hilbert hint given, but is being ignored" << endl; return null; ); if ring opts.Hilbert === degreesRing ring m then opts.Hilbert