This namespace contains functions for calculating the greatest common divisor of multivariate p/Polynomial
instances.
This namespace will eventually dispatch between a sparse GCD algorithm and Euclid's; for now it only contains a "classical" implementation of Euclid's algorithm.
Stateful instances required for GCD memoization and stats tracking.
This first block of functions provides utilities for logging statistics on the GCD search, as well as for limiting the time of attempts with a time limit and stopwatch.
Continuations
The GCD implementation below uses a continuation-passing style to apply transformations to each polynomial that make the process more efficient. First, a few helper functions, and then a number of continuations used to compute GCDs.
Now we come to the GCD routines. There are a few here, to handle simple cases like dividing a monomial into a larger polynomial, or taking the GCD of sequences of coefficients.
The GCD of a sequence of integers is the simplest case; simply reduce across the sequence using g/gcd
. The next-easiest case is the GCD of a coefficient and a polynomial.
Wih these two in hand, there are a few trivial cases that are nice to catch before dispatching more heavyweight routines.
Next, the case of the GCD of polynomials. If one of the sides is a monomial, the GCD is easy.
For example, Loading... divides Loading... trivially; the GCD is Loading....
See the docstring below for a description.
The next-toughest case is the GCD of two univariate polynomials. The 'classical' way to do this is with the Euclidean algorithm for univariate polynomials. This method can be extended to multivariate polynomials by using [[p/lower-arity]] to push all but the first variable into the coefficients, and passing a gcd
argument to [[euclidean-gcd]] that will recursively do the same until we hit bottom, at a univariate polynomial with non-polynomial coefficients.
The next function pairs [[euclidean-gcd]] with one of our continuations from above; [[with-content-removed]] removes the initial greatest common divisor of the coefficients of u
and v
before calling [[euclidean-gcd]], to keep the size of the coefficients small.
[[full-gcd]] extends [[univariate-gcd]] by using [[p/with-lower-arity]] and [[with-content-removed]] to recursively handle the first, principal variable using [[euclidean-gcd]], but passing a recursive call to [[full-gcd]] that the functions will use to handle their coefficients (which are polynomials of one less arity!)
The following block installs appropriate GCD and LCM routines between polynomial and coefficient instances.