source: git/Singular/weight.cc @ 82716e

spielwiese
Last change on this file since 82716e was 104fd57, checked in by Wilfred Pohl <pohl@…>, 26 years ago
Metrowerks without weight0.c git-svn-id: file:///usr/local/Singular/svn/trunk@1471 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: weight.cc,v 1.7 1998-04-27 09:11:56 pohl Exp $ */
5
6/*
7* ABSTRACT:
8*/
9
10#include <math.h>
11#include "mod2.h"
12#include "tok.h"
13#include "mmemory.h"
14#include "polys.h"
15#include "intvec.h"
16#include "febase.h"
17#include "ipid.h"
18#include "ipshell.h"
19#include "subexpr.h"
20#include "ideals.h"
21#include "weight.h"
22
23/*0 implementation*/
24
25pFDegProc pFDegOld;
26pLDegProc pLDegOld;
27#ifndef __MWERKS__
28extern "C" double (*wFunctional)(int *degw, int *lpol, int npol,
29       double *rel, double wx);
30extern "C" double wFunctionalMora(int *degw, int *lpol, int npol,
31       double *rel, double wx);
32extern "C" double wFunctionalBuch(int *degw, int *lpol, int npol,
33       double *rel, double wx);
34extern "C" double * wDouble(void *adr);       
35extern "C" void wAdd(int *A, int mons, int kn, int xx);
36extern "C" void wNorm(int *degw, int *lpol, int npol, double *rel);
37extern "C" void wFirstSearch(int *A, int *x, int mons,
38        int *lpol, int npol, double *rel, double *fopt);
39extern "C" void wSecondSearch(int *A, int *x, int *lpol,
40        int npol, int mons, double *rel, double *fk);
41extern "C" void wGcd(int *x, int n);       
42extern double nsqr;       
43#else
44short * ecartWeights=NULL;
45extern int pVariables;
46
47static double * wDouble(void *adr)
48{
49  long i = (long)adr;
50  return (double *)((i+7)&(~7));
51}
52
53double nsqr;
54double (*wFunctional)(int *degw, int *lpol, int npol,
55       double *rel, double wx);
56
57
58static double wFunctionalMora(int *degw, int *lpol, int npol,
59       double *rel, double wx)
60{
61  int  i, j, e1, ecu, ecl, ec;
62  int  *ex;
63  double gfmax, gecart, ghom, pfmax;
64  double *r;
65
66  ex = degw;
67  r = rel;
68  gfmax = (double)0.0;
69  gecart = (double)0.4 + (double)npol;
70  ghom = (double)1.0;
71  for (i = 0; i < npol; i++)
72  {
73    ecl = ecu = e1 = *ex++;
74    for (j = lpol[i] - 1; j; j--)
75    {
76      ec = *ex++;
77      if (ec > ecu)
78        ecu = ec;
79      else if (ec < ecl)
80        ecl = ec;
81    }
82    pfmax = (double)ecl / (double)ecu;
83    if (pfmax < ghom)
84      ghom = pfmax;
85    pfmax = (double)e1 / (double)ecu;
86    if (pfmax > (double)0.5)
87      gecart -= (pfmax * pfmax);
88    else
89      gecart -= (double)0.25;
90    ecu = 2 * ecu - ecl;
91    gfmax += (double)(ecu * ecu) * (*r++);
92  }
93  if (ghom > (double)0.8)
94  {
95    ghom *= (double)5.0;
96    gecart *= ((double)5.0 - ghom);
97  }
98  return (gfmax * gecart) / pow(wx, nsqr);
99}
100
101
102static double wFunctionalBuch(int *degw, int *lpol, int npol,
103       double *rel, double wx)
104{
105  int  i, j, ecl, ecu, ec;
106  int  *ex;
107  double gfmax, ghom, pfmax;
108  double *r;
109
110  ex = degw;
111  r = rel;
112  gfmax = (double)0.0;
113  ghom = (double)1.0;
114  for (i = 0; i < npol; i++)
115  {
116    ecu = ecl = *ex++;
117    for (j = lpol[i] - 1; j; j--)
118    {
119      ec = *ex++;
120      if (ec < ecl)
121        ecl = ec;
122      else if (ec > ecu)
123        ecu = ec;
124    }
125    pfmax = (double)ecl / (double)ecu;
126    if (pfmax < ghom)
127      ghom = pfmax;
128    gfmax += (double)(ecu * ecu) * (*r++);
129  }
130  if (ghom > (double)0.5)
131    gfmax *= ((double)1.0 - (ghom * ghom)) / (double)0.75;
132  return gfmax / pow(wx, nsqr);
133}
134
135
136static void wSub(int *A, int mons, int kn, int xx)
137{
138  int  i, *B, *ex;
139
140  B = A + ((kn - 1) * mons);
141  ex = A + (pVariables * mons);
142  if (xx == 1)
143  {
144    for (i = mons; i; i--)
145      *ex++ -= *B++;
146  }
147  else
148  {
149    for (i = mons; i; i--)
150      *ex++ -= (*B++) * xx;
151  }
152}
153
154
155static void wAdd(int *A, int mons, int kn, int xx)
156{
157  int  i, *B, *ex;
158
159  B = A + ((kn - 1) * mons);
160  ex = A + (pVariables * mons);
161  if (xx == 1)
162  {
163    for (i = mons; i; i--)
164      *ex++ += *B++;
165  }
166  else
167  {
168    for (i = mons; i; i--)
169      *ex++ += (*B++) * xx;
170  }
171}
172
173
174static void wFirstSearch(int *A, int *x, int mons,
175  int *lpol, int npol, double *rel, double *fopt)
176{
177  int  a0, a, n, xn, t, xx, y1;
178  int  *y, *degw, *xopt;
179  double  fy, fmax, wx;
180  double *pr;
181  void *adr;
182
183  fy = *fopt;
184  n = pVariables;
185  xn = n + 6 + (21 / n);
186  a0 = n * sizeof(double) + 8;
187  a = n * sizeof(int);
188  y = (int * )Alloc(a);
189  adr = (void * )Alloc(a0);
190  pr = wDouble(adr);
191  *pr = (double)1.0;
192  *y = 0;
193  degw = A + (n * mons);
194  xopt = x + (n + 2);
195  t = 1;
196  loop
197  {
198    while (t < n)
199    {
200      xx = x[t] + 1;
201      wx = pr[t-1] * (double)xx;
202      y1 = y[t-1] + xx;
203      if ((y1 + n - t) <= xn)
204      {
205        pr[t] = wx;
206        y[t] = y1;
207        x[t] = xx;
208        if (xx > 1)
209          wAdd(A, mons, t, 1);
210        t++;
211      }
212      else
213      {
214        xx = x[t] - 1;
215        x[t] = 0;
216        if (xx!=0)
217          wSub(A, mons, t, xx);
218        t--;
219        if (t==0)
220        {
221          *fopt = fy;
222          Free((ADDRESS)y, a);
223          Free((ADDRESS)adr, a0);
224          return;
225        }
226      }
227    }
228    xx = xn - y[t-1];
229    wx = pr[t-1] * (double)xx;
230    x[t] = xx;
231    xx--;
232    if (xx!=0)
233      wAdd(A, mons, t, xx);
234    fmax = (*wFunctional)(degw, lpol, npol, rel, wx);
235    if (xx!=0)
236      wSub(A, mons, t, xx);
237    if (fmax < fy)
238    {
239      fy = fmax;
240      memcpy(xopt, x + 1, a);
241    }
242    t--;
243  } /* end loop */
244}
245
246
247static double wPrWeight(int *x, int n)
248{
249  int i;
250  double y;
251
252  y = (double)x[n];
253  for (i = n - 1; i; i--)
254    y *= (double)x[i];
255  return y;
256}
257
258
259static void wEstimate(int *A, int *x, int *lpol, int npol, int mons,
260double wx, double *rel, double *fopt, int *s0, int *s1, int *s2)
261{
262  int  n, i1, i2, k0 = 0, k1 = 0, k2 = 0;
263  int  *degw;
264  double fo1, fo2, fmax, wx1, wx2;
265
266  n = pVariables;
267  degw = A + (n * mons);
268  fo2 = fo1 = (double)1.0e10;
269  for (i1 = n; i1; i1--)
270  {
271    if (x[i1] > 1)
272    {
273      wSub(A, mons, i1, 1);
274      wx1 = wx - wx / (double)x[i1];
275      x[i1]--;
276      fmax = (*wFunctional)(degw, lpol, npol, rel, wx1);
277      if (fmax < fo1)
278      {
279        fo1 = fmax;
280        k0 = i1;
281      }
282      for (i2 = i1; i2; i2--)
283      {
284        if (x[i2] > 1)
285        {
286          wSub(A, mons, i2, 1);
287          wx2 = wx1 - wx1 / (double)x[i2];
288          fmax = (*wFunctional)(degw, lpol, npol, rel, wx2);
289          if (fmax < fo2)
290          {
291            fo2 = fmax;
292            k1 = i1;
293            k2 = i2;
294          }
295          wAdd(A, mons, i2, 1);
296        }
297      }
298      wAdd(A, mons, i1, 1);
299      x[i1]++;
300    }
301  }
302  if (fo1 < fo2)
303  {
304    *fopt = fo1;
305    *s0 = k0;
306  }
307  else
308  {
309    *fopt = fo2;
310    *s0 = 0;
311  }
312  *s1 = k1;
313  *s2 = k2;
314}
315
316
317static void wSecondSearch(int *A, int *x, int *lpol,
318int npol, int mons, double *rel, double *fk)
319{
320  int  n, s0, s1, s2, *xopt;
321  double  one, fx, fopt, wx;
322
323  n = pVariables;
324  xopt = x + (n + 2);
325  fopt = *fk * (double)0.999999999999;
326  wx = wPrWeight(x, n);
327  one = (double)1.0;
328  loop
329  {
330    wEstimate(A, x, lpol, npol, mons, wx, rel, &fx, &s0, &s1, &s2);
331    if (fx > fopt)
332    {
333      if (s0!=0)
334        x[s0]--;
335      else if (s1!=0)
336      {
337        x[s1]--;
338        x[s2]--;
339      }
340      else
341        break;
342    }
343    else
344    {
345      fopt = fx;
346      if (s0!=0)
347      {
348        x[s0]--;
349        memcpy(xopt, x + 1, n * sizeof(int));
350        if (s1==0)
351          break;
352      }
353      else if (s1!=0)
354      {
355        x[s1]--;
356        x[s2]--;
357        memcpy(xopt, x + 1, n * sizeof(int));
358      }
359      else
360        break;
361    }
362    if (s0!=0)
363      wSub(A, mons, s0, 1);
364    else
365    {
366      wSub(A, mons, s1, 1);
367      wSub(A, mons, s2, 1);
368    }
369    wx = wPrWeight(x, n);
370  }
371  *fk = fopt;
372}
373
374
375static void wGcd(int *x, int n)
376{
377  int i, b, a, h;
378
379  i = n;
380  b = x[i];
381  loop
382  {
383    i--;
384    if (i==0)
385      break;
386    a = x[i];
387    if (a < b)
388    {
389      h = a;
390      a = b;
391      b = h;
392    }
393    do
394    {
395      h = a % b;
396      a = b;
397      b = h;
398    }
399    while (b!=0);
400    b = a;
401    if (b == 1)
402      return;
403  }
404  for (i = n; i; i--)
405    x[i] /= b;
406}
407
408
409static void wSimple(int *x, int n)
410{
411  int g, min, c, d, f, kopt, k, i;
412  int *xopt;
413  double sopt, s1, s2;
414
415  xopt = x + (n + 1);
416  kopt = k = g = 0;
417  min = 1000000;
418  for (i = n; i; i--)
419  {
420    c = xopt[i];
421    if (c > 1)
422    {
423      if (c < min)
424        min = c;
425      if (c > k)
426        k = c;
427    }
428    else
429      g = 1;
430  }
431  k -= min;
432  if ((g==0) && (k < 4))
433    return;
434  if (k < min)
435    min = k+1;
436  sopt = (double)1.0e10;
437  for (k = min; k > 1; k--)
438  {
439    s2 = s1 = (double)0.0;
440    for(i = n; i; i--)
441    {
442      c = xopt[i];
443      if (c > 1)
444      {
445        d = c / k;
446        d *= k;
447        f = d = c - d;
448        if (f!=0)
449        {
450          f = k - f;
451          if (f < d)
452            s2 += (double)f / (double)c;
453          else
454            s1 += (double)d / (double)c;
455        }
456      }
457    }
458    s1 += s2 + sqrt(s1 * s2);
459    s1 -= (double)0.01 * sqrt((double)k);
460    if (s1 < sopt)
461    {
462      sopt = s1;
463      kopt = k;
464    }
465  }
466  for(i = n; i; i--)
467  {
468    x[i] = 1;
469    c = xopt[i];
470    if (c > 1)
471    {
472      d = c / kopt;
473      d *= kopt;
474      x[i] = d;
475      d = c - d;
476      if ((d!=0) && (kopt < 2 * d))
477        x[i] += kopt;
478    }
479  }
480  if (g==0)
481    wGcd(x, n);
482}
483
484
485static void wNorm(int *degw, int *lpol, int npol, double *rel)
486{
487  int  i, j, ecu, ec;
488  int  *ex;
489  double *r;
490
491  ex = degw;
492  r = rel;
493  for (i = 0; i < npol; i++)
494  {
495    ecu = *ex++;
496    for (j = lpol[i] - 1; j; j--)
497    {
498      ec = *ex++;
499      if (ec > ecu)
500        ecu = ec;
501    }
502    *r = (double)1.0 / (double)(ecu * ecu);
503    r++;
504  }
505}
506#endif /* __MWERKS */
507
508
509static void wDimensions(polyset s, int sl, int *lpol, int *npol, int *mons)
510{
511  int  i, i1, j, k;
512  poly p, q;
513
514  i1 = j = 0;
515  for (i = 0; i <= sl; i++)
516  {
517    p = s[i];
518    if (p!=NULL)
519    {
520      k = 1;
521      q = pNext(p);
522      while (q!=NULL)
523      {
524        k++;
525        q = pNext(q);
526      }
527      if (k > 1)
528      {
529        lpol[i1++] = k;
530        j += k;
531      }
532    }
533  }
534  *npol = i1;
535  *mons = j;
536}
537
538
539static void wInit(polyset s, int sl, int mons, int *A) 
540{
541  int  n, a, i, j, *B, *C;
542  poly p, q;
543  Exponent_t *pl;
544
545  B = A;
546  n = pVariables;
547  a = (n + 1) * sizeof(Exponent_t);
548  pl = (Exponent_t * )Alloc(a);
549  for (i = 0; i <= sl; i++)
550  {
551    p = s[i];
552    if (p!=NULL)
553    {
554      q = pNext(p);
555      if (q!=NULL)
556      {
557        C = B;
558        B++;
559        pGetExpV(p, pl);
560        for (j = 0; j < n; j++)
561        {
562          *C = pl[j+1];
563          C += mons;
564        }
565      }
566      while (q!=NULL)
567      {
568        C = B;
569        B++;
570        pGetExpV(q, pl);
571        for (j = 0; j < n; j++)
572        {
573          *C = pl[j+1];
574          C += mons;
575        }
576        q = pNext(q);
577      }
578    }
579  }
580  Free((ADDRESS)pl, a);
581}
582
583static void wCall(polyset s, int sl, int *x)
584{
585  int  n, q, npol, mons, i;
586  int  *A, *xopt, *lpol, *degw;
587  double  f1, fx, eps, *rel;
588  void *adr;
589
590  n = pVariables;
591  lpol = (int * )Alloc((sl + 1) * sizeof(int));
592  wDimensions(s, sl, lpol, &npol, &mons);
593  xopt = x + (n + 1);
594  for (i = n; i; i--)
595    xopt[i] = 1;
596  if (mons==0)
597  {
598    Free((ADDRESS)lpol, (sl + 1) * sizeof(int));
599    return;
600  }
601  adr = (void * )Alloc(npol * sizeof(double) + 8);
602  rel = wDouble(adr);
603  q = (n + 1) * mons * sizeof(int);
604  A = (int * )Alloc(q);
605  wInit(s, sl, mons, A);
606  degw = A + (n * mons);
607  memset(degw, 0, mons * sizeof(int));
608  for (i = n; i; i--)
609    wAdd(A, mons, i, 1);
610  wNorm(degw, lpol, npol, rel);
611  f1 = (*wFunctional)(degw, lpol, npol, rel, (double)1.0);
612  if (TEST_OPT_PROT) Print("// %e\n",f1);
613  eps = f1;
614  fx = (double)2.0 * eps;
615  memset(x, 0, (n + 1) * sizeof(int));
616  wFirstSearch(A, x, mons, lpol, npol, rel, &fx);
617  if (TEST_OPT_PROT) Print("// %e\n",fx);
618  memcpy(x + 1, xopt + 1, n * sizeof(int));
619  memset(degw, 0, mons * sizeof(int));
620  for (i = n; i; i--)
621  {
622    x[i] *= 16;
623    wAdd(A, mons, i, x[i]);
624  }
625  wSecondSearch(A, x, lpol, npol, mons, rel, &fx);
626  if (TEST_OPT_PROT) Print("// %e\n",fx);
627  if (fx >= eps)
628  {
629    for (i = n; i; i--)
630      xopt[i] = 1;
631  }
632  else
633  {
634    wGcd(xopt, n);
635//    if (BTEST1(22))
636//    {
637//      f1 = fx + (double)0.1 * (f1 - fx);
638//      wSimple(x, n);
639//      memset(degw, 0, mons * sizeof(int));
640//      for (i = n; i; i--)
641//        wAdd(A, mons, i, x[i]);
642//      eps = wPrWeight(x, n);
643//      fx = (*wFunctional)(degw, lpol, npol, rel, eps);
644//      if (fx < f1)
645//      {
646//        if (TEST_OPT_PROT) Print("// %e\n",fx);
647//        memcpy(xopt + 1, x + 1, n * sizeof(int));
648//      }
649//    }
650  }
651  Free((ADDRESS)A, q);
652  Free((ADDRESS)lpol, (sl + 1) * sizeof(int));
653  Free((ADDRESS)adr, npol * sizeof(double) + 8);
654}
655
656
657void kEcartWeights(polyset s, int sl, short *eweight)
658{
659  int  n, i;
660  int  *x;
661
662  *eweight = 0;
663  n = pVariables;
664  nsqr = (double)2.0 / (double)n;
665  if (pOrdSgn == -1)
666    wFunctional = wFunctionalMora;
667  else
668    wFunctional = wFunctionalBuch;
669  x = (int * )Alloc(2 * (n + 1) * sizeof(int));
670  wCall(s, sl, x);
671  for (i = n; i; i--)
672    eweight[i] = x[i + n + 1];
673  Free((ADDRESS)x, 2 * (n + 1) * sizeof(int));
674}
675
676
677BOOLEAN kWeight(leftv res,leftv id)
678{
679  ideal F=(ideal)id->Data();
680  intvec * iv = new intvec(pVariables);
681  polyset s;
682  int  sl, n, i;
683  int  *x;
684
685  res->data=(char *)iv;
686  s = F->m;
687  sl = IDELEMS(F) - 1;
688  n = pVariables;
689  nsqr = (double)2.0 / (double)n;
690  wFunctional = wFunctionalBuch;
691  x = (int * )Alloc(2 * (n + 1) * sizeof(int));
692  wCall(s, sl, x);
693  for (i = n; i; i--)
694    (*iv)[i-1] = x[i + n + 1];
695  Free((ADDRESS)x, 2 * (n + 1) * sizeof(int));
696  return FALSE;
697}
698
699BOOLEAN kQHWeight(leftv res,leftv v)
700{
701  res->data=(char *)idQHomWeights((ideal)v->Data());
702  if (res->data==NULL)
703    res->data=(char *)new intvec(pVariables);
704  return FALSE;
705}
706
707short * iv2array(intvec * iv)
708{
709  short *s=(short *)Alloc((pVariables+1)*sizeof(short));
710  int len=iv->length();
711  int i;
712
713  for (i=1;i<=len;i++)
714    s[i]= (*iv)[i-1];
715  for (;i<=pVariables;i++)
716    s[i]= 1;
717  return s;
718}
719
720/*2
721*computes the degree of the leading term of the polynomial
722*with respect to given ecartWeights
723*used for Graebes method if BTEST1(31) is set
724*/
725int totaldegreeWecart(poly p)
726{
727  int i;
728  int j =0;
729
730  for (i=pVariables; i; i--)
731    j += (int)(pGetExp(p,i) * ecartWeights[i]);
732  return  j;
733}
734
735/*2
736*computes the maximal degree of all terms of the polynomial
737*with respect to given ecartWeights and
738*computes the length of the polynomial
739*used for Graebes method if BTEST1(31) is set
740*/
741int maxdegreeWecart(poly p,int *l)
742{
743  short k=pGetComp(p);
744  int ll=1;
745  int  t,max;
746
747  max=totaldegreeWecart(p);
748  pIter(p);
749  while ((p!=NULL) && (pGetComp(p)==k))
750  {
751    t=totaldegreeWecart(p);
752    if (t>max) max=t;
753    ll++;
754    pIter(p);
755  }
756  *l=ll;
757  return max;
758}
Note: See TracBrowser for help on using the repository browser.