source: git/Singular/weight0.c @ c4bbf1f

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