Repository navigation
Split the solution set along equal coordinates and find separating elements from the multiplication matrices - #388
Merged
Conversation
mohabsafey
marked this pull request as draft
October 31, 2026 21:03
mohabsafey
marked this pull request as ready for review
October 31, 2026 21:15
mohabsafey
marked this pull request as draft
November 2, 2026 21:13
mohabsafey
marked this pull request as ready for review
November 2, 2026 21:54
Contributor
Author
|
Hi, apologies for the switches between the "ready for review" and "draft" modes. I think it is now ready for review |
Contributor
Author
|
The one thing I wonder is the following: should we change the interface? At the moment, the command-line user has access to flags that control the behaviour of msolve. Since the interface is not changed in this PR, a user from AlgebraicSolving.jl will just have the default behaviour without possible control on changing it |
When the parametrization over QQ fails because the default linear form does not separate the solutions, msolve used to try new linear forms one after the other, with a full F4 run for each attempt. It now builds the multiplication matrices modulo the prime of that run and searches for a separating element directly. The number of distinct solutions is the degree of the squarefree part of the minimal polynomial of a random linear form. The search first tries the single variables, then builds a sparse linear form with small coefficients greedily, adding one variable at a time until the minimal polynomial reaches the degree reached by a random form. The form found is added with a new variable as before. Its small coefficients lower the height of the parametrization, so fewer primes are needed. Setting MSOLVE_SEPELEM=0 restores the former behaviour. For a non-radical ideal, the eliminating polynomial of the form found has the degree of the squarefree part found by the search, and the parametrization is now accepted directly. This fixes nonradical-radicalshape, for which the former flow returned only one of the two solutions. The references for cyclic5 and issue-230 change because the search picks different linear forms. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… slows F4 Adding the separating linear form with a new variable can make the Groebner basis much larger: on the coplanarity system (coming from image-based visual servoing systems), it grows from 358280 to 714997 terms, and the F4 learning time from 19.5 to 123 seconds. At the first prime, msolve now counts the nonzero terms of all the F4 matrices, with the form and for the original system, using a new counter in neogb. If there are more than 20% more terms with the form, the multi-modular steps run F4 on the original system and compute the parametrization of the linear form from its multiplication matrix: a Krylov sequence, Berlekamp-Massey for the eliminating polynomial, and the coordinates from the scalar sequences as in FGLM. These counts do not depend on the machine or on the number of threads, so neither does the choice. At the first prime, this parametrization is checked against the one from FGLM. It also handles non-radical ideals, returning the squarefree eliminating polynomial. MSOLVE_SEPDENSE=0 disables this path and MSOLVE_SEPDENSE=2 forces it. On coplanarity, the F4 matrices have 292 million terms with the form against 93 million without; the output is unchanged and the time goes from 9734 to 1668 seconds. On the fekete-valdes n6 systems (coming from the characterization of logarithmic Fekete critical configurations), the matrices have 27% more terms, and a prime costs 80 seconds instead of 128. On G1 and square1.pZ, the counts differ by less than 2% and the usual path is kept, which is also the faster one there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On some systems, the eliminating polynomial is a product of many factors of small height. On the fekete-valdes n6 system, it has 8924 bits, while its 392 factors over Q have at most 71 bits. At the first prime, msolve now splits the eliminating polynomial by taking gcds with the differences of the coordinates: two solutions are in the same component when the same pairs of their coordinates are equal. If the largest component has degree at most a quarter of the number of solutions, each component is lifted on its own, on either path (FGLM or the multiplication matrix). A component is identified across primes by its degree and by its pattern of equal coordinates, and it is done when its rational reconstruction is confirmed by one more prime. The parametrization of the whole solution set is then recombined over Q by CRT in Q[t]. If the components differ at three primes, msolve falls back to the usual lifting. MSOLVE_SPLIT=0 disables the splitting. On fekete-valdes n6, the output is unchanged: 8 primes are needed instead of 309, and the time goes from 29094 to 4093 seconds. The fekete-valdes n5 system is added as a test: its 32 components are lifted with 2 primes instead of 9. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When the solution set splits along equalities of coordinates, each component now keeps its own parametrization over Q, with an integer eliminating polynomial of small degree and height. The real roots are isolated component by component, and the coordinates of each root are refined from the parametrization of its component instead of the one of the whole solution set. The points are then gathered and sorted by the value of the separating element, as before. The parametrization of the whole solution set is still recombined by CRT in Q[t] when it is printed (-P 1 or -P 2) and for the Julia interface, which always returns it; with -P 0, it is no longer built. On fekete-valdes n5, the 38 points are the same as with the global isolation, in the same order. Many coordinates are now exact: a linear component gives its rational root exactly, so the output prints [1 / 2, 1 / 2] instead of an interval around 1/2. The references of the test are updated accordingly. On fekete-valdes n6p0idealVarsReordered (392 components, 398 real roots), with -P 1 -t 1, the extraction of the real roots goes from 10211 s (5.8 s of isolation, the rest refining the coordinates) down to 0.01 s, and msolve from 14502 s down to 3996 s. On n6p0idealMaxRank3 (261 components, 267 real roots), it goes from 113 s down to 0.01 s, and msolve from 2706 s down to 2591 s. In both cases, the points are the same and come in the same order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
When a linear form is added with a new variable, the last coordinate of each real point is hidden by decrementing its number of coordinates, so real_point_clear never freed it. AddressSanitizer reported these leaks with -P 0 and -P 1, for instance 664 bytes on cyclic5 and 1120 bytes on fekete-valdes n5. They are now cleared when the coordinate is hidden. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test added with the splitting of the solution set was listed in Makefile.am but not in AC_CONFIG_LINKS, so its script, input and reference outputs were missing from the tarball and make distcheck failed. They are now listed with the other tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…jections The search for a separating element computed the degree of the minimal polynomial of each candidate form from its dense multiplication matrix, with a Wiedemann sequence: about 2 D^3 operations per form, D being the number of solutions. On noon6 (D = 717), the 32 forms tested took 9.7 of the 10.4 seconds of msolve, and on noon7 (D = 2187), the 61 forms took 985 seconds, while msolve took 383 seconds before the search was introduced. For a radical ideal, the random form computed first separates the solutions. Its parametrization x_v = X_v(t) mod Q is now computed once, and the degree for a form sum c_v x_v is the one of the minimal polynomial of sum c_v X_v in F_p[t]/(Q), from the sequence of the projections of its powers: 2 D products modulo Q. The degrees are the same up to an unlucky choice of the projections, so the same forms are found. Non-radical ideals keep the dense matrices. The search now takes 2.85 seconds on noon6 and 73 seconds on noon7, with the same forms and the same outputs. msolve takes 3.6 seconds on noon6 (5.6 before the search was introduced) and 128 seconds on noon7 (383). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he eliminating polynomial split_set_mpz_upoly copied each coordinate with its own length, so a coordinate whose leading coefficient vanishes lost it, while the usual lifting always writes deg(elim) coefficients. The parametrization was the same, but the output differed from the one of the usual lifting. This showed up on the coplanarity system of the visual servoing benchmarks, where four coordinates have degree 778 for an eliminating polynomial of degree 780. The coordinates are now padded with zeros to deg(elim) coefficients. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…plitting by options The search for a separating element, the route of the multi-modular steps with a separating linear form and the splitting of the solutions along equalities of coordinates were controlled by the environment variables MSOLVE_SEPELEM, MSOLVE_SEPDENSE and MSOLVE_SPLIT. They are replaced by the options --separating-element (1: search, the default, 0: no search), --dense-route (0: chosen from the sizes of the F4 matrices, the default, 1: never through the multiplication matrix of the original system, 2: always when it applies) and --split (0: when the largest component has at most a quarter of the solutions, the default, 1: never, 2: whenever there are several components). Their values are kept in data_gens_ff_t, and they are described among the advanced options of the help, whose column of option names is widened for them. msolve no longer reads environment variables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add a subsection on the options --separating-element, --dense-route and --split to the section on flags and options of the tutorial. It explains why the last variable must be separating, what each option controls, its default value, and whether the result depends on it. It also notes that the search for a separating element is not used when the staircase is rejected, and that forcing the splitting may slow down the computation, since the lifting of a large component costs about as much as that of all the solutions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new test runs cyclic5-qq with the options --separating-element, --dense-route and --split, with one and two threads. On this system, the last variable is not separating, the search finds the linear form 0 4 3 2 1, and the multi-modular steps use the original system. The solutions split into 6 components, the largest of degree 20 out of 70, so the splitting is not used by default and --split 2 forces it. Without the search (--separating-element 0), the changes of variable order fail and the linear form 1 2 3 4 5 is added: the output is compared with a new reference. With the other options, it is compared with the reference of the existing test of cyclic5-qq. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mohabsafey
force-pushed
the
sep-element
branch
from
November 7, 2026 12:20
67b5ca0 to
e44c6e2
Compare
mohabsafey
marked this pull request as ready for review
November 7, 2026 12:39
Contributor
|
Looks good to me! Thanks! |
wegank
reviewed
Nov 9, 2026
Member
|
Is there anything preventing this from merging (further reviews from Christian and Vincent, I suppose)? |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
It targets systems where the parametrization over QQ is much larger than the solution set requires. Either the chosen linear form makes F4 much harder, or the eliminating polynomial is a product of many factors of small height. Outputs are unchanged, except that some coordinates are now printed exactly.
Changes
nonradical-radicalshape, for which only one of its two solutions was returned.--separating-element 0restores the former behaviour.--dense-route 1disables this path,--dense-route 2forces it.-P 1,-P 2) or returned to Julia.--split 1disables the splitting,--split 2forces it whenever there are several components.--separating-element,--dense-routeand--split, described among the advanced options of the help and in a new subsection of the tutorial;test/diff/diff_cyclic5-qq-options.shexercises them.[1 / 2, 1 / 2]instead of an interval).-P 0,-P 1). This leak predates this PR.Benchmarks
The runs use
-t 1. Timings are in seconds, before → after the corresponding commit. They were measured on the former base of this PR, that is #384 on top of master before #390 and #392 were merged; the impact of these merges is discussed below the table.The coplanarity system comes from the computation of the equilibria of image-based visual servoing controllers [1]. The fekete-valdes systems come from the characterization of logarithmic Fekete critical configurations [2].
-P 1-P 1-P 1-P 2-P 2-P 2On coplanarity, the former flow tried 15 linear forms and settled on a dense one,
(1, 4, 9, …, 169); its time is the CPU time, since that run shared the machine with another one. The sparse form found by the search halves the number of primes, but it makes F4 three times slower per prime: the F4 matrices have 292 million terms with the form against 93 million without. The multiplication-matrix path removes this cost. On n6p0idealVarsReordered, the extraction of the real roots goes from 10211 s to 0.01 s. On fekete-valdes n5, the former flow tried three linear forms, each with a full F4 run, before finding one that separates the solutions; the search finds a sparse form in 0.01 s. On G1 and square1.pZ, the term counts differ by less than 2% and the usual path is kept. On noon7, the search tests 61 forms in 73 s; with the dense test of the first commit, it took 985 s, which the last commit fixes. On eco, katsura and the random systems, no splitting occurs and nothing changes.Impact of #390 and #392
#390 and #392 make F4 faster at each prime. This mostly benefits master on the systems where this PR saves many primes, so the gains of this PR are smaller on the current master, although its own timings do not change. The table below compares the current master (#390, #392 and #384 merged) with this PR rebased on it:
-t 1, median of 5 random seeds (min–max), 2 runs at a time.-P 2-P 1-P 2-P 2-P 2-P 2-P 2The timings of this PR are about those of the table above (noon7 127 s, noon6 3.6 s, fekete-valdes n5 0.14 s), but master went from 383 to 278 s on noon7 and from 5.6 to 4.0 s on noon6, so the speedups drop from 3.0 to 2.2 and from 1.55 to 1.11. On noon6, most of the time of this PR is now spent in the search for a separating element. On eco10, kat10, random2_7_7 and noon5, the outputs are identical to those of master; peak memory is unchanged except on noon6 (36 → 44 MB). The coplanarity and fekete-valdes n6 systems were not rerun on the current master.
[1] A. Colotti, J. García Fontán, A. Goldsztejn, S. Briot, F. Chaumette, O. Kermorgant, M. Safey El Din. Determination of All Stable and Unstable Equilibria for Image-Point-Based Visual Servoing. IEEE Transactions on Robotics 40, pp. 3406–3424, 2024. https://doi.org/10.1109/TRO.2024.3422050
[2] D. Armentano, L. Bentancur, F. Carrasco, M. Fiori, M. Valdés, M. Velasco. Characterization of Logarithmic Fekete Critical Configurations of at Most Six Points in All Dimensions. ISSAC 2025, pp. 309–318. https://doi.org/10.1145/3747199.3747575
Testing
finalize_f4(neogb) and in a call ofrational_reconstruction_paramwhose parameterresultwas removed in Speed up the lifting of rational parametrizations over QQ #384. The new countermat_ntermsis now copied back to the global meta data only outside the application of the trace, likemin_deg_in_first_deg_fall, since the trace may be applied for several primes in parallel; this PR reads it only after the learning run at the first prime. On the systems listed below and with the options--dense-routeand--split, the separating forms, term counts, components, numbers of primes and outputs are the same as before the rebase.make checkpasses (75/75).fekete-valdes-n5-qqis added as a test. The references for cyclic5, issue-230 and nonradical-radicalshape change because the search picks other linear forms, and nonradical-radicalshape now returns both solutions.-P 0,-P 1and-P 2, 1 and 2 threads, and with the multiplication-matrix path forced.Parts of this PR were written with the assistance of Claude Code (Claude Opus 5.5); all changes were reviewed and tested by the author.
🤖 Generated with Claude Code