source: git/Singular/fast_maps.cc @ 324dc0

fieker-DuValspielwiese
Last change on this file since 324dc0 was 324dc0, checked in by Olaf Bachmann <obachman@…>, 22 years ago
syntax error corrected git-svn-id: file:///usr/local/Singular/svn/trunk@5738 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.2 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.10 2002-01-19 13:08:46 obachman 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#include "fast_maps.h"
19
20#if 0
21// paste into extra.cc
22    if(strcmp(sys_cmd,"map")==0)
23    {
24      ring image_r = currRing;
25      map theMap = (map)h->Data();
26      ideal image_id = (ideal) theMap;
27      ring map_r = IDRING(idroot->get(theMap->preimage, myynest));
28      ideal map_id = IDIDEAL(map_r->idroot->get(h->Next()->Name(), myynest));
29
30      ring src_r, dest_r;
31      maMap_CreateRings(map_id, map_r, image_id, image_r, src_r, dest_r);
32      mapoly mp;
33      maideal mideal;
34         
35      maMap_CreatePolyIdeal(map_id, map_r, src_r, dest_r, mp, mideal);
36      maPoly_Out(mp, src_r);
37      return FALSE;
38    }
39
40// use as Singular source template
41ring map_r = 32003, (a, b, c), Dp;
42ideal map_id = a, ab, c3 + ab, a2b + ab;
43
44
45ring image_r;
46ideal image_id = x2y3, y, z+x6;
47
48map Phi = map_r, image_id;
49
50
51system("map", Phi, map_id);
52
53#endif
54/*******************************************************************************
55**
56*F  debugging stuff
57*/
58void maMonomial_Out(mapoly monomial, ring src_r, ring dest_r = NULL)
59{
60  p_wrp(monomial->src, src_r);
61  printf(" ref:%d", monomial->ref);
62  if (dest_r != NULL)
63  {
64    printf(" dest:");
65    p_wrp(monomial->dest, dest_r);
66  }
67  printf("\n");
68  fflush(stdout);
69}
70
71void maPoly_Out(mapoly mpoly, ring src_r, ring dest_r = NULL)
72{
73  while (mpoly != NULL)
74  {
75    maMonomial_Out(mpoly, src_r, dest_r);
76    mpoly = mpoly->next;
77  }
78}
79
80
81/*******************************************************************************
82**
83*F  mapolyCreate  . . . . . . . . . . . . . . .  Creates mapoly
84*/
85static omBin mapolyBin = omGetSpecBin(sizeof(mapoly_s));
86static omBin macoeffBin = omGetSpecBin(sizeof(macoeff_s));
87
88mapoly maMonomial_Create(poly p, ring r_p, sBucket_pt bucket = NULL)
89{
90  mapoly mp = (mapoly) omAlloc0Bin(mapolyBin);
91  mp->src = p;
92  p->next = NULL;
93
94  if (bucket != NULL)
95  {
96    mp->coeff = (macoeff) omAlloc0Bin(macoeffBin);
97    mp->coeff->bucket = bucket;
98    mp->coeff->n = pGetCoeff(p);
99  }
100  mp->ref = 1;
101  return mp;
102}
103
104void maMonomial_Destroy(mapoly mp, ring src_r, ring dest_r = NULL)
105{
106  if (mp != NULL)
107  {
108    p_LmFree(mp->src, src_r);
109    if (mp->coeff != NULL)
110    {
111      macoeff coeff, next = mp->coeff;
112      do
113      {
114        coeff = next;
115        next = coeff->next;
116        omFreeBin(coeff, macoeffBin);
117      }
118      while (next != NULL);
119      if (mp->dest != NULL) 
120      {
121        assume(dest_r != NULL);
122        p_Delete(&(mp->dest), dest_r);
123      }
124      omFreeBin(mp, mapolyBin);
125    }
126  }
127}
128
129/*******************************************************************************
130**
131*F  maPoly_InsertMonomial . . . . . . . . .insertion of a monomial into mapoly
132*/
133mapoly maPoly_InsertMonomial(mapoly into, mapoly what, ring src_r)
134{
135  if (into == NULL)
136  {
137    into = what;
138    return what;
139  }
140 
141  mapoly iter = into;
142  mapoly prev = NULL;
143 
144  Top:
145  p_LmCmpAction(iter->src, what->src, src_r, goto Equal, goto Greater, goto Smaller);
146 
147
148  Greater:
149  if (iter->next == NULL)
150  {
151    iter->next = what;
152    return into;
153  }
154  prev = iter;
155  iter = iter->next;
156  goto Top;
157 
158  Smaller:
159  if (prev == NULL)
160  {
161    what->next = iter;
162    return what;
163  }
164  prev->next = what;
165  what->next = iter;
166  return into;
167 
168  Equal:
169  iter->ref += what->ref;
170  macoeff coeff = what->coeff;
171  if (coeff != NULL) 
172  {
173    while (coeff->next != NULL) coeff = coeff->next;
174    coeff->next = iter->coeff;
175    iter->coeff = what->coeff;
176    what->coeff = NULL;
177  }
178  maMonomial_Free(what, src_r);
179  return into;
180}
181
182mapoly maPoly_InsertMonomial(mapoly into, poly p, ring src_r, sBucket_pt bucket = NULL)
183{
184  return maPoly_InsertMonomial(into, maMonomial_Create(p, src_r, bucket), src_r);
185}
186
187static mapoly maPoly_InsertPoly(mapoly into, poly what, ring src_r, sBucket_pt bucket)
188{
189  poly next;
190 
191  while (what != NULL)
192  {
193    next = what->next;
194    into = maPoly_InsertMonomial(into, what, src_r, bucket);
195    what = next;
196  }
197  return into;
198}
199
200void maMap_CreatePolyIdeal(ideal map_id, ring map_r, ring src_r, ring dest_r,
201                           mapoly &mp, maideal &mideal)
202{
203  mideal = (maideal) omAlloc0(sizeof(maideal_s));
204  mideal->n = IDELEMS(map_id);
205  mideal->buckets = (sBucket_pt*) omAlloc0(mideal->n*sizeof(sBucket_pt));
206  int i;
207  mp = NULL;
208 
209  for (i=0; i<mideal->n; i++)
210  {
211    if (map_id->m[i] != NULL)
212    {
213      mideal->buckets[i] = sBucketCreate(dest_r);
214      mp = maPoly_InsertPoly(mp, 
215                             prShallowCopyR_NoSort(map_id->m[i], map_r, src_r),
216                             src_r,                     
217                             mideal->buckets[i]);
218    }
219  }
220}
221
222void maMap_CreateRings(ideal map_id, ring map_r, 
223                       ideal image_id, ring image_r, 
224                       ring &src_r, ring &dest_r)
225{
226  src_r = map_r;
227  dest_r = image_r;
228}
229
230
231ideal maIdeal_2_Ideal(maideal m_id, ring dest_r)
232{
233  ideal res = idInit(m_id->n, 1);
234  int l;
235 
236  for (int i= 0; i < m_id->n; i++)
237  {
238    sBucketDestroyMerge(m_id->buckets[i], &(res->m[i]), &l);
239  }
240  return res;
241}
242
243#if 0
244
245/*******************************************************************************
246**
247*F  maMaxExp  . . . . . . . . . . . .  returns maximal exponent of result of map
248*/
249
250// return maximal monomial if max_map_monomials are substituted into pi_m
251static poly maGetMaxExpP(poly* max_map_monomials,
252                         int n_max_map_monomials, ring map_r,
253                         poly pi_m, ring pi_r)
254{
255  int n = min(pi_r->N, n_max_map_monomials);
256  int i, j;
257  Exponent_t e_i, e_j;
258  poly m_i, map_j = p_Init(map_r);
259 
260  for (i=1; i <= n; i++)
261  {
262    e_i = p_GetExp(pi_m, i, pi_r);
263    m_i = max_map_monomials[i-1];
264    if (e_i > 0 && m_i != NULL && ! p_IsConstantComp(m_i, map_r))
265    {
266      for (j = 1; j<= map_r->N; j++)
267      {
268        e_j = p_GetExp(m_i, j, map_r);
269        if (e_j > 0)
270        {
271          p_AddExp(map_j, j, e_j*e_i, map_r);
272        }
273      }
274    }
275  }
276  return map_j;
277}
278
279// returns maximal monomial if map_id is applied to pi_id
280static poly maGetMaxExpP(ideal map_id, ring map_r, ideal pi_id, ring pi_r)
281{
282  poly* max_map_monomials = (poly*) omAlloc(IDELEMS(map_id)*sizeof(poly));
283  poly max_pi_i, max_map_i;
284  poly max_map = p_Init(map_r);
285 
286  int i, j;
287  for (i=0; i<IDELEMS(map_id); i++)
288  {
289    max_map_monomials[i] = p_GetMaxExpP(map_id->m[i], map_r);
290  }
291 
292  for (i=0; i<IDELEMS(pi_id); i++)
293  {
294    max_pi_i = p_GetMaxExpP(pi_id->m[i], pi_r);
295    max_map_i = maGetMaxExpP(max_map_monomials, IDELEMS(map_id), map_r,
296                              max_pi_i, pi_r);
297    // get maximum
298    for (j = 1; j<= map_r->N; j++)
299    {
300      if (p_GetExp(max_map, j, map_r) < p_GetExp(max_map_i, j, map_r))
301        p_SetExp(max_map, j, p_GetExp(max_map_i, j, map_r), map_r);
302    }
303    p_LmFree(max_pi_i, pi_r);
304    p_LmFree(max_map_i, map_r);
305  }
306  return max_map;
307}
308
309// returns maximal exponent if map_id is applied to pi_id
310static Exponent_t maGetMaxExp(ideal map_id, ring map_r, ideal pi_id, ring pi_r)
311{
312  poly p = maGetMaxExpP(map_id, map_r, pi_id, pi_r);
313  Exponent_t max = p_GetMaxExp(p, map_r);
314  p_LmFree(p, map_r);
315  return max;
316}
317
318// construct ring/map ideal  in/with which we perform computations
319// return TRUE if ordering changed (not yet implemented), false, otherwise
320static BOOLEAN maGetCompIdealRing(ideal map_id, ring map_r, ideal pi_id,
321                                   ring pi_r, ideal &comp_map_id, ring &comp_r)
322{
323  Exponent_t max_exp = maGetMaxExp(map_id, map_r, pi_id, pi_r);
324
325  comp_r = rModifyRing(map_r, FALSE, !idIsModule(pi_id, pi_r), max_exp);
326  if (comp_r != map_r)
327  {
328    if (TEST_OPT_PROT)
329      Print("[%d:%d]", (long) comp_r->bitmask, comp_r->ExpL_Size);
330    comp_map_id = idrShallowCopyR_NoSort(map_id, map_r, comp_r);
331  }
332  else
333    comp_map_id = map_id;
334 
335  return FALSE;
336}
337
338static void maDestroyCompIdealRing(ideal map_id, ring map_r,
339                                    ideal comp_map_id, ring &comp_r,
340                                    ideal &result, BOOLEAN sort=FALSE)
341{
342  if (map_r != comp_r)
343  {
344    result = idrMoveR(result, comp_r, map_r);
345    id_ShallowDelete(&comp_map_id, comp_r);
346    rKillModifiedRing(comp_r);
347  }
348}
349
350/*******************************************************************************
351**
352*F  maEggt  . . . . . . . . . . . . . . . . . . . . . . . .  returns extended ggt
353*/
354// return NULL if deg(ggt(m1, m2)) < 2
355// else return m = ggT(m1, m2) and q1, q2 such that m1 = q1*m m2 = q2*m
356static poly maEggT(const poly m1, const poly m2, poly &q1, poly &q2,const ring r)
357{
358  int i;
359  int dg = 0;
360  poly ggt = NULL;
361  for (i=1; i<=r->N; i++)
362  {
363    Exponent_t e1 = p_GetExp(m1, i, r);
364    Exponent_t e2 = p_GetExp(m2, i, r);
365    if (e1 > 0 && e2 > 0)
366    {
367      Exponent_t em = (e1 > e2 ? e2 : e1);
368      if (dg < 2)
369      {
370        ggt = p_Init(r);
371        q1 = p_Init(r);
372        q2 = p_Init(r);
373      }
374      dg += em;
375      p_SetExp(ggt, i, em, r);
376      p_SetExp(q1, i, e1 - em, r);
377      p_SetExp(q2, i, e2 - em, r);
378    }
379  }
380  if (ggt != NULL)
381  {
382    p_Setm(ggt, r);
383    p_Setm(q1, r);
384    p_Setm(q2, r);
385  }
386  return ggt;
387}
388
389/*******************************************************************************
390**
391*F  maGetMapRing  . . . . . . . . . . . . gets ring and ideal with which we work
392*/
393static ring maGetWeightedRing(ideal theMap, ring map_r) 
394{
395  // we work in a ring with ordering Deg,WeightedDegree,vars
396  // First, construct weighted degrees
397  int* weights = (int*) omAlloc0(map_r->N);
398  int i;
399  int n = min(map_r->N, IDELEMS(theMap));
400
401  for (i=0; i<n; i++)
402  {
403    weights[i] = pLength(theMap->m[i]);
404  }
405  return rModifyRing_Wp(map_r, weights);
406}
407static void maDestroyWeightedRing(ring r)
408{
409  rKillModified_Wp_Ring(r);
410}
411
412
413
414
415
416static void maMap_2_maPoly(ideal source_id, ring source_r, ring weight_r, ring comp_r,
417                           mapoly &mp, maideal &mideal)
418{
419  mideal = (maideal) omAlloc0(sizeof(maideal_s));
420  mideal->n = IDELEMS(source_id);
421  mideal->buckets = (sBucket_pt*) omAlloc0(mideal->n*sizeof(sBucket_pt));
422  int i;
423  mp = NULL;
424 
425  for (i=0; i<mideal->n; i++)
426  {
427    if (source_id->m[i] != NULL)
428    {
429      mideal->buckets[i] = sBucketCreate(comp_r);
430      mapInsertPoly(mp,
431                    prShallowCopyR_NoSort(source_id->m[i], source_r, weight_r),
432                    weight_r,                     
433                    mideal->buckets[i]);
434    }
435    maPoly_Out(mp, source_r);
436  }
437}
438
439
440
441
442
443static mapoly maFindBestggT(mapoly mp, mapoly in, poly ggT, poly fp, poly fq)
444{
445  int ggt_deg = 0;
446  poly p = mp->src;
447  mapoly mq = NULL;
448 
449  ggT = NULL;
450  fp = NULL;
451  fq = NULL;
452  while (in != NULL && in->factors > 1 && pFDeg(in->src) > ggt_deg)
453  {
454    poly q1, q2, q;
455//    q = maEggT(p, in->src, q1, q2);
456    if (q != NULL)
457    {
458      if (pFDeg(q) > fft_deg)
459      {
460        if (ggT != NULL)
461        {
462          p_LmFree(ggT);
463          p_LmFree(fp);
464          p_LmFree(fq);
465        }
466        ggT = q;
467        fp = q1;
468        fq = q2;
469      }
470      else
471      {
472        p_LmFree(q);
473        p_LmFree(q1);
474        p_LmFree(q2);
475      }
476    }
477  }
478}
479
480     
481static mapoly maPrepareEval(mapoly mp, ring r)
482{
483  mapoly res = NULL;
484  mapoly next = mp;
485 
486  while (mp != NULL)
487  {
488    next = mp->next;
489    mp->next = res;
490    res = mp;
491    if (mp->factors > 1 && mp->f1 == NULL && mp->f2 == NULL)
492    {
493      poly fp, fq, ggT;
494      mapoly mq = maFindBestggT(mp, next, ggT, fp, fq);
495      if (mq != NULL)
496      {
497        assume(fp != NULL);
498        mp->f1 = maInsertMonomial(next, fp, r, NULL);
499       
500        if (ggT != NULL)
501        {
502          assume(fq != NULL);
503          mapoly mggT = maInsertMonomial(next, ggT, r, NULL);
504          mq->f1 = maInsertMonomial(next, fq, r, NULL);
505          mq->f2 = mggT;
506          mp->f2 = mggT;
507          mggT->ref++;
508        }
509        else
510        {
511          assume(fq == NULL);
512          mp->f2 = mq;
513          mq->ref++;
514        }
515      }
516    }
517    mp = next;
518  }
519  return res;
520}
521/*******************************************************************************
522**
523*F  ideal_2_maideal . . . . . . . . . . . . . . . . .  converts ideal to maideal
524*/
525mapoly ideal_2_maideal(ideal id, ring r, maideal mid, ring mr, ring comp_ring,
526                       nMapFunc nMap)
527{
528  mid->n = IDELEMS(id);
529  mid->buckets = (sBucket_pt*)omAlloc(mid->n*sizeof(sBucket_pt));
530  mapoly mpoly = NULL;
531 
532  for (int i=0; i<mid->n; i++)
533  {
534    mid->buckets[i] = sBucketCreate(comp_ring);
535    mapoly mpoly_i = poly_2_mapoly(id->m[i], mid, nMap, mid->buckets[i]);
536    mpoly = mapAdd(mpoly, mpoly_i);
537  }
538  return mpoly;
539}
540
541ideal maideal_2_ideal(ideal orig_id,
542                      maideal mideal, ring comp_ring, ring dest_ring)
543{
544  ideal id = idInit(IDELEMS(orig_id), orig_id->rank);
545  for (int i=0; i<mid->n; i++)
546  {
547    sBucketDestroyAdd(mid->buckets[i], &(id->m[i]), &dummy);
548  }
549 
550  if (comp_ring != dest_ring)
551    id = idrMoveR_NoSort(id, comp_ring);
552 
553  return id;
554}
555
556#endif
557
558
559   
560   
561                   
562 
563   
564
565
566
567
568
569
570
571
572 
573 
574 
575 
576
577 
578     
Note: See TracBrowser for help on using the repository browser.