source: git/Singular/weight0.c @ 402a67

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