source: git/Singular/LIB/solve.lib @ 4713c6

fieker-DuValspielwiese
Last change on this file since 4713c6 was fb86b6b, checked in by Hans Schönemann <hannes@…>, 21 years ago
*hannes: port from V-2-0 git-svn-id: file:///usr/local/Singular/svn/trunk@6837 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 49.7 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="$Id: solve.lib,v 1.26 2003-07-18 14:13:15 Singular Exp $";
3category="Symbolic-numerical solving";
4info="
5LIBRARY: solve.lib     Complex Solving of Polynomial Systems
6AUTHOR:  Moritz Wenk,  email: wenk@mathematik.uni-kl.de
7         Wilfred Pohl, email: pohl@mathematik.uni-kl.de
8
9PROCEDURES:
10laguerre_solve(p,[..]); find all roots of univariate polynomial p
11solve(i,[..]);          all roots of 0-dim. ideal i using triangular sets
12ures_solve(i,[..]);     find all roots of 0-dimensional ideal i with resultants
13mp_res_mat(i,[..]);     multipolynomial resultant matrix of ideal i
14interpolate(p,v,d);     interpolate poly from evaluation points i and results j
15fglm_solve(i,[..]);     find roots of 0-dim. ideal using FGLM and lex_solve
16lex_solve(i,p,[..]);    find roots of reduced lexicographic standard basis
17simplexOut(l);          prints solution of simplex in nice format
18triangLf_solve(l,[..]); find roots using triangular sys. (factorizing Lazard)
19triangM_solve(l,[..]);  find roots of given triangular system (Moeller)
20triangL_solve(l,[..]);  find roots using triangular system (Lazard)
21triang_solve(l,p,[..]); find roots of given triangular system
22";
23
24LIB "triang.lib";    // needed for triang_solve
25
26///////////////////////////////////////////////////////////////////////////////
27
28proc laguerre_solve( poly f, list # )
29"USAGE:   laguerre_solve(f [, m, l, n, s] ); f = polynomial,@*
30         m, l, n, s = integers (control parameters of the method)
31@format
32 m: precision of output in digits ( 4 <= m), if basering is not ring of
33      complex numbers;
34 l: precision of internal computation in decimal digits ( l >=8 )
35      only if the basering is not complex or complex with smaller precision;
36 n: control of multiplicity of roots or of splitting of f into
37      squarefree factors
38      n < 0, no split of f (good, if all roots are simple)
39      n >= 0, try to split
40      n = 0, return only different roots
41      n > 0, find all roots (with multiplicity)
42 s: s != 0, returns ERROR if  | f(root) | > 0.1^m (when computing in the
43      current ring)
44 ( default: m, l, n, s = 8, 30, 1, 0 )
45@end format
46ASSUME:  f is a univariate polynomial;@*
47         basering has characteristic 0 and is either complex or without
48         parameters.
49RETURN:  list of (complex) roots of the polynomial f, depending on n. The
50         result is of type
51@format
52 string: if the basering is not complex,
53 number: otherwise.
54@end format
55NOTE:    If printlevel >0: displays comments ( default = 0 ).
56         If s != 0 and if the procedure stops with ERROR, try a higher
57         internal precision m.
58EXAMPLE: example laguerre_solve; shows an example
59"
60{
61  if (char(basering)!=0){ERROR("characteristic of basering not 0");}
62  if ((charstr(basering)[1]=="0") and (npars(basering)!=0))
63    {ERROR("basering has parameters");}
64  int OLD_COMPLEX=0;
65  int iv=checkv(f);  // check for variable appearing in f
66  if(iv==0){ERROR("Wrong polynomial!");}
67  poly v=var(iv);    // f univariate in v
68
69  int solutionprec=8;// set the control
70  int numberprec=30;
71  int splitcontrol=1;
72  int rootcheck=0;
73  if(size(#)>0){solutionprec=#[1];if(solutionprec<4){solutionprec=4;}}
74  if(size(#)>1){numberprec=#[2];if(numberprec<8){numberprec=8;}}
75  if(solutionprec>numberprec){numberprec=solutionprec;}
76  if(size(#)>2){splitcontrol=#[3];}
77  if(size(#)>3){rootcheck=#[4];}
78  int prot=printlevel-voice+2;
79  int ringprec=0;
80
81  poly p=divzero(f,iv); // divide out zeros as solution
82  int iz=deg(f)-deg(p); // multiplicity of zero solution
83  if(prot!=0)
84  {
85    string pout;
86    string nl=newline;
87    pout="//BEGIN laguerre_solve";
88    if(iz!=0){pout=pout+nl+"//zeros: divide out "+string(iz);}
89    dbprint(prot,pout);
90  }
91  string ss,tt,oo;
92  ss="";oo=ss;
93  if(npars(basering)==1)
94  {
95    if(OLD_COMPLEX)
96    {
97      tt="1,"+string(par(1));
98      if(tt==charstr(basering))
99      {ss=tt;ringprec=system("getPrecDigits");}
100    }
101    else
102    {
103      tt=charstr(basering);
104      if(size(tt)>7)
105      {
106        if(string(tt[1..7])=="complex")
107        {
108          ss=tt;
109          ringprec=system("getPrecDigits");
110        }
111      }
112    }
113  }
114
115  list roots,simple;
116  if(deg(p)==0) // only zero was root
117  {
118    roots=addzero(roots,ss,iz,splitcontrol);
119    if(prot!=0){dbprint(prot,"//END laguerre_solve");}
120    return(roots);
121  }
122
123  if(prot!=0)// more informations
124  {
125    pout="//control: complex ring with precision "+string(numberprec);
126    if(size(ss)==0){pout=pout+nl+
127        "//         basering not complex, hence solutiontype string";
128    if(solutionprec<numberprec){pout=pout+nl+
129        "//         with precision "+string(solutionprec);}}
130    if(splitcontrol<0){pout=pout+nl+ "//       no spliting";}
131    if(splitcontrol==0){pout=pout+nl+"//       output without multiple roots";}
132    if(rootcheck){pout=pout+nl+
133        "//         check roots with precision "+string(solutionprec);}
134    dbprint(prot,pout);
135  }
136
137  def rn = basering;// set the complex ground field
138  if (ringprec<numberprec)
139  {
140    tt="ring lagc=(complex,"+string(numberprec)+","+string(numberprec)+
141       "),"+string(var(iv))+",lp;";
142    execute(tt);
143    poly p=imap(rn,p);
144    poly v=var(1);
145  }
146  int ima=0;
147  if(size(ss)!=0){ima=checkim(p);}
148  number prc=0.1;// set precision of the solution
149  prc=prc^solutionprec;
150  if(prot!=0)
151  {
152    if(ringprec<numberprec){pout="//working in:  "+tt;}
153    if((size(ss)!=0)&&(ima!=0)){pout=pout+nl+
154        "//         polynomial has complex coefficients";}
155    dbprint(prot,pout);
156  }
157
158  int i1=1;
159  int i2=1;
160  ideal SPLIT=p;
161  if(splitcontrol>=0)// splitting
162  {
163    if(prot!=0){dbprint(prot,"//split in working ring:");}
164    SPLIT=splitsqrfree(p,v);
165    i1=size(SPLIT);
166    if((i1==1)&&(charstr(rn)=="0"))
167    {
168      if(prot!=0){dbprint(prot,"//split exact in basering:");}
169      setring rn;
170      if(v>1)
171      {
172        ideal SQQQQ=splitsqrfree(p,v);
173        setring lagc;
174        SPLIT=imap(rn,SQQQQ);
175      }
176      else
177      {
178        oo="ring exa=0,"+string(var(1))+",lp;";
179        execute(oo);
180        ideal SQQQQ=splitsqrfree(imap(rn,p),var(1));
181        setring lagc;
182        SPLIT=imap(exa,SQQQQ);
183        kill exa;
184      }
185      i1=size(SPLIT);
186    }
187    if(prot!=0)
188    {
189      if(i1>1)
190      {
191        int i3=deg(SPLIT[1]);
192        pout="//results of split(the squarefree factors):";
193        if(i3>0){pout=pout+nl+
194           "//  multiplicity "+string(i2)+", degree "+string(i3);}
195        while(i2<i1)
196        {
197          i2++;
198          i3=deg(SPLIT[i2]);
199          if(i3>0){pout=pout+nl+
200             "//  multiplicity "+string(i2)+", degree "+string(i3);}
201        }
202        dbprint(prot,pout);
203        i2=1;
204      }
205      else
206      {
207        if(charstr(rn)=="0"){dbprint(prot,"// polynomial is squarefree");}
208        else{dbprint(prot,"// split without result");}
209      }
210    }
211  }
212
213  p=SPLIT[1];// the first part
214  if(deg(p)>0)
215  {
216    roots=laguerre(p,numberprec,1);// the ring is already complex, hence numberprec is dummy
217    if((size(roots)==0)||(string(roots[1])=="0")){ERROR("laguerre: no roots found");}
218    if(rootcheck){checkroots(p,v,roots,ima,prc);}
219  }
220  while(i2<i1)
221  {
222    i2++;
223    p=SPLIT[i2];// the part with multiplicity i2
224    if(deg(p)>0)
225    {
226      simple=laguerre(p,numberprec,1);
227      if((size(simple)==0)||(string(simple[1])=="0")){ERROR("laguerre: no roots found");}
228      if(rootcheck){checkroots(p,v,simple,ima,prc);}
229      if(splitcontrol==0)// no multiple roots
230      {
231        roots=roots+simple;
232      }
233      else// multiple roots
234      {
235        roots=roots+makemult(simple,i2);
236      }
237    }
238  }
239
240  if((solutionprec<numberprec)&&(size(ss)==0))// shorter output
241  {
242    oo="ring lout=(complex,"+string(solutionprec)+",1),"
243    +string(var(1))+",lp;";
244    execute(oo);
245    list roots=imap(lagc,roots);
246    roots=transroots(roots);
247    if(iz>0){roots=addzero(roots,ss,iz,splitcontrol);}
248    if(prot!=0){dbprint(prot,"//END laguerre_solve");}
249    return(roots);
250  }
251  if(size(ss)==0){roots=transroots(roots);}// transform to string
252  else         // or map in basering
253  {
254    if(ringprec<numberprec)
255    {
256      setring rn;
257      list roots=imap(lagc,roots);
258    }
259  }
260  if(iz>0){roots=addzero(roots,ss,iz,splitcontrol);}
261  if(prot!=0){dbprint(prot,"//END laguerre_solve");}
262  return(roots);
263}
264example
265{
266    "EXAMPLE:";echo=2;
267    // Find all roots of an univariate polynomial using Laguerre's method:
268    ring rs1= 0,(x,y),lp;
269    poly f = 15x5 + x3 + x2 - 10;
270    // 10 digits precision
271    laguerre_solve(f,10);
272
273    // Now with complex coefficients,
274    // internal precision is 30 digits (default)
275    printlevel=2;
276    ring rsc= (real,10,i),x,lp;
277    poly f = (15.4+i*5)*x^5 + (25.0e-2+i*2)*x^3 + x2 - 10*i;
278    list l = laguerre_solve(f);
279    l;
280    // check result, value of substituted poly should be near to zero
281    // remember that l contains a list of strings
282    // in the case of a different ring
283    subst(f,x,l[1]);
284    subst(f,x,l[2]);
285}
286//////////////////////////////////////////////////////////////////////////////
287//                subprocedures for laguerre_solve
288/*
289*  if p depends only on var(i)
290*       returns i
291*  otherwise    0
292*/
293static proc checkv(poly p)
294{
295  int n=nvars(basering);
296  int i=0;
297  int v;
298
299  while (n>0)
300  {
301    if ((p-subst(p,var(n),0))!=0)
302    {
303      i++;
304      if (i>1){return(0);}
305      v=n;
306    }
307    n--;
308  }
309  return(v);
310}
311/*
312*  if p has only real coefficients
313*       returns 0
314*  otherwise    1
315*/
316static proc checkim(poly p)
317{
318  poly q=p;
319
320  while(q!=0)
321  {
322    if(impart(leadcoef(q))!=0){return(1);}
323    q=q-lead(q);
324  }
325  return(0);
326}
327/*
328*  make multiplicity m
329*/
330static proc makemult(list si,int m)
331{
332  int k0=0;
333  int k1=size(si);
334  int k2,k3;
335  number ro;
336  list msi;
337
338  for(k2=1;k2<=k1;k2++)
339  {
340    ro=si[k2];
341    for(k3=m;k3>0;k3--){k0++;msi[k0]=ro;}
342  }
343  return(msi);
344}
345/*
346*  returns 1 for n<1
347*/
348static proc cmp1(number n)
349{
350  number r=repart(n);
351  number i=impart(n);
352  number c=r*r+i*i;
353  if(c>1){return(1);}
354  else{return(0);}
355}
356/*
357*  exact division of polys f/g
358*  (should be internal)
359*/
360static proc exdiv(poly f,poly g,poly v)
361{
362  int d1=deg(f);
363  int d2=deg(g);
364  poly r0=f;
365  poly rf=0;
366  poly h;
367  number n,m;
368
369  m=leadcoef(g);
370  while ((r0!=0)&&(d1>=d2))
371  {
372    n=leadcoef(r0)/m;
373    h=n*v^(d1-d2);
374    rf=rf+h;
375    r0=r0-h*g;
376    d1=deg(r0);
377  }
378  return(cleardenom(rf));
379}
380/*
381*  p is univariant in x
382*  perform a split of p into squarefree factors
383*  such that the returned ideal 'split' consists of
384*  the faktors, i.e.
385*    p = n * product ( split[i]^i ) , n a number
386*/
387static proc splitsqrfree(poly p, poly x)
388{
389  int dd=deg(p);
390  if(dd==1){return(p);}
391  int i=1;
392  int j;
393  ideal h,split;
394  poly high;
395
396  h=interred(ideal(p,diff(p,x)));
397  if(deg(h[1])==0){return(p);}
398  high=h[1];
399  split[1]=exdiv(p,high,x);
400  while(1)
401  {
402    h=interred(ideal(split[i],high));
403    j=deg(h[1]);
404    if(j==0){return(p);}
405    if(deg(h[1])==deg(split[i]))
406    {
407      split=split,split[i];
408      split[i]=1;
409    }
410    else
411    {
412      split[i]=exdiv(split[i],h[1],x);
413      split=split,h[1];
414      dd=dd-deg(split[i])*i;
415    }
416    j=j*(i+1);
417    if(j==dd){break;}
418    if(j>dd){return(p);}
419    high=exdiv(high,h[1],x);
420    if(deg(high)==0){return(p);};
421    i++;
422  }
423  return(split);
424}
425/*
426*  see checkroots
427*/
428static proc nerr(number n,number m)
429{
430  int r;
431  number z=0;
432  number nr=repart(n);
433  number ni=impart(n);
434  if(nr<z){nr=z-nr;}
435  if(ni<z){ni=nr-ni;}
436  else{ni=nr+ni;}
437  if(ni<m){r=0;}
438  else{r=1;}
439  return(r);
440}
441/*
442*  returns ERROR for nerr(p(r[i]))>=pr
443*/
444static proc checkroots(poly p,poly v,list r,int ima,number pr)
445{
446  int i=0;
447  int j;
448  number n,m;
449  ideal li;
450
451  while(i<size(r))
452  {
453    i++;
454    n=r[i];
455    j=cmp1(n);
456    if(j!=0){li[1]=v/n-1;m=1;}
457    else{li[1]=v-n;m=n;}
458    if((ima==0)&&(impart(n)!=0))
459    {
460      i++;
461      n=r[i];
462      if(j!=0){li[1]=li[1]*(v/n-1);}
463      else{li[1]=li[1]*(v-n);m=m*n;}
464    }
465    attrib(li,"isSB",1);
466    n=leadcoef(reduce(p,li));n=n/m;
467    if(n!=0)
468    {if(nerr(n,pr)!=0){ERROR("Unsufficient accuracy!");}}
469  }
470}
471/*
472*  transforms thr result to string
473*/
474static proc transroots(list r)
475{
476  int i=size(r);
477  while (i>0)
478  {
479    r[i]=string(r[i]);
480    i--;
481  }
482  return(r);
483}
484/*
485* returns a poly without zeroroots
486*/
487static proc divzero(poly f,int iv);
488{
489  poly p=f;
490  poly q=p;
491  poly r;
492  while(p==q)
493  {
494    q=p/var(iv);
495    r=q*var(iv);
496    if(r==p){p=q;}
497  }
498  return(p);
499}
500/*
501*  add zeros to solution
502*/
503static proc addzero(list zz,string ss,int iz,int a)
504{
505    int i=1;
506    int j=size(zz);
507
508    if(size(ss)==0){zz[j+1]="0";}
509    else{zz[j+1]=number(0);}
510    if(a==0){return(zz);}
511    while(i<iz)
512    {
513      i++;
514      if(size(ss)==0){zz[j+i]="0";}
515      else{zz[j+i]=number(0);}
516    }
517    return(zz);
518}
519///////////////////////////////////////////////////////////////////////////////
520
521proc solve( ideal G, list # )
522"USAGE:   solve(G [, m, n, l] ); G = ideal,
523         m, n, l = integers (control parameters of the method)
524 @format
525         m: precision of output in digits ( 4 <= m) and of the
526            generated ring of complex numbers;
527         n: control of multiplicity
528            n = 0, return all different roots
529            n != 0, find all roots (with multiplicity)
530         l: precision of internal computation in decimal digits ( l >=8 )
531            only if the basering is not complex or complex with smaller
532            precision,
533         ( default: m, n, l = 8, 0, 30 or
534                    for (n != 0 and size(#) = 2) l = 60 )
535 @end format
536ASSUME:  the ideal is 0-dimensional;@*
537         basering has characteristic 0 and is either complex or
538         without parameters;
539RETURN:  list of solutions of the ideal G, depending on n; one solution is a
540         list of complex numbers in the generated output ring (the new
541         basering).
542@format
543 The result is a list L
544    n  = 0: a list of all different solutions (L[i]),
545    n != 0: a list of two elements,
546            L[i][1] contains all different solutions with the same multiplicity
547            L[i][2] the multiplicity
548 L is ordered w.r.t. multiplicity (the smallest first).
549@end format
550NOTE:    If the problem is not 0-dim. the procedure stops with ERROR, if the
551         ideal G is not a lex. standard basis, it is generated with internal
552         computation (Hilbert driven), if the input-ring (with char 0) has
553         the name "<A>", the lexicographical and complex output-ring has the
554         name "<A>C".
555EXAMPLE: example solve; shows an example
556"
557{
558// test if basering admissible
559  if (char(basering)!=0){ERROR("characteristic of basering not 0");}
560  if ((charstr(basering)[1]=="0") and (npars(basering)!=0)){ERROR("basering has parameters");}
561
562// some global settings and control
563  int outprec = 8;
564  int mu = 0;
565  int prec = 30;
566  if (size(#)>0){outprec = #[1];if (outprec<4){outprec = 4;}}
567  if (size(#)>1){mu = #[2];}
568  if (size(#)>2){prec = #[3];if (prec<8){prec = 8;}}
569  else {if(mu!=0){prec = 60;}}
570  if (outprec>prec){prec = outprec;}
571  string rinC = nameof(basering)+"C";
572  string sord = ordstr(basering);
573  int nv = nvars(basering);
574  def rin = basering;
575  intvec ovec = option(get);
576  option(redSB);
577  option(returnSB);
578  int sb = attrib(G,"isSB");
579  int lp = 0;
580  if (size(sord)==size("C,lp()"+string(nv)))
581  {
582    lp = find(sord,"lp");
583  }
584
585// ERROR
586  if (sb){if (dim(G)!=0){ERROR("ideal not zero-dimensional");}}
587
588// the trivial homog case
589  if (homog(G))
590  {
591    if (sb==0)
592    {
593      execute("ring dphom=("+charstr(rin)+"),("+
594      varstr(rin)+"),dp;");
595      ideal G = std(imap(rin,G));
596      if (dim(G)!=0){ERROR("ideal not zero-dimensional");}
597    }
598    changering(rinC,outprec);
599    list ret0;
600    if (mu==0){ret0[1] = zerolist(nv);}
601    else{ret0[1] = list(zerolist(nv),list(vdim(G)));}
602    option(set,ovec);
603    keepring basering;
604    return(ret0);
605  }
606
607// look for reduced standard basis in lex
608  if (sb*lp==0)
609  {
610    if (sb==0)
611    {
612      execute("ring dphilb=("+charstr(rin)+"),("+
613      varstr(rin)+"),dp;");
614      ideal G = imap(rin,G);
615      G = std(G);
616      if (dim(G)!=0){ERROR("ideal not zero-dimensional");}
617    }
618    else
619    {
620      def dphilb = basering;     
621    }   
622    execute("ring lexhilb=("+charstr(rin)+"),("+
623    varstr(rin)+"),lp;");
624    option(redTail);
625    ideal H = fglm(dphilb,G);
626    kill dphilb;
627    H = simplify(H,2);
628    if (lp){setring rin;}
629    else
630    {
631      execute("ring lplex=("+charstr(rin)+"),("+
632      varstr(rin)+"),lp;");
633    }
634    ideal H = imap(lexhilb,H);
635    kill lexhilb;
636  }
637  else{ideal H = interred(G);}
638
639// only 1 variable
640  def hr = basering;
641  if (nv==1)
642  {
643    if ((mu==0) and (charstr(basering)[1]=="0")) // special case
644    {
645      list L = laguerre_solve(H[1],prec,prec,mu,0); // list of strings
646      changering(rinC,outprec);
647      list sp;
648      for (int ii=1; ii<=size(L); ii++ )
649      {
650        execute("sp[ii]="+L[ii]);
651      }
652      keepring basering;
653      return(sp);
654    }
655    else
656    {
657      execute("ring internC=(complex,"+string(prec)+
658                 "),("+varstr(basering)+"),lp;");
659
660      ideal H = imap(hr,H);
661      list sp = splittolist(splitsqrfree(H[1],var(1)));
662      int jj = size(sp);
663      while(jj>0)
664      {
665        sp[jj][1] = laguerre(sp[jj][1],prec,1);
666        jj--;
667      }
668      setring hr;
669      changering(rinC,outprec);
670      list sp=imap(internC,sp);
671
672      keepring basering;
673      if(mu!=0){return(sp);}
674      jj = size(sp);
675      list ll=sp[jj][1];
676      while(jj>1)
677      {
678        jj--;
679        ll = sp[jj][1]+ll;
680      }
681      return(ll);
682    }   
683  }   
684 
685
686// the triangular sets (not univariate case)
687  attrib(H,"isSB",1);
688  if (mu==0)
689  {
690    list sp = triangMH(H); // faster, but destroy multiplicity
691  }
692  else
693  {
694    list sp = triangM(H);
695  }
696
697//   create the complex ring and map the result
698  if (outprec<prec)
699  {
700    execute("ring internC=(complex,"+string(prec)+
701            "),("+varstr(hr)+"),lp;");
702  }
703  else
704  {
705    changering(rinC,prec);
706  }
707  list triC = imap(hr,sp);
708
709// solve the tridiagonal systems
710  int js = size(triC);
711  list ret1;
712  if (mu==0)
713  {
714    ret1 = trisolve(list(),triC[1],prec);
715    while (js>1)
716    {
717      ret1 = trisolve(list(),triC[js],prec)+ret1;
718      js--;
719    }
720  }
721  else
722  {
723    ret1 = mutrisolve(list(),triC[1],prec);
724    while (js>1)
725    {
726      ret1 = addlist(mutrisolve(list(),triC[js],prec),ret1,1);
727      js--;
728    }
729    ret1 = finalclear(ret1);
730  }
731
732// final computations
733  option(set,ovec);
734  if (outprec==prec)
735  {
736    keepring basering;
737    return(ret1);
738  }
739  changering(rinC,outprec);
740  keepring basering;
741  return(imap(internC,ret1));
742}
743example
744{
745    "EXAMPLE:";echo=2;
746    // Find all roots of a multivariate ideal using triangular sets:
747    int d=4;// with these 3 parameters you may construct
748    int t=3;// very hard problems for 'solve'
749    int s=2;
750    int i;
751    ring A=0,(x(1..d)),dp;
752    poly p=-1;
753    for(i=d;i>0;i--){p=p+x(i)^s;}
754    ideal I=x(d)^t-x(d)^s+p;
755    for(i=d-1;i>0;i--){I=x(i)^t-x(i)^s+p,I;}
756    I;
757    // the mutiplicity is
758    vdim(std(I));
759    list l1=solve(I,6,0);
760    // the current ring is
761    AC;
762    // you must start with char. 0
763    setring A;
764    list l2=solve(I,6,1);
765    // the number of different solutions is
766    size(l1);
767    // this is equal to
768    size(l2[1][1])+size(l2[2][1]);
769    // the number of solutions with multiplicity is
770    size(l2[1][1])*l2[1][2]+size(l2[2][1])*l2[2][2];
771    // the solutions with multiplicity
772    l2[2][2];
773    // are
774    l2[2][1];
775}
776//////////////////////////////////////////////////////////////////////////////
777//                subprocedures for solve
778
779/* ----------------------- support ----------------------- */
780/*
781* the complex ring with precision outprec
782* has the well defined name: rinC
783* 1. if such a ring exists with the precision outprec,
784*    this will be the current ring
785* 2. otherwise such a ring will be created
786*/
787static proc changering(string rinC, int outprec)
788{
789  string rinDC = "ring "+rinC+"=(complex,"+string(outprec)+
790                 "),("+varstr(basering)+"),lp;";
791  string h = "int ex=defined("+rinC+");";
792
793  execute(h);
794  if (ex)
795  {
796    h = "setring "+rinC+";";
797    execute(h);
798    if (system("getPrecDigits")==outprec)
799    {"// name of current ring: "+rinC;}
800    else
801    {
802      execute("kill "+rinC+";");
803      execute(rinDC);
804      execute("export "+rinC+";");
805      "// name of new current ring: "+rinC;
806    }
807  }
808  else
809  {
810    execute(rinDC);
811    execute("export "+rinC+";");
812    "// name of new current ring: "+rinC;
813  }
814  keepring basering;
815}
816
817/*
818* return one zero-solution
819*/
820static proc zerolist(int nv)
821{
822  list ret;
823  int i;
824  number o=0;
825
826  for (i=nv;i>0;i--){ret[i] = o;}
827  return(ret);
828}
829
830/* ----------------------- check solution ----------------------- */
831static proc multsol(list ff, int c)
832{
833  int i,j;
834
835  i = 0;
836  j = size(ff);
837  while (j>0)
838  {
839    if(c){i = i+ff[j][2]*size(ff[j][1]);}
840    else{i = i+size(ff[j][1]);}
841    j--;
842  }
843  return(i);
844}
845
846/*
847* the inputideal A => zero ?
848*/
849static proc checksol(ideal A, list lr)
850{
851  int d = nvars(basering);
852  list ro;
853  ideal re,h;
854  int i,j,k;
855
856  for (i=size(lr);i>0;i--)
857  {
858    ro = lr[i];
859    for (j=d;j>0;j--)
860    {
861      re[j] = var(j)-ro[j];
862    }
863    attrib(re,"isSB",1);
864    k = size(reduce(A,re));
865    if (k){return(i);}
866  }
867  return(0);
868}
869
870/*
871*  compare 2 solutions: returns 0 for equal
872*/
873static proc cmpn(list a,list b)
874{
875  int ii;
876
877  for(ii=size(a);ii>0;ii--){if(a[ii]!=b[ii]) break;}
878  return(ii);
879}
880
881/*
882*  delete equal solutions in the list
883*/
884static proc delequal(list r, int w)
885{
886  list h;
887  int i,j,k,c;
888
889  if (w)
890  {
891    k = size(r);
892    h = r[k][1];
893    k--;
894    while (k>0)
895    {
896      h = r[k][1]+h;
897      k--;
898    }
899  }
900  else{h = r;}
901  k=size(h);
902  i=1;
903  while(i<k)
904  {
905    j=k;
906    while(j>i)
907    {
908      c=cmpn(h[i],h[j]);
909      if(c==0)
910      {
911        h=delete(h,j);
912        k--;
913      }
914      j--;
915    }
916    i++;
917  }
918  return(h);
919}
920
921/* ----------------------- substitution ----------------------- */
922/*
923* instead of subst(T,var(v),n), much faster
924*   need option(redSB) !
925*/
926static proc linreduce(ideal T, int v, number n)
927{
928  ideal re = var(v)-n;
929  attrib (re,"isSB",1);
930  return (reduce(T,re));
931}
932
933/* ----------------------- triangular solution ----------------------- */
934/*
935* solution of one tridiagonal system T
936*   with precision prec
937*   T[1] is univariant in var(1)
938*   list o is empty for the first call
939*/
940static proc trisolve(list o, ideal T, int prec)
941{
942  list lroots,ll;
943  ideal S;
944  int i,d;
945
946  d = size(T);
947  S = interred(ideal(T[1],diff(T[1],var(d))));
948  if (deg(S[1]))
949  {
950    T[1] = exdiv(T[1],S[1],var(d));
951  }
952  ll = laguerre(T[1],prec,1);
953  for (i=size(ll);i>0;i--){ll[i] = list(ll[i])+o;}
954  if (d==1){return(ll);}
955  for (i=size(ll);i>0;i--)
956  {
957    S = linreduce(ideal(T[2..d]),d,ll[i][1]);
958    lroots = trisolve(ll[i],S,prec)+lroots;
959  }
960  return(lroots);
961}
962
963/* ------------------- triangular solution (mult) ------------------- */
964/*
965*  recompute equal solutions w.r.t. multiplicity
966*/
967static proc finalclear(list b)
968{
969  list a = b;
970  list r;
971  int i,l,ju,j,k,ku,mu,c;
972
973// a[i] only
974  i = 1;
975  while (i<=size(a))
976  {
977    ju = size(a[i][1]);
978    j = 1;
979    while (j<=ju)
980    {
981      mu = 1;
982      k = j+1;
983      while (k<=ju)
984      {
985        c = cmpn(a[i][1][j],a[i][1][k]);
986        if (c==0)
987        {
988          a[i][1] = delete(a[i][1],k);
989          ju--;
990          mu++;
991        }
992        else{k++;}
993      }
994      if (mu>1)
995      {
996        r[1] = a[i];
997        r[1][1] = list(a[i][1][j]);
998        a[i][1] = delete(a[i][1],j);
999        a = addlist(r,a,mu);
1000        ju--;
1001      }
1002      else{j++;}
1003    }
1004    if (ju==0){a = delete(a,i);}
1005    else{i++;}
1006  }
1007// a[i], a[l]
1008  i = 1;
1009  while (i<size(a))
1010  {
1011    ju = size(a[i][1]);
1012    l = i+1;
1013    while (l<=size(a))
1014    {
1015      ku = size(a[l][1]);
1016      j = 1;
1017      while (j<=ju)
1018      {
1019        mu = 0;
1020        k = 1;
1021        while (k<=ku)
1022        {
1023          c = cmpn(a[i][1][j],a[l][1][k]);
1024          if (c==0)
1025          {
1026            mu = a[i][2]+a[l][2];
1027            r[1] = a[l];
1028            r[1][1] = list(a[l][1][k]);
1029            r[1][2] = mu;
1030            a[l][1] = delete(a[l][1],k);
1031            a = addlist(r,a,1);
1032            ku--;
1033            break;
1034          }
1035          else{k++;}
1036        }
1037        if (mu)
1038        {
1039          a[i][1] = delete(a[i][1],j);
1040          ju--;
1041        }
1042        else{j++;}
1043      }
1044      if (ku){l++;}
1045      else
1046      {
1047        a = delete(a,l);
1048      }
1049    }
1050    if (ju){i++;}
1051    else
1052    {
1053      a = delete(a,i);
1054    }
1055  }
1056  return(a);
1057}
1058
1059/*
1060* convert to list
1061*/
1062static proc splittolist(ideal sp)
1063{
1064  int j = size(sp);
1065  list spl = list(list(sp[j],j));
1066
1067  j--;
1068  while (j>0)
1069  {
1070    if (deg(sp[j]))
1071    {
1072      spl = list(list(sp[j],j))+spl;
1073    }
1074    j--;
1075  }
1076  return(spl);
1077}
1078
1079/*
1080*  multiply the multiplicity
1081*/
1082static proc multlist(list a, int m)
1083{
1084  int i;
1085  for (i=size(a);i>0;i--){a[i][2] = a[i][2]*m;}
1086  return(a);
1087}
1088
1089/*
1090*  a+b w.r.t. to multiplicity as ordering
1091*    (programming like spolys)
1092*/
1093static proc addlist(list a, list b, int m)
1094{
1095  int i,j,k,l,s;
1096  list r = list();
1097
1098  if (m>1){a = multlist(a,m);}
1099  k = size(a);
1100  l = size(b);
1101  i = 1;
1102  j = 1;
1103  while ((i<=k)&&(j<=l))
1104  {
1105    s = a[i][2]-b[j][2];
1106    if (s>=0)
1107    {
1108      r = r+list(b[j]);
1109      j++;
1110      if (s==0)
1111      {
1112        s = size(r);
1113        r[s][1] = r[s][1]+a[i][1];
1114        i++;
1115      }
1116    }
1117    else
1118    {
1119      r = r+list(a[i]);
1120      i++;
1121    }
1122  }
1123  if (i>k)
1124  {
1125    if (j<=l){r = r+list(b[j..l]);}
1126  }
1127  else{r = r+list(a[i..k]);}
1128  return(r);
1129}
1130
1131/*
1132* solution of one tridiagonal system T with multiplicity
1133*   with precision prec
1134*   T[1] is univariant in var(1)
1135*   list o is empty for the first call
1136*/
1137static proc mutrisolve(list o, ideal T, int prec)
1138{
1139  list lroots,ll,sp;
1140  ideal S,h;
1141  int i,d,m,z;
1142
1143  d = size(T);
1144  sp = splittolist(splitsqrfree(T[1],var(d)));
1145  if (d==1){return(l_mutrisolve(sp,o,prec));}
1146  z = size(sp);
1147  while (z>0)
1148  {
1149    m = sp[z][2];
1150    ll = laguerre(sp[z][1],prec,1);
1151    i = size(ll);
1152    while(i>0)
1153    {
1154      h = linreduce(ideal(T[2..d]),d,ll[i]);
1155      if (size(lroots))
1156      {
1157        lroots = addlist(mutrisolve(list(ll[i])+o,h,prec),lroots,m);
1158      }
1159      else
1160      {
1161        lroots = mutrisolve(list(ll[i])+o,h,prec);
1162        if (m>1){lroots=multlist(lroots,m);}
1163      }
1164      i--;
1165    }
1166    z--;
1167  }
1168  return(lroots);
1169}
1170
1171/*
1172*  the last call, we are ready
1173*/
1174static proc l_mutrisolve(list sp, list o, int prec)
1175{
1176  list lroots,ll;
1177  int z,m,i;
1178
1179  z = size(sp);
1180  while (z>0)
1181  {
1182    m = sp[z][2];
1183    ll = laguerre(sp[z][1],prec,1);
1184    for (i=size(ll);i>0;i--){ll[i] = list(ll[i])+o;}
1185    if (size(lroots))
1186    {
1187      lroots = addlist(list(list(ll,m)),lroots,1);
1188    }
1189    else
1190    {
1191      lroots = list(list(ll,m));
1192    }
1193    z--;
1194  }
1195  return(lroots);
1196}
1197///////////////////////////////////////////////////////////////////////////////
1198
1199proc ures_solve( ideal gls, list # )
1200"USAGE:   ures_solve(i [, k, p] ); i = ideal, k, p = integers
1201@format
1202   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,
1203   k=1: use resultant matrix of Macaulay which works only for
1204          homogeneous ideals,
1205   p>0: defines precision of the long floats for internal computation
1206          if the basering is not complex (in decimal digits),
1207   (default: k=0, p=30)
1208@end format
1209ASSUME:  i is a zerodimensional ideal with
1210         nvars(basering) = ncols(i) = number of vars
1211         actually occurring in i,
1212RETURN:  list of all (complex) roots of the polynomial system i = 0; the
1213         result is of type
1214@format
1215   string: if the basering is not complex,
1216   number: otherwise.
1217@end format
1218EXAMPLE: example ures_solve; shows an example
1219"
1220{
1221    int typ=0;// defaults
1222    int prec=30;
1223
1224    if ( size(#) > 0 )
1225    {
1226        typ= #[1];
1227        if ( typ < 0 || typ > 1 )
1228        {
1229            ERROR("Valid values for second parameter k are:
1230                   0: use sparse Resultant (default)
1231                   1: use Macaulay Resultant");
1232        }
1233    }
1234    if ( size(#) > 1 )
1235    {
1236        prec= #[2];
1237        if ( prec < 8 )
1238        {
1239            prec = 8;
1240        }
1241    }
1242
1243    return(uressolve(gls,typ,prec,1));
1244    // the last nonzero parameter gives an extra run of
1245    // Laguerre's algorithm leading to better results
1246}
1247example
1248{
1249    "EXAMPLE:";echo=2;
1250    // compute the intersection points of two curves
1251    ring rsq = 0,(x,y),lp;
1252    ideal gls=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1253    ures_solve(gls,0,16);
1254    // result is a list (x,y)-coordinates as strings
1255
1256    // now with complex coefficient field, precision is 20 digits
1257    ring rsc= (real,20,I),(x,y),lp;
1258    ideal i = (2+3*I)*x2 + (0.35+I*45.0e-2)*y2 - 8, x2 + xy + (42.7)*y2;
1259    list l= ures_solve(i,0,10);
1260    // result is a list of (x,y)-coordinates of complex numbers
1261    l;
1262    // check the result
1263    subst(subst(i[1],x,l[1][1]),y,l[1][2]);
1264}
1265///////////////////////////////////////////////////////////////////////////////
1266
1267proc mp_res_mat( ideal i, list # )
1268"USAGE:   mp_res_mat(i [, k] ); i ideal, k integer,
1269@format
1270    k=0: sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,
1271    k=1: resultant matrix of Macaulay (k=0 is default)
1272@end format
1273ASSUME:  The number of elements in the input system must be the number of
1274         variables in the basering plus one;
1275         if k=1 then i must be homogeneous.
1276RETURN:  module representing the multipolynomial resultant matrix
1277EXAMPLE: example mp_res_mat; shows an example
1278"
1279{
1280    int typ=0;
1281
1282    if ( size(#) > 0 )
1283    {
1284        typ= #[1];
1285        if ( typ < 0 || typ > 1 )
1286        {
1287            ERROR("Valid values for third parameter are:
1288                   0: sparse resultant (default)
1289                   1: Macaulay resultant");
1290        }
1291    }
1292
1293    return(mpresmat(i,typ));
1294
1295}
1296example
1297{
1298    "EXAMPLE:";echo=2;
1299    // compute resultant matrix in ring with parameters (sparse resultant matrix)
1300    ring rsq= (0,u0,u1,u2),(x1,x2),lp;
1301    ideal i= u0+u1*x1+u2*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
1302    module m = mp_res_mat(i);
1303    print(m);
1304    // computing sparse resultant
1305    det(m);
1306
1307    // compute resultant matrix (Macaulay resultant matrix)
1308    ring rdq= (0,u0,u1,u2),(x0,x1,x2),lp;
1309    ideal h=  homog(imap(rsq,i),x0);
1310    h;
1311
1312    module m = mp_res_mat(h,1);
1313    print(m);
1314    // computing Macaulay resultant (should be the same as above!)
1315    det(m);
1316
1317    // compute numerical sparse resultant matrix
1318    setring rsq;
1319    ideal ir= 15+2*x1+5*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
1320    module mn = mp_res_mat(ir);
1321    print(mn);
1322    // computing sparse resultant
1323    det(mn);
1324}
1325///////////////////////////////////////////////////////////////////////////////
1326
1327proc interpolate( ideal p, ideal w, int d )
1328"USAGE:   interpolate(p,v,d); p,v=ideals of numbers, d=integer
1329ASSUME:  Ground field K is the field of rational numbers, p and v are lists
1330         of elements of the ground field K with p[j] != -1,0,1, size(p) = n
1331         (= number of vars) and size(v)=N=(d+1)^n.
1332RETURN:  poly f, the unique polynomial f of degree n*d with prescribed values
1333         v[i] at the points p(i)=(p[1]^(i-1),..,p[n]^(i-1)), i=1,..,N.
1334NOTE:    mainly useful when n=1, i.e. f is satisfying f(p^(i-1)) = v[i],
1335         i=1..d+1.
1336SEE ALSO: vandermonde.
1337EXAMPLE: example interpolate; shows an example
1338"
1339{
1340    return(vandermonde(p,w,d));
1341}
1342example
1343{
1344    "EXAMPLE:";  echo=2;
1345    ring r1 = 0,(x),lp;
1346    // determine f with deg(f) = 4 and
1347    // v = values of f at points 3^0, 3^1, 3^2, 3^3, 3^4
1348    ideal v=16,0,11376,1046880,85949136;
1349    interpolate( 3, v, 4 );
1350}
1351///////////////////////////////////////////////////////////////////////////////
1352
1353static proc psubst( int d, int dd, int n, list resl,
1354                    ideal fi, int elem, int nv, int prec )
1355{
1356    //   nv: number of ring variables         (fixed value)
1357    // elem: number of elements in ideal fi   (fixed value)
1358    //   fi: input ideal                      (fixed value)
1359    //   rl: output list of roots
1360    // resl: actual list of roots
1361    //    n:
1362    //   dd: actual element of fi
1363    //    d: actual variable
1364
1365    int olddd=dd;
1366
1367    if ( pdebug>=1 )
1368    {"// 0 step "+string(dd)+" of "+string(elem);}
1369
1370    if ( dd <= elem )
1371    {
1372        int loop = 1;
1373        int k;
1374        list lsr,lh;
1375        poly ps;
1376        int thedd;
1377
1378        if ( pdebug>=1 )
1379        {"// 1 dd = "+string(dd);}
1380
1381        thedd=0;
1382        while ( (dd+1 <= elem) && loop )
1383        {
1384            ps= fi[dd+1];
1385
1386            if ( n-1 > 0 )
1387            {
1388                if ( pdebug>=2 )
1389                {
1390                    "// 2 ps=fi["+string(dd+1)+"]"+" size="
1391                        +string(size(coeffs(ps,var(n-1))))
1392                        +"  leadexp(ps)="+string(leadexp(ps));
1393                }
1394                if ( size(coeffs(ps,var(n-1))) == 1 )
1395                {
1396                    dd++;
1397                    // hier Leading-Exponent pruefen???
1398                    // oder ist das Poly immer als letztes in der Liste?!?
1399                    // leadexp(ps)
1400                }
1401                else
1402                {
1403                    loop=0;
1404                }
1405            }
1406            else
1407            {
1408                if ( pdebug>=2 )
1409                {
1410                    "// 2 ps=fi["+string(dd+1)+"]"+"  leadexp(ps)="
1411                        +string(leadexp(ps));
1412                }
1413                dd++;
1414            }
1415        }
1416        thedd=dd;
1417        ps= fi[thedd];
1418
1419        if ( pdebug>=1 )
1420        {
1421            "// 3    fi["+string(thedd-1)+"]"+"  leadexp(fi[thedd-1])="
1422                +string(leadexp(fi[thedd-1]));
1423            "// 3 ps=fi["+string(thedd)+"]"+"  leadexp(ps)="
1424                +string(leadexp(ps));
1425        }
1426
1427        for ( k= nv; k > nv-d; k-- )
1428        {
1429            if ( pdebug>=2 )
1430            {
1431                "// 4 subst(fi["+string(thedd)+"],"
1432                    +string(var(k))+","+string(resl[k])+");";
1433            }
1434            ps = subst(ps,var(k),resl[k]);
1435        }
1436
1437        if ( pdebug>=2 )
1438        { "// 5 substituted ps="+string(ps); }
1439
1440        if ( ps != 0 )
1441        {
1442            lsr= laguerre_solve( ps, prec, prec, 0 );
1443        }
1444        else
1445        {
1446            if ( pdebug>=1 )
1447            { "// 30 ps == 0, thats not cool..."; }
1448            lsr=@ln; // lsr=number(0);
1449        }
1450
1451        if ( pdebug>=1 )
1452        { "// 6 laguerre_solve found roots: lsr["+string(size(lsr))+"]"; }
1453
1454        if ( size(lsr) > 1 )
1455        {
1456            if ( pdebug>=1 )
1457            {
1458                "// 10 checking roots found before, range "
1459                    +string(dd-olddd)+" -- "+string(dd);
1460                "// 10 thedd = "+string(thedd);
1461            }
1462
1463            int i,j,l;
1464            int ls=size(lsr);
1465            int lss;
1466            poly pss;
1467            list nares;
1468            int rroot;
1469            int nares_size;
1470
1471
1472            for ( i = 1; i <= ls; i++ ) // lsr[1..ls]
1473            {
1474                rroot=1;
1475
1476                if ( pdebug>=2 )
1477                {"// 13 root lsr["+string(i)+"] = "+string(lsr[i]);}
1478                for ( l = 0; l <= dd-olddd; l++ )
1479                {
1480                    if ( l+olddd != thedd )
1481                    {
1482                        if ( pdebug>=2 )
1483                        {"// 11 checking ideal element "+string(l+olddd);}
1484                        ps=fi[l+olddd];
1485                        if ( pdebug>=3 )
1486                        {"// 14 ps=fi["+string(l+olddd)+"]";}
1487                        for ( k= nv; k > nv-d; k-- )
1488                        {
1489                            if ( pdebug>=3 )
1490                            {
1491                                "// 11 subst(fi["+string(olddd+l)+"],"
1492                                    +string(var(k))+","+string(resl[k])+");";
1493                            }
1494                            ps = subst(ps,var(k),resl[k]);
1495
1496                        }
1497
1498                        pss=subst(ps,var(k),lsr[i]); // k=nv-d
1499                        if ( pdebug>=3 )
1500                        { "// 15 0 == "+string(pss); }
1501                        if ( pss != 0 )
1502                        {
1503                            if ( system("complexNearZero",
1504                                        leadcoef(pss),
1505                                        prec) )
1506                            {
1507                                if ( pdebug>=2 )
1508                                { "// 16 root "+string(i)+" is a real root"; }
1509                            }
1510                            else
1511                            {
1512                                if ( pdebug>=2 )
1513                                { "// 17 0 == "+string(pss); }
1514                                rroot=0;
1515                            }
1516                        }
1517
1518                    }
1519                }
1520
1521                if ( rroot == 1 ) // add root to list ?
1522                {
1523                    if ( size(nares) > 0 )
1524                    {
1525                        nares=nares[1..size(nares)],lsr[i];
1526                    }
1527                    else
1528                    {
1529                        nares=lsr[i];
1530                    }
1531                    if ( pdebug>=2 )
1532                    { "// 18 added root to list nares"; }
1533                }
1534            }
1535
1536            nares_size=size(nares);
1537            if ( nares_size == 0 )
1538            {
1539                "Numerical problem: No root found...";
1540                "Output may be incorrect!";
1541                nares=@ln;
1542            }
1543
1544            if ( pdebug>=1 )
1545            { "// 20 found <"+string(size(nares))+"> roots"; }
1546
1547            for ( i= 1; i <= nares_size; i++ )
1548            {
1549                resl[nv-d]= nares[i];
1550
1551                if ( dd < elem )
1552                {
1553                    if ( i > 1 )
1554                    {
1555                        rn@++; 
1556                    }
1557                    psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec );
1558                }
1559                else
1560                {
1561                    if ( i > 1 ) {  rn@++; }  //bug found by O.Labs
1562                    if ( pdebug>=1 )
1563                    {"// 30_1 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
1564                    if ( pdebug>=2 )
1565                    { resl; }
1566                    rlist[rn@]=resl;
1567                }
1568            }
1569        }
1570        else
1571        {
1572            if ( pdebug>=2 )
1573            { "// 21 found root to be: "+string(lsr[1]); }
1574            resl[nv-d]= lsr[1];
1575
1576            if ( dd < elem )
1577            {
1578                psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec );
1579            }
1580            else
1581            {
1582                if ( pdebug>=1 )
1583                { "// 30_2 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
1584                if ( pdebug>=2 )
1585                { resl; }
1586                rlist[rn@]=resl;
1587            }
1588        }
1589    }
1590}
1591
1592///////////////////////////////////////////////////////////////////////////////
1593
1594proc fglm_solve( ideal fi, list # )
1595"USAGE:   fglm_solve(i [, p] ); i ideal, p integer
1596ASSUME:  the ground field has char 0.
1597RETURN:  a list of numbers, the complex roots of i;
1598         p>0: gives precision of complex numbers in decimal digits (default:
1599         p=30).
1600NOTE:    The procedure uses a standard basis of i to determine all complex
1601         roots of i.
1602         It creates a ring rC with the same number of variables but with
1603         complex coefficients (and precision p).
1604EXAMPLE: example fglm_solve; shows an example
1605"
1606{
1607    int prec=30;
1608
1609    if ( size(#)>=1  && typeof(#[1])=="int")
1610    {
1611        prec=#[1];
1612    }
1613
1614    lex_solve(stdfglm(fi),prec);
1615    keepring basering;
1616}
1617example
1618{
1619    "EXAMPLE:";echo=2;
1620    ring r = 0,(x,y),lp;
1621    // compute the intersection points of two curves
1622    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1623    fglm_solve(s,10);
1624    rlist;
1625}
1626
1627///////////////////////////////////////////////////////////////////////////////
1628
1629proc lex_solve( ideal fi, list # )
1630"USAGE:   lex_solve( i[,p] ); i=ideal, p=integer,
1631 @format
1632  p>0: gives precision of complex numbers in decimal digits (default: p=30).
1633 @end format
1634ASSUME:  i is a reduced lexicographical Groebner bases of a zero-dimensional
1635         ideal, sorted by increasing leading terms.
1636RETURN:  nothing
1637CREATE:  The procedure creates a complec ring with the same variables but
1638         with complex coefficients (and precision p).
1639         In this ring a list rlist of numbers is created, in which the complex
1640         roots of i are stored.
1641EXAMPLE: example lex_solve; shows an example
1642"
1643{
1644    int prec=30;
1645
1646    if ( size(#)>=1  && typeof(#[1])=="int")
1647    {
1648        prec=#[1];
1649    }
1650
1651    if ( !defined(pdebug) )
1652    {
1653        int pdebug;
1654        pdebug=0;
1655        export pdebug;
1656    }
1657
1658    string orings= nameof(basering);
1659    def oring= basering;
1660
1661    // change the ground field to complex numbers
1662    string nrings= "ring "+orings+"C=(complex,"+string(prec)
1663        +"),("+varstr(basering)+"),lp;";
1664    execute(nrings);
1665
1666    if ( pdebug>=0 )
1667    { "// name of new ring: "+string(nameof(basering));}
1668
1669    // map fi from old to new ring
1670    ideal fi= imap(oring,fi);
1671
1672    // list with entry 0 (number)
1673    number nn=0;
1674    if ( !defined(@ln) )
1675    {
1676        list @ln;
1677        export @ln;
1678    }
1679    @ln=nn;
1680
1681    int idelem= size(fi);
1682    int nv= nvars(basering);
1683    int i,j,k,lis;
1684    list resl,li;
1685
1686    if ( !defined(rlist) )
1687    {
1688        list rlist;
1689        export rlist;
1690    }
1691
1692    if ( !defined(rn@) )
1693    {
1694        int rn@;
1695        export rn@;
1696    }
1697    rn@=0;
1698
1699    li= laguerre_solve(fi[1],prec,prec,0);
1700    lis= size(li);
1701
1702    if ( pdebug>=1 )
1703    {"// laguerre found roots: "+string(size(li));}
1704
1705    for ( j= 1; j <= lis; j++ )
1706    {
1707        if ( pdebug>=1 )
1708        {"// root "+string(j);}
1709        rn@++;
1710        resl[nv]= li[j];
1711        psubst( 1, 2, nv-1, resl, fi, idelem, nv, prec );
1712    }
1713
1714    if ( pdebug>=0 )
1715    {"// list of roots: "+nameof(rlist);}
1716
1717    // keep the ring and exit
1718    keepring basering;
1719}
1720example
1721{
1722    "EXAMPLE:";echo=2;
1723    ring r = 0,(x,y),lp;
1724    // compute the intersection points of two curves
1725    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1726    lex_solve(stdfglm(s),10);
1727    rlist;
1728}
1729
1730///////////////////////////////////////////////////////////////////////////////
1731
1732proc triangLf_solve( ideal fi, list # )
1733"USAGE:   triangLf_solve(i [, p] ); i ideal, p integer,
1734         p>0: gives precision of complex numbers in digits (default: p=30).
1735ASSUME:  the ground field has char 0;  i is a zero-dimensional ideal
1736RETURN:  nothing
1737CREATE:  The procedure creates a ring rC with the same number of variables but
1738         with complex coefficients (and precision p).@*
1739         In rC a list rlist of numbers is created, in which the complex
1740         roots of i are stored.@*
1741         The proc uses a triangular system (Lazard's Algorithm with
1742         factorization) computed from a standard basis to determine recursively
1743         all complex roots with Laguerre's algorithm of input ideal i.
1744EXAMPLE: example triangLf_solve; shows an example
1745"
1746{
1747    int prec=30;
1748
1749    if ( size(#)>=1  && typeof(#[1])=="int")
1750    {
1751        prec=#[1];
1752    }
1753
1754    triang_solve(triangLfak(stdfglm(fi)),prec);
1755    keepring basering;
1756}
1757example
1758{
1759    "EXAMPLE:";echo=2;
1760    ring r = 0,(x,y),lp;
1761    // compute the intersection points of two curves
1762    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1763    triangLf_solve(s,10);
1764    rlist;
1765}
1766
1767///////////////////////////////////////////////////////////////////////////////
1768
1769proc triangM_solve( ideal fi, list # )
1770"USAGE:   triangM_solve(i [, p ] ); i=ideal, p=integer,
1771         p>0: gives precision of complex numbers in digits (default: p=30).
1772ASSUME:  the ground field has char 0;@*
1773         i zero-dimensional ideal
1774RETURN:  nothing
1775CREATE:  The procedure creates a ring rC with the same number of variables but
1776         with complex coefficients (and precision p).@*
1777         In rC a list rlist of numbers is created, in which the complex
1778         roots of i are stored.@*
1779         The proc uses a triangular system (Moellers Algorithm) computed from a
1780         standard basis to determine recursively all complex roots with
1781         Laguerre's algorithm of input ideal i.
1782EXAMPLE: example triangM_solve; shows an example
1783"
1784{
1785    int prec=30;
1786
1787    if ( size(#)>=1  && typeof(#[1])=="int")
1788    {
1789        prec=#[1];
1790    }
1791
1792    triang_solve(triangM(stdfglm(fi)),prec);
1793    keepring basering;
1794}
1795example
1796{
1797    "EXAMPLE:";echo=2;
1798    ring r = 0,(x,y),lp;
1799    // compute the intersection points of two curves
1800    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1801    triangM_solve(s,10);
1802    rlist;
1803}
1804
1805///////////////////////////////////////////////////////////////////////////////
1806
1807proc triangL_solve( ideal fi, list # )
1808"USAGE:   triangL_solve(i [, p] ); i=ideal, p=integer,@*
1809         p>0: gives precision of complex numbers in digits (default: p=30).
1810ASSUME:  the ground field has char 0; i is a zero-dimensional ideal.
1811RETURN:  nothing
1812CREATE:  The procedure creates a ring rC with the same number of variables but
1813         with complex coefficients (and precision p).@*
1814         In rC a list rlist of numbers is created, in which the complex
1815         roots of i are stored.@*
1816         The proc uses a triangular system (Lazard's Algorithm) computed from
1817         a standard basis to determine recursively all complex roots with
1818         Laguerre's algorithm of input ideal i.
1819EXAMPLE: example triangL_solve; shows an example
1820"
1821{
1822    int prec=30;
1823
1824    if ( size(#)>=1  && typeof(#[1])=="int")
1825    {
1826        prec=#[1];
1827    }
1828
1829    triang_solve(triangL(stdfglm(fi)),prec);
1830    keepring basering;
1831}
1832example
1833{
1834    "EXAMPLE:";echo=2;
1835    ring r = 0,(x,y),lp;
1836    // compute the intersection points of two curves
1837    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1838    triangL_solve(s,10);
1839    rlist;
1840}
1841
1842
1843///////////////////////////////////////////////////////////////////////////////
1844
1845proc triang_solve( list lfi, int prec, list # )
1846"USAGE:   triang_solve(l,p [, d] ); l=list, p,d=integers,@*
1847         l a list of finitely many triangular systems, such that the union of
1848         their varieties equals the variety of the initial ideal.@*
1849         p>0: gives precision of complex numbers in digits,@*
1850         d>0: gives precision (1<d<p) for near-zero-determination,@*
1851         (default: d=1/2*p).
1852ASSUME:  the ground field has char 0;@*
1853         l was computed using Algorithm of Lazard or Algorithm of Moeller
1854         (see triang.lib).
1855RETURN:  nothing
1856CREATE:  The procedure creates a ring rC with the same number of variables but
1857         with complex coefficients (and precision p).@*
1858         In rC a list rlist of numbers is created, in which the complex
1859         roots of i are stored.@*
1860EXAMPLE: example triang_solve; shows an example
1861"
1862{
1863    if ( !defined(pdebug) )
1864    {
1865        int pdebug;
1866        export pdebug;
1867    }
1868    pdebug=0;
1869
1870    string orings= nameof(basering);
1871    def oring= basering;
1872
1873    // change the ground field to complex numbers
1874    string nrings= "ring "+orings+"C=(real,"+string(prec)
1875        +",I),("+varstr(basering)+"),lp;";
1876    execute(nrings);
1877
1878    if ( pdebug>=0 )
1879    { "// name of new ring: "+string(nameof(basering));}
1880
1881    // list with entry 0 (number)
1882    number nn=0;
1883    if ( !defined(@ln) )
1884    {
1885        list @ln;
1886        export @ln;
1887    }
1888    @ln=nn;
1889
1890    // set number of digits for zero-comparison of roots
1891    if ( !defined(myCompDigits) )
1892    {
1893        int myCompDigits;
1894        export  myCompDigits;
1895    }
1896    if ( size(#)>=1  && typeof(#[1])=="int" )
1897    {
1898        myCompDigits=#[1];
1899    }
1900    else
1901    {
1902        myCompDigits=(system("getPrecDigits"));
1903    }
1904
1905    if ( pdebug>=1 )
1906    {"// myCompDigits="+string(myCompDigits);}
1907
1908    int idelem;
1909    int nv= nvars(basering);
1910    int i,j,k,lis;
1911    list resu,li;
1912
1913    if ( !defined(rlist) )
1914    {
1915        list rlist;
1916        export rlist;
1917    }
1918
1919    if ( !defined(rn@) )
1920    {
1921        int rn@;
1922        export rn@;
1923    }
1924    rn@=0;
1925
1926    // map the list
1927    list lfi= imap(oring,lfi);
1928
1929    int slfi= size(lfi);
1930    ideal fi;
1931
1932    for ( i= 1; i <= slfi; i++ )
1933    {
1934        // map fi from old to new ring
1935        fi= lfi[i]; //imap(oring,lfi[i]);
1936
1937        idelem= size(fi);
1938
1939        // solve fi[1]
1940        li= laguerre_solve(fi[1],myCompDigits,myCompDigits,0);
1941        lis= size(li);
1942
1943        if ( pdebug>=1 )
1944        {"// laguerre found roots: "+string(size(li));}
1945
1946        for ( j= 1; j <= lis; j++ )
1947        {
1948            if ( pdebug>=1 )
1949            {"// root "+string(j);}
1950            rn@++;
1951            resu[nv]= li[j];
1952            psubst( 1, 2, nv-1, resu, fi, idelem, nv, myCompDigits );
1953        }
1954    }
1955
1956    if ( pdebug>=0 )
1957    {"// list of roots: "+nameof(rlist);}
1958    // keep the ring and exit
1959    keepring basering;
1960}
1961example
1962{
1963    "EXAMPLE:";echo=2;
1964    ring r = 0,(x,y),lp;
1965    // compute the intersection points of two curves
1966    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1967    triang_solve(triangLfak(stdfglm(s)),10);
1968    rlist;
1969}
1970
1971///////////////////////////////////////////////////////////////////////////////
1972
1973proc simplexOut(list l)
1974"USAGE:   simplexOut(l); l list
1975ASSUME:  l is the output of simplex.
1976RETURN:  nothing. The procedure prints the computed solution of simplex
1977         (as strings) in a nice format.     
1978SEE ALSO: simplex
1979EXAMPLE: example simplexOut; shows an example
1980"
1981{
1982  int i,j;
1983  matrix m= l[1];
1984  intvec iposv= l[3];
1985  int icase= l[2];
1986
1987  int cols= ncols(m);
1988  int rows= nrows(m);
1989
1990  int N= l[6];
1991
1992  if ( 1 == icase )  // objective function is unbound
1993  {
1994    "objective function is unbound";
1995    return();
1996  }
1997  if ( -1 == icase )  // no solution satisfies the given constraints
1998  {
1999    "no solution satisfies the given constraints";
2000    return();
2001  }
2002  if ( -2 == icase )  // other error
2003  {
2004    "an error occurred during simplex computation!";
2005    return();
2006  }
2007
2008  for ( i = 1; i <= rows; i++ )
2009  {
2010    if (i == 1)
2011    {
2012      "z = "+string(m[1][1]);
2013    }
2014    else
2015    {
2016      if ( iposv[i-1] <= N )
2017      {
2018        "x"+string(iposv[i-1])+" = "+string(m[i,1]);
2019      }
2020//        else
2021//        {
2022//               "Y"; iposv[i-1]-N+1;
2023//        }
2024    }
2025  }
2026}
2027example
2028{
2029  "EXAMPLE:";echo=2;
2030  ring r = (real,10),(x),lp;
2031
2032  // consider the max. problem:
2033  //
2034  //    maximize  x(1) + x(2) + 3*x(3) - 0.5*x(4)
2035  //
2036  //  with constraints:   x(1) +          2*x(3)          <= 740
2037  //                             2*x(2)          - 7*x(4) <=   0
2038  //                               x(2) -   x(3) + 2*x(4) >=   0.5
2039  //                      x(1) +   x(2) +   x(3) +   x(4)  =   9
2040  //
2041  matrix sm[5][5]=   0, 1, 1, 3,-0.5,
2042                   740,-1, 0,-2, 0,
2043                     0, 0,-2, 0, 7,
2044                   0.5, 0,-1, 1,-2,
2045                     9,-1,-1,-1,-1;
2046
2047  int n = 4;  // number of constraints
2048  int m = 4;  // number of variables
2049  int m1= 2;  // number of <= constraints
2050  int m2= 1;  // number of >= constraints
2051  int m3= 1;  // number of == constraints
2052
2053  list sol=simplex(sm, n, m, m1, m2, m3);
2054  simplexOut(sol);
2055}
2056
2057
2058// local Variables: ***
2059// c-set-style: bsd ***
2060// End: ***
Note: See TracBrowser for help on using the repository browser.