source: git/libpolys/polys/weight0.c @ e6cdad

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