Gröbner basis library
grobx0.73.3
Fast Gröbner bases over ℚ and GF(p): a 4×–6× speedup over Maple and msolve.
cargo add grobxpip install grobx
01 Speed
Loading measurements…
- Bar and factor: geometric mean of a program's time over grobx's, minus the cost of a trivial call, across the tuning and holdout sets of our corpus of polynomial systems, every basis in grevlex.
- A timeout counts as 2× the time limit (PAR-2). An instance is left out where either program returned a wrong result or failed, where both timed out, or where one finished only after the other's time limit.
- Single threaded with the clock pinned. Generic builds, not tuned for CPU features.
02 Usage
The instance is text in msolve's format: the variables, the characteristic (0 for ℚ), then the generators. The answer is the reduced basis as text, in grevlex unless the call names lex or a block order.
// cargo add grobx
use grobx::{Params, groebner};
fn main() -> Result<(), grobx::Error> {
let text = "x,y,z
0
x+y+z,
x*y+y*z+z*x,
x*y*z-1";
let r = groebner(text, &Params::default())?;
println!("{}", r.basis.unwrap());
Ok(())
}
[x+y+z,
y^2+y*z+z^2,
z^3-1]:# pip install grobx
import grobx
text = """x,y,z
0
x+y+z,
x*y+y*z+z*x,
x*y*z-1"""
r = grobx.groebner(text)
print(r.basis)
[x+y+z,
y^2+y*z+z^2,
z^3-1]:#include <stdio.h>
#include <grobx.h>
int main(void)
{
const char *text = "x,y,z\n"
"0\n"
"x+y+z,\n"
"x*y+y*z+z*x,\n"
"x*y*z-1";
grobx_params params = grobx_params_default();
grobx_result r;
if (grobx_groebner(text, ¶ms, &r) != GROBX_OK) {
fprintf(stderr, "%s\n", r.error);
grobx_result_free(&r);
return 1;
}
printf("%s", r.basis);
grobx_result_free(&r);
return 0;
}
[x+y+z,
y^2+y*z+z^2,
z^3-1]:read "/path/to/Grobx.mpl":
with(Grobx):
Basis([x+y+z, x*y+y*z+z*x, x*y*z-1], tdeg(x, y, z));
[x+y+z, y^2+y*z+z^2, z^3-1]# sage -pip install grobx-sage
import grobx_sage
R.<x,y,z> = PolynomialRing(QQ)
grobx_sage.groebner_basis(R.ideal(x+y+z, x*y+y*z+z*x, x*y*z-1))
[z^3 - 1, y^2 + y*z + z^2, x + y + z]grobx <<EOF
x,y,z
0
x+y+z,
x*y+y*z+z*x,
x*y*z-1
EOF
grobx: seed 5775019298346386988
[x+y+z,
y^2+y*z+z^2,
z^3-1]:03 Capabilities
- Fields
- GF(p) for primes below 2⁶⁴, and ℚ.
- Algorithm
- Signature F4 in F4-RB form, with Koszul and coprime syzygies and Roune–Stillman base divisors, handing over to plain F4 where that is faster. Plain F4 with Gebauer–Möller criteria and GBLA-style multiline reduction. Over ℚ, Traverso's trace learning, Chinese remaindering, and Monagan's maximal quotient rational reconstruction, confirmed at one more random prime, which the lift does not use.
- Orders
- grevlex; lex, by FGLM where the ideal is zero-dimensional and by F4 in lex otherwise; block and elimination orders.
- Limits
- No extension fields GF(pᵏ); no weighted or matrix orders.
- Bounds
- A deadline, a cancel flag, a memory ceiling. A bounded run says why it stopped.
- Threads
- Single-threaded; multi-threading to come.
- Reproducible
- One seed drives every random choice.
- Output
- The reduced Gröbner basis.
- Interfaces
- Rust, Python, C/C++, Maple, Sage, CLI.
- Platform
- Linux and Windows on x86-64; macOS on Apple Silicon; WebAssembly in the browser; Rust 1.97 and later; Python 3.12 and later.
04 Origin
An AI agent, Claude Opus 5.5, writes grobx's code under my direction. I decide its features and design its architecture, the objective every change is measured by, and the corpus it is measured on. Within that frame, the agent implements ideas from the original research papers, measures them, and keeps a change only where it is faster and still correct.
Anyone can check the result: the source is open, the test instances are public, the benchmarks are on this site, and every basis grobx computed for them matches the reference programs' answers.
I hold a doctorate in computer science from the University of Kassel. I am no expert in Gröbner bases, but I have 40 years of experience in software engineering.