source: git/Singular/LIB/ntsolve.lib @ a5f564

spielwiese
Last change on this file since a5f564 was a5f564, checked in by Gert-Martin Greuel <greuel@…>, 23 years ago
* Greuel: Syntax von nt_solve und triMNewton vereinheitlicht, * Syntax von nt_solve erweitert, die von triMNewton geaendert git-svn-id: file:///usr/local/Singular/svn/trunk@4921 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.1 KB
Line 
1//(GMG, last modified 16.12.00)
2///////////////////////////////////////////////////////////////////////////////
3version="$Id: ntsolve.lib,v 1.8 2000-12-16 01:14:43 greuel Exp $";
4info="
5LIBRARY:  ntsolve.lib     REAL NEWTON SOLVING OF POLYNOMIAL SYSTEMS
6AUTHORS:  Wilfred Pohl, email: pohl@mathematik.uni-kl.de
7          Dietmar Hillebrand
8
9PROCEDURES:
10 nt_solve(G,..);        find one real root of 0-dimensional ideal G
11 triMNewton(G,..);      find one real root for 0-dim triangular system G
12";
13
14///////////////////////////////////////////////////////////////////////////////
15
16proc nt_solve (ideal gls, ideal ini, list #)
17"USAGE:   nt_solve(gls,ini[,ipar]); gls ideal, ini ideal, ipar list or intvec
18         gls: contains the equations, for which a solution will be computed
19         ini: ideal of initial values (approximate solutions to start with)
20         ipar: control integers (default: ipar = 100,10)
21         ipar[1] - max. number of iterations
22         ipar[2] - accuracy (we have the l_2-norm ||.||): accept solution
23         sol if ||gls(sol)|| < eps0*(0.1^ipar[2]) where eps0 = ||gls(ini)||
24         is the initial error
25ASSUME:  gls is a zerodimensional ideal with nvars(basering) = size(gls) (>1)
26RETURN:  ideal, coordinates of one solution (if found), 0 else
27NOTE:    printlevel >0: displays comments (default =0)
28EXAMPLE: example nt_solve; shows an example
29"
30{
31    def rn = basering;
32    int di = size(gls);
33    if (nvars(basering) != di){
34      ERROR("// wrong number of equations");}
35    if (size(ini) != di){
36      ERROR("// wrong number of initial values");}
37    int prec = system("getPrecDigits"); // precision
38
39    int i1,i2,i3;
40    int itmax, acc;
41    intvec ipar;
42    if ( size(#)>0 ){
43       i1=1;
44       if (typeof(#[1])=="intvec") {ipar=#[1];}
45       if (typeof(#[1])=="int") {ipar[1]=#[1];}
46       if ( size(#)>1 ){
47          i1=2;
48          if (typeof(#[2])=="int") {ipar[2]=#[2];}
49       }
50    }
51
52    int prot = printlevel-voice+2;  // prot=printlevel (default:prot=0)
53    if (i1 < 1){itmax = 100;}else{itmax = ipar[1];}
54    if (i1 < 2){acc = prec/2;}else{acc = ipar[2];}
55    if ((acc <= 0)||(acc > prec-1)){acc = prec-1;}
56
57    int dpl = di+1;
58    string out;
59    out = "ring rnewton=(real,prec),("+varstr(basering)+"),(c,dp);";
60    execute(out);
61
62    ideal gls1=imap(rn,gls);
63    module nt,sub;
64    sub = transpose(jacob(gls1));
65    for (i1=di;i1>0;i1--){
66      if(sub[i1]==0){break;}}
67    if (i1>0){
68      setring rn; kill rnewton;
69      ERROR("// one var not in equation");}
70
71    list direction;
72    ideal ini1;
73    ini1 = imap(rn,ini);
74    number dum,y1,y2,y3,genau;
75    genau = 0.1;
76    dum = genau;
77    genau = genau^acc;
78
79    for (i1=di;i1>0;i1--){
80      sub[i1]=sub[i1]+gls1[i1]*gen(dpl);}
81    nt = sub;
82    for (i1=di;i1>0;i1--){
83      nt = subst(nt,var(i1),ini1[i1]);}
84
85    // now we have in sub the general structure
86    // and in nt the structure with subst. vars
87
88    // compute initial error
89    y1 = ml2norm(nt,genau);
90    dbprint(prot,"// initial error = "+string(y1));
91    y2 = genau*y1;
92
93  // begin of iteration
94  for(i3=1;i3<=itmax;i3++){
95     dbprint(prot,"// iteration: "+string(i3));
96
97    // find newton direction
98    direction=bareiss(nt,1,-1);
99
100    // find dumping
101    dum = linesearch(gls1,ini1,direction[1],y1,dum,genau);
102    if (i3%5 == 0)
103    {
104      if (dum <= 0.000001)
105      {
106        dum = 1.0;
107      }
108    }
109    dbprint(prot,"// dumping = "+string(dum));
110
111    // new value
112    for(i1=di;i1>0;i1--){
113      ini1[i1]=ini1[i1]-dum*direction[1][i1];}
114    nt = sub;
115    for (i1=di;i1>0;i1--){
116      nt = subst(nt,var(i1),ini1[i1]);}
117    y1 = ml2norm(nt,genau);
118    dbprint(prot,"// error = "+string(y1));
119    if(y1<y2){break;} // we are ready
120  }
121
122    if (y1>y2){
123      "// ** WARNING: iteration bound reached with error > error bound!";}
124    setring rn;
125    ini = imap(rnewton,ini1);
126    kill rnewton;
127    return(ini);
128}
129example
130{
131    "EXAMPLE:";echo=2;
132    ring rsq = (real,40),(x,y,z,w),lp;
133    ideal gls =  x2+y2+z2-10, y2+z3+w-8, xy+yz+xz+w5 - 1,w3+y;
134    ideal ini = 3.1,2.9,1.1,0.5;
135    intvec ipar = 200,0;
136    ideal sol = nt_solve(gls,ini,ipar);
137    sol;
138}
139///////////////////////////////////////////////////////////////////////////////
140
141static proc sqrt (number wr, number wa, number wg)
142{
143  number es,we;
144  number wb=wa;
145  number wf=wb*wb-wr;
146  if(wf>0){
147    es=wf;}
148  else{
149    es=-wf;}
150  we=wg*es;
151  while (es>we)
152  {
153    wf=wf/(wb+wb);
154    wb=wb-wf;
155    wf=wb*wb-wr;
156    if(wf>0){
157      es=wf;}
158    else{
159      es=-wf;}
160  }
161  return(wb);
162}
163
164static proc il2norm (ideal H, number wg)
165{
166  number wa,wb;
167  int wi,dpl;
168  wa = leadcoef(H[1]);
169  wa = wa*wa;
170  for(wi=size(H);wi>1;wi--)
171  {
172    wb=leadcoef(H[wi]);
173    wa=wa+wb*wb;
174  }
175  return(sqrt(wa,wa,wg));
176}
177
178static proc ml2norm (module H, number wg)
179{
180  number wa,wb;
181  int wi,dpl;
182  dpl = size(H)+1;
183  wa = leadcoef(H[1][dpl]);
184  wa = wa*wa;
185  for(wi=size(H);wi>1;wi--)
186  {
187    wb=leadcoef(H[wi][dpl]);
188    wa=wa+wb*wb;
189  }
190  return(sqrt(wa,wa,wg));
191}
192
193static
194proc linesearch(ideal nl, ideal aa, ideal bb,
195number z1, number tt, number gg)
196{
197  int ii,d;
198  ideal cc,jn;
199  number ss,z2,z3,mm;
200
201  mm=0.000001;
202  ss=tt;
203  d=size(nl);
204  cc=aa;
205  for(ii=d;ii>0;ii--){cc[ii]=cc[ii]-ss*bb[ii];}
206  jn=nl;
207  for(ii=d;ii>0;ii--){jn=subst(jn,var(ii),cc[ii]);}
208  z2=il2norm(jn,gg);
209  z3=-1;
210  while(z2>=z1)
211  {
212    ss=0.5*ss;
213    if(ss<mm){return (mm);}
214    cc=aa;
215    for(ii=d;ii>0;ii--)
216    {
217      cc[ii]=cc[ii]-ss*bb[ii];
218    }
219    jn=nl;
220    for(ii=d;ii>0;ii--){jn=subst(jn,var(ii),cc[ii]);}
221    z3=z2;
222    z2=il2norm(jn,gg);
223  }
224  if(z3<0)
225  {
226    while(z3<z2)
227    {
228      ss=ss+ss;
229      cc=aa;
230      for(ii=d;ii>0;ii--)
231      {
232        cc[ii]=cc[ii]-ss*bb[ii];
233      }
234      jn=nl;
235      for(ii=d;ii>0;ii--){jn=subst(jn,var(ii),cc[ii]);}
236      if(z3>0){z2=z3;}
237      z3=il2norm(jn,gg);
238    }
239  }
240  z2=z2-z1;
241  z3=z3-z1;
242  ss=0.25*ss*(z3-4*z2)/(z3-2*z2);
243  if(ss>1.0){return (1.0);}
244  if(ss<mm){return (mm);}
245  return(ss);
246}
247///////////////////////////////////////////////////////////////////////////////
248//
249//   Multivariate Newton for triangular systems
250//   algorithms for solving algebraic system of dimension zero
251//   written by Dietmar Hillebrand
252///////////////////////////////////////////////////////////////////////////////
253
254proc triMNewton (ideal G, ideal a, list #)
255"USAGE:  triMNewton(G,a[,ipar]); G ideal, a ideal, ipar list or intvec
256ASSUME:  G:   g1,..,gn, a triangular system of n equations in n vars,
257              i.e gi=gi(var(n-i+1),..,var(n))
258         a:   ideal of numbers, coordinates of an approximation of a common
259              zero of G to start with (with a[i] to be substituted in var(i))
260         ipar: control integer vector (default: ipar = 100,10)
261         ipar[1] - max. number of iterations
262         ipar[2] - accuracy (we have as norm |.| absolute value ):
263         accept solution  sol if |G(sol)| < |G(a)|*(0.1^ipar[2])
264         itb: int, the maximal number of iterations performed
265         err: number, an error bound
266RETURN:  an ideal, coordinates of a better approximation of a zero of G
267EXAMPLE: example triMNewton; shows an example
268"
269{
270    int prot = printlevel;
271    int i1,i2,i3;
272    intvec ipar;
273    if ( size(#)>0 ){
274       i1=1;
275       if (typeof(#[1])=="intvec") {ipar=#[1];}
276       if (typeof(#[1])=="int") {ipar[1]=#[1];}
277       if ( size(#)>1 ){
278          i1=2;
279          if (typeof(#[2])=="int") {ipar[2]=#[2];}
280       }
281    }
282    int itb, err;
283    if (i1 < 1) {itb = 100;} else {itb = ipar[1];}
284    if (i1 < 2) {err = 10;} else {err = ipar[2];}
285 
286    if (itb == 0)
287    {
288       dbprint(prot,"// ** iteration bound reached with error > error bound!");
289       return(a);
290    }
291
292    int i,j,k;
293    ideal p=G;
294    matrix J=jacob(G);
295    list h;
296    poly hh;
297    int fertig=1;
298    int n=nvars(basering);
299
300    for (i = 1; i <= n; i++)
301    {
302        for (j = n; j >= n-i+1; j--)
303        {
304            p[i] = subst(p[i],var(j),a[j]);
305            for (k = n; k >= n-i+1; k--)
306            {
307                J[i,k] = subst(J[i,k],var(j),a[j]);
308            }
309        }
310        if (J[i,n-i+1] == 0)
311        {
312            ERROR("// ideal not radical");
313            return();
314        }
315
316        // solve linear equations
317        hh = -p[i];
318        for (j = n; j >= n-i+2; j--)
319        {
320            hh = hh - J[i,j]*h[j];
321        }
322        h[n-i+1] = number(hh/J[i,n-i+1]);
323    }
324
325    for (i = 1; i <= n; i++)
326    {
327        if ( abs(h[i]) > (1/10)^err)
328        {
329            fertig = 0;
330            break;
331        }
332    }
333    if ( not fertig )
334    {
335        if (prot > 0)
336        {
337           "// error:"; print(abs(h[i]));
338           "// iterations to be performed: "+string(itb);
339        }
340        for (i = 1; i <= n; i++)
341        {
342            a[i] = a[i] + h[i];
343        }
344        ipar = itb-1,err;
345        return(triMNewton(G,a,ipar));
346    }
347    else
348    {
349        return(a);
350    }
351}
352example
353{ "EXAMPLE:"; echo = 2;
354   ring r = (real,30),(z,y,x),(lp);
355   ideal i = x^2-1,y^2+x4-3,z2-y4+x-1;
356   ideal a = 2,3,4;
357   intvec e = 20,10;
358   ideal l = triMNewton(i,a,e);
359   l;
360}
361///////////////////////////////////////////////////////////////////////////////
362
363static proc abs( number r)
364{
365   if (r >= 0)
366   {
367       return(r);
368   }
369   else
370   {
371       return(-r);
372   }
373}
374///////////////////////////////////////////////////////////////////////////////
375
Note: See TracBrowser for help on using the repository browser.