@@ -248,14 +248,105 @@ function rational_parametrization(
248248 return I. rat_param
249249end
250250
251+ @doc Markdown. doc"""
252+ rational_solutions(I::Ideal{T} where T <: MPolyElem, <keyword arguments>)
253+
254+ Given an ideal `I` with a finite solution set over the complex numbers, return
255+ the rational roots of the ideal.
256+
257+ # Arguments
258+ - `I::Ideal{T} where T <: MPolyElem`: input generators.
259+ - `initial_hts::Int=17`: initial hash table size `log_2`.
260+ - `nr_thrds::Int=1`: number of threads for parallel linear algebra.
261+ - `max_nr_pairs::Int=0`: maximal number of pairs per matrix, only bounded by minimal degree if `0`.
262+ - `la_option::Int=2`: linear algebra option: exact sparse-dense (`1`), exact sparse (`2`, default), probabilistic sparse-dense (`42`), probabilistic sparse(`44`).
263+ - `info_level::Int=0`: info level printout: off (`0`, default), summary (`1`), detailed (`2`).
264+ - `precision::Int=32`: bit precision for the computed solutions.
265+
266+ # Examples
267+ ```jldoctest
268+ julia> using AlgebraicSolving
269+
270+ julia> R,(x1,x2,x3) = PolynomialRing(QQ, ["x1","x2","x3"])
271+ (Multivariate Polynomial Ring in x1, x2, x3 over Rational Field, Nemo.fmpq_mpoly[x1, x2, x3])
272+
273+ julia> I = Ideal([x1+2*x2+2*x3-1, x1^2+2*x2^2+2*x3^2-x1, 2*x1*x2+2*x2*x3-x2])
274+ Nemo.fmpq_mpoly[x1 + 2*x2 + 2*x3 - 1, x1^2 - x1 + 2*x2^2 + 2*x3^2, 2*x1*x2 + 2*x2*x3 - x2]
275+
276+ julia> rat_sols = rational_solutions(I)
277+ 2-element Vector{Vector{fmpq}}:
278+ [1, 0, 0]
279+ [1//3, 0, 1//3]
280+
281+ julia> map(r->map(p->evaluate(p, r), I.gens), rat_sols)
282+ 4-element Vector{Vector{fmpq}}:
283+ [0, 0, 0]
284+ [0, 0, 0]
285+
286+ """
287+ function rational_solutions (
288+ I:: Ideal{T} where T <: MPolyElem ; # input generators
289+ initial_hts:: Int = 17 , # hash table size, default 2^17
290+ nr_thrds:: Int = 1 , # number of threads
291+ max_nr_pairs:: Int = 0 , # number of pairs maximally chosen
292+ # in symbolic preprocessing
293+ la_option:: Int = 2 , # linear algebra option
294+ info_level:: Int = 0 , # info level for print outs
295+ precision:: Int = 32 # precision of the solution set
296+ )
297+ isdefined (I, :rat_param ) ||
298+ _core_msolve (I,
299+ initial_hts = initial_hts,
300+ nr_thrds = nr_thrds,
301+ max_nr_pairs = max_nr_pairs,
302+ la_option = la_option,
303+ info_level = info_level,
304+ precision = precision)
305+ param_t = I. rat_param
306+
307+ nvars = length (param_t. vars)
308+ lpol = filter (l-> degree (l) == 1 , keys (factor (param_t. elim). fac))
309+ nb = length (lpol)
310+
311+ rat_elim = [- coeff (l, 0 )// coeff (l, 1 ) for l in lpol]
312+ rat_den = map (l-> evaluate (param_t. denom, l), rat_elim)
313+ rat_num = map (r-> map (l-> evaluate (l, r), param_t. param), rat_elim)
314+
315+ rat_sols = Vector {Vector{fmpq}} (undef, nb)
316+
317+ if length (param_t. vars) == parent (I). nvars
318+
319+ for i in 1 : nb
320+ rat_sols[i] = Vector {fmpq} (undef, nvars)
321+ for j in 1 : (nvars- 1 )
322+ rat_sols[i][j] = rat_num[i][j] // rat_den[i]
323+ end
324+ rat_sols[i][nvars] = rat_elim[i]
325+ end
326+
327+ else
328+
329+ for i in 1 : nb
330+ rat_sols[i] = Vector {fmpq} (undef, nvars - 1 )
331+ for j in 1 : (nvars- 1 )
332+ rat_sols[i][j] = rat_num[i][j] // rat_den[i]
333+ end
334+ end
335+
336+ end
337+
338+ return rat_sols
339+
340+ end
341+
251342@doc Markdown. doc"""
252343 real_solutions(I::Ideal{T} where T <: MPolyElem, <keyword arguments>)
253344
254345Given an ideal `I` with a finite solution set over the complex numbers, return
255346the real roots of the ideal with a given precision (default 32 bits).
256347
257348**Note**: At the moment only QQ is supported as ground field. If the dimension of the ideal
258- is greater then zero an empty array is returned.
349+ is greater than zero an empty array is returned.
259350
260351# Arguments
261352- `I::Ideal{T} where T <: MPolyElem`: input generators.
0 commit comments