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

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