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

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