1 | /////////////////////////////////////////////////////////////////////////////// |
---|
2 | version="$Id: solve.lib,v 1.18 2000-12-22 14:48:14 greuel Exp $"; |
---|
3 | category="Symbolic-numerical solving"; |
---|
4 | info=" |
---|
5 | LIBRARY: solve.lib Complex Solving of Polynomial Systems |
---|
6 | AUTHOR: Moritz Wenk, email: wenk@mathematik.uni-kl.de |
---|
7 | |
---|
8 | PROCEDURES: |
---|
9 | ures_solve(i,..); find all roots of 0-dimensional ideal i with resultants |
---|
10 | mp_res_mat(i,..); multipolynomial resultant matrix of ideal i |
---|
11 | laguerre_solve(p,..); find all roots of univariate polynom p |
---|
12 | interpolate(i,j,d); interpolate poly from evaluation points i and results j |
---|
13 | fglm_solve(i,p,...); find roots of 0-dim. ideal using FGLM and lex_solve |
---|
14 | triangL_solve(l,p,...); find roots using triangular system (Lazard) |
---|
15 | triangLf_solve(l,p,..); find roots using triangular sys. (factorizing Lazard) |
---|
16 | triangM_solve(l,p,...); find roots of given triangular system (Moeller) |
---|
17 | lex_solve(i,p,...); find roots of reduced lexicographic standard basis |
---|
18 | triang_solve(l,p,...); find roots of given triangular system |
---|
19 | pcheck(i,l,...); checks if elements (numbers) of l are roots of ideal i |
---|
20 | "; |
---|
21 | |
---|
22 | LIB "triang.lib"; // needed for triang*_solve |
---|
23 | |
---|
24 | /////////////////////////////////////////////////////////////////////////////// |
---|
25 | |
---|
26 | proc ures_solve( ideal gls, list # ) |
---|
27 | "USAGE: ures_solve(i[,k,l,m]); i ideal, k,l,m integers |
---|
28 | k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky |
---|
29 | k=1: use resultant matrix of Macaulay (k=0 is default) |
---|
30 | l>0: defines precision of fractional part if ground field is Q |
---|
31 | m=0,1,2: number of iterations for approximation of roots (default=2) |
---|
32 | ASSUME: i is a zerodimensional ideal with |
---|
33 | nvars(basering) = ncols(i) = number of vars actually occuring in i |
---|
34 | RETURN: list of all (complex) roots of the polynomial system i = 0, |
---|
35 | of type number if the ground field is the complex numbers, |
---|
36 | of type string if the ground field is the rational or real numbers |
---|
37 | EXAMPLE: example ures_solve; shows an example |
---|
38 | " |
---|
39 | { |
---|
40 | int typ=0; |
---|
41 | int polish=2; |
---|
42 | int prec=30; |
---|
43 | |
---|
44 | if ( size(#) >= 1 ) |
---|
45 | { |
---|
46 | typ= #[1]; |
---|
47 | if ( typ < 0 || typ > 1 ) |
---|
48 | { |
---|
49 | ERROR("Valid values for second parameter k are: |
---|
50 | 0: use sparse Resultant (default) |
---|
51 | 1: use Macaulay Resultant"); |
---|
52 | } |
---|
53 | } |
---|
54 | if ( size(#) >= 2 ) |
---|
55 | { |
---|
56 | prec= #[2]; |
---|
57 | if ( prec == 0 ) { prec = 30; } |
---|
58 | if ( prec < 0 ) |
---|
59 | { |
---|
60 | ERROR("Third parameter l must be positive!"); |
---|
61 | } } |
---|
62 | if ( size(#) >= 3 ) |
---|
63 | { |
---|
64 | polish= #[3]; |
---|
65 | if ( polish < 0 || polish > 2 ) |
---|
66 | { |
---|
67 | ERROR("Valid values for fourth parameter m are: |
---|
68 | 0,1,2: number of iterations for approximation of roots"); |
---|
69 | } |
---|
70 | } |
---|
71 | |
---|
72 | if ( size(#) > 3 ) |
---|
73 | { |
---|
74 | ERROR("only three parameters allowed!"); |
---|
75 | } |
---|
76 | |
---|
77 | return(uressolve(gls,typ,prec,polish)); |
---|
78 | |
---|
79 | } |
---|
80 | example |
---|
81 | { |
---|
82 | "EXAMPLE:";echo=2; |
---|
83 | // compute the intersection points of two curves |
---|
84 | ring rsq = 0,(x,y),lp; |
---|
85 | ideal gls= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
86 | ures_solve(gls); |
---|
87 | // result is a list (x,y)-coordinates as strings |
---|
88 | |
---|
89 | // now with complex coefficient field, precision is 20 digits |
---|
90 | ring rsc= (real,20,I),(x,y),lp; |
---|
91 | ideal i = (2+3*I)*x2 + (0.35+I*45.0e-2)*y2 - 8, x2 + xy + (42.7)*y2; |
---|
92 | list l= ures_solve(i); |
---|
93 | // result is a list of (x,y)-coordinates of complex numbers |
---|
94 | l; |
---|
95 | // check the result |
---|
96 | subst(subst(i[1],x,l[1][1]),y,l[1][2]); |
---|
97 | } |
---|
98 | /////////////////////////////////////////////////////////////////////////////// |
---|
99 | |
---|
100 | proc laguerre_solve( poly f, list # ) |
---|
101 | "USAGE: laguerre_solve( p[,l,m]); f poly, l,m integers |
---|
102 | l>0: defines precision of fractional part if ground field is Q |
---|
103 | m=0,1,2: number of iterations for approximation of roots (default=2) |
---|
104 | ASSUME: p is an univariate polynom |
---|
105 | RETURN: list of all (complex) roots of the polynomial p; |
---|
106 | of type number if the ground field is the complex numbers, |
---|
107 | of type string if the ground field is the rational or real numbers |
---|
108 | EXAMPLE: example laguerre_solve; shows an example |
---|
109 | " |
---|
110 | { |
---|
111 | int polish=2; |
---|
112 | int prec=30; |
---|
113 | |
---|
114 | if ( size(#) >= 1 ) |
---|
115 | { |
---|
116 | prec= #[1]; |
---|
117 | if ( prec == 0 ) { prec = 30; } |
---|
118 | if ( prec < 0 ) |
---|
119 | { |
---|
120 | ERROR("Fisrt parameter must be positive!"); |
---|
121 | } |
---|
122 | } |
---|
123 | if ( size(#) >= 2 ) |
---|
124 | { |
---|
125 | polish= #[2]; |
---|
126 | if ( polish < 0 || polish > 2 ) |
---|
127 | { |
---|
128 | ERROR("Valid values for third parameter are: |
---|
129 | 0,1,2: number of iterations for approximation of roots"); |
---|
130 | } |
---|
131 | } |
---|
132 | if ( size(#) > 2 ) |
---|
133 | { |
---|
134 | ERROR("only two parameters allowed!"); |
---|
135 | } |
---|
136 | |
---|
137 | return(laguerre(f,prec,polish)); |
---|
138 | |
---|
139 | } |
---|
140 | example |
---|
141 | { |
---|
142 | "EXAMPLE:";echo=2; |
---|
143 | // Find all roots of an univariate polynomial using Laguerre's method: |
---|
144 | ring rs1= 0,(x,y),lp; |
---|
145 | poly f = 15x5 + x3 + x2 - 10; |
---|
146 | laguerre_solve(f); |
---|
147 | |
---|
148 | // Now with 10 digits precision: |
---|
149 | laguerre_solve(f,10); |
---|
150 | |
---|
151 | // Now with complex coefficients, precision is 20 digits: |
---|
152 | ring rsc= (real,20,I),x,lp; |
---|
153 | poly f = (15.4+I*5)*x^5 + (25.0e-2+I*2)*x^3 + x2 - 10*I; |
---|
154 | list l = laguerre_solve(f); |
---|
155 | l; |
---|
156 | // check result, value of substituted poly should be near to zero |
---|
157 | subst(f,x,l[1]); |
---|
158 | subst(f,x,l[2]); |
---|
159 | } |
---|
160 | /////////////////////////////////////////////////////////////////////////////// |
---|
161 | |
---|
162 | proc mp_res_mat( ideal i, list # ) |
---|
163 | "USAGE: mp_res_mat(i[,k]); i ideal, k integer |
---|
164 | k=0: sparse resultant matrix of Gelfand, Kapranov and Zelevinsky |
---|
165 | k=1: resultant matrix of Macaulay (k=0 is default) |
---|
166 | ASSUME: nvars(basering) = ncols(i)-1 = number of vars actually occuring in i, |
---|
167 | for k=1 i must be homogeneous |
---|
168 | RETURN: module representing the multipolynomial resultant matrix |
---|
169 | EXAMPLE: example mp_res_mat; shows an example |
---|
170 | " |
---|
171 | { |
---|
172 | int typ=2; |
---|
173 | |
---|
174 | if ( size(#) == 1 ) |
---|
175 | { |
---|
176 | typ= #[1]; |
---|
177 | if ( typ < 0 || typ > 1 ) |
---|
178 | { |
---|
179 | ERROR("Valid values for third parameter are: |
---|
180 | 0: sparse resultant (default) |
---|
181 | 1: Macaulay resultant"); |
---|
182 | } |
---|
183 | } |
---|
184 | if ( size(#) > 1 ) |
---|
185 | { |
---|
186 | ERROR("only two parameters allowed!"); |
---|
187 | } |
---|
188 | |
---|
189 | return(mpresmat(i,typ)); |
---|
190 | |
---|
191 | } |
---|
192 | example |
---|
193 | { |
---|
194 | "EXAMPLE:";echo=2; |
---|
195 | // compute resultant matrix in ring with parameters (sparse resultant matrix) |
---|
196 | ring rsq= (0,u0,u1,u2),(x1,x2),lp; |
---|
197 | ideal i= u0+u1*x1+u2*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16; |
---|
198 | module m = mp_res_mat(i); |
---|
199 | print(m); |
---|
200 | // computing sparse resultant |
---|
201 | det(m); |
---|
202 | |
---|
203 | // compute resultant matrix (Macaulay resultant matrix) |
---|
204 | ring rdq= (0,u0,u1,u2),(x0,x1,x2),lp; |
---|
205 | ideal h= homog(imap(rsq,i),x0); |
---|
206 | h; |
---|
207 | |
---|
208 | module m = mp_res_mat(h,1); |
---|
209 | print(m); |
---|
210 | // computing Macaulay resultant (should be the same as above!) |
---|
211 | det(m); |
---|
212 | |
---|
213 | // compute numerical sparse resultant matrix |
---|
214 | setring rsq; |
---|
215 | ideal ir= 15+2*x1+5*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16; |
---|
216 | module mn = mp_res_mat(ir); |
---|
217 | print(mn); |
---|
218 | // computing sparse resultant |
---|
219 | det(mn); |
---|
220 | } |
---|
221 | /////////////////////////////////////////////////////////////////////////////// |
---|
222 | |
---|
223 | proc interpolate( ideal p, ideal w, int d ) |
---|
224 | "USAGE: interpolate(p,v,d); p,v ideals, d int |
---|
225 | ASSUME: ground field K is the rational numbers, |
---|
226 | p and v consist of numbers of the ground filed K, p must have |
---|
227 | n elements, v must have N=(d+1)^n elements where n=nvars(basering) |
---|
228 | and d=deg(f) (f is the unknown polynomial in K[x1,...,xn]) |
---|
229 | COMPUTE: polynomial f with values given by v at points p1,..,pN derived from p; |
---|
230 | more precisely: consider p as point in K^n and v as N elements in K, |
---|
231 | let p1,..,pN be the points in K^n obtained by evaluating all monomials |
---|
232 | of degree 0,1,...,N at p in lexicographical order, |
---|
233 | then the procedure computes the polynomial f satisfying f(pi) = v[i] |
---|
234 | RETURN: polynomial f of degree d |
---|
235 | NOTE: mainly useful for n=1, with f satisfying f(p^(i-1)) = v[i], i=1..d+1 |
---|
236 | EXAMPLE: example interpolate; shows an example |
---|
237 | " |
---|
238 | { |
---|
239 | return(vandermonde(p,w,d)); |
---|
240 | } |
---|
241 | example |
---|
242 | { |
---|
243 | "EXAMPLE:"; echo=2; |
---|
244 | ring r1 = 0,(x),lp; |
---|
245 | // determine f with deg(f) = 4 and |
---|
246 | // v = values of f at points 3^0, 3^1, 3^2, 3^3, 3^4 |
---|
247 | ideal v=16,0,11376,1046880,85949136; |
---|
248 | interpolate( 3, v, 4 ); |
---|
249 | |
---|
250 | ring r2 = 0,(x,y),dp; |
---|
251 | // determine f with deg(f) = 3 and |
---|
252 | // v = values of f at 16 points (2,3)^0=(1,1),...,(2,3)^15=(2^15,3^15) |
---|
253 | // valuation point (2,3) |
---|
254 | ideal p = 2,3; |
---|
255 | ideal v= 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16; |
---|
256 | poly ip= interpolate( p,v,3 ); |
---|
257 | ip; |
---|
258 | // compute poly at point 2,3, result must be 2 |
---|
259 | subst(subst(ip,x,2),y,3); |
---|
260 | // compute poly at point 2^15,3^15, result must be 16 |
---|
261 | subst(subst(ip,x,2^15),y,3^15); |
---|
262 | } |
---|
263 | /////////////////////////////////////////////////////////////////////////////// |
---|
264 | |
---|
265 | static proc psubst( int d, int dd, int n, list res, |
---|
266 | ideal fi, int elem, int nv ) |
---|
267 | { |
---|
268 | // nv: number of ring variables (fixed value) |
---|
269 | // elem: number of elements in ideal fi (fixed value) |
---|
270 | // fi: input ideal (fixed value) |
---|
271 | // rl: output list of roots |
---|
272 | // res: actual list of roots |
---|
273 | // n: |
---|
274 | // dd: actual element of fi |
---|
275 | // d: actual variable |
---|
276 | |
---|
277 | int olddd=dd; |
---|
278 | |
---|
279 | if ( pdebug>=1 ) |
---|
280 | {"// 0 step "+string(dd)+" of "+string(elem);} |
---|
281 | |
---|
282 | if ( dd <= elem ) |
---|
283 | { |
---|
284 | int loop = 1; |
---|
285 | int k; |
---|
286 | list lsr,lh; |
---|
287 | poly ps; |
---|
288 | int thedd; |
---|
289 | |
---|
290 | if ( pdebug>=1 ) |
---|
291 | {"// 1 dd = "+string(dd);} |
---|
292 | |
---|
293 | thedd=0; |
---|
294 | while ( (dd+1 <= elem) && loop ) |
---|
295 | { |
---|
296 | ps= fi[dd+1]; |
---|
297 | |
---|
298 | if ( n-1 > 0 ) |
---|
299 | { |
---|
300 | if ( pdebug>=2 ) |
---|
301 | { |
---|
302 | "// 2 ps=fi["+string(dd+1)+"]"+" size=" |
---|
303 | +string(size(coeffs(ps,var(n-1)))) |
---|
304 | +" leadexp(ps)="+string(leadexp(ps)); |
---|
305 | } |
---|
306 | if ( size(coeffs(ps,var(n-1))) == 1 ) |
---|
307 | { |
---|
308 | dd++; |
---|
309 | // hier Leading-Exponent puefen??? |
---|
310 | // oder ist das Poly immer als letztes in der Liste?!? |
---|
311 | // leadexp(ps) |
---|
312 | } |
---|
313 | else |
---|
314 | { |
---|
315 | loop=0; |
---|
316 | } |
---|
317 | } |
---|
318 | else |
---|
319 | { |
---|
320 | if ( pdebug>=2 ) |
---|
321 | { |
---|
322 | "// 2 ps=fi["+string(dd+1)+"]"+" leadexp(ps)=" |
---|
323 | +string(leadexp(ps)); |
---|
324 | } |
---|
325 | dd++; |
---|
326 | } |
---|
327 | } |
---|
328 | thedd=dd; |
---|
329 | ps= fi[thedd]; |
---|
330 | |
---|
331 | if ( pdebug>=1 ) |
---|
332 | { |
---|
333 | "// 3 fi["+string(thedd-1)+"]"+" leadexp(fi[thedd-1])=" |
---|
334 | +string(leadexp(fi[thedd-1])); |
---|
335 | "// 3 ps=fi["+string(thedd)+"]"+" leadexp(ps)=" |
---|
336 | +string(leadexp(ps)); |
---|
337 | } |
---|
338 | |
---|
339 | for ( k= nv; k > nv-d; k-- ) |
---|
340 | { |
---|
341 | if ( pdebug>=2 ) |
---|
342 | { |
---|
343 | "// 4 subst(fi["+string(thedd)+"]," |
---|
344 | +string(var(k))+","+string(res[k])+");"; |
---|
345 | } |
---|
346 | ps = subst(ps,var(k),res[k]); |
---|
347 | } |
---|
348 | |
---|
349 | if ( pdebug>=2 ) |
---|
350 | { "// 5 substituted ps="+string(ps); } |
---|
351 | |
---|
352 | if ( ps != 0 ) |
---|
353 | { |
---|
354 | lsr= laguerre_solve( ps ); |
---|
355 | } |
---|
356 | else |
---|
357 | { |
---|
358 | if ( pdebug>=1 ) |
---|
359 | { "// 30 ps == 0, thats not cool..."; } |
---|
360 | lsr=@ln; // lsr=number(0); |
---|
361 | } |
---|
362 | |
---|
363 | if ( pdebug>=1 ) |
---|
364 | { "// 6 laguerre_solve found roots: lsr["+string(size(lsr))+"]"; } |
---|
365 | |
---|
366 | if ( size(lsr) > 1 ) |
---|
367 | { |
---|
368 | if ( pdebug>=1 ) |
---|
369 | { |
---|
370 | "// 10 checking roots found before, range " |
---|
371 | +string(dd-olddd)+" -- "+string(dd); |
---|
372 | "// 10 thedd = "+string(thedd); |
---|
373 | } |
---|
374 | |
---|
375 | int i,j,l; |
---|
376 | int ls=size(lsr); |
---|
377 | int lss; |
---|
378 | poly pss; |
---|
379 | list nares; |
---|
380 | int rroot; |
---|
381 | int nares_size; |
---|
382 | |
---|
383 | |
---|
384 | for ( i = 1; i <= ls; i++ ) // lsr[1..ls] |
---|
385 | { |
---|
386 | rroot=1; |
---|
387 | |
---|
388 | if ( pdebug>=2 ) |
---|
389 | {"// 13 root lsr["+string(i)+"] = "+string(lsr[i]);} |
---|
390 | for ( l = 0; l <= dd-olddd; l++ ) |
---|
391 | { |
---|
392 | if ( l+olddd != thedd ) |
---|
393 | { |
---|
394 | if ( pdebug>=2 ) |
---|
395 | {"// 11 checking ideal element "+string(l+olddd);} |
---|
396 | ps=fi[l+olddd]; |
---|
397 | if ( pdebug>=3 ) |
---|
398 | {"// 14 ps=fi["+string(l+olddd)+"]";} |
---|
399 | for ( k= nv; k > nv-d; k-- ) |
---|
400 | { |
---|
401 | if ( pdebug>=3 ) |
---|
402 | { |
---|
403 | "// 11 subst(fi["+string(olddd+l)+"]," |
---|
404 | +string(var(k))+","+string(res[k])+");"; |
---|
405 | } |
---|
406 | ps = subst(ps,var(k),res[k]); |
---|
407 | |
---|
408 | } |
---|
409 | |
---|
410 | pss=subst(ps,var(k),lsr[i]); // k=nv-d |
---|
411 | if ( pdebug>=3 ) |
---|
412 | { "// 15 0 == "+string(pss); } |
---|
413 | if ( pss != 0 ) |
---|
414 | { |
---|
415 | if ( system("complexNearZero", |
---|
416 | leadcoef(pss), |
---|
417 | myCompDigits) ) |
---|
418 | { |
---|
419 | if ( pdebug>=2 ) |
---|
420 | { "// 16 root "+string(i)+" is a real root"; } |
---|
421 | } |
---|
422 | else |
---|
423 | { |
---|
424 | if ( pdebug>=2 ) |
---|
425 | { "// 17 0 == "+string(pss); } |
---|
426 | rroot=0; |
---|
427 | } |
---|
428 | } |
---|
429 | |
---|
430 | } |
---|
431 | } |
---|
432 | |
---|
433 | if ( rroot == 1 ) // add root to list ? |
---|
434 | { |
---|
435 | if ( size(nares) > 0 ) |
---|
436 | { |
---|
437 | nares=nares[1..size(nares)],lsr[i]; |
---|
438 | } |
---|
439 | else |
---|
440 | { |
---|
441 | nares=lsr[i]; |
---|
442 | } |
---|
443 | if ( pdebug>=2 ) |
---|
444 | { "// 18 added root to list nares"; } |
---|
445 | } |
---|
446 | } |
---|
447 | |
---|
448 | nares_size=size(nares); |
---|
449 | if ( nares_size == 0 ) |
---|
450 | { |
---|
451 | "Numerical problem: No root found..."; |
---|
452 | "Output may be incorrect!"; |
---|
453 | nares=@ln; |
---|
454 | } |
---|
455 | |
---|
456 | if ( pdebug>=1 ) |
---|
457 | { "// 20 found <"+string(size(nares))+"> roots"; } |
---|
458 | |
---|
459 | for ( i= 1; i <= nares_size; i++ ) |
---|
460 | { |
---|
461 | res[nv-d]= nares[i]; |
---|
462 | |
---|
463 | if ( dd < elem ) |
---|
464 | { |
---|
465 | if ( i > 1 ) |
---|
466 | { |
---|
467 | rn@++; |
---|
468 | } |
---|
469 | psubst( d+1, dd+1, n-1, res, fi, elem, nv ); |
---|
470 | } |
---|
471 | else |
---|
472 | { |
---|
473 | if ( pdebug>=1 ) |
---|
474 | {"// 30_1 <"+string(rn@)+"> "+string(size(res))+" <-----";} |
---|
475 | if ( pdebug>=2 ) |
---|
476 | { res; } |
---|
477 | rlist[rn@]=res; |
---|
478 | } |
---|
479 | } |
---|
480 | } |
---|
481 | else |
---|
482 | { |
---|
483 | if ( pdebug>=2 ) |
---|
484 | { "// 21 found root to be: "+string(lsr[1]); } |
---|
485 | res[nv-d]= lsr[1]; |
---|
486 | |
---|
487 | if ( dd < elem ) |
---|
488 | { |
---|
489 | psubst( d+1, dd+1, n-1, res, fi, elem, nv ); |
---|
490 | } |
---|
491 | else |
---|
492 | { |
---|
493 | if ( pdebug>=1 ) |
---|
494 | { "// 30_2 <"+string(rn@)+"> "+string(size(res))+" <-----";} |
---|
495 | if ( pdebug>=2 ) |
---|
496 | { res; } |
---|
497 | rlist[rn@]=res; |
---|
498 | } |
---|
499 | } |
---|
500 | } |
---|
501 | } |
---|
502 | |
---|
503 | /////////////////////////////////////////////////////////////////////////////// |
---|
504 | |
---|
505 | proc fglm_solve( ideal fi, list # ) |
---|
506 | "USAGE: fglm_solve( i [, d ] ); i ideal, p integer. |
---|
507 | p gives precision of complex numbers in digits, |
---|
508 | uses a standard basis computed from fi to determine |
---|
509 | recursively all complex roots of fi |
---|
510 | RETURN: a list of complex roots of type number. |
---|
511 | NOTE: changes the given ring to the ring ring with complex coefficient |
---|
512 | field with precision p in digits. |
---|
513 | EXAMPLE: example fglm_solve; shows an example |
---|
514 | " |
---|
515 | { |
---|
516 | int prec=30; |
---|
517 | |
---|
518 | if ( size(#)>=1 && typeof(#[1])=="int") |
---|
519 | { |
---|
520 | prec=#[1]; |
---|
521 | } |
---|
522 | |
---|
523 | lex_solve(stdfglm(fi),prec); |
---|
524 | keepring basering; |
---|
525 | } |
---|
526 | example |
---|
527 | { |
---|
528 | "EXAMPLE:";echo=2; |
---|
529 | ring r = 0,(x,y),lp; |
---|
530 | // compute the intersection points of two curves |
---|
531 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
532 | fglm_solve(s); |
---|
533 | rlist; |
---|
534 | } |
---|
535 | |
---|
536 | /////////////////////////////////////////////////////////////////////////////// |
---|
537 | |
---|
538 | proc lex_solve( ideal fi, int prec, list # ) |
---|
539 | "USAGE: lex_solve( i, d [, l] ); i ideal, p,d,l integers. |
---|
540 | i a reduced lexicographical Groebner bases of a zero-dimensional |
---|
541 | ideal (i), sorted by increasing leading terms. |
---|
542 | p gives precision of complex numbers in digits, |
---|
543 | d gives precision (1<d<p) for near-zero-determination (default:1/2*p), |
---|
544 | l gives debug level (-1: no output,..., 3: lots of output, 0: default) |
---|
545 | RETURN: a list of complex roots of type number. |
---|
546 | NOTE: changes the given ring to the ring ring with complex coefficient |
---|
547 | field with precision p in digits. |
---|
548 | EXAMPLE: example lex_solve; shows an example |
---|
549 | " |
---|
550 | { |
---|
551 | if ( !defined(pdebug) ) |
---|
552 | { |
---|
553 | int pdebug; |
---|
554 | export pdebug; |
---|
555 | } |
---|
556 | pdebug=0; |
---|
557 | |
---|
558 | string orings= nameof(basering); |
---|
559 | def oring= basering; |
---|
560 | |
---|
561 | // change the ground field to complex numbers |
---|
562 | string nrings= "ring "+orings+"C=(real,"+string(prec) |
---|
563 | +",I),("+varstr(basering)+"),lp;"; |
---|
564 | execute(nrings); |
---|
565 | |
---|
566 | if ( pdebug>=0 ) |
---|
567 | { "// name of new ring: "+string(nameof(basering));} |
---|
568 | |
---|
569 | // map fi from old to new ring |
---|
570 | ideal fi= imap(oring,fi); |
---|
571 | |
---|
572 | // list with entry 0 (number) |
---|
573 | number nn=0; |
---|
574 | if ( !defined(@ln) ) |
---|
575 | { |
---|
576 | list @ln; |
---|
577 | export @ln; |
---|
578 | } |
---|
579 | @ln=nn; |
---|
580 | |
---|
581 | // set number of digits for zero-comparison of roots |
---|
582 | if ( !defined(myCompDigits) ) |
---|
583 | { |
---|
584 | int myCompDigits; |
---|
585 | export myCompDigits; |
---|
586 | } |
---|
587 | if ( size(#)>=1 && typeof(#[1])=="int") |
---|
588 | { |
---|
589 | myCompDigits=#[1]; |
---|
590 | } |
---|
591 | else |
---|
592 | { |
---|
593 | myCompDigits=(system("getPrecDigits")/2); |
---|
594 | } |
---|
595 | |
---|
596 | if ( pdebug>=1 ) |
---|
597 | {"// myCompDigits="+string(myCompDigits);} |
---|
598 | |
---|
599 | int idelem= size(fi); |
---|
600 | int nv= nvars(basering); |
---|
601 | int i,j,k,lis; |
---|
602 | list res,li; |
---|
603 | |
---|
604 | if ( !defined(rlist) ) |
---|
605 | { |
---|
606 | list rlist; |
---|
607 | export rlist; |
---|
608 | } |
---|
609 | |
---|
610 | if ( !defined(rn@) ) |
---|
611 | { |
---|
612 | int rn@; |
---|
613 | export rn@; |
---|
614 | } |
---|
615 | rn@=0; |
---|
616 | |
---|
617 | li= laguerre_solve(fi[1]); |
---|
618 | lis= size(li); |
---|
619 | |
---|
620 | if ( pdebug>=1 ) |
---|
621 | {"// laguerre found roots: "+string(size(li));} |
---|
622 | |
---|
623 | for ( j= 1; j <= lis; j++ ) |
---|
624 | { |
---|
625 | if ( pdebug>=1 ) |
---|
626 | {"// root "+string(j);} |
---|
627 | rn@++; |
---|
628 | res[nv]= li[j]; |
---|
629 | psubst( 1, 2, nv-1, res, fi, idelem, nv ); |
---|
630 | } |
---|
631 | |
---|
632 | if ( pdebug>=0 ) |
---|
633 | {"// list of roots: "+nameof(rlist);} |
---|
634 | |
---|
635 | // keep the ring and exit |
---|
636 | keepring basering; |
---|
637 | } |
---|
638 | example |
---|
639 | { |
---|
640 | "EXAMPLE:";echo=2; |
---|
641 | ring r = 0,(x,y),lp; |
---|
642 | // compute the intersection points of two curves |
---|
643 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
644 | lex_solve(stdfglm(s),30); |
---|
645 | rlist; |
---|
646 | } |
---|
647 | |
---|
648 | /////////////////////////////////////////////////////////////////////////////// |
---|
649 | |
---|
650 | proc triangLf_solve( ideal fi, list # ) |
---|
651 | "USAGE: triangLf_solve( i [, d ] ); i ideal, p integer. |
---|
652 | i zero-dimensional ideal |
---|
653 | p gives precision of complex numbers in digits, |
---|
654 | uses a triangular system (Lazard's Algorithm with factorization) |
---|
655 | computed from a standard basis to determine recursively all complex |
---|
656 | roots with Laguerre's algorithm of input ideal i |
---|
657 | RETURN: a list of complex roots of type number. |
---|
658 | NOTE: changes the given ring to the ring ring with complex coefficient |
---|
659 | field with precision p in digits. |
---|
660 | EXAMPLE: example triangLf_solve; shows an example |
---|
661 | " |
---|
662 | { |
---|
663 | int prec=30; |
---|
664 | |
---|
665 | if ( size(#)>=1 && typeof(#[1])=="int") |
---|
666 | { |
---|
667 | prec=#[1]; |
---|
668 | } |
---|
669 | |
---|
670 | triang_solve(triangLfak(stdfglm(fi)),prec); |
---|
671 | keepring basering; |
---|
672 | } |
---|
673 | example |
---|
674 | { |
---|
675 | "EXAMPLE:";echo=2; |
---|
676 | ring r = 0,(x,y),lp; |
---|
677 | // compute the intersection points of two curves |
---|
678 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
679 | triangLf_solve(s); |
---|
680 | rlist; |
---|
681 | } |
---|
682 | |
---|
683 | /////////////////////////////////////////////////////////////////////////////// |
---|
684 | |
---|
685 | proc triangM_solve( ideal fi, list # ) |
---|
686 | "USAGE: triangM_solve( i [, d ] ); i ideal, p integer. |
---|
687 | i zero-dimensional ideal |
---|
688 | p gives precision of complex numbers in digits, |
---|
689 | uses a triangular system (Moellers Algorithm) computed from a standard |
---|
690 | basis to determine recursively all complex roots with Laguerre's |
---|
691 | algorithm of input ideal i |
---|
692 | RETURN: a list of complex roots of type number. |
---|
693 | NOTE: changes the given ring to the ring ring with complex coefficient |
---|
694 | field with precision p in digits. |
---|
695 | EXAMPLE: example triangM_solve; shows an example |
---|
696 | " |
---|
697 | { |
---|
698 | int prec=30; |
---|
699 | |
---|
700 | if ( size(#)>=1 && typeof(#[1])=="int") |
---|
701 | { |
---|
702 | prec=#[1]; |
---|
703 | } |
---|
704 | |
---|
705 | triang_solve(triangM(stdfglm(fi)),prec); |
---|
706 | keepring basering; |
---|
707 | } |
---|
708 | example |
---|
709 | { |
---|
710 | "EXAMPLE:";echo=2; |
---|
711 | ring r = 0,(x,y),lp; |
---|
712 | // compute the intersection points of two curves |
---|
713 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
714 | triangM_solve(s); |
---|
715 | rlist; |
---|
716 | } |
---|
717 | |
---|
718 | /////////////////////////////////////////////////////////////////////////////// |
---|
719 | |
---|
720 | proc triangL_solve( ideal fi, list # ) |
---|
721 | "USAGE: triangL_solve( i [, d ] ); i ideal, p integer. |
---|
722 | i zero-dimensional ideal |
---|
723 | p gives precision of complex numbers in digits, |
---|
724 | uses a triangular system (Lazard's Algorithm) |
---|
725 | computed from a standard basis to determine recursively all complex |
---|
726 | roots with Laguerre's algorithm of input ideal i |
---|
727 | RETURN: a list of complex roots of type number. |
---|
728 | NOTE: changes the given ring to the ring ring with complex coefficient |
---|
729 | field with precision p in digits. |
---|
730 | EXAMPLE: example triangL_solve; shows an example |
---|
731 | " |
---|
732 | { |
---|
733 | int prec=30; |
---|
734 | |
---|
735 | if ( size(#)>=1 && typeof(#[1])=="int") |
---|
736 | { |
---|
737 | prec=#[1]; |
---|
738 | } |
---|
739 | |
---|
740 | triang_solve(triangL(stdfglm(fi)),prec); |
---|
741 | keepring basering; |
---|
742 | } |
---|
743 | example |
---|
744 | { |
---|
745 | "EXAMPLE:";echo=2; |
---|
746 | ring r = 0,(x,y),lp; |
---|
747 | // compute the intersection points of two curves |
---|
748 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
749 | triangL_solve(s); |
---|
750 | rlist; |
---|
751 | } |
---|
752 | |
---|
753 | |
---|
754 | /////////////////////////////////////////////////////////////////////////////// |
---|
755 | |
---|
756 | proc triang_solve( list lfi, int prec, list # ) |
---|
757 | "USAGE: triang_solve( i, d [, l] ); l list, p,d,l integers. |
---|
758 | l a list of finitely many triangular systems, such that |
---|
759 | the union of their varieties equals the variety of the |
---|
760 | initial ideal. |
---|
761 | p gives precision of complex numbers in digits, |
---|
762 | d gives precision (1<d<p) for near-zero-determination (default:1/2*p), |
---|
763 | l gives debug level (-1: no output,..., 3: lots of output, 0: default) |
---|
764 | ASSUME: l was computed using Algorithm of Lazard or |
---|
765 | Algorithm of Moeller (see triang.lib). |
---|
766 | RETURN: a list of complex roots of type number. |
---|
767 | NOTE: changes the given ring to the ring ring with complex coefficient |
---|
768 | field with precision p in digits. |
---|
769 | EXAMPLE: example triang_solve; shows an example |
---|
770 | " |
---|
771 | { |
---|
772 | if ( !defined(pdebug) ) |
---|
773 | { |
---|
774 | int pdebug; |
---|
775 | export pdebug; |
---|
776 | } |
---|
777 | pdebug=0; |
---|
778 | |
---|
779 | string orings= nameof(basering); |
---|
780 | def oring= basering; |
---|
781 | |
---|
782 | // change the ground field to complex numbers |
---|
783 | string nrings= "ring "+orings+"C=(real,"+string(prec) |
---|
784 | +",I),("+varstr(basering)+"),lp;"; |
---|
785 | execute(nrings); |
---|
786 | |
---|
787 | if ( pdebug>=0 ) |
---|
788 | { "// name of new ring: "+string(nameof(basering));} |
---|
789 | |
---|
790 | // list with entry 0 (number) |
---|
791 | number nn=0; |
---|
792 | if ( !defined(@ln) ) |
---|
793 | { |
---|
794 | list @ln; |
---|
795 | export @ln; |
---|
796 | } |
---|
797 | @ln=nn; |
---|
798 | |
---|
799 | // set number of digits for zero-comparison of roots |
---|
800 | if ( !defined(myCompDigits) ) |
---|
801 | { |
---|
802 | int myCompDigits; |
---|
803 | export myCompDigits; |
---|
804 | } |
---|
805 | if ( size(#)>=1 && typeof(#[1])=="int" ) |
---|
806 | { |
---|
807 | myCompDigits=#[1]; |
---|
808 | } |
---|
809 | else |
---|
810 | { |
---|
811 | myCompDigits=(system("getPrecDigits")/2); |
---|
812 | } |
---|
813 | |
---|
814 | if ( pdebug>=1 ) |
---|
815 | {"// myCompDigits="+string(myCompDigits);} |
---|
816 | |
---|
817 | int idelem; |
---|
818 | int nv= nvars(basering); |
---|
819 | int i,j,k,lis; |
---|
820 | list res,li; |
---|
821 | |
---|
822 | if ( !defined(rlist) ) |
---|
823 | { |
---|
824 | list rlist; |
---|
825 | export rlist; |
---|
826 | } |
---|
827 | |
---|
828 | if ( !defined(rn@) ) |
---|
829 | { |
---|
830 | int rn@; |
---|
831 | export rn@; |
---|
832 | } |
---|
833 | rn@=0; |
---|
834 | |
---|
835 | // map the list |
---|
836 | list lfi= imap(oring,lfi); |
---|
837 | |
---|
838 | int slfi= size(lfi); |
---|
839 | ideal fi; |
---|
840 | |
---|
841 | for ( i= 1; i <= slfi; i++ ) |
---|
842 | { |
---|
843 | // map fi from old to new ring |
---|
844 | fi= lfi[i]; //imap(oring,lfi[i]); |
---|
845 | |
---|
846 | idelem= size(fi); |
---|
847 | |
---|
848 | // solve fi[1] |
---|
849 | li= laguerre_solve(fi[1],myCompDigits,2); |
---|
850 | lis= size(li); |
---|
851 | |
---|
852 | if ( pdebug>=1 ) |
---|
853 | {"// laguerre found roots: "+string(size(li));} |
---|
854 | |
---|
855 | for ( j= 1; j <= lis; j++ ) |
---|
856 | { |
---|
857 | if ( pdebug>=1 ) |
---|
858 | {"// root "+string(j);} |
---|
859 | rn@++; |
---|
860 | res[nv]= li[j]; |
---|
861 | psubst( 1, 2, nv-1, res, fi, idelem, nv ); |
---|
862 | } |
---|
863 | } |
---|
864 | |
---|
865 | if ( pdebug>=0 ) |
---|
866 | {"// list of roots: "+nameof(rlist);} |
---|
867 | |
---|
868 | // keep the ring and exit |
---|
869 | keepring basering; |
---|
870 | } |
---|
871 | example |
---|
872 | { |
---|
873 | "EXAMPLE:";echo=2; |
---|
874 | ring r = 0,(x,y),lp; |
---|
875 | // compute the intersection points of two curves |
---|
876 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
877 | triang_solve(triangLfak(stdfglm(s)),30); |
---|
878 | rlist; |
---|
879 | } |
---|
880 | |
---|
881 | /////////////////////////////////////////////////////////////////////////////// |
---|
882 | |
---|
883 | proc pcheck( ideal fi, list sols, list # ) |
---|
884 | "USAGE: pcheck( i, l [, n] ); i ideal, l list, n integer |
---|
885 | i system of equations, l list of numers assumend |
---|
886 | to be roots of i. |
---|
887 | RETURN: 1 iff all elements of l are roots of i, else 0 |
---|
888 | EXAMPLE: example pcheck; shows an example |
---|
889 | " |
---|
890 | { |
---|
891 | int i,j,k,nnrfound; |
---|
892 | int ss= size(sols); |
---|
893 | int nv= nvars(basering); |
---|
894 | poly ps; |
---|
895 | number nn; |
---|
896 | int cprec=0; |
---|
897 | |
---|
898 | if ( size(#)>=1 && typeof(#[1])=="int" ) |
---|
899 | { |
---|
900 | cprec=#[1]; |
---|
901 | } |
---|
902 | if ( cprec <= 0 ) |
---|
903 | { |
---|
904 | cprec=system("getPrecDigits")/2; |
---|
905 | } |
---|
906 | |
---|
907 | nnrfound=1; |
---|
908 | for ( j= 1; j <= size(fi); j++ ) |
---|
909 | { |
---|
910 | for ( i= 1; i <= ss; i++ ) |
---|
911 | { |
---|
912 | ps= fi[j]; |
---|
913 | for ( k= 1; k <= nv; k++ ) |
---|
914 | { |
---|
915 | ps = subst(ps,var(k),sols[i][k]); |
---|
916 | } |
---|
917 | //ps; |
---|
918 | nn= leadcoef(ps); |
---|
919 | if ( nn != 0 ) |
---|
920 | { |
---|
921 | if ( !system("complexNearZero",nn,cprec) ) |
---|
922 | { |
---|
923 | " no root: ideal["+string(j)+"]( root " |
---|
924 | +string(i)+"): 0 != "+string(ps); |
---|
925 | nnrfound=0; |
---|
926 | } |
---|
927 | } |
---|
928 | } |
---|
929 | } |
---|
930 | return(nnrfound); |
---|
931 | } |
---|
932 | example |
---|
933 | { |
---|
934 | "EXAMPLE:";echo=2; |
---|
935 | ring r = 0,(x,y),lp; |
---|
936 | // compute the intersection points of two curves |
---|
937 | ideal s= x2 + y2 - 10, x2 + xy + 2y2 - 16; |
---|
938 | lex_solve(stdfglm(s),30); |
---|
939 | rlist; |
---|
940 | pcheck(rlist); |
---|
941 | } |
---|
942 | |
---|
943 | /////////////////////////////////////////////////////////////////////////////// |
---|
944 | |
---|
945 | proc simplexOut(list l) |
---|
946 | "USAGE: simpelxOut(l); l list |
---|
947 | ASSUME: |
---|
948 | RETURN: |
---|
949 | EXAMPLE: example simplexOut; shows an example |
---|
950 | " |
---|
951 | { |
---|
952 | int i,j; |
---|
953 | matrix m= l[1]; |
---|
954 | intvec iposv= l[3]; |
---|
955 | int icase= l[2]; |
---|
956 | |
---|
957 | int cols= ncols(m); |
---|
958 | int rows= nrows(m); |
---|
959 | |
---|
960 | int N= l[6]; |
---|
961 | |
---|
962 | if ( -1 == icase ) // objective function is unbound |
---|
963 | { |
---|
964 | "objective function is unbound"; |
---|
965 | return; |
---|
966 | } |
---|
967 | if ( 1 == icase ) // no solution satisfies the given constraints |
---|
968 | { |
---|
969 | "no solution satisfies the given constraints"; |
---|
970 | return; |
---|
971 | } |
---|
972 | if ( -2 == icase ) // other error |
---|
973 | { |
---|
974 | "an error occurred during simplex computation!"; |
---|
975 | return; |
---|
976 | } |
---|
977 | |
---|
978 | for ( i = 1; i <= rows; i++ ) |
---|
979 | { |
---|
980 | if (i == 1) |
---|
981 | { |
---|
982 | "z = "+string(m[1][1]); |
---|
983 | } |
---|
984 | else |
---|
985 | { |
---|
986 | if ( iposv[i-1] <= N+1 ) |
---|
987 | { |
---|
988 | "x"+string(i-1)+" = "+string(m[1][iposv[i-1]]); |
---|
989 | } |
---|
990 | // else |
---|
991 | // { |
---|
992 | // "Y"; iposv[i-1]-N+1; |
---|
993 | // } |
---|
994 | } |
---|
995 | } |
---|
996 | } |
---|
997 | example |
---|
998 | { |
---|
999 | "EXAMPLE:";echo=2; |
---|
1000 | ring r = (real,10),(x),lp; |
---|
1001 | |
---|
1002 | // suppose we have the |
---|
1003 | |
---|
1004 | matrix sm[5][5]=( 0, 1, 1, 3,-0.5, |
---|
1005 | 740,-1, 0,-2, 0, |
---|
1006 | 0, 0,-2, 0, 7, |
---|
1007 | 0.5, 0,-1, 1,-2, |
---|
1008 | 9,-1,-1,-1,-1); |
---|
1009 | |
---|
1010 | // simplex input: |
---|
1011 | // 1: matrix |
---|
1012 | // 2: number of variables |
---|
1013 | // 3: total number of constraints (#4+#5+#6) |
---|
1014 | // 4: number of <= constraints |
---|
1015 | // 5: number of >= constraints |
---|
1016 | // 6: number of == constraints |
---|
1017 | |
---|
1018 | list sol= simplex(sm, 4, 4, 2, 1, 1); |
---|
1019 | simplexOut(sol); |
---|
1020 | } |
---|
1021 | |
---|
1022 | /////////////////////////////////////////////////////////////////////////////// |
---|
1023 | |
---|
1024 | // local Variables: *** |
---|
1025 | // c-set-style: bsd *** |
---|
1026 | // End: *** |
---|