source: git/Singular/fast_maps.cc @ bbc80ab

fieker-DuValspielwiese
Last change on this file since bbc80ab was bbc80ab, checked in by Hans Schönemann <hannes@…>, 22 years ago
*hannes: mapolyEval git-svn-id: file:///usr/local/Singular/svn/trunk@5724 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    fast_maps.cc
6 *  Purpose: implementation of fast maps
7 *  Author:  obachman (Olaf Bachmann)
8 *  Created: 02/01
9 *  Version: $Id: fast_maps.cc,v 1.3 2002-01-19 09:54:51 Singular Exp $
10 *******************************************************************/
11#include "mod2.h"
12#include <omalloc.h>
13#include "p_polys.h"
14#include "prCopy.h"
15#include "ideals.h"
16#include "ring.h"
17#include "febase.h"
18
19/*******************************************************************************
20**
21*F  maMaxExp  . . . . . . . . . . . .  returns maximal exponent of result of map
22*/
23
24// return maximal monomial if max_map_monomials are substituted into pi_m
25static poly maGetMaxExpP(poly* max_map_monomials, 
26                         int n_max_map_monomials, ring map_r, 
27                         poly pi_m, ring pi_r)
28{
29  int n = min(pi_r->N, n_max_map_monomials);
30  int i, j;
31  Exponent_t e_i, e_j;
32  poly m_i, map_j = p_Init(map_r);
33 
34  for (i=1; i <= n; i++)
35  {
36    e_i = p_GetExp(pi_m, i, pi_r);
37    m_i = max_map_monomials[i-1];
38    if (e_i > 0 && m_i != NULL && ! p_IsConstantComp(m_i, map_r))
39    {
40      for (j = 1; j<= map_r->N; j++)
41      {
42        e_j = p_GetExp(m_i, j, map_r);
43        if (e_j > 0)
44        {
45          p_AddExp(map_j, j, e_j*e_i, map_r);
46        }
47      }
48    }
49  }
50  return map_j;
51}
52
53// returns maximal exponent if map_id is applied to pi_id
54static Exponent_t maGetMaxExp(ideal map_id, ring map_r, ideal pi_id, ring pi_r)
55{
56  Exponent_t max=0;
57  poly* max_map_monomials = (poly*) omAlloc(IDELEMS(map_id)*sizeof(poly));
58  poly max_pi_i, max_map_i;
59 
60  int i, j;
61  for (i=0; i<IDELEMS(map_id); i++)
62  {
63    max_map_monomials[i] = p_GetMaxExpP(map_id->m[i], map_r);
64  }
65 
66  for (i=0; i<IDELEMS(pi_id); i++)
67  {
68    max_pi_i = p_GetMaxExpP(pi_id->m[i], pi_r);
69    max_map_i = maGetMaxExpP(max_map_monomials, IDELEMS(map_id), map_r, 
70                              max_pi_i, pi_r);
71    Exponent_t temp = p_GetMaxExp(max_map_i, map_r);
72    if (temp> max){
73      max=temp;
74    }
75
76    p_LmFree(max_pi_i, pi_r);
77    p_LmFree(max_map_i, map_r);
78  }
79  return max;
80}
81
82
83// construct ring/map ideal  in/with which we perform computations
84// return TRUE if ordering changed (not yet implemented), false, otherwise
85static BOOLEAN maGetCompIdealRing(ideal map_id, ring map_r, ideal pi_id, 
86                                   ring pi_r, ideal &comp_map_id, ring &comp_r)
87{
88  Exponent_t max_exp = maGetMaxExp(map_id, map_r, pi_id, pi_r);
89
90  comp_r = rModifyRing(map_r, FALSE, !idIsModule(pi_id, pi_r), max_exp);
91  if (comp_r != map_r)
92  {
93    if (TEST_OPT_PROT)
94      Print("[%d:%d]", (long) comp_r->bitmask, comp_r->ExpL_Size);
95    comp_map_id = idrShallowCopyR_NoSort(map_id, map_r, comp_r);
96  }
97  else
98    comp_map_id = map_id;
99 
100  return FALSE;
101}
102
103static void maDestroyCompIdealRing(ideal map_id, ring map_r, 
104                                    ideal comp_map_id, ring &comp_r,
105                                    ideal &result, BOOLEAN sort=FALSE)
106{
107  if (map_r != comp_r)
108  {
109    result = idrMoveR(result, comp_r, map_r);
110    id_ShallowDelete(&comp_map_id, comp_r);
111    rKillModifiedRing(comp_r);
112  }
113}
114
115/*******************************************************************************
116**
117*F  maEggt  . . . . . . . . . . . . . . . . . . . . . . . .  returns extended ggt
118*/
119// return NULL if deg(ggt(m1, m2)) < 2
120// else return m = ggT(m1, m2) and q1, q2 such that m1 = q1*m m2 = q2*m
121static poly maEggT(const poly m1, const poly m2, poly &q1, poly &q2,const ring r)
122{
123  int i;
124  int dg = 0;
125  poly ggt = NULL;
126  for (i=1; i<=r->N; i++)
127  {
128    Exponent_t e1 = p_GetExp(m1, i, r);
129    Exponent_t e2 = p_GetExp(m2, i, r);
130    if (e1 > 0 && e2 > 0)
131    {
132      Exponent_t em = (e1 > e2 ? e2 : e1);
133      if (dg < 2)
134      {
135        ggt = p_Init(r);
136        q1 = p_Init(r);
137        q2 = p_Init(r);
138      }
139      dg += em;
140      p_SetExp(ggt, i, em, r);
141      p_SetExp(q1, i, e1 - em, r);
142      p_SetExp(q2, i, e2 - em, r);
143    }
144  }
145  if (ggt != NULL)
146  {
147    p_Setm(ggt, r);
148    p_Setm(q1, r);
149    p_Setm(q2, r);
150  }
151  return ggt;
152}
153
154/*******************************************************************************
155**
156*F  maGetMapRing  . . . . . . . . . . . . gets ring and ideal with which we work
157*/
158static ring maGetWeightedRing(ideal theMap, ring map_r) 
159{
160  // we work in a ring with ordering Deg,WeightedDegree,vars
161  // First, construct weighted degrees
162  int* weights = (int*) omAlloc0(map_r->N);
163  int i;
164  int n = min(map_r->N, IDELEMS(theMap));
165
166  for (i=0; i<n; i++)
167  {
168    weights[i] = pLength(theMap->m[i]);
169  }
170  return rModifyRing_Wp(map_r, weights);
171}
172static void maDestroyWeightedRing(ring r)
173{
174  rKillModified_Wp_Ring(r);
175}
176
177/*******************************************************************************
178**
179*S  mapoly, macoeff . . . . . . . . . . . . definition of structs/classes
180*/
181class macoeff_s;
182class mapoly_s;
183class maideal_s;
184typedef class mapoly_s*  mapoly;
185typedef class macoeff_s* macoeff;
186typedef class maideal_s* maideal;
187
188class mapoly_s
189{
190public:
191  mapoly    next;
192  int       factors;    // -1: not set, 0: constant, 1, 2, 3
193  poly      src;        // monomial from WeightedRing
194  poly      dest;       // poly in CompRing
195  mapoly    f1, f2;     // if f1 != NULL && f2 != NULL then dest = f1*f2
196  int       ref;        // use to catch last usage to save last copy
197  macoeff   coeff;      // list of coeffs to use
198};
199
200class macoeff_s 
201{
202public:
203  macoeff       next;
204  number        n;
205  sBucket_pt    bucket;
206};
207
208class maideal_s
209{
210public:
211  int n;
212  sBucket_pt* buckets;
213};
214/*******************************************************************************
215**
216*F  mapolyCreate  . . . . . . . . . . . . . . .  Creates mapoly
217*/
218static omBin mapolyBin = omGetSpecBin(sizeof(mapoly_s));
219static omBin macoeffBin = omGetSpecBin(sizeof(macoeff_s));
220mapoly mapolyCreate(poly p, sBucket_pt bucket)
221{
222  long cost, factors;
223  maGetCostFactors(p, r_p, cost, factors);
224
225  // factors < 0, i.e. monomial maps to zero
226  if (factors < 0)
227    return NULL;
228
229  if (cost
230  mapoly mp = (mapoly) omAlloc0Bin(mapolyBin);
231  mp->src = p;
232  maGetCostFactors(src, mp->cost, mp->factors);
233  if (mp->factors == -1)
234  {
235   
236 
237  if (bucket != NULL)
238  {
239    mp->coeff = (macoeff) omAlloc0Bin(macoeffBin);
240    mp->coeff->bucket = bucket;
241    mp->coeff->n = pGetCoeff(p);
242  }
243  else
244  {
245    what->ref = 1;
246  }
247  return mp;
248}
249
250/*******************************************************************************
251**
252*F  mapInsert . . . . . . . . . . . . . . .insertion of monomial/poly into mpoly
253*/
254static int maGetFactors(poly p, ring r)
255{
256  int fac = 0;
257 
258  for (i=1; i<=r->N;i++)
259  {
260    fac += p_GetExp(p, i, r);
261    if (fac >= 3)
262      return fac;
263  }
264}
265
266static mapoly mapInsertMonomial(mapoly &into, mapoly what, ring w_r)
267{
268  if (into == NULL)
269  {
270    into = what;
271    return what;
272  }
273 
274  mapoly iter = into;
275  mapoly prev = NULL;
276 
277  Top:
278  p_LmCmpAction(iter->src, what->src, w_r,goto Greater, goto Equal, goto Smaller);
279 
280  Greater:
281  prev = iter;
282  iter = iter->next;
283  if (iter == NULL) goto Smaller;
284  goto Top;
285 
286  Smaller:
287  what->next = iter;
288  if (what->factors == -1)
289    what->factors = maGetFactors(what->src, w_r);
290  if (prev != NULL) 
291    prev->next = what;
292  return what;
293 
294  Equal:
295  iter->ref += what->ref;
296  macoeff coeff = what->coeff;
297  if (coeff != NULL) 
298  {
299    while (coeff->next != NULL) coeff = coeff->next;
300    coeff->next = iter->coeff;
301    iter->coeff = what->coeff;
302  }
303  p_LmFree(what->src, w_r);
304  omFreeBinAddr(what);
305  return iter;
306}
307
308static mapoly mapInsertMonomial(mapoly &into, poly what, ring w_r, 
309                                sBucket_pt bucket)
310{
311  return mapInsertMonomial(into, mapolyCreate(what, bucket), w_r);
312}
313
314static mapoly mapInsertPoly(mapoly &into, poly what, ring w_r, sBucket_pt bucket)
315{
316  poly next;
317 
318  while (what != NULL)
319  {
320    next = what->next;
321    into = mapInsertMonomial(into, what, w_r, bucket);
322    what = next;
323  }
324  return into;
325}
326
327/*******************************************************************************
328**
329*F  maMap_2_maPoly  . . . . . . . . . . . construnct maideal and mapoly from map
330*/
331static void maMap_2_maPoly(ideal theMap, ring map_r, ring weight_r, ring comp_r,
332                           mapoly &mp, maideal &mideal)
333{
334  mideal = (maideal) omAlloc0(sizeof(maideal_s));
335  mideal->n = IDELEMS(theMap);
336  mideal->buckets = (sBucket_pt*) omAlloc0(mideal->n*sizeof(sBucket_pt));
337  int i;
338  mp = NULL;
339 
340  for (i=0; i<mideal->n; i++)
341  {
342    if (theMap->m[i] != NULL)
343    {
344      mideal->buckets[i] = sBucketCreate(comp_r);
345      mapInsertPoly(mp, 
346                    prShallowCopyR_NoSort(theMap->m[i], map_r, weight_r),
347                    weight_r,                     
348                    mideal->buckets[i]);
349    }
350  }
351}
352
353static mapoly maFindBestggT(mapoly mp, mapoly in, poly ggT, poly fp, poly fq)
354{
355  int ggt_deg = 0;
356  poly p = mp->src;
357  mapoly mq = NULL;
358 
359  ggT = NULL;
360  fp = NULL;
361  fq = NULL;
362  while (in != NULL && in->factors > 1 && pFDeg(in->src) > ggt_deg)
363  {
364    poly q1, q2, q;
365    q = maEggT(p, in->src, q1, q2);
366    if (q != NULL)
367    {
368      if (pFDeg(q) > fft_deg)
369      {
370        if (ggT != NULL)
371        {
372          p_LmFree(ggT);
373          p_LmFree(fp);
374          p_LmFree(fq);
375        }
376        ggT = q;
377        fp = q1;
378        fq = q2;
379      }
380      else
381      {
382        p_LmFree(q);
383        p_LmFree(q1);
384        p_LmFree(q2);
385      }
386    }
387  }
388}
389
390     
391static mapoly maPrepareEval(mapoly mp, ring r)
392{
393  mapoly res = NULL;
394  mapoly next = mp;
395 
396  while (mp != NULL)
397  {
398    next = mp->next;
399    mp->next = res;
400    res = mp;
401    if (mp->factors > 1 && mp->f1 == NULL && mp->f2 == NULL)
402    {
403      poly fp, fq, ggT;
404      mapoly mq = maFindBestggT(mp, next, ggT, fp, fq);
405      if (mq != NULL)
406      {
407        assume(fp != NULL);
408        mp->f1 = maInsertMonomial(next, fp, r, NULL);
409       
410        if (ggT != NULL)
411        {
412          assume(fq != NULL);
413          mapoly mggT = maInsertMonomial(next, ggT, r, NULL);
414          mq->f1 = maInsertMonomial(next, fq, r, NULL);
415          mq->f2 = mggT;
416          mp->f2 = mggT;
417          mggT->ref++;
418        }
419        else
420        {
421          assume(fq == NULL);
422          mp->f2 = mq;
423          mq->ref++;
424        }
425      }
426    }
427    mp = next;
428  }
429  return res;
430}
431   
432   
433#if 0
434/*******************************************************************************
435**
436*F  ideal_2_maideal . . . . . . . . . . . . . . . . .  converts ideal to maideal
437*/
438mapoly ideal_2_maideal(ideal id, ring r, maideal mid, ring mr, ring comp_ring,
439                       nMapFunc nMap)
440{
441  mid->n = IDELEMS(id);
442  mid->buckets = (sBucket_pt*)omAlloc(mid->n*sizeof(sBucket_pt));
443  mapoly mpoly = NULL;
444 
445  for (int i=0; i<mid->n; i++)
446  {
447    mid->buckets[i] = sBucketCreate(comp_ring);
448    mapoly mpoly_i = poly_2_mapoly(id->m[i], mid, nMap, mid->buckets[i]);
449    mpoly = mapAdd(mpoly, mpoly_i);
450  }
451  return mpoly;
452}
453
454ideal maideal_2_ideal(ideal orig_id,
455                      maideal mideal, ring comp_ring, ring dest_ring)
456{
457  ideal id = idInit(IDELEMS(orig_id), orig_id->rank);
458  for (int i=0; i<mid->n; i++)
459  {
460    sBucketDestroyAdd(mid->buckets[i], &(id->m[i]), &dummy);
461  }
462 
463  if (comp_ring != dest_ring)
464    id = idrMoveR_NoSort(id, comp_ring);
465 
466  return id;
467}
468#endif
469
470/*****************************************************************
471* evaluate all monomial in the mapoly list,
472* put the results also into the corresponding sBuckets
473******************************************************************/
474
475void mapolyEval(mapoly root)
476{
477  // invert the list rooted at root:
478  if ((root!=NULL) && (root->next!=NULL))
479  {
480    mapoly q=root->next;
481    mapoly qn;
482    root->next=NULL;
483    do
484    {
485      qn=q->next;
486      q->next=root;
487      root=q;
488    }
489    while (qn !=NULL);
490  }
491
492  mapoly p=root;
493  while (p!=NULL)
494  {
495     // look at each mapoly: compute its value in ->dest
496     if (p->dest==NULL)
497     {
498       if (p->factors==0) p->dest=pOne();
499       else if (p->factors==2)
500       {
501         poly f1=p->f1->dest;
502         p->f1->ref--;
503         poly f2=p->f2->dest;
504         p->f2->ref--;
505         if (p->f1->ref>0) f1=pCopy(f1);
506         else
507         {
508           // clear p->f1
509           p->f1->dest=NULL;
510         }
511         if (p->f2->ref>0) f2=pCopy(f2);
512         else
513         {
514           // clear p->f2
515           p->f2->dest=NULL;
516         }
517         p->dest=pMult(f1,f2);
518      // substitute the monomial: go through macoeff
519         int len=pLength(p->dest);
520         macoeff c=p->coeff;
521         macoeff cc;
522         while (c!=NULL)
523         {
524           poly t=ppMult_nn(p->dest,c->n);
525           sBucket_Add_p(c->bucket, t, len);
526           cc=c;
527           c=c->next;
528           // clean up
529           nDelete(&(cc->n));
530           omFreeBin(cc,macoeffBin);
531         }
532         p->coeff=NULL;
533       } /* p->factors==2 */
534     } /* p->dest==NULL */
535     p=p->next;
536   }
537}
Note: See TracBrowser for help on using the repository browser.