source: git/Singular/fast_maps.cc @ fbd9c62

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