source: git/Singular/LIB/solve.lib

spielwiese
Last change on this file was c089ce, checked in by Hans Schoenemann <hannes@…>, 15 months ago
fix: remove some execute from solve.lib
  • Property mode set to 100644
File size: 58.0 KB
Line 
1////////////////////////////////////////////////////////////////////////////
2version="version solve.lib 4.3.1.3 Feb_2023 "; // $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 information
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 splitting";}
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("Insufficient 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 interactive 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      def `outL`=SOL;
709      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=imap(hr,L);
759        export SOL;
760        if (nodisp==0) { print(SOL); }
761        option(set,ovec);
762        dbprint( printlevel-voice+3,"
763// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
764// is stored.
765// To access the list of complex solutions, type (if the name R was assigned
766// to the return value):
767        setring R; SOL; ");
768        return(rinC);
769      }
770      else
771      {
772        setring (Top::`outR`);
773        list SOL=imap(hr,L);
774        def `outL`=SOL;
775        export `outL`;
776        if (nodisp==0) { print(SOL); }
777        option(set,ovec);
778        kill SOL;
779        return("result exported to "+outR+" as list "+outL);
780      }
781    }
782    else
783    {
784      ring internC = create_ring("(complex,"+string(prec)+")", "("+varstr(basering)+")", "lp");
785      ideal H = imap(hr,H);
786      list sp = splittolist(splitsqrfree(H[1],var(1)));
787      jj = size(sp);
788      while(jj>0)
789      {
790        sp[jj][1] = laguerre(sp[jj][1],prec,1);
791        jj--;
792      }
793      setring hr;
794      if (oldr!=1)
795      {
796        ring rinC = create_ring("(complex,"+string(outprec)+")", "("+varstr(basering)+")", "lp");
797        list SOL;
798        list sp=imap(internC,sp);
799        if(mu!=0){ SOL=sp; }
800        else
801        {
802          jj = size(sp);
803          SOL=sp[jj][1];
804          while(jj>1)
805          {
806            jj--;
807            SOL = sp[jj][1]+SOL;
808          }
809        }
810        export SOL;
811        if (nodisp==0) { print(SOL); }
812        option(set,ovec);
813        dbprint( printlevel-voice+3,"
814// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
815// is stored.
816// To access the list of complex solutions, type (if the name R was assigned
817// to the return value):
818        setring R; SOL; ");
819        return(rinC);
820      }
821      else
822      {
823        setring (Top::`outR`);
824        list SOL;
825        list sp=imap(internC,sp);
826        if(mu!=0){ SOL=sp; }
827        else
828        {
829          jj = size(sp);
830          SOL=sp[jj][1];
831          while(jj>1)
832          {
833            jj--;
834            SOL = sp[jj][1]+SOL;
835          }
836        }
837        kill sp;
838        def `outL`=SOL;
839        export `outL`;
840        if (nodisp==0) { print(SOL); }
841        option(set,ovec);
842        kill SOL;
843        return("result exported to "+outR+" as list "+outL);
844      }
845    }
846  }
847
848// the triangular sets (not univariate case)
849  attrib(H,"isSB",1);
850  if (mu==0)
851  {
852    list sp = triangMH(H); // faster, but destroy multiplicity
853  }
854  else
855  {
856    list sp = triangM(H);
857  }
858
859//   create the complex ring and map the result
860  if (outprec<prec)
861  {
862    ring internC = create_ring("(complex,"+string(prec)+")", "("+varstr(hr)+")", "lp");
863  }
864  else
865  {
866    ring rinC = create_ring("(complex,"+string(outprec)+")", "("+varstr(basering)+")", "lp");
867  }
868  list triC = imap(hr,sp);
869
870// solve the tridiagonal systems
871  int js = size(triC);
872  list ret1;
873  if (mu==0)
874  {
875    ret1 = trisolve(list(),triC[1],prec);
876    while (js>1)
877    {
878      ret1 = trisolve(list(),triC[js],prec)+ret1;
879      js--;
880    }
881  }
882  else
883  {
884    ret1 = mutrisolve(list(),triC[1],prec);
885    while (js>1)
886    {
887      ret1 = addlist(mutrisolve(list(),triC[js],prec),ret1,1);
888      js--;
889    }
890    ret1 = finalclear(ret1);
891  }
892
893// final computations
894  option(set,ovec);
895  if (outprec==prec)
896  { // we are in ring rinC
897    if (oldr!=1)
898    {
899      list SOL=ret1;
900      export SOL;
901      if (nodisp==0) { print(SOL); }
902      dbprint( printlevel-voice+3,"
903// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
904// is stored.
905// To access the list of complex solutions, type (if the name R was assigned
906// to the return value):
907        setring R; SOL; ");
908      return(rinC);
909    }
910    else
911    {
912      setring (Top::`outR`);
913      list SOL=imap(rinC,ret1);
914      def `outL`=SOL;
915      export `outL`;
916      if (nodisp==0) { print(SOL); }
917      kill SOL;
918      return("result exported to "+outR+" as list "+outL);
919    }
920  }
921  else
922  {
923    if (oldr!=1)
924    {
925      ring rinC = create_ring("(complex,"+string(outprec)+")", "("+varstr(basering)+")", "lp");
926      list SOL=imap(internC,ret1);
927      export SOL;
928      if (nodisp==0) { print(SOL); }
929      dbprint( printlevel-voice+3,"
930// 'solve' created a ring, in which a list SOL of numbers (the complex solutions)
931// is stored.
932// To access the list of complex solutions, type (if the name R was assigned
933// to the return value):
934        setring R; SOL; ");
935      return(rinC);
936    }
937    else
938    {
939      setring (Top::`outR`);
940      list SOL=imap(internC,ret1);
941      def `outL`=SOL;
942      export `outL`;
943      if (nodisp==0) { print(SOL); }
944      kill SOL;
945      return("result exported to "+outR+" as list "+outL);
946    }
947  }
948}
949example
950{
951    "EXAMPLE:";echo=2;
952    // Find all roots of a multivariate ideal using triangular sets:
953    int d,t,s = 4,3,2 ;
954    int i;
955    ring A=0,x(1..d),dp;
956    poly p=-1;
957    for (i=d; i>0; i--) { p=p+x(i)^s; }
958    ideal I = x(d)^t-x(d)^s+p;
959    for (i=d-1; i>0; i--) { I=x(i)^t-x(i)^s+p,I; }
960    I;
961    // the multiplicity is
962    vdim(std(I));
963    def AC=solve(I,6,0,"nodisplay");  // solutions should not be displayed
964    // list of solutions is stored in AC as the list SOL (default name)
965    setring AC;
966    size(SOL);               // number of different solutions
967    SOL[5];                  // the 5th solution
968    // you must start with char. 0
969    setring A;
970    def AC1=solve(I,6,1,"nodisplay");
971    setring AC1;
972    size(SOL);               // number of different multiplicities
973    SOL[1][1][1];            // a solution with
974    SOL[1][2];               // multiplicity 1
975    SOL[2][1][1];            // a solution with
976    SOL[2][2];               // multiplicity 12
977    // the number of different solutions is equal to
978    size(SOL[1][1])+size(SOL[2][1]);
979    // the number of complex solutions (counted with multiplicities) is
980    size(SOL[1][1])*SOL[1][2]+size(SOL[2][1])*SOL[2][2];
981}
982//////////////////////////////////////////////////////////////////////////////
983//                subprocedures for solve
984
985
986/*
987* return one zero-solution
988*/
989static proc zerolist(int nv)
990{
991  list ret;
992  int i;
993  number o=0;
994
995  for (i=nv;i>0;i--){ret[i] = o;}
996  return(ret);
997}
998
999/* ----------------------- check solution ----------------------- */
1000static proc multsol(list ff, int c)
1001{
1002  int i,j;
1003
1004  i = 0;
1005  j = size(ff);
1006  while (j>0)
1007  {
1008    if(c){i = i+ff[j][2]*size(ff[j][1]);}
1009    else{i = i+size(ff[j][1]);}
1010    j--;
1011  }
1012  return(i);
1013}
1014
1015/*
1016* the inputideal A => zero ?
1017*/
1018static proc checksol(ideal A, list lr)
1019{
1020  int d = nvars(basering);
1021  list ro;
1022  ideal re,h;
1023  int i,j,k;
1024
1025  for (i=size(lr);i>0;i--)
1026  {
1027    ro = lr[i];
1028    for (j=d;j>0;j--)
1029    {
1030      re[j] = var(j)-ro[j];
1031    }
1032    attrib(re,"isSB",1);
1033    k = size(reduce(A,re,5));
1034    if (k){return(i);}
1035  }
1036  return(0);
1037}
1038
1039/*
1040*  compare 2 solutions: returns 0 for equal
1041*/
1042static proc cmpn(list a,list b)
1043{
1044  int ii;
1045
1046  for(ii=size(a);ii>0;ii--){if(a[ii]!=b[ii]) break;}
1047  return(ii);
1048}
1049
1050/*
1051*  delete equal solutions in the list
1052*/
1053static proc delequal(list r, int w)
1054{
1055  list h;
1056  int i,j,k,c;
1057
1058  if (w)
1059  {
1060    k = size(r);
1061    h = r[k][1];
1062    k--;
1063    while (k>0)
1064    {
1065      h = r[k][1]+h;
1066      k--;
1067    }
1068  }
1069  else{h = r;}
1070  k=size(h);
1071  i=1;
1072  while(i<k)
1073  {
1074    j=k;
1075    while(j>i)
1076    {
1077      c=cmpn(h[i],h[j]);
1078      if(c==0)
1079      {
1080        h=delete(h,j);
1081        k--;
1082      }
1083      j--;
1084    }
1085    i++;
1086  }
1087  return(h);
1088}
1089
1090/* ----------------------- substitution ----------------------- */
1091/*
1092* instead of subst(T,var(v),n), much faster
1093*   need option(redSB) !
1094*/
1095static proc linreduce(ideal T, int v, number n)
1096{
1097  ideal re = var(v)-n;
1098  attrib (re,"isSB",1);
1099  return (reduce(T,re));
1100}
1101
1102/* ----------------------- triangular solution ----------------------- */
1103/*
1104* solution of one tridiagonal system T
1105*   with precision prec
1106*   T[1] is univariant in var(1)
1107*   list o is empty for the first call
1108*/
1109static proc trisolve(list o, ideal T, int prec)
1110{
1111  list lroots,ll;
1112  ideal S;
1113  int i,d;
1114
1115  d = size(T);
1116  S = interred(ideal(T[1],diff(T[1],var(d))));
1117  if (deg(S[1]))
1118  {
1119    T[1] = exdiv(T[1],S[1],var(d));
1120  }
1121  ll = laguerre(T[1],prec,1);
1122  for (i=size(ll);i>0;i--){ll[i] = list(ll[i])+o;}
1123  if (d==1){return(ll);}
1124  for (i=size(ll);i>0;i--)
1125  {
1126    S = linreduce(ideal(T[2..d]),d,ll[i][1]);
1127    lroots = trisolve(ll[i],S,prec)+lroots;
1128  }
1129  return(lroots);
1130}
1131
1132/* ------------------- triangular solution (mult) ------------------- */
1133/*
1134*  recompute equal solutions w.r.t. multiplicity
1135*/
1136static proc finalclear(list b)
1137{
1138  list a = b;
1139  list r;
1140  int i,l,ju,j,k,ku,mu,c;
1141
1142// a[i] only
1143  i = 1;
1144  while (i<=size(a))
1145  {
1146    ju = size(a[i][1]);
1147    j = 1;
1148    while (j<=ju)
1149    {
1150      mu = 1;
1151      k = j+1;
1152      while (k<=ju)
1153      {
1154        c = cmpn(a[i][1][j],a[i][1][k]);
1155        if (c==0)
1156        {
1157          a[i][1] = delete(a[i][1],k);
1158          ju--;
1159          mu++;
1160        }
1161        else{k++;}
1162      }
1163      if (mu>1)
1164      {
1165        r[1] = a[i];
1166        r[1][1] = list(a[i][1][j]);
1167        a[i][1] = delete(a[i][1],j);
1168        a = addlist(r,a,mu);
1169        ju--;
1170      }
1171      else{j++;}
1172    }
1173    if (ju==0){a = delete(a,i);}
1174    else{i++;}
1175  }
1176// a[i], a[l]
1177  i = 1;
1178  while (i<size(a))
1179  {
1180    ju = size(a[i][1]);
1181    l = i+1;
1182    while (l<=size(a))
1183    {
1184      ku = size(a[l][1]);
1185      j = 1;
1186      while (j<=ju)
1187      {
1188        mu = 0;
1189        k = 1;
1190        while (k<=ku)
1191        {
1192          c = cmpn(a[i][1][j],a[l][1][k]);
1193          if (c==0)
1194          {
1195            mu = a[i][2]+a[l][2];
1196            r[1] = a[l];
1197            r[1][1] = list(a[l][1][k]);
1198            r[1][2] = mu;
1199            a[l][1] = delete(a[l][1],k);
1200            a = addlist(r,a,1);
1201            ku--;
1202            break;
1203          }
1204          else{k++;}
1205        }
1206        if (mu)
1207        {
1208          a[i][1] = delete(a[i][1],j);
1209          ju--;
1210        }
1211        else{j++;}
1212      }
1213      if (ku){l++;}
1214      else
1215      {
1216        a = delete(a,l);
1217      }
1218    }
1219    if (ju){i++;}
1220    else
1221    {
1222      a = delete(a,i);
1223    }
1224  }
1225  return(a);
1226}
1227
1228/*
1229* convert to list
1230*/
1231static proc splittolist(ideal sp)
1232{
1233  int j = size(sp);
1234  list spl = list(list(sp[j],j));
1235
1236  j--;
1237  while (j>0)
1238  {
1239    if (deg(sp[j]))
1240    {
1241      spl = list(list(sp[j],j))+spl;
1242    }
1243    j--;
1244  }
1245  return(spl);
1246}
1247
1248/*
1249*  multiply the multiplicity
1250*/
1251static proc multlist(list a, int m)
1252{
1253  int i;
1254  for (i=size(a);i>0;i--){a[i][2] = a[i][2]*m;}
1255  return(a);
1256}
1257
1258/*
1259*  a+b w.r.t. to multiplicity as ordering
1260*    (programming like spolys)
1261*/
1262static proc addlist(list a, list b, int m)
1263{
1264  int i,j,k,l,s;
1265  list r = list();
1266
1267  if (m>1){a = multlist(a,m);}
1268  k = size(a);
1269  l = size(b);
1270  i = 1;
1271  j = 1;
1272  while ((i<=k)&&(j<=l))
1273  {
1274    s = a[i][2]-b[j][2];
1275    if (s>=0)
1276    {
1277      r = r+list(b[j]);
1278      j++;
1279      if (s==0)
1280      {
1281        s = size(r);
1282        r[s][1] = r[s][1]+a[i][1];
1283        i++;
1284      }
1285    }
1286    else
1287    {
1288      r = r+list(a[i]);
1289      i++;
1290    }
1291  }
1292  if (i>k)
1293  {
1294    if (j<=l){r = r+list(b[j..l]);}
1295  }
1296  else{r = r+list(a[i..k]);}
1297  return(r);
1298}
1299
1300/*
1301* solution of one tridiagonal system T with multiplicity
1302*   with precision prec
1303*   T[1] is univariant in var(1)
1304*   list o is empty for the first call
1305*/
1306static proc mutrisolve(list o, ideal T, int prec)
1307{
1308  list lroots,ll,sp;
1309  ideal S,h;
1310  int i,d,m,z;
1311
1312  d = size(T);
1313  sp = splittolist(splitsqrfree(T[1],var(d)));
1314  if (d==1){return(l_mutrisolve(sp,o,prec));}
1315  z = size(sp);
1316  while (z>0)
1317  {
1318    m = sp[z][2];
1319    ll = laguerre(sp[z][1],prec,1);
1320    i = size(ll);
1321    while(i>0)
1322    {
1323      h = linreduce(ideal(T[2..d]),d,ll[i]);
1324      if (size(lroots))
1325      {
1326        lroots = addlist(mutrisolve(list(ll[i])+o,h,prec),lroots,m);
1327      }
1328      else
1329      {
1330        lroots = mutrisolve(list(ll[i])+o,h,prec);
1331        if (m>1){lroots=multlist(lroots,m);}
1332      }
1333      i--;
1334    }
1335    z--;
1336  }
1337  return(lroots);
1338}
1339
1340/*
1341*  the last call, we are ready
1342*/
1343static proc l_mutrisolve(list sp, list o, int prec)
1344{
1345  list lroots,ll;
1346  int z,m,i;
1347
1348  z = size(sp);
1349  while (z>0)
1350  {
1351    m = sp[z][2];
1352    ll = laguerre(sp[z][1],prec,1);
1353    for (i=size(ll);i>0;i--){ll[i] = list(ll[i])+o;}
1354    if (size(lroots))
1355    {
1356      lroots = addlist(list(list(ll,m)),lroots,1);
1357    }
1358    else
1359    {
1360      lroots = list(list(ll,m));
1361    }
1362    z--;
1363  }
1364  return(lroots);
1365}
1366///////////////////////////////////////////////////////////////////////////////
1367
1368proc ures_solve( ideal gls, list # )
1369"USAGE:   ures_solve(i [, k, p] ); i = ideal, k, p = integers
1370   k=0: use sparse resultant matrix of Gelfand, Kapranov and Zelevinsky, @*
1371   k=1: use resultant matrix of Macaulay which works only for
1372          homogeneous ideals,@*
1373   p>0: defines precision of the long floats for internal computation
1374          if the basering is not complex (in decimal digits),
1375   (default: k=0, p=30)
1376ASSUME:  i is a zerodimensional ideal given by a quadratic system, that is,@*
1377         nvars(basering) = ncols(i) = number of vars actually occurring in i,
1378RETURN:  If the ground field is the field of complex numbers: list of numbers
1379         (the complex roots of the polynomial system i=0). @*
1380         Otherwise: ring @code{R} with the same number of variables but with
1381         complex coefficients (and precision p). @code{R} comes with a list
1382         @code{SOL} of numbers, in which complex roots of the polynomial
1383         system i are stored: @*
1384EXAMPLE: example ures_solve; shows an example
1385"
1386{
1387  int typ=0;// defaults
1388  int prec=30;
1389
1390  if ( size(#) > 0 )
1391  {
1392    typ= #[1];
1393    if ( typ < 0 || typ > 1 )
1394    {
1395      ERROR("Valid values for second parameter k are:
1396                   0: use sparse Resultant (default)
1397                   1: use Macaulay Resultant");
1398    }
1399  }
1400  if ( size(#) > 1 )
1401  {
1402    prec= #[2];
1403    if ( prec < 8 )
1404    {
1405      prec = 8;
1406    }
1407  }
1408
1409  list LL=uressolve(gls,typ,prec,1);
1410  int sizeLL=size(LL);
1411  if (sizeLL==0)
1412  {
1413    dbprint(printlevel-voice+3,"No solution found!");
1414    return(list());
1415  }
1416  if (typeof(LL[1][1])=="string")
1417  {
1418    int ii,jj;
1419    int nv=size(LL[1]);
1420    ring rinC = create_ring("(complex,"+string(prec)+",I)", "("+varstr(basering)+")", "lp");
1421    list SOL,SOLnew;
1422    for (ii=1; ii<=sizeLL; ii++)
1423    {
1424      SOLnew=list();
1425      for (jj=1; jj<=nv; jj++)
1426      {
1427        execute("SOLnew["+string(jj)+"]="+LL[ii][jj]+";");
1428      }
1429      SOL[ii]=SOLnew;
1430    }
1431    kill SOLnew;
1432    export SOL;
1433    dbprint( printlevel-voice+3,"
1434// 'ures_solve' created a ring, in which a list SOL of numbers (the complex
1435// solutions) is stored.
1436// To access the list of complex solutions, type (if the name R was assigned
1437// to the return value):
1438        setring R; SOL; ");
1439    return(rinC);
1440  }
1441  else
1442  {
1443    return(LL);
1444  }
1445}
1446example
1447{
1448    "EXAMPLE:";echo=2;
1449    // compute the intersection points of two curves
1450    ring rsq = 0,(x,y),lp;
1451    ideal gls=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1452    def R=ures_solve(gls,0,16);
1453    setring R; SOL;
1454}
1455///////////////////////////////////////////////////////////////////////////////
1456
1457proc mp_res_mat( ideal i, list # )
1458"USAGE:   mp_res_mat(i [, k] ); i ideal, k integer,
1459    k=0: sparse resultant matrix of Gelfand, Kapranov and Zelevinsky,@*
1460    k=1: resultant matrix of Macaulay (k=0 is default)
1461ASSUME:  The number of elements in the input system must be the number of
1462         variables in the basering plus one;
1463         if k=1 then i must be homogeneous.
1464RETURN:  module representing the multipolynomial resultant matrix
1465EXAMPLE: example mp_res_mat; shows an example
1466"
1467{
1468  int typ=0;
1469
1470  if ( size(#) > 0 )
1471  {
1472    typ= #[1];
1473    if ( typ < 0 || typ > 1 )
1474    {
1475      ERROR("Valid values for third parameter are:
1476                   0: sparse resultant (default)
1477                   1: Macaulay resultant");
1478    }
1479  }
1480  return(mpresmat(i,typ));
1481}
1482example
1483{
1484    "EXAMPLE:";echo=2;
1485    // compute resultant matrix in ring with parameters (sparse resultant matrix)
1486    ring rsq= (0,u0,u1,u2),(x1,x2),lp;
1487    ideal i= u0+u1*x1+u2*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
1488    module m = mp_res_mat(i);
1489    print(m);
1490    // computing sparse resultant
1491    det(m);
1492
1493    // compute resultant matrix (Macaulay resultant matrix)
1494    ring rdq= (0,u0,u1,u2),(x0,x1,x2),lp;
1495    ideal h=  homog(imap(rsq,i),x0);
1496    h;
1497
1498    module m = mp_res_mat(h,1);
1499    print(m);
1500    // computing Macaulay resultant (should be the same as above!)
1501    det(m);
1502
1503    // compute numerical sparse resultant matrix
1504    setring rsq;
1505    ideal ir= 15+2*x1+5*x2,x1^2 + x2^2 - 10,x1^2 + x1*x2 + 2*x2^2 - 16;
1506    module mn = mp_res_mat(ir);
1507    print(mn);
1508    // computing sparse resultant
1509    det(mn);
1510}
1511///////////////////////////////////////////////////////////////////////////////
1512
1513proc interpolate( ideal p, ideal w, int d )
1514"USAGE:   interpolate(p,v,d); p,v=ideals of numbers, d=integer
1515ASSUME:  Ground field K is the field of rational numbers, p and v are lists
1516         of elements of the ground field K with p[j] != -1,0,1, size(p) = n
1517         (= number of vars) and size(v)=N=(d+1)^n.
1518RETURN:  poly f, the unique polynomial f of degree n*d with prescribed values
1519         v[i] at the points p(i)=(p[1]^(i-1),..,p[n]^(i-1)), i=1,..,N.
1520NOTE:    mainly useful when n=1, i.e. f is satisfying f(p^(i-1)) = v[i],
1521         i=1..d+1.
1522SEE ALSO: vandermonde.
1523EXAMPLE: example interpolate; shows an example
1524"
1525{
1526    return(vandermonde(p,w,d));
1527}
1528example
1529{
1530    "EXAMPLE:";  echo=2;
1531    ring r1 = 0,(x),lp;
1532    // determine f with deg(f) = 4 and
1533    // v = values of f at points 3^0, 3^1, 3^2, 3^3, 3^4
1534    ideal v=16,0,11376,1046880,85949136;
1535    interpolate( 3, v, 4 );
1536}
1537
1538///////////////////////////////////////////////////////////////////////////////
1539// changed for Singular 3
1540// Return value is now a list: (rlist, rn@)
1541static proc psubst( int d, int dd, int n, list resl,
1542                    ideal fi, int elem, int nv, int prec, int rn@, list rlist)
1543{
1544    //   nv: number of ring variables         (fixed value)
1545    // elem: number of elements in ideal fi   (fixed value)
1546    //   fi: input ideal                      (fixed value)
1547    //   rl: output list of roots
1548    // resl: actual list of roots
1549    //    n:
1550    //   dd: actual element of fi
1551    //    d: actual variable
1552
1553    list LL;
1554    int pdebug;
1555    int olddd=dd;
1556
1557    dbprint(printlevel-voice+2, "// 0 step "+string(dd)+" of "+string(elem) );
1558
1559    if ( dd <= elem )
1560    {
1561        int loop = 1;
1562        int k;
1563        list lsr,lh;
1564        poly ps;
1565        int thedd;
1566
1567        dbprint( printlevel-voice+1,"// 1 dd = "+string(dd) );
1568
1569        thedd=0;
1570        while ( (dd+1 <= elem) && loop )
1571        {
1572            ps= fi[dd+1];
1573
1574            if ( n-1 > 0 )
1575            {
1576                dbprint( printlevel-voice,
1577                    "// 2 ps=fi["+string(dd+1)+"]"+" size="
1578                        +string(size(coeffs(ps,var(n-1))))
1579                        +"  leadexp(ps)="+string(leadexp(ps)) );
1580
1581                if ( size(coeffs(ps,var(n-1))) == 1 )
1582                {
1583                    dd++;
1584                    // hier Leading-Exponent pruefen???
1585                    // oder ist das Polynom immer als letztes in der Liste?!?
1586                    // leadexp(ps)
1587                }
1588                else
1589                {
1590                    loop=0;
1591                }
1592            }
1593            else
1594            {
1595                dbprint( printlevel-voice,
1596                    "// 2 ps=fi["+string(dd+1)+"]"+"  leadexp(ps)="
1597                        +string(leadexp(ps)) );
1598                dd++;
1599            }
1600        }
1601        thedd=dd;
1602        ps= fi[thedd];
1603
1604        dbprint( printlevel-voice+1,
1605            "// 3    fi["+string(thedd-1)+"]"+"  leadexp(fi[thedd-1])="
1606                +string(leadexp(fi[thedd-1])) );
1607        dbprint( printlevel-voice+1,
1608            "// 3 ps=fi["+string(thedd)+"]"+"  leadexp(ps)="
1609                +string(leadexp(ps)) );
1610
1611        for ( k= nv; k > nv-d; k-- )
1612        {
1613            dbprint( printlevel-voice,
1614                "// 4 subst(fi["+string(thedd)+"],"
1615                    +string(var(k))+","+string(resl[k])+");" );
1616            ps = subst(ps,var(k),resl[k]);
1617        }
1618
1619        dbprint( printlevel-voice, "// 5 substituted ps="+string(ps) );
1620
1621        if ( ps != 0 )
1622        {
1623            lsr= laguerre_solve( ps, prec, prec, 0 );
1624        }
1625        else
1626        {
1627            dbprint( printlevel-voice+1,"// 30 ps == 0, that's not cool...");
1628            lsr=list(number(0));
1629        }
1630
1631        dbprint( printlevel-voice+1,
1632         "// 6 laguerre_solve found roots: lsr["+string(size(lsr))+"]" );
1633
1634        if ( size(lsr) > 1 )
1635        {
1636            dbprint( printlevel-voice+1,
1637                "// 10 checking roots found before, range "
1638                    +string(dd-olddd)+" -- "+string(dd) );
1639            dbprint( printlevel-voice+1,
1640                "// 10 thedd = "+string(thedd) );
1641
1642            int i,j,l;
1643            int ls=size(lsr);
1644            int lss;
1645            poly pss;
1646            list nares;
1647            int rroot;
1648            int nares_size;
1649
1650
1651            for ( i = 1; i <= ls; i++ ) // lsr[1..ls]
1652            {
1653                rroot=1;
1654
1655                if ( pdebug>=2 )
1656                {"// 13 root lsr["+string(i)+"] = "+string(lsr[i]);}
1657                for ( l = 0; l <= dd-olddd; l++ )
1658                {
1659                    if ( l+olddd != thedd )
1660                    {
1661                        if ( pdebug>=2 )
1662                        {"// 11 checking ideal element "+string(l+olddd);}
1663                        ps=fi[l+olddd];
1664                        if ( pdebug>=3 )
1665                        {"// 14 ps=fi["+string(l+olddd)+"]";}
1666                        for ( k= nv; k > nv-d; k-- )
1667                        {
1668                            if ( pdebug>=3 )
1669                            {
1670                                "// 11 subst(fi["+string(olddd+l)+"],"
1671                                    +string(var(k))+","+string(resl[k])+");";
1672                            }
1673                            ps = subst(ps,var(k),resl[k]);
1674
1675                        }
1676
1677                        pss=subst(ps,var(k),lsr[i]); // k=nv-d
1678                        if ( pdebug>=3 )
1679                        { "// 15 0 == "+string(pss); }
1680                        if ( pss != 0 )
1681                        {
1682                            if ( system("complexNearZero",
1683                                        leadcoef(pss),
1684                                        prec) )
1685                            {
1686                                if ( pdebug>=2 )
1687                                { "// 16 root "+string(i)+" is a real root"; }
1688                            }
1689                            else
1690                            {
1691                                if ( pdebug>=2 )
1692                                { "// 17 0 == "+string(pss); }
1693                                rroot=0;
1694                            }
1695                        }
1696
1697                    }
1698                }
1699
1700                if ( rroot == 1 ) // add root to list ?
1701                {
1702                    if ( size(nares) > 0 )
1703                    {
1704                        nares=nares[1..size(nares)],lsr[i];
1705                    }
1706                    else
1707                    {
1708                        nares=lsr[i];
1709                    }
1710                    if ( pdebug>=2 )
1711                    { "// 18 added root to list nares"; }
1712                }
1713            }
1714
1715            nares_size=size(nares);
1716            if ( nares_size == 0 )
1717            {
1718                "Numerical problem: No root found...";
1719                "Output may be incorrect!";
1720                nares=list(number(0));
1721            }
1722
1723            if ( pdebug>=1 )
1724            { "// 20 found <"+string(size(nares))+"> roots"; }
1725
1726            for ( i= 1; i <= nares_size; i++ )
1727            {
1728                resl[nv-d]= nares[i];
1729
1730                if ( dd < elem )
1731                {
1732                    if ( i > 1 )
1733                    {
1734                        rn@++;
1735                    }
1736                    LL = psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec,
1737                                 rn@, rlist );
1738                    rlist = LL[1];
1739                    rn@ = LL[2];
1740                }
1741                else
1742                {
1743                   if ( i > 1 ) {  rn@++; }  //bug found by O.Labs
1744                   if ( pdebug>=1 )
1745                   {"// 30_1 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
1746                   if ( pdebug>=2 ){ resl; }
1747                   rlist[rn@]=resl;
1748                }
1749            }
1750        }
1751        else
1752        {
1753            if ( pdebug>=2 )
1754            { "// 21 found root to be: "+string(lsr[1]); }
1755            resl[nv-d]= lsr[1];
1756
1757            if ( dd < elem )
1758            {
1759                LL= psubst( d+1, dd+1, n-1, resl, fi, elem, nv, prec,
1760                            rn@, rlist );
1761                rlist = LL[1];
1762                rn@ = LL[2];
1763            }
1764            else
1765            {
1766                if ( pdebug>=1 )
1767                { "// 30_2 <"+string(rn@)+"> "+string(size(resl))+" <-----";}
1768                if ( pdebug>=2 )
1769                { resl; }
1770                rlist[rn@]=resl;
1771            }
1772        }
1773    }
1774    return(list(rlist,rn@));
1775}
1776
1777///////////////////////////////////////////////////////////////////////////////
1778
1779proc fglm_solve( ideal fi, list # )
1780"USAGE:   fglm_solve(i [, p] ); i ideal, p integer
1781ASSUME:  the ground field has char 0.
1782RETURN:  ring @code{R} with the same number of variables but with complex
1783         coefficients (and precision p). @code{R} comes with a list
1784         @code{rlist} of numbers, in which the complex roots of i are stored.@*
1785         p>0: gives precision of complex numbers in decimal digits [default:
1786         p=30].
1787NOTE:    The procedure uses a standard basis of i to determine all complex
1788         roots of i.
1789EXAMPLE: example fglm_solve; shows an example
1790"
1791{
1792    int prec=30;
1793
1794    if ( size(#)>=1  && typeof(#[1])=="int")
1795    {
1796        prec=#[1];
1797    }
1798    def save=basering;
1799    list L=ringlist(save);
1800    L[3]=list(list("lp",1:nvars(save)),list("C",1));
1801    def Rlex=ring(L);
1802    setring Rlex;
1803    ideal fi=fetch(save,fi);
1804    fi=stdfglm(fi);
1805    def R = lex_solve(fi,prec);
1806    dbprint( printlevel-voice+3,"
1807// 'fglm_solve' created a ring, in which a list rlist of numbers (the
1808// complex solutions) is stored.
1809// To access the list of complex solutions, type (if the name R was assigned
1810// to the return value):
1811        setring R; rlist; ");
1812    return(R);
1813}
1814example
1815{
1816    "EXAMPLE:";echo=2;
1817    ring r = 0,(x,y),dp;
1818    // compute the intersection points of two curves
1819    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1820    def R = fglm_solve(s,10);
1821    setring R; rlist;
1822}
1823
1824///////////////////////////////////////////////////////////////////////////////
1825
1826proc lex_solve( ideal fi, list # )
1827"USAGE:   lex_solve( i[,p] ); i=ideal, p=integer,
1828  p>0: gives precision of complex numbers in decimal digits (default: p=30).
1829ASSUME:  i is a reduced lexicographical Groebner bases of a zero-dimensional
1830         ideal, sorted by increasing leading terms.
1831RETURN:  ring @code{R} with the same number of variables but with complex
1832         coefficients (and precision p). @code{R} comes with a list
1833         @code{rlist} of numbers, in which the complex roots of i are stored.
1834EXAMPLE: example lex_solve; shows an example
1835"
1836{
1837    int prec=30;
1838    list LL;
1839
1840    if ( size(#)>=1  && typeof(#[1])=="int")
1841    {
1842        prec=#[1];
1843    }
1844
1845    if ( !defined(pdebug) ) { int pdebug; }
1846    def oring= basering;
1847
1848    // change the ground field to complex numbers
1849    list l1 = ringlist(basering)[2];
1850    ring RC = create_ring("(complex,"+string(prec)+")", l1, "lp");
1851
1852    // map fi from old to new ring
1853    ideal fi= imap(oring,fi);
1854
1855    int idelem= size(fi);
1856    int nv= nvars(basering);
1857    int i,j,k,lis;
1858    list resl,li;
1859
1860    if ( !defined(rlist) )
1861    {
1862        list rlist;
1863        export rlist;
1864    }
1865
1866    li= laguerre_solve(fi[1],prec,prec,0);
1867    lis= size(li);
1868
1869    dbprint(printlevel-voice+2,"// laguerre found roots: "+string(size(li)));
1870    int rn@;
1871
1872    for ( j= 1; j <= lis; j++ )
1873    {
1874        dbprint(printlevel-voice+1,"// root "+string(j) );
1875        rn@++;
1876        resl[nv]= li[j];
1877        LL = psubst( 1, 2, nv-1, resl, fi, idelem, nv, prec, rn@, rlist );
1878        rlist=LL[1];
1879        rn@=LL[2];
1880    }
1881
1882    dbprint( printlevel-voice+3,"
1883// 'lex_solve' created a ring, in which a list rlist of numbers (the
1884// complex solutions) is stored.
1885// To access the list of complex solutions, type (if the name R was assigned
1886// to the return value):
1887        setring R; rlist; ");
1888
1889    return(RC);
1890}
1891example
1892{
1893    "EXAMPLE:";echo=2;
1894    ring r = 0,(x,y),lp;
1895    // compute the intersection points of two curves
1896    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1897    def R = lex_solve(stdfglm(s),10);
1898    setring R; rlist;
1899}
1900
1901///////////////////////////////////////////////////////////////////////////////
1902
1903proc triangLf_solve( ideal fi, list # )
1904"USAGE:   triangLf_solve(i [, p] ); i ideal, p integer,
1905         p>0: gives precision of complex numbers in digits (default: p=30).
1906ASSUME:  the ground field has char 0;  i is a zero-dimensional ideal
1907RETURN:  ring @code{R} with the same number of variables but with complex
1908         coefficients (and precision p). @code{R} comes with a list
1909         @code{rlist} of numbers, in which the complex roots of i are stored.
1910NOTE:    The procedure uses a triangular system (Lazard's Algorithm with
1911         factorization) computed from a standard basis to determine
1912         recursively all complex roots of the input ideal i with Laguerre's
1913         algorithm.
1914EXAMPLE: example triangLf_solve; shows an example
1915"
1916{
1917    int prec=30;
1918
1919    if ( size(#)>=1  && typeof(#[1])=="int")
1920    {
1921        prec=#[1];
1922    }
1923
1924    def save=basering;
1925    list L=ringlist(save);
1926    L[3]=list(list("lp",1:nvars(save)),list("C",1));
1927    def Rlex=ring(L);
1928    setring Rlex;
1929    ideal fi=fetch(save,fi);
1930    fi=stdfglm(fi);
1931    def R=triang_solve(triangLfak(fi),prec);
1932    dbprint( printlevel-voice+3,"
1933// 'triangLf_solve' created a ring, in which a list rlist of numbers (the
1934// complex solutions) is stored.
1935// To access the list of complex solutions, type (if the name R was assigned
1936// to the return value):
1937        setring R; rlist; ");
1938    return(R);
1939}
1940example
1941{
1942    "EXAMPLE:";echo=2;
1943    ring r = 0,(x,y),lp;
1944    // compute the intersection points of two curves
1945    ideal s = x2 + y2 - 10, x2 + xy + 2y2 - 16;
1946    def R = triangLf_solve(s,10);
1947    setring R; rlist;
1948}
1949
1950///////////////////////////////////////////////////////////////////////////////
1951
1952proc triangM_solve( ideal fi, list # )
1953"USAGE:   triangM_solve(i [, p ] ); i=ideal, p=integer,
1954         p>0: gives precision of complex numbers in digits (default: p=30).
1955ASSUME:  the ground field has char 0;@*
1956         i zero-dimensional ideal
1957RETURN:  ring @code{R} with the same number of variables but with complex
1958         coefficients (and precision p). @code{R} comes with a list
1959         @code{rlist} of numbers, in which the complex roots of i are stored.
1960NOTE:    The procedure uses a triangular system (Moellers Algorithm) computed
1961         from a standard basis  of input ideal i to determine recursively all
1962         complex roots with Laguerre's algorithm.
1963EXAMPLE: example triangM_solve; shows an example
1964"
1965{
1966    int prec=30;
1967
1968    if ( size(#)>=1  && typeof(#[1])=="int")
1969    {
1970        prec=#[1];
1971    }
1972
1973    def save=basering;
1974    list L=ringlist(save);
1975    L[3]=list(list("lp",1:nvars(save)),list("C",1));
1976    def Rlex=ring(L);
1977    setring Rlex;
1978    ideal fi=fetch(save,fi);
1979    fi=stdfglm(fi);
1980    def R = triang_solve(triangM(fi),prec);
1981    dbprint( printlevel-voice+3,"
1982// 'triangM_solve' created a ring, in which a list rlist of numbers (the
1983// complex solutions) is stored.
1984// To access the list of complex solutions, type (if the name R was assigned
1985// to the return value):
1986        setring R; rlist; ");
1987    return(R);
1988}
1989example
1990{
1991    "EXAMPLE:";echo=2;
1992    ring r = 0,(x,y),lp;
1993    // compute the intersection points of two curves
1994    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
1995    def R = triangM_solve(s,10);
1996    setring R; rlist;
1997}
1998
1999///////////////////////////////////////////////////////////////////////////////
2000
2001proc triangL_solve( ideal fi, list # )
2002"USAGE:   triangL_solve(i [, p] ); i=ideal, p=integer,@*
2003         p>0: gives precision of complex numbers in digits (default: p=30).
2004ASSUME:  the ground field has char 0; i is a zero-dimensional ideal.
2005RETURN:  ring @code{R} with the same number of variables, but with complex
2006         coefficients (and precision p). @code{R} comes with a list
2007         @code{rlist} of numbers, in which the complex roots of i are stored.
2008NOTE:    The procedure uses a triangular system (Lazard's Algorithm) computed
2009         from a standard basis of input ideal i to determine recursively all
2010         complex roots with Laguerre's algorithm.
2011EXAMPLE: example triangL_solve; shows an example
2012"
2013{
2014    int prec=30;
2015
2016    if ( size(#)>=1  && typeof(#[1])=="int")
2017    {
2018        prec=#[1];
2019    }
2020
2021    def save=basering;
2022    list L=ringlist(save);
2023    L[3]=list(list("lp",1:nvars(save)),list("C",1));
2024    def Rlex=ring(L);
2025    setring Rlex;
2026    ideal fi=fetch(save,fi);
2027    fi=stdfglm(fi);
2028    def R=triang_solve(triangL(fi),prec);
2029    dbprint( printlevel-voice+3,"
2030// 'triangL_solve' created a ring, in which a list rlist of numbers (the
2031// complex solutions) is stored.
2032// To access the list of complex solutions, type (if the name R was assigned
2033// to the return value):
2034        setring R; rlist; ");
2035    return(R);
2036}
2037example
2038{
2039    "EXAMPLE:";echo=2;
2040    ring r = 0,(x,y),lp;
2041    // compute the intersection points of two curves
2042    ideal s =  x2 + y2 - 10, x2 + xy + 2y2 - 16;
2043    def R = triangL_solve(s,10);
2044    setring R; rlist;
2045}
2046
2047
2048///////////////////////////////////////////////////////////////////////////////
2049
2050proc triang_solve( list lfi, int prec, list # )
2051"USAGE:   triang_solve(l,p [,d] ); l=list, p,d=integers@*
2052         l is a list of finitely many triangular systems, such that the union of
2053         their varieties equals the variety of the initial ideal.@*
2054         p>0: gives precision of complex numbers in digits,@*
2055         d>0: gives precision (1<d<p) for near-zero-determination,@*
2056         (default: d=1/2*p).
2057ASSUME:  the ground field has char 0;@*
2058         l was computed using the algorithm of Lazard or the algorithm of
2059         Moeller (see triang.lib).
2060RETURN:  ring @code{R} with the same number of variables, but with complex
2061         coefficients (and precision p). @code{R} comes with a list
2062         @code{rlist} of numbers, in which the complex roots of l are stored.@*
2063EXAMPLE: example triang_solve; shows an example
2064"
2065{
2066    def oring= basering;
2067    list LL;
2068
2069    // change the ground field to complex numbers
2070    list l2 = ringlist(basering)[2];
2071    ring RC = create_ring("(complex,"+string(prec)+",I)", l2, "lp");
2072
2073    // list with entry 0 (number)
2074    number nn=0;
2075
2076    // set number of digits for zero-comparison of roots
2077    if ( !defined(myCompDigits) )
2078    {
2079        int myCompDigits;
2080    }
2081    if ( size(#)>=1  && typeof(#[1])=="int" )
2082    {
2083        myCompDigits=#[1];
2084    }
2085    else
2086    {
2087        myCompDigits=(system("getPrecDigits"));
2088    }
2089
2090    dbprint( printlevel-voice+2,"// myCompDigits="+string(myCompDigits) );
2091
2092    int idelem;
2093    int nv= nvars(basering);
2094    int i,j,lis;
2095    list resu,li;
2096
2097    if ( !defined(rlist) )
2098    {
2099        list rlist;
2100        export rlist;
2101    }
2102
2103    int rn@=0;
2104
2105    // map the list
2106    list lfi= imap(oring,lfi);
2107    int slfi= size(lfi);
2108
2109    ideal fi;
2110    for ( i= 1; i <= slfi; i++ )
2111    {
2112        // map fi from old to new ring
2113        fi= lfi[i]; //imap(oring,lfi[i]);
2114
2115        idelem= size(fi);
2116
2117        // solve fi[1]
2118        li= laguerre_solve(fi[1],myCompDigits,myCompDigits,0);
2119        lis= size(li);
2120
2121        dbprint( printlevel-voice+2,"// laguerre found roots: "+string(lis) );
2122
2123        for ( j= 1; j <= lis; j++ )
2124        {
2125            dbprint( printlevel-voice+2,"// root "+string(j) );
2126            rn@++;
2127            resu[nv]= li[j];
2128            LL = psubst( 1, 2, nv-1, resu, fi, idelem, nv, myCompDigits,
2129                         rn@, rlist );
2130            rlist = LL[1];
2131            rn@ = LL[2];
2132        }
2133    }
2134
2135    dbprint( printlevel-voice+3,"
2136// 'triang_solve' created a ring, in which a list rlist of numbers (the
2137// complex solutions) is stored.
2138// To access the list of complex solutions, type (if the name R was assigned
2139// to the return value):
2140        setring R; rlist; ");
2141
2142    return(RC);
2143}
2144example
2145{
2146    "EXAMPLE:";echo=2;
2147    ring r = 0,(x,y),lp;
2148    // compute the intersection points of two curves
2149    ideal s=  x2 + y2 - 10, x2 + xy + 2y2 - 16;
2150    def R=triang_solve(triangLfak(stdfglm(s)),10);
2151    setring R; rlist;
2152}
2153
2154///////////////////////////////////////////////////////////////////////////////
2155
2156proc simplexOut(list l)
2157"USAGE:   simplexOut(l); l list
2158ASSUME:  l is the output of simplex.
2159RETURN:  Nothing. The procedure prints the computed solution of simplex
2160         (as strings) in a nice format.
2161SEE ALSO: simplex
2162EXAMPLE: example simplexOut; shows an example
2163"
2164{
2165  int i,j;
2166  matrix m= l[1];
2167  intvec iposv= l[3];
2168  int icase= l[2];
2169
2170  int cols= ncols(m);
2171  int rows= nrows(m);
2172
2173  int N= l[6];
2174
2175  if ( 1 == icase )  // objective function is unbound
2176  {
2177    "objective function is unbound";
2178    return();
2179  }
2180  if ( -1 == icase )  // no solution satisfies the given constraints
2181  {
2182    "no solution satisfies the given constraints";
2183    return();
2184  }
2185  if ( -2 == icase )  // other error
2186  {
2187    "an error occurred during simplex computation!";
2188    return();
2189  }
2190
2191  for ( i = 1; i <= rows; i++ )
2192  {
2193    if (i == 1)
2194    {
2195      "z = "+string(m[1][1]);
2196    }
2197    else
2198    {
2199      if ( iposv[i-1] <= N )
2200      {
2201        "x"+string(iposv[i-1])+" = "+string(m[i,1]);
2202      }
2203//        else
2204//        {
2205//               "Y"; iposv[i-1]-N+1;
2206//        }
2207    }
2208  }
2209}
2210example
2211{
2212  "EXAMPLE:";echo=2;
2213  ring r = (real,10),(x),lp;
2214
2215  // consider the max. problem:
2216  //
2217  //    maximize  x(1) + x(2) + 3*x(3) - 0.5*x(4)
2218  //
2219  //  with constraints:   x(1) +          2*x(3)          <= 740
2220  //                             2*x(2)          - 7*x(4) <=   0
2221  //                               x(2) -   x(3) + 2*x(4) >=   0.5
2222  //                      x(1) +   x(2) +   x(3) +   x(4)  =   9
2223  //
2224  matrix sm[5][5]=   0, 1, 1, 3,-0.5,
2225                   740,-1, 0,-2, 0,
2226                     0, 0,-2, 0, 7,
2227                   0.5, 0,-1, 1,-2,
2228                     9,-1,-1,-1,-1;
2229
2230  int n = 4;  // number of constraints
2231  int m = 4;  // number of variables
2232  int m1= 2;  // number of <= constraints
2233  int m2= 1;  // number of >= constraints
2234  int m3= 1;  // number of == constraints
2235
2236  list sol=simplex(sm, n, m, m1, m2, m3);
2237  simplexOut(sol);
2238}
2239
2240
2241// local Variables: ***
2242// c-set-style: bsd ***
2243// End: ***
Note: See TracBrowser for help on using the repository browser.