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

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