source: git/Singular/weight0.c @ 63be42

spielwiese
Last change on this file since 63be42 was 069fcf, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: minor cleanups git-svn-id: file:///usr/local/Singular/svn/trunk@2136 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: weight0.c,v 1.4 1998-06-12 18:11:03 Singular Exp $ */
5
6/*
7* ABSTRACT:
8*/
9
10#include <math.h>
11#include <string.h>
12#include "mod2.h"
13#include "tok.h"
14#include "mmemory.h"
15
16double wFunctionalMora(int *degw, int *lpol, int npol,
17       double *rel, double wx);
18double wFunctionalBuch(int *degw, int *lpol, int npol,
19       double *rel, double wx);
20void wAdd(int *A, int mons, int kn, int xx);
21void wNorm(int *degw, int *lpol, int npol, double *rel);
22void wFirstSearch(int *A, int *x, int mons,
23        int *lpol, int npol, double *rel, double *fopt);
24void wSecondSearch(int *A, int *x, int *lpol,
25        int npol, int mons, double *rel, double *fk);
26void wGcd(int *x, int n);
27/*0 implementation*/
28
29short * ecartWeights=NULL;
30extern int pVariables;
31
32#ifdef ALIGN_8
33#define wDouble(A) ((double *)A)
34#else
35double * wDouble(void *adr)
36{
37  long i = (long)adr;
38  return (double *)((i+7)&(~7));
39}
40#endif
41
42double wNsqr;
43double (*wFunctional)(int *degw, int *lpol, int npol,
44       double *rel, double wx);
45
46
47double wFunctionalMora(int *degw, int *lpol, int npol,
48       double *rel, double wx)
49{
50  int  i, j, e1, ecu, ecl, ec;
51  int  *ex;
52  double gfmax, gecart, ghom, pfmax;
53  double *r;
54
55  ex = degw;
56  r = rel;
57  gfmax = (double)0.0;
58  gecart = (double)0.4 + (double)npol;
59  ghom = (double)1.0;
60  for (i = 0; i < npol; i++)
61  {
62    ecl = ecu = e1 = *ex++;
63    for (j = lpol[i] - 1; j!=0; j--)
64    {
65      ec = *ex++;
66      if (ec > ecu)
67        ecu = ec;
68      else if (ec < ecl)
69        ecl = ec;
70    }
71    pfmax = (double)ecl / (double)ecu;
72    if (pfmax < ghom)
73      ghom = pfmax;
74    pfmax = (double)e1 / (double)ecu;
75    if (pfmax > (double)0.5)
76      gecart -= (pfmax * pfmax);
77    else
78      gecart -= (double)0.25;
79    ecu = 2 * ecu - ecl;
80    gfmax += (double)(ecu * ecu) * (*r++);
81  }
82  if (ghom > (double)0.8)
83  {
84    ghom *= (double)5.0;
85    gecart *= ((double)5.0 - ghom);
86  }
87  return (gfmax * gecart) / pow(wx, wNsqr);
88}
89
90
91double wFunctionalBuch(int *degw, int *lpol, int npol,
92       double *rel, double wx)
93{
94  int  i, j, ecl, ecu, ec;
95  int  *ex;
96  double gfmax, ghom, pfmax;
97  double *r;
98
99  ex = degw;
100  r = rel;
101  gfmax = (double)0.0;
102  ghom = (double)1.0;
103  for (i = 0; i < npol; i++)
104  {
105    ecu = ecl = *ex++;
106    for (j = lpol[i] - 1; j!=0 ; j--)
107    {
108      ec = *ex++;
109      if (ec < ecl)
110        ecl = ec;
111      else if (ec > ecu)
112        ecu = ec;
113    }
114    pfmax = (double)ecl / (double)ecu;
115    if (pfmax < ghom)
116      ghom = pfmax;
117    gfmax += (double)(ecu * ecu) * (*r++);
118  }
119  if (ghom > (double)0.5)
120    gfmax *= ((double)1.0 - (ghom * ghom)) / (double)0.75;
121  return gfmax / pow(wx, wNsqr);
122}
123
124
125static void wSub(int *A, int mons, int kn, int xx)
126{
127  int  i, *B, *ex;
128
129  B = A + ((kn - 1) * mons);
130  ex = A + (pVariables * mons);
131  i = mons;
132  if (xx == 1)
133  {
134    for (/* i=mons */; i!=0 ; i--)
135      *ex++ -= *B++;
136  }
137  else
138  {
139    for (/* i=mons */; i!=0 ; i--)
140      *ex++ -= (*B++) * xx;
141  }
142}
143
144
145void wAdd(int *A, int mons, int kn, int xx)
146{
147  int  i, *B, *ex;
148
149  B = A + ((kn - 1) * mons);
150  ex = A + (pVariables * mons);
151  i = mons;
152  if (xx == 1)
153  {
154    for (/* i=mons */; i!=0 ; i--)
155      *ex++ += *B++;
156  }
157  else
158  {
159    for (/* i=mons */; i!=0 ; i--)
160      *ex++ += (*B++) * xx;
161  }
162}
163
164
165void wFirstSearch(int *A, int *x, int mons,
166  int *lpol, int npol, double *rel, double *fopt)
167{
168  int  a0, a, n, xn, t, xx, y1;
169  int  *y, *degw, *xopt;
170  double  fy, fmax, wx;
171  double *pr;
172  void *adr;
173
174  fy = *fopt;
175  n = pVariables;
176  xn = n + 6 + (21 / n);
177  a0 = n * sizeof(double) + 8;
178  a = n * sizeof(int);
179  y = (int * )Alloc(a);
180  adr = (void * )Alloc(a0);
181  pr = wDouble(adr);
182  *pr = (double)1.0;
183  *y = 0;
184  degw = A + (n * mons);
185  xopt = x + (n + 2);
186  t = 1;
187  loop
188  {
189    while (t < n)
190    {
191      xx = x[t] + 1;
192      wx = pr[t-1] * (double)xx;
193      y1 = y[t-1] + xx;
194      if ((y1 + n - t) <= xn)
195      {
196        pr[t] = wx;
197        y[t] = y1;
198        x[t] = xx;
199        if (xx > 1)
200          wAdd(A, mons, t, 1);
201        t++;
202      }
203      else
204      {
205        xx = x[t] - 1;
206        x[t] = 0;
207        if (xx!=0)
208          wSub(A, mons, t, xx);
209        t--;
210        if (t==0)
211        {
212          *fopt = fy;
213          Free((ADDRESS)y, a);
214          Free((ADDRESS)adr, a0);
215          return;
216        }
217      }
218    }
219    xx = xn - y[t-1];
220    wx = pr[t-1] * (double)xx;
221    x[t] = xx;
222    xx--;
223    if (xx!=0)
224      wAdd(A, mons, t, xx);
225    fmax = (*wFunctional)(degw, lpol, npol, rel, wx);
226    if (xx!=0)
227      wSub(A, mons, t, xx);
228    if (fmax < fy)
229    {
230      fy = fmax;
231      memcpy(xopt, x + 1, a);
232    }
233    t--;
234  } /* end loop */
235}
236
237
238static double wPrWeight(int *x, int n)
239{
240  int i;
241  double y;
242
243  y = (double)x[n];
244  for (i = n - 1; i!=0 ; i--)
245    y *= (double)x[i];
246  return y;
247}
248
249
250static void wEstimate(int *A, int *x, int *lpol, int npol, int mons,
251double wx, double *rel, double *fopt, int *s0, int *s1, int *s2)
252{
253  int  n, i1, i2, k0 = 0, k1 = 0, k2 = 0;
254  int  *degw;
255  double fo1, fo2, fmax, wx1, wx2;
256
257  n = pVariables;
258  degw = A + (n * mons);
259  fo2 = fo1 = (double)1.0e10;
260  for (i1 = n; i1!=0 ; i1--)
261  {
262    if (x[i1] > 1)
263    {
264      wSub(A, mons, i1, 1);
265      wx1 = wx - wx / (double)x[i1];
266      x[i1]--;
267      fmax = (*wFunctional)(degw, lpol, npol, rel, wx1);
268      if (fmax < fo1)
269      {
270        fo1 = fmax;
271        k0 = i1;
272      }
273      for (i2 = i1; i2!=0 ; i2--)
274      {
275        if (x[i2] > 1)
276        {
277          wSub(A, mons, i2, 1);
278          wx2 = wx1 - wx1 / (double)x[i2];
279          fmax = (*wFunctional)(degw, lpol, npol, rel, wx2);
280          if (fmax < fo2)
281          {
282            fo2 = fmax;
283            k1 = i1;
284            k2 = i2;
285          }
286          wAdd(A, mons, i2, 1);
287        }
288      }
289      wAdd(A, mons, i1, 1);
290      x[i1]++;
291    }
292  }
293  if (fo1 < fo2)
294  {
295    *fopt = fo1;
296    *s0 = k0;
297  }
298  else
299  {
300    *fopt = fo2;
301    *s0 = 0;
302  }
303  *s1 = k1;
304  *s2 = k2;
305}
306
307
308void wSecondSearch(int *A, int *x, int *lpol,
309int npol, int mons, double *rel, double *fk)
310{
311  int  n, s0, s1, s2, *xopt;
312  double  one, fx, fopt, wx;
313
314  n = pVariables;
315  xopt = x + (n + 2);
316  fopt = *fk * (double)0.999999999999;
317  wx = wPrWeight(x, n);
318  one = (double)1.0;
319  loop
320  {
321    wEstimate(A, x, lpol, npol, mons, wx, rel, &fx, &s0, &s1, &s2);
322    if (fx > fopt)
323    {
324      if (s0!=0)
325        x[s0]--;
326      else if (s1!=0)
327      {
328        x[s1]--;
329        x[s2]--;
330      }
331      else
332        break;
333    }
334    else
335    {
336      fopt = fx;
337      if (s0!=0)
338      {
339        x[s0]--;
340        memcpy(xopt, x + 1, n * sizeof(int));
341        if (s1==0)
342          break;
343      }
344      else if (s1!=0)
345      {
346        x[s1]--;
347        x[s2]--;
348        memcpy(xopt, x + 1, n * sizeof(int));
349      }
350      else
351        break;
352    }
353    if (s0!=0)
354      wSub(A, mons, s0, 1);
355    else
356    {
357      wSub(A, mons, s1, 1);
358      wSub(A, mons, s2, 1);
359    }
360    wx = wPrWeight(x, n);
361  }
362  *fk = fopt;
363}
364
365
366void wGcd(int *x, int n)
367{
368  int i, b, a, h;
369
370  i = n;
371  b = x[i];
372  loop
373  {
374    i--;
375    if (i==0)
376      break;
377    a = x[i];
378    if (a < b)
379    {
380      h = a;
381      a = b;
382      b = h;
383    }
384    do
385    {
386      h = a % b;
387      a = b;
388      b = h;
389    }
390    while (b!=0);
391    b = a;
392    if (b == 1)
393      return;
394  }
395  for (i = n; i!=0 ; i--)
396    x[i] /= b;
397}
398
399
400static void wSimple(int *x, int n)
401{
402  int g, min, c, d, f, kopt, k, i;
403  int *xopt;
404  double sopt, s1, s2;
405
406  xopt = x + (n + 1);
407  kopt = k = g = 0;
408  min = 1000000;
409  for (i = n; i!=0 ; i--)
410  {
411    c = xopt[i];
412    if (c > 1)
413    {
414      if (c < min)
415        min = c;
416      if (c > k)
417        k = c;
418    }
419    else
420      g = 1;
421  }
422  k -= min;
423  if ((g==0) && (k < 4))
424    return;
425  if (k < min)
426    min = k+1;
427  sopt = (double)1.0e10;
428  for (k = min; k > 1; k--)
429  {
430    s2 = s1 = (double)0.0;
431    for(i = n; i!=0 ; i--)
432    {
433      c = xopt[i];
434      if (c > 1)
435      {
436        d = c / k;
437        d *= k;
438        f = d = c - d;
439        if (f!=0)
440        {
441          f = k - f;
442          if (f < d)
443            s2 += (double)f / (double)c;
444          else
445            s1 += (double)d / (double)c;
446        }
447      }
448    }
449    s1 += s2 + sqrt(s1 * s2);
450    s1 -= (double)0.01 * sqrt((double)k);
451    if (s1 < sopt)
452    {
453      sopt = s1;
454      kopt = k;
455    }
456  }
457  for(i = n; i!=0 ; i--)
458  {
459    x[i] = 1;
460    c = xopt[i];
461    if (c > 1)
462    {
463      d = c / kopt;
464      d *= kopt;
465      x[i] = d;
466      d = c - d;
467      if ((d!=0) && (kopt < 2 * d))
468        x[i] += kopt;
469    }
470  }
471  if (g==0)
472    wGcd(x, n);
473}
474
475
476void wNorm(int *degw, int *lpol, int npol, double *rel)
477{
478  int  i, j, ecu, ec;
479  int  *ex;
480  double *r;
481
482  ex = degw;
483  r = rel;
484  for (i = 0; i < npol; i++)
485  {
486    ecu = *ex++;
487    for (j = lpol[i] - 1; j!=0 ; j--)
488    {
489      ec = *ex++;
490      if (ec > ecu)
491        ecu = ec;
492    }
493    *r = (double)1.0 / (double)(ecu * ecu);
494    r++;
495  }
496}
Note: See TracBrowser for help on using the repository browser.