source: git/Singular/LIB/solve.lib @ f10ed0

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