source: git/Singular/LIB/solve.lib @ 0ba413

spielwiese
Last change on this file since 0ba413 was 0ba413, checked in by Wilfred Pohl <pohl@…>, 22 years ago
better comments and precision git-svn-id: file:///usr/local/Singular/svn/trunk@5698 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 37.3 KB
Line 
1//last change: 13.02.2001 (Eric Westenberger)
2///////////////////////////////////////////////////////////////////////////////
3version="$Id: solve.lib,v 1.24 2001-12-11 09:42:15 pohl Exp $";
4category="Symbolic-numerical solving";
5info="
6LIBRARY: solve.lib     Complex Solving of Polynomial Systems
7AUTHOR:  Moritz Wenk,  email: wenk@mathematik.uni-kl.de
8
9PROCEDURES:
10ures_solve(i,[..]);     find all roots of 0-dimensional ideal i with resultants
11laguerre_solve(p,[..]); find all roots of univariate polynomial p
12mp_res_mat(i,[..]);     multipolynomial resultant matrix of ideal i
13interpolate(p,v,d);     interpolate poly from evaluation points i and results j
14fglm_solve(i,[..]);     find roots of 0-dim. ideal using FGLM and lex_solve
15lex_solve(i,p,[..]);    find roots of reduced lexicographic standard basis
16triangLf_solve(l,[..]); find roots using triangular sys. (factorizing Lazard)
17triangM_solve(l,[..]);  find roots of given triangular system (Moeller)
18triangL_solve(l,[..]);  find roots using triangular system (Lazard)
19triang_solve(l,p,[..]); find roots of given triangular system
20pcheck(i,l,[..]);       checks if elements (numbers) of l are roots of ideal i";
21
22LIB "triang.lib";    // needed for triang_solve
23
24///////////////////////////////////////////////////////////////////////////////
25
26proc ures_solve( ideal gls, list # )
27"USAGE:   ures_solve(i [, k, p] ); i = ideal, k, p = integers
28 @format
29         k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,
30         k=1: use resultant matrix of Macaulay which works only for
31              homogeneous ideals,
32         p>0: defines precision of the long floats for internal computation
33              if the basering is not complex (in decimal digits),
34              (default: k, p = 0, 30)
35 @end format
36ASSUME:  i is a zerodimensional ideal with
37         nvars(basering) = ncols(i) = number of vars
38         actually occuring in i,
39RETURN:  list of all (complex) roots of the polynomial system i = 0,
40 @format
41         the result is
42         of type string: if the basering is not complex,
43         of type number: otherwise.
44 @end format
45EXAMPLE: example ures_solve; shows an example
46"
47{
48    int typ=0;// defaults
49    int prec=30;
50
51    if ( size(#) > 0 )
52    {
53        typ= #[1];
54        if ( typ < 0 || typ > 1 )
55        {
56            ERROR("Valid values for second parameter k are:
57                   0: use sparse Resultant (default)
58                   1: use Macaulay Resultant");
59        }
60    }
61    if ( size(#) > 1 )
62    {
63        prec= #[2];
64        if ( prec < 8 )
65        {
66            prec = 8;
67        }
68    }
69
70    return(uressolve(gls,typ,prec,1));
71    // the last nonzero parameter gives an extra run of
72    // Laguerre's algorithm leading to better results
73}
74example
75{
76    "EXAMPLE:";echo=2;
77    // compute the intersection points of two curves
78    ring rsq = 0,(x,y),lp;
79    ideal gls=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
80    ures_solve(gls,0,16);
81    // result is a list (x,y)-coordinates as strings
82
83    // now with complex coefficient field, precision is 20 digits
84    ring rsc= (real,20,I),(x,y),lp;
85    ideal i = (2+3*I)*x2 + (0.35+I*45.0e-2)*y2 - 8, x2 + xy + (42.7)*y2;
86    list l= ures_solve(i,0,10);
87    // result is a list of (x,y)-coordinates of complex numbers
88    l;
89    // check the result
90    subst(subst(i[1],x,l[1][1]),y,l[1][2]);
91}
92///////////////////////////////////////////////////////////////////////////////
93
94proc laguerre_solve( poly f, list # )
95"USAGE:   laguerre_solve(f [, l, m, n, s] ); f = polynomial,@*
96         l, m, n, s = integers (control parameters of the method)
97 @format
98         l: precision of internal computation in decimal digits ( l >=8 )
99            only if the basering is not complex or complex with smaller
100            precision,
101         m: precision of output in digits ( 4 <= m <= l ), if basering is not
102            the ring of complex numbers;
103            (if s != 0, m defines also the precision of the residual error
104            i.e. | f(root) | should be <= 0.1^m ).
105         n: control of multiplicity of roots or of splitting of f into
106            squarefree factors
107            n < 0, no split of f (good, if all roots are simple)
108            n >= 0, try to split
109            n = 0, return only different roots
110            n > 0, find all roots (with multiplicity)
111         s: s != 0, returns ERROR if  | f(root) | > 0.1^m
112         ( default: l, m, n, s = 30, 10, 1, 0 )
113 @end format
114ASSUME:  f is an univariate polynomial
115RETURN:  list of (complex) roots of the polynomial f, depending on n.
116 @format
117         The result is
118         of type string: if the basering is not complex,
119         of type number: otherwise.
120 @end format
121NOTE:    If printlevel >0: displays comments ( default = 0 ).
122         If s != 0 and if the procrdure stops with ERROR, try a higher
123         internal precision m.
124EXAMPLE: example laguerre_solve; shows an example
125"
126{
127  int OLD_COMPLEX=0;
128  int iv=checkv(f);
129  if(iv==0){ERROR("Wrong polynomial!");}
130  poly v=var(iv);
131
132  int numberprec=30;// set the control
133  int solutionprec=10;
134  int splitcontrol=1;
135  int rootcheck=0;
136  if(size(#)>0){numberprec=#[1];
137    if(numberprec<8){numberprec=8;}}
138  if(size(#)>1){solutionprec=#[2];
139    if(solutionprec<4){solutionprec=4;}
140    if(solutionprec>numberprec){solutionprec=numberprec;}}
141  if(size(#)>2){splitcontrol=#[3];}
142  if(size(#)>3){rootcheck=#[4];}
143  int prot=printlevel-voice+2;
144  int ringprec=0;
145
146  poly p=divzero(f,iv);// divide out zeros as solution
147  int iz=deg(f)-deg(p);
148  if(prot!=0)
149  {
150    string pout;
151    string nl=newline;
152    pout="//BEGIN laguerre_solve";
153    if(iz!=0){pout=pout+nl+"//zeros: divide out "+string(iz);}
154    dbprint(prot,pout);
155  }
156  string ss,tt,oo;
157  ss="";oo=ss;
158  if(npars(basering)==1)
159  {
160    if(OLD_COMPLEX)
161    {
162      tt="1,"+string(par(1));
163      if(tt==charstr(basering))
164      {ss=tt;ringprec=system("getPrecDigits");}
165    }
166    else
167    {
168      tt=charstr(basering);
169      if(size(tt)>7)
170      {
171        if(tt[1..7]=="complex")
172        {
173          ss=tt;
174          ringprec=system("getPrecDigits");
175        }
176      }
177    }
178  }
179
180  list roots,simple;
181  if(deg(p)==0)// only zeros
182  {
183    roots=addzero(roots,ss,iz,splitcontrol);
184    if(prot!=0){dbprint(prot,"//END laguerre_solve");}
185    return(roots);
186  }
187
188  if(prot!=0)// more informations
189  {
190    pout="//control: complex ring with precision "+string(numberprec);
191    if(size(ss)==0){pout=pout+nl+
192        "//         basering not complex, hence solutiontype string";
193    if(solutionprec<numberprec){pout=pout+nl+
194        "//         with precision "+string(solutionprec);}}
195    if(splitcontrol<0){pout=pout+nl+ "//       no spliting";}
196    if(splitcontrol==0){pout=pout+nl+"//       output without multiple roots";}
197    if(rootcheck){pout=pout+nl+
198        "//         check roots with precision "+string(solutionprec);}
199    dbprint(prot,pout);
200  }
201
202  def rn = basering;// set the complex groundfield
203  if (ringprec<numberprec)
204  {
205    tt="ring lagc=(complex,"+string(numberprec)+","+string(numberprec)+
206       "),"+string(var(iv))+",lp;";
207    execute(tt);
208    poly p=imap(rn,p);
209    poly v=var(1);
210  }
211  int ima=0;
212  if(size(ss)!=0){ima=checkim(p);}
213  number prc=0.1;// set precision of the solution
214  prc=prc^solutionprec;
215  if(prot!=0)
216  {
217    if(ringprec<numberprec){pout="//working in:  "+tt;}
218    if((size(ss)!=0)&&(ima!=0)){pout=pout+nl+
219        "//         polynomial has complex coefficients";}
220    dbprint(prot,pout);
221  }
222
223  int i1=1;
224  int i2=1;
225  ideal SPLIT=p;
226  if(splitcontrol>=0)// spliting
227  {
228    if(prot!=0){dbprint(prot,"//split in working ring:");}
229    SPLIT=splitsqrfree(p,v);
230    i1=size(SPLIT);
231    if((i1==1)&&(charstr(rn)=="0"))
232    {
233      if(prot!=0){dbprint(prot,"//split exact in basering:");}
234      setring rn;
235      if(v>1)
236      {
237        ideal SQQQQ=splitsqrfree(p,v);
238        setring lagc;
239        SPLIT=imap(rn,SQQQQ);
240      }
241      else
242      {
243        oo="ring exa=0,"+string(var(1))+",lp;";
244        execute(oo);
245        ideal SQQQQ=splitsqrfree(imap(rn,p),var(1));
246        setring lagc;
247        SPLIT=imap(exa,SQQQQ);
248        kill exa;
249      }
250      i1=size(SPLIT);
251    }
252    if(prot!=0)
253    {
254      if(i1>1)
255      {
256        int i3=deg(SPLIT[1]);
257        pout="//results of split(the squarefree factors):";
258        if(i3>0){pout=pout+nl+
259           "//  multiplicity "+string(i2)+", degree "+string(i3);}
260        while(i2<i1)
261        {
262          i2++;
263          i3=deg(SPLIT[i2]);
264          if(i3>0){pout=pout+nl+
265             "//  multiplicity "+string(i2)+", degree "+string(i3);}
266        }
267        dbprint(prot,pout);
268        i2=1;
269      }
270      else
271      {
272        if(charstr(rn)=="0"){dbprint(prot,"// polynomial is squarefree");}
273        else{dbprint(prot,"// split without result");}
274      }
275    }
276  }
277
278  p=SPLIT[1];// the first part
279  if(deg(p)>0)
280  {
281    roots=laguerre(p,numberprec,1);// the ring is already complex, hence numberprec is dummy
282    if((size(roots)==0)||(string(roots[1])=="0")){ERROR("laguerre: no roots found");}
283    if(rootcheck){checkroots(p,v,roots,ima,prc);}
284  }
285  while(i2<i1)
286  {
287    i2++;
288    p=SPLIT[i2];// the part with multiplicity i2
289    if(deg(p)>0)
290    {
291      simple=laguerre(p,numberprec,1);
292      if((size(simple)==0)||(string(simple[1])=="0")){ERROR("laguerre: no roots found");}
293      if(rootcheck){checkroots(p,v,simple,ima,prc);}
294      if(splitcontrol==0)// no multiple roots
295      {
296        roots=roots+simple;
297      }
298      else// multiple roots
299      {
300        roots=roots+makemult(simple,i2);
301      }
302    }
303  }
304
305  if((solutionprec<numberprec)&&(size(ss)==0))// shorter output
306  {
307    oo="ring lout=(complex,"+string(solutionprec)+",1),"
308    +string(var(1))+",lp;";
309    execute(oo);
310    list roots=imap(lagc,roots);
311    roots=transroots(roots);
312    if(iz>0){roots=addzero(roots,ss,iz,splitcontrol);}
313    if(prot!=0){dbprint(prot,"//END laguerre_solve");}
314    return(roots);
315  }
316  if(size(ss)==0){roots=transroots(roots);}// transform to string
317  else         // or map in basering
318  {
319    if(ringprec<numberprec)
320    {
321      setring rn;
322      list roots=imap(lagc,roots);
323    }
324  }
325  if(iz>0){roots=addzero(roots,ss,iz,splitcontrol);}
326  if(prot!=0){dbprint(prot,"//END laguerre_solve");}
327  return(roots);
328}
329example
330{
331    "EXAMPLE:";echo=2;
332    // Find all roots of an univariate polynomial using Laguerre's method:
333    ring rs1= 0,(x,y),lp;
334    poly f = 15x5 + x3 + x2 - 10;
335    // 10 digits precision
336    laguerre_solve(f,10);
337
338    // Now with complex coefficients,
339    // internal precision is 30 digits (default)
340    printlevel=2;
341    ring rsc= (real,10,I),x,lp;
342    poly f = (15.4+I*5)*x^5 + (25.0e-2+I*2)*x^3 + x2 - 10*I;
343    list l = laguerre_solve(f);
344    l;
345    // check result, value of substituted poly should be near to zero
346    subst(f,x,l[1]);
347    subst(f,x,l[2]);
348}
349//////////////////////////////////////////////////////////////////////////////
350//                subprocedures for laguerre_solve
351/*
352*  if p depends only on var(i)
353*       returns i
354*  otherwise    0
355*/
356static proc checkv(poly p)
357{
358  int n=nvars(basering);
359  int i=0;
360  int v;
361
362  while (n>0)
363  {
364    if ((p-subst(p,var(n),0))!=0)
365    {
366      i++;
367      if (i>1){return(0);}
368      v=n;
369    }
370    n--;
371  }
372  return(v);
373}
374/*
375*  if p hase only real coefficients
376*       returns 0
377*  otherwise    1
378*/
379static proc checkim(poly p)
380{
381  poly q=p;
382
383  while(q!=0)
384  {
385    if(impart(leadcoef(q))!=0){return(1);}
386    q=q-lead(q);
387  }
388  return(0);
389}
390/*
391*  make multiplicity m
392*/
393static proc makemult(list si,int m)
394{
395  int k0=0;
396  int k1=size(si);
397  int k2,k3;
398  number ro;
399  list msi;
400
401  for(k2=1;k2<=k1;k2++)
402  {
403    ro=si[k2];
404    for(k3=m;k3>0;k3--){k0++;msi[k0]=ro;}
405  }
406  return(msi);
407}
408/*
409*  returns 1 for n<1
410*/
411static proc cmp1(number n)
412{
413  number r=repart(n);
414  number i=impart(n);
415  number c=r*r+i*i;
416  if(c>1){return(1);}
417  else{return(0);}
418}
419/*
420*  exact division of polys f/g
421*  (should be internal)
422*/
423static proc exdiv(poly f,poly g,poly v)
424{
425  int d1=deg(f);
426  int d2=deg(g);
427  poly r0=f;
428  poly rf=0;
429  poly h;
430  number n,m;
431
432  m=leadcoef(g);
433  while ((r0!=0)&&(d1>=d2))
434  {
435    n=leadcoef(r0)/m;
436    h=n*v^(d1-d2);
437    rf=rf+h;
438    r0=r0-h*g;
439    d1=deg(r0);
440  }
441  return(cleardenom(rf));
442}
443/*
444*  p is uniform in x
445*  perform a split of p into squarefree factors
446*  such that the returned ideal 'split' consists of
447*  the faktors, i.e.
448*    p = n * product ( split[i]^i ) , n a number
449*/
450proc splitsqrfree(poly p, poly x)
451{
452  int i=1;
453  int dd=deg(p);
454  int j;
455  ideal h,split;
456  poly high;
457
458  if(x<1){ERROR("wrog ringorder!");}
459  h=p,diff(p,x);
460  h=interred(h);
461  if(deg(h[1])==0){return(p);}
462  high=h[1];
463  split[1]=exdiv(p,high,x);
464  while(1)
465  {
466    h=split[i],high;
467    h=interred(h);
468    j=deg(h[1]);
469    if(j==0){return(p);}
470    if(deg(h[1])==deg(split[i]))
471    {
472      split=split,split[i];
473      split[i]=1;
474    }
475    else
476    {
477      split[i]=exdiv(split[i],h[1],x);
478      split=split,h[1];
479      dd=dd-deg(split[i])*i;
480    }
481    j=j*(i+1);
482    if(j==dd){break;}
483    if(j>dd){return(p);}
484    high=exdiv(high,h[1],x);
485    if(deg(high)==0){return(p);};
486    i++;
487  }
488  return(split);
489}
490/*
491*  see checkroots
492*/
493static proc nerr(number n,number m)
494{
495  int r;
496  number z=0;
497  number nr=repart(n);
498  number ni=impart(n);
499  if(nr<z){nr=z-nr;}
500  if(ni<z){ni=nr-ni;}
501  else{ni=nr+ni;}
502  if(ni<m){r=0;}
503  else{r=1;}
504  return(r);
505}
506/*
507*  returns ERROR for nerr(p(r[i]))>=pr
508*/
509static proc checkroots(poly p,poly v,list r,int ima,number pr)
510{
511  int i=0;
512  int j;
513  number n,m;
514  ideal li;
515
516  while(i<size(r))
517  {
518    i++;
519    n=r[i];
520    j=cmp1(n);
521    if(j!=0){li[1]=v/n-1;m=1;}
522    else{li[1]=v-n;m=n;}
523    if((ima==0)&&(impart(n)!=0))
524    {
525      i++;
526      n=r[i];
527      if(j!=0){li[1]=li[1]*(v/n-1);}
528      else{li[1]=li[1]*(v-n);m=m*n;}
529    }
530    attrib(li,"isSB",1);
531    n=leadcoef(reduce(p,li));n=n/m;
532    if(n!=0)
533    {if(nerr(n,pr)!=0){ERROR("Unsufficient accuracy!");}}
534  }
535}
536/*
537*  transforms thr result to string
538*/
539static proc transroots(list r)
540{
541  int i=size(r);
542  while (i>0)
543  {
544    r[i]=string(r[i]);
545    i--;
546  }
547  return(r);
548}
549/*
550* returns a poly without zeroroots
551*/
552static proc divzero(poly f,int iv);
553{
554  poly p=f;
555  poly q=p;
556  poly r;
557  while(p==q)
558  {
559    q=p/var(iv);
560    r=q*var(iv);
561    if(r==p){p=q;}
562  }
563  return(p);
564}
565/*
566*  add zeros to solution
567*/
568static proc addzero(list zz,string ss,int iz,int a)
569{
570    int i=1;
571    int j=size(zz);
572
573    if(size(ss)==0){zz[j+1]="0";}
574    else{zz[j+1]=number(0);}
575    if(a==0){return(zz);}
576    while(i<iz)
577    {
578      i++;
579      if(size(ss)==0){zz[j+i]="0";}
580      else{zz[j+i]=number(0);}
581    }
582    return(zz);
583}
584///////////////////////////////////////////////////////////////////////////////
585
586proc mp_res_mat( ideal i, list # )
587"USAGE:   mp_res_mat(i [, k] ); i ideal, k integer,
588 @format
589         k=0: sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,
590         k=1: resultant matrix of Macaulay (k=0 is default)
591 @end format
592ASSUME:
593 @format
594         the number of elements in the input system must be
595         the number of variables in the basering plus one,
596         if k=1 then i must be homogeneous,
597 @end format
598RETURN:  module representing the multipolynomial resultant matrix
599EXAMPLE: example mp_res_mat; shows an example
600"
601{
602    int typ=0;
603
604    if ( size(#) > 0 )
605    {
606        typ= #[1];
607        if ( typ < 0 || typ > 1 )
608        {
609            ERROR("Valid values for third parameter are:
610                   0: sparse resultant (default)
611                   1: Macaulay resultant");
612        }
613    }
614
615    return(mpresmat(i,typ));
616
617}
618example
619{
620    "EXAMPLE:";echo=2;
621    // compute resultant matrix in ring with parameters (sparse resultant matrix)
622    ring rsq= (0,u0,u1,u2),(x1,x2),lp;
623    ideal i= u0+u1*x1+u2*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
624    module m = mp_res_mat(i);
625    print(m);
626    // computing sparse resultant
627    det(m);
628
629    // compute resultant matrix (Macaulay resultant matrix)
630    ring rdq= (0,u0,u1,u2),(x0,x1,x2),lp;
631    ideal h=  homog(imap(rsq,i),x0);
632    h;
633
634    module m = mp_res_mat(h,1);
635    print(m);
636    // computing Macaulay resultant (should be the same as above!)
637    det(m);
638
639    // compute numerical sparse resultant matrix
640    setring rsq;
641    ideal ir= 15+2*x1+5*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
642    module mn = mp_res_mat(ir);
643    print(mn);
644    // computing sparse resultant
645    det(mn);
646}
647///////////////////////////////////////////////////////////////////////////////
648
649proc interpolate( ideal p, ideal w, int d )
650"USAGE:   interpolate(p,v,d); p,v=ideals of numbers, d=integer
651ASSUME:
652@format
653         ground field K are the rational numbers,
654         p and v consists of elements of the ground field K
655         with the following number of elements:
656         size(p) = n and size(v)=N=(d+1)^n with n equals
657         the number of variables,
658         p is considered as point in K^n and with
659         pi=(p[1]^i,..,p[n]^i), i=1,..,N the returned
660         polynomial f satisfies f(pi) = v[i]
661         (p[j] != -1,0,1);
662@end format
663RETURN:
664@format
665         the unique polynomial f of degree n*d with prescribed
666         values v at certain points p1,..,pN derived from p;
667@end format
668NOTE:    mainly useful when n=1, i.e. f is satisfying
669@format
670         f(p^(i-1)) = v[i], i=1..d+1
671@end format
672EXAMPLE: example interpolate; shows an example
673"
674{
675    return(vandermonde(p,w,d));
676}
677example
678{
679    "EXAMPLE:";  echo=2;
680    ring r1 = 0,(x),lp;
681    // determine f with deg(f) = 4 and
682    // v = values of f at points 3^0, 3^1, 3^2, 3^3, 3^4
683    ideal v=16,0,11376,1046880,85949136;
684    interpolate( 3, v, 4 );
685}
686///////////////////////////////////////////////////////////////////////////////
687
688static proc psubst( int d, int dd, int n, list resl,
689                    ideal fi, int elem, int nv, int prec )
690{
691    //   nv: number of ring variables         (fixed value)
692    // elem: number of elements in ideal fi   (fixed value)
693    //   fi: input ideal                      (fixed value)
694    //   rl: output list of roots
695    // resl: actual list of roots
696    //    n:
697    //   dd: actual element of fi
698    //    d: actual variable
699
700    int olddd=dd;
701
702    if ( pdebug>=1 )
703    {"// 0 step "+string(dd)+" of "+string(elem);}
704
705    if ( dd <= elem )
706    {
707        int loop = 1;
708        int k;
709        list lsr,lh;
710        poly ps;
711        int thedd;
712
713        if ( pdebug>=1 )
714        {"// 1 dd = "+string(dd);}
715
716        thedd=0;
717        while ( (dd+1 <= elem) && loop )
718        {
719            ps= fi[dd+1];
720
721            if ( n-1 > 0 )
722            {
723                if ( pdebug>=2 )
724                {
725                    "// 2 ps=fi["+string(dd+1)+"]"+" size="
726                        +string(size(coeffs(ps,var(n-1))))
727                        +"  leadexp(ps)="+string(leadexp(ps));
728                }
729                if ( size(coeffs(ps,var(n-1))) == 1 )
730                {
731                    dd++;
732                    // hier Leading-Exponent pruefen???
733                    // oder ist das Poly immer als letztes in der Liste?!?
734                    // leadexp(ps)
735                }
736                else
737                {
738                    loop=0;
739                }
740            }
741            else
742            {
743                if ( pdebug>=2 )
744                {
745                    "// 2 ps=fi["+string(dd+1)+"]"+"  leadexp(ps)="
746                        +string(leadexp(ps));
747                }
748                dd++;
749            }
750        }
751        thedd=dd;
752        ps= fi[thedd];
753
754        if ( pdebug>=1 )
755        {
756            "// 3    fi["+string(thedd-1)+"]"+"  leadexp(fi[thedd-1])="
757                +string(leadexp(fi[thedd-1]));
758            "// 3 ps=fi["+string(thedd)+"]"+"  leadexp(ps)="
759                +string(leadexp(ps));
760        }
761
762        for ( k= nv; k > nv-d; k-- )
763        {
764            if ( pdebug>=2 )
765            {
766                "// 4 subst(fi["+string(thedd)+"],"
767                    +string(var(k))+","+string(resl[k])+");";
768            }
769            ps = subst(ps,var(k),resl[k]);
770        }
771
772        if ( pdebug>=2 )
773        { "// 5 substituted ps="+string(ps); }
774
775        if ( ps != 0 )
776        {
777            lsr= laguerre_solve( ps, prec, prec/2, 0 );
778        }
779        else
780        {
781            if ( pdebug>=1 )
782            { "// 30 ps == 0, thats not cool..."; }
783            lsr=@ln; // lsr=number(0);
784        }
785
786        if ( pdebug>=1 )
787        { "// 6 laguerre_solve found roots: lsr["+string(size(lsr))+"]"; }
788
789        if ( size(lsr) > 1 )
790        {
791            if ( pdebug>=1 )
792            {
793                "// 10 checking roots found before, range "
794                    +string(dd-olddd)+" -- "+string(dd);
795                "// 10 thedd = "+string(thedd);
796            }
797
798            int i,j,l;
799            int ls=size(lsr);
800            int lss;
801            poly pss;
802            list nares;
803            int rroot;
804            int nares_size;
805
806
807            for ( i = 1; i <= ls; i++ ) // lsr[1..ls]
808            {
809                rroot=1;
810
811                if ( pdebug>=2 )
812                {"// 13 root lsr["+string(i)+"] = "+string(lsr[i]);}
813                for ( l = 0; l <= dd-olddd; l++ )
814                {
815                    if ( l+olddd != thedd )
816                    {
817                        if ( pdebug>=2 )
818                        {"// 11 checking ideal element "+string(l+olddd);}
819                        ps=fi[l+olddd];
820                        if ( pdebug>=3 )
821                        {"// 14 ps=fi["+string(l+olddd)+"]";}
822                        for ( k= nv; k > nv-d; k-- )
823                        {
824                            if ( pdebug>=3 )
825                            {
826                                "// 11 subst(fi["+string(olddd+l)+"],"
827                                    +string(var(k))+","+string(resl[k])+");";
828                            }
829                            ps = subst(ps,var(k),resl[k]);
830
831                        }
832
833                        pss=subst(ps,var(k),lsr[i]); // k=nv-d
834                        if ( pdebug>=3 )
835                        { "// 15 0 == "+string(pss); }
836                        if ( pss != 0 )
837                        {
838                            if ( system("complexNearZero",
839                                        leadcoef(pss),
840                                        prec) )
841                            {
842                                if ( pdebug>=2 )
843                                { "// 16 root "+string(i)+" is a real root"; }
844                            }
845                            else
846                            {
847                                if ( pdebug>=2 )
848                                { "// 17 0 == "+string(pss); }
849                                rroot=0;
850                            }
851                        }
852
853                    }
854                }
855
856                if ( rroot == 1 ) // add root to list ?
857                {
858                    if ( size(nares) > 0 )
859                    {
860                        nares=nares[1..size(nares)],lsr[i];
861                    }
862                    else
863                    {
864                        nares=lsr[i];
865                    }
866                    if ( pdebug>=2 )
867                    { "// 18 added root to list nares"; }
868                }
869            }
870
871            nares_size=size(nares);
872            if ( nares_size == 0 )
873            {
874                "Numerical problem: No root found...";
875                "Output may be incorrect!";
876                nares=@ln;
877            }
878
879            if ( pdebug>=1 )
880            { "// 20 found <"+string(size(nares))+"> roots"; }
881
882            for ( i= 1; i <= nares_size; i++ )
883            {
884                resl[nv-d]= nares[i];
885
886                if ( dd < elem )
887                {
888                    if ( i > 1 )
889                    {
890                        rn@++;
891                    }
892                    psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec );
893                }
894                else
895                {
896                    if ( pdebug>=1 )
897                    {"// 30_1 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
898                    if ( pdebug>=2 )
899                    { resl; }
900                    rlist[rn@]=resl;
901                }
902            }
903        }
904        else
905        {
906            if ( pdebug>=2 )
907            { "// 21 found root to be: "+string(lsr[1]); }
908            resl[nv-d]= lsr[1];
909
910            if ( dd < elem )
911            {
912                psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec );
913            }
914            else
915            {
916                if ( pdebug>=1 )
917                { "// 30_2 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
918                if ( pdebug>=2 )
919                { resl; }
920                rlist[rn@]=resl;
921            }
922        }
923    }
924}
925
926///////////////////////////////////////////////////////////////////////////////
927
928proc fglm_solve( ideal fi, list # )
929"USAGE:   fglm_solve(i [, p] ); i=ideal, p=integer,
930 @format
931         p>0: gives precision of complex numbers
932         in decimal digits (default: p=30),
933 @end format
934ASSUME:  the ground field has char 0.
935RETURN:
936 @format
937         a list of complex roots of type number, the procedure
938         uses a standard basis of i to determine all complex
939         roots of i.
940 @end format
941NOTE:
942 @format
943         The procedure creates a ring rC with the same number
944         of variables but with complex coefficients (and precision p).
945 @end format
946EXAMPLE: example fglm_solve; shows an example
947"
948{
949    int prec=30;
950
951    if ( size(#)>=1  && typeof(#[1])=="int")
952    {
953        prec=#[1];
954    }
955
956    lex_solve(stdfglm(fi),prec);
957    keepring basering;
958}
959example
960{
961    "EXAMPLE:";echo=2;
962    ring r = 0,(x,y),lp;
963    // compute the intersection points of two curves
964    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
965    fglm_solve(s,10);
966    rlist;
967}
968
969///////////////////////////////////////////////////////////////////////////////
970
971proc lex_solve( ideal fi, list # )
972"USAGE:   lex_solve( i[,p] ); i=ideal, p=integer,
973 @format
974         p>0: gives precision of complex numbers
975         in decimal digits (default: p=30),
976 @end format
977ASSUME:
978 @format
979         i is a reduced lexicographical Groebner bases of a
980         zero-dimensional ideal (i), sorted by increasing leading terms.
981 @end format
982RETURN:  nothing
983CREATE:
984 @format
985         The procedure creates a complec ring with the same variables but
986         with complex coefficients (and precision p).
987         In this ring a list @code{rlist} of numbers is created,
988         in which the complex roots of i are stored.
989 @format
990EXAMPLE: example lex_solve; shows an example
991"
992{
993    int prec=30;
994
995    if ( size(#)>=1  && typeof(#[1])=="int")
996    {
997        prec=#[1];
998    }
999
1000    if ( !defined(pdebug) )
1001    {
1002        int pdebug;
1003        pdebug=0;
1004        export pdebug;
1005    }
1006
1007    string orings= nameof(basering);
1008    def oring= basering;
1009
1010    // change the ground field to complex numbers
1011    string nrings= "ring "+orings+"C=(complex,"+string(prec)
1012        +"),("+varstr(basering)+"),lp;";
1013    execute(nrings);
1014
1015    if ( pdebug>=0 )
1016    { "// name of new ring: "+string(nameof(basering));}
1017
1018    // map fi from old to new ring
1019    ideal fi= imap(oring,fi);
1020
1021    // list with entry 0 (number)
1022    number nn=0;
1023    if ( !defined(@ln) )
1024    {
1025        list @ln;
1026        export @ln;
1027    }
1028    @ln=nn;
1029
1030    int idelem= size(fi);
1031    int nv= nvars(basering);
1032    int i,j,k,lis;
1033    list resl,li;
1034
1035    if ( !defined(rlist) )
1036    {
1037        list rlist;
1038        export rlist;
1039    }
1040
1041    if ( !defined(rn@) )
1042    {
1043        int rn@;
1044        export rn@;
1045    }
1046    rn@=0;
1047
1048    li= laguerre_solve(fi[1],prec,prec/2,0);
1049    lis= size(li);
1050
1051    if ( pdebug>=1 )
1052    {"// laguerre found roots: "+string(size(li));}
1053
1054    for ( j= 1; j <= lis; j++ )
1055    {
1056        if ( pdebug>=1 )
1057        {"// root "+string(j);}
1058        rn@++;
1059        resl[nv]= li[j];
1060        psubst( 1, 2, nv-1, resl, fi, idelem, nv, prec );
1061    }
1062
1063    if ( pdebug>=0 )
1064    {"// list of roots: "+nameof(rlist);}
1065
1066    // keep the ring and exit
1067    keepring basering;
1068}
1069example
1070{
1071    "EXAMPLE:";echo=2;
1072    ring r = 0,(x,y),lp;
1073    // compute the intersection points of two curves
1074    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1075    lex_solve(stdfglm(s),10);
1076    rlist;
1077}
1078
1079///////////////////////////////////////////////////////////////////////////////
1080
1081proc triangLf_solve( ideal fi, list # )
1082"USAGE:   triangLf_solve(i [, p] ); i ideal, p integer,
1083p>0: gives precision of complex numbers in digits,@*
1084(default: p=30)
1085ASSUME:  the ground field has char 0;@*
1086         i zero-dimensional ideal
1087RETURN:  nothing
1088CREATE:  The procedure creates a ring rC with the same number of variables but
1089         with complex coefficients (and precision p).@*
1090         In rC a list @code{rlist} of numbers is created, in which the complex
1091         roots of i are stored.@*
1092         The proc uses a triangular system (Lazard's Algorithm with factorization)
1093         computed from a standard basis to determine recursively all complex
1094         roots with Laguerre's algorithm of input ideal i.
1095EXAMPLE: example triangLf_solve; shows an example
1096"
1097{
1098    int prec=30;
1099
1100    if ( size(#)>=1  && typeof(#[1])=="int")
1101    {
1102        prec=#[1];
1103    }
1104
1105    triang_solve(triangLfak(stdfglm(fi)),prec);
1106    keepring basering;
1107}
1108example
1109{
1110    "EXAMPLE:";echo=2;
1111    ring r = 0,(x,y),lp;
1112    // compute the intersection points of two curves
1113    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1114    triangLf_solve(s,10);
1115    rlist;
1116}
1117
1118///////////////////////////////////////////////////////////////////////////////
1119
1120proc triangM_solve( ideal fi, list # )
1121"USAGE:   triangM_solve(i [, p ] ); i=ideal, p=integer,
1122p>0: gives precision of complex numbers in digits,@*
1123(default: p=30)
1124ASSUME:  the ground field has char 0;@*
1125         i zero-dimensional ideal
1126RETURN:  nothing
1127CREATE:  The procedure creates a ring rC with the same number of variables but
1128         with complex coefficients (and precision p).@*
1129         In rC a list @code{rlist} of numbers is created, in which the complex
1130         roots of i are stored.@*
1131         The proc uses a triangular system (Moellers Algorithm) computed from a
1132         standard basis to determine recursively all complex roots with Laguerre's
1133         algorithm of input ideal i.
1134EXAMPLE: example triangM_solve; shows an example
1135"
1136{
1137    int prec=30;
1138
1139    if ( size(#)>=1  && typeof(#[1])=="int")
1140    {
1141        prec=#[1];
1142    }
1143
1144    triang_solve(triangM(stdfglm(fi)),prec);
1145    keepring basering;
1146}
1147example
1148{
1149    "EXAMPLE:";echo=2;
1150    ring r = 0,(x,y),lp;
1151    // compute the intersection points of two curves
1152    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1153    triangM_solve(s,10);
1154    rlist;
1155}
1156
1157///////////////////////////////////////////////////////////////////////////////
1158
1159proc triangL_solve( ideal fi, list # )
1160"USAGE:   triangL_solve(i [, p] ); i=ideal, p=integer,@*
1161p>0: gives precision of complex numbers in digits,@*
1162(default: p=30)
1163ASSUME:  the ground field has char 0;@*
1164         i zero-dimensional ideal
1165RETURN:  nothing
1166CREATE:  The procedure creates a ring rC with the same number of variables but
1167         with complex coefficients (and precision p).@*
1168         In rC a list @code{rlist} of numbers is created, in which the complex
1169         roots of i are stored.@*
1170         The proc uses a triangular system (Lazard's Algorithm)
1171         computed from a standard basis to determine recursively all complex
1172         roots with Laguerre's algorithm of input ideal i.
1173EXAMPLE: example triangL_solve; shows an example
1174"
1175{
1176    int prec=30;
1177
1178    if ( size(#)>=1  && typeof(#[1])=="int")
1179    {
1180        prec=#[1];
1181    }
1182
1183    triang_solve(triangL(stdfglm(fi)),prec);
1184    keepring basering;
1185}
1186example
1187{
1188    "EXAMPLE:";echo=2;
1189    ring r = 0,(x,y),lp;
1190    // compute the intersection points of two curves
1191    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1192    triangL_solve(s,10);
1193    rlist;
1194}
1195
1196
1197///////////////////////////////////////////////////////////////////////////////
1198
1199proc triang_solve( list lfi, int prec, list # )
1200"USAGE:   triang_solve(l,p [, d] ); l=list, p,d=integers,@*
1201l a list of finitely many triangular systems, such that
1202the union of their varieties equals the variety of the
1203initial ideal.@*
1204p>0: gives precision of complex numbers in digits,@*
1205d>0: gives precision (1<d<p) for near-zero-determination,@*
1206(default: d=1/2*p)
1207
1208ASSUME:  the ground field has char 0;@*
1209         l was computed using Algorithm of Lazard or Algorithm of Moeller
1210         (see triang.lib).
1211RETURN:  nothing
1212CREATE:  The procedure creates a ring rC with the same number of variables but
1213         with complex coefficients (and precision p).@*
1214         In rC a list @code{rlist} of numbers is created, in which the complex
1215         roots of i are stored.@*
1216EXAMPLE: example triang_solve; shows an example
1217"
1218{
1219    if ( !defined(pdebug) )
1220    {
1221        int pdebug;
1222        export pdebug;
1223    }
1224    pdebug=0;
1225
1226    string orings= nameof(basering);
1227    def oring= basering;
1228
1229    // change the ground field to complex numbers
1230    string nrings= "ring "+orings+"C=(real,"+string(prec)
1231        +",I),("+varstr(basering)+"),lp;";
1232    execute(nrings);
1233
1234    if ( pdebug>=0 )
1235    { "// name of new ring: "+string(nameof(basering));}
1236
1237    // list with entry 0 (number)
1238    number nn=0;
1239    if ( !defined(@ln) )
1240    {
1241        list @ln;
1242        export @ln;
1243    }
1244    @ln=nn;
1245
1246    // set number of digits for zero-comparison of roots
1247    if ( !defined(myCompDigits) )
1248    {
1249        int myCompDigits;
1250        export  myCompDigits;
1251    }
1252    if ( size(#)>=1  && typeof(#[1])=="int" )
1253    {
1254        myCompDigits=#[1];
1255    }
1256    else
1257    {
1258        myCompDigits=(system("getPrecDigits"));
1259    }
1260
1261    if ( pdebug>=1 )
1262    {"// myCompDigits="+string(myCompDigits);}
1263
1264    int idelem;
1265    int nv= nvars(basering);
1266    int i,j,k,lis;
1267    list res,li;
1268
1269    if ( !defined(rlist) )
1270    {
1271        list rlist;
1272        export rlist;
1273    }
1274
1275    if ( !defined(rn@) )
1276    {
1277        int rn@;
1278        export rn@;
1279    }
1280    rn@=0;
1281
1282    // map the list
1283    list lfi= imap(oring,lfi);
1284
1285    int slfi= size(lfi);
1286    ideal fi;
1287
1288    for ( i= 1; i <= slfi; i++ )
1289    {
1290        // map fi from old to new ring
1291        fi= lfi[i]; //imap(oring,lfi[i]);
1292
1293        idelem= size(fi);
1294
1295        // solve fi[1]
1296        li= laguerre_solve(fi[1],myCompDigits,myCompDigits/2,0);
1297        lis= size(li);
1298
1299        if ( pdebug>=1 )
1300        {"// laguerre found roots: "+string(size(li));}
1301
1302        for ( j= 1; j <= lis; j++ )
1303        {
1304            if ( pdebug>=1 )
1305            {"// root "+string(j);}
1306            rn@++;
1307            res[nv]= li[j];
1308            psubst( 1, 2, nv-1, res, fi, idelem, nv, myCompDigits );
1309        }
1310    }
1311
1312    if ( pdebug>=0 )
1313    {"// list of roots: "+nameof(rlist);}
1314    // keep the ring and exit
1315    keepring basering;
1316}
1317example
1318{
1319    "EXAMPLE:";echo=2;
1320    ring r = 0,(x,y),lp;
1321    // compute the intersection points of two curves
1322    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1323    triang_solve(triangLfak(stdfglm(s)),10);
1324    rlist;
1325}
1326
1327///////////////////////////////////////////////////////////////////////////////
1328
1329proc pcheck( ideal fi, list sols, list # )
1330"USAGE:   pcheck(i,l [, d] ); i=ideal, l=list, d=integer,@*
1331d>0: precision in digits for near-zero determination
1332ASSUME: the ground field has char 0;@*
1333        l is a list of numbers
1334RETURN: 1 iff all elements of l are roots of i, else 0
1335EXAMPLE: example pcheck; shows an example
1336"
1337{
1338    int i,j,k,nnrfound;
1339    int ss= size(sols);
1340    int nv= nvars(basering);
1341    poly ps;
1342    number nn;
1343    int cprec=0;
1344
1345    if ( size(#)>=1  && typeof(#[1])=="int" )
1346    {
1347        cprec=#[1];
1348    }
1349    if ( cprec <= 0 )
1350    {
1351        cprec=system("getPrecDigits")/2;
1352    }
1353
1354    nnrfound=1;
1355    for ( j= 1; j <= size(fi); j++ )
1356    {
1357        for ( i= 1; i <= ss; i++ )
1358        {
1359            ps= fi[j];
1360            for ( k= 1; k <= nv; k++ )
1361            {
1362                ps = subst(ps,var(k),sols[i][k]);
1363            }
1364            //ps;
1365            nn= leadcoef(ps);
1366            if ( nn != 0 )
1367            {
1368                if ( !system("complexNearZero",nn,cprec) )
1369                {
1370                    " no root: ideal["+string(j)+"]( root "
1371                        +string(i)+"): 0 != "+string(ps);
1372                    nnrfound=0;
1373                }
1374            }
1375        }
1376    }
1377    return(nnrfound);
1378}
1379example
1380{
1381    "EXAMPLE:";echo=2;
1382    ring r = 0,(x,y),lp;
1383    // compute the intersection points of two curves
1384    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1385    lex_solve(stdfglm(s),10);
1386    rlist;
1387    ideal s=imap(r,s);
1388    pcheck(s,rlist);
1389}
1390
1391///////////////////////////////////////////////////////////////////////////////
1392
1393proc simplexOut(list l)
1394"USAGE:   simpelxOut(l); l list
1395ASSUME:
1396RETURN:
1397EXAMPLE: example simplexOut; shows an example
1398"
1399{
1400  int i,j;
1401  matrix m= l[1];
1402  intvec iposv= l[3];
1403  int icase= l[2];
1404
1405  int cols= ncols(m);
1406  int rows= nrows(m);
1407
1408  int N= l[6];
1409
1410  if ( -1 == icase )  // objective function is unbound
1411  {
1412    "objective function is unbound";
1413    return;
1414  }
1415  if ( 1 == icase )  // no solution satisfies the given constraints
1416  {
1417    "no solution satisfies the given constraints";
1418    return;
1419  }
1420  if ( -2 == icase )  // other error
1421  {
1422    "an error occurred during simplex computation!";
1423    return;
1424  }
1425
1426  for ( i = 1; i <= rows; i++ )
1427  {
1428    if (i == 1)
1429    {
1430      "z = "+string(m[1][1]);
1431    }
1432    else
1433    {
1434      if ( iposv[i-1] <= N+1 )
1435      {
1436        "x"+string(i-1)+" = "+string(m[1][iposv[i-1]]);
1437      }
1438//        else
1439//        {
1440//               "Y"; iposv[i-1]-N+1;
1441//        }
1442    }
1443  }
1444}
1445example
1446{
1447    "EXAMPLE:";echo=2;
1448    ring r = (real,10),(x),lp;
1449
1450    // suppose we have the
1451
1452    matrix sm[5][5]=(  0, 1, 1, 3,-0.5,
1453                     740,-1, 0,-2, 0,
1454                       0, 0,-2, 0, 7,
1455                     0.5, 0,-1, 1,-2,
1456                       9,-1,-1,-1,-1);
1457
1458    // simplex input:
1459    // 1: matrix
1460    // 2: number of variables
1461    // 3: total number of constraints (#4+#5+#6)
1462    // 4: number of <= constraints
1463    // 5: number of >= constraints
1464    // 6: number of == constraints
1465
1466    list sol= simplex(sm, 4, 4, 2, 1, 1);
1467    simplexOut(sol);
1468}
1469
1470///////////////////////////////////////////////////////////////////////////////
1471
1472// local Variables: ***
1473// c-set-style: bsd ***
1474// End: ***
Note: See TracBrowser for help on using the repository browser.