source: git/Singular/maps.cc @ 5480da

spielwiese
Last change on this file since 5480da was 47faf56, checked in by Olaf Bachmann <obachman@…>, 26 years ago
* ring handling: from pChangeRing to rChangeCurrRing was prepared * various fixes towards working COMP_FAST * fixed gcd content problem of factory git-svn-id: file:///usr/local/Singular/svn/trunk@1010 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: maps.cc,v 1.7 1998-01-12 18:59:50 obachman Exp $ */
5/*
6* ABSTRACT - the mapping of polynomials to other rings
7*/
8
9#include "mod2.h"
10#include "tok.h"
11#include "febase.h"
12#include "polys.h"
13#include "numbers.h"
14#include "ipid.h"
15#include "ring.h"
16#include "ideals.h"
17#include "matpol.h"
18#include "mmemory.h"
19#include "kstd1.h"
20#include "lists.h"
21#include "longalg.h"
22#include "maps.h"
23
24#define MAX_MAP_DEG 32
25
26/*2
27* copy a map
28*/
29map maCopy(map theMap)
30{
31  int i;
32  map m=(map)idInit(IDELEMS(theMap),0);
33  for (i=IDELEMS(theMap)-1; i>=0; i--)
34      m->m[i] = pCopy(theMap->m[i]);
35  m->preimage=mstrdup(theMap->preimage);
36  return m;
37}
38
39poly maEval(map theMap, poly p,ring preimage_r,matrix s)
40{
41  poly result = NULL,q,pp;
42  int i,modulComp;
43  int varnum = preimage_r->N;
44 
45//  for(i=1; i<=varnum; i++)
46//  {
47//    pTest(theMap->m[i-1]);
48//  }
49  while (p!=NULL)
50  {
51    q=pOne();
52    pSetCoeff(q,nMap(pGetCoeff(p)));
53
54    for(i=1; i<=varnum; i++)
55    {
56      int pExp=pRingGetExp(preimage_r, p,i);
57      if (pExp != 0)
58      {
59        if (theMap->m[i-1]!=NULL)
60        {
61          poly p1=theMap->m[i-1];
62          if((s!=NULL)&&(pExp<(MAX_MAP_DEG*2)))
63          {
64            int e=min(pExp,MAX_MAP_DEG);
65            if(MATELEM(s,i,e)!=NULL)
66              pp=pCopy(MATELEM(s,i,e));
67            else
68            {
69              int j=2;
70              poly p0=p1;
71              if(MATELEM(s,i,1)==NULL)
72              {
73                MATELEM(s,i,1)=pCopy(p1/*theMap->m[i-1]*/);
74              }
75              else
76              {
77                while((j<=e)&&(MATELEM(s,i,j)!=NULL))
78                {
79                  j++;
80                }
81                p0=MATELEM(s,i,j-1);
82              }
83              for(;j<=e;j++)
84              {
85                p0=MATELEM(s,i,j)=pMult(pCopy(p0/*MATELEM(s,i,j-1)*/),
86                                        pCopy(p1/*theMap->m[i-1]*/));
87              }
88              pp=pCopy(p0/*MATELEM(s,i,e)*/);
89            }
90            while(e!=pExp/*pRingGetExp(preimage_r, p,i)*/)
91            {
92              // e is the current exponent,
93              // MAX_MAP_DEG the max exponent in the table
94              // pExp the end exponent
95              pp=pMult(pp,pCopy(MATELEM(s,i,min(MAX_MAP_DEG,pExp-e))));
96              e+=min(MAX_MAP_DEG,pExp-e);
97            }
98          }
99          else
100          {
101            pp = pPower(pCopy(p1/*theMap->m[i-1]*/),pExp/*pRingGetExp(preimage_r, p,i)*/);
102          }
103          q = pMult(q,pp);
104        }
105        else
106        {
107          pDelete(&q);
108          break;
109        }
110      }
111    }
112    modulComp = pRingGetComp(preimage_r, p);
113    if (q!=NULL) pSetCompP(q,modulComp);
114    result = pAdd(result,q);
115    pIter(p);
116  }
117  if (currRing->minpoly!=NULL) result=pMult(result,pOne());
118  pTest(result);
119  return result;
120}
121
122/*2
123*shifts the variables between minvar and maxvar of p  \in p_ring to the
124*first maxvar-minvar+1 variables in the actual ring
125*be carefull: there is no range check for the variables of p
126*/
127static poly pChangeSizeOfPoly(ring p_ring, poly p,int minvar,int maxvar)
128{
129  int i;
130  poly result = NULL,resultWorkP;
131  number n;
132
133  if (p==NULL) return result;
134  else result = pInit();
135  resultWorkP = result;
136  while (p!=NULL)
137  {
138    for (i=minvar;i<=maxvar;i++)
139      pSetExp(resultWorkP,i-minvar+1,pRingGetExp(p_ring,p,i));
140    pSetComp(resultWorkP,pRingGetComp(p_ring,p));
141    n=nCopy(pGetCoeff(p));
142    pSetCoeff(resultWorkP,n);
143    pSetm(resultWorkP);
144    pIter(p);
145    if (p!=NULL)
146    {
147      pNext(resultWorkP) = pInit();
148      pIter(resultWorkP);
149    }
150  }
151  return result;
152}
153
154
155/*2
156*returns the preimage of id under theMap,
157*if id is empty or zero the kernel is computed
158*/
159ideal maGetPreimage(ring theImageRing, map theMap, ideal id)
160{
161  int i,j,sizeofpoly;
162  int ordersize;
163  poly p,pp,q;
164  ideal temp1;
165  ideal temp2;
166  short  ** wv;
167#define blockmax 5
168  int orders[blockmax],block0[blockmax], block1[blockmax];
169  int imagepvariables = theImageRing->N;
170  ring sourcering = currRing;
171  int N = pVariables+imagepvariables;
172  sip_sring tmpR;
173
174  memset(block0, 0,sizeof(block0));
175  memset(block1, 0,sizeof(block1));
176  memset(orders, 0,sizeof(orders));
177  if (theImageRing->OrdSgn == 1) orders[0] = ringorder_dp;
178  else orders[0] = ringorder_ls;
179  block1[0] = imagepvariables;
180  block0[0] = 1;
181  /*
182  *if (sourcering->order[blockmax])
183  *{
184  *  if (sourcering->OrdSgn == 1) orders[1] = ringorder_dp;
185  *  else orders[1] = ringorder_ls;
186  *  block1[1] = N;
187  *}
188  *else
189  */
190  {
191    i=0;
192    while(sourcering->order[i])
193    {
194      orders[i+1] = sourcering->order[i];
195      block0[i+1] = sourcering->block0[i]+imagepvariables;
196      block1[i+1] = sourcering->block1[i]+imagepvariables;
197      i++;
198    }
199  }
200  ordersize=i+1;
201  wv = (short **) Alloc(ordersize * sizeof(short **));
202  memset(wv,0,ordersize * sizeof(short **));
203  for (i--;i!=0 ;i--) wv[i+1] = sourcering->wvhdl[i];
204  tmpR = *currRing;
205  tmpR.N = N;
206  tmpR.order = orders;
207  tmpR.block0 = block0;
208  tmpR.block1 = block1;
209  tmpR.wvhdl = wv;
210  rComplete(&tmpR);
211
212  // change to new ring
213  rChangeCurrRing(&tmpR, FALSE);
214  sizeofpoly = pMonomSize; /*POLYSIZE+sizeof(monomial);*/
215  if (id==NULL)
216    j = 0;
217  else
218    j = IDELEMS(id);
219  temp1 = idInit(sourcering->N+j,1);
220  for (i=0;i<sourcering->N;i++)
221  {
222    if ((i<IDELEMS(theMap)) && (theMap->m[i]!=NULL))
223    {
224      p = pChangeSizeOfPoly(theImageRing, theMap->m[i],1,imagepvariables);
225      q = p;
226      while (pNext(q)) pIter(q);
227      pNext(q) = pOne();
228      pIter(q);
229    }
230    else
231      q = p = pOne();
232    pGetCoeff(q)=nNeg(pGetCoeff(q));
233    pSetExp(q,i+1+imagepvariables,1);
234    pSetm(q);
235    temp1->m[i] = p;
236  }
237  for (i=sourcering->N;i<sourcering->N+j;i++)
238  {
239    temp1->m[i] = pChangeSizeOfPoly(theImageRing,
240                                    id->m[i-sourcering->N],1,imagepvariables);
241  }
242  // we ignore here homogenity - may be changed later:
243  temp2 = std(temp1,NULL,isNotHomog,NULL);
244  idDelete(&temp1);
245  for (i=0;i<IDELEMS(temp2);i++)
246  {
247    if (pLowVar(temp2->m[i])<imagepvariables) pDelete(&(temp2->m[i]));
248  }
249
250  // let's get back to the original ring
251  rChangeCurrRing(sourcering, FALSE);
252  temp1 = idInit(5,1);
253  j = 0;
254  for (i=0;i<IDELEMS(temp2);i++)
255  {
256    p = temp2->m[i];
257    temp2->m[i]=NULL;
258    if (p!=NULL)
259    {
260      q = pChangeSizeOfPoly(&tmpR, p,imagepvariables+1,N);
261      if (j>=IDELEMS(temp1))
262      {
263        pEnlargeSet(&(temp1->m),IDELEMS(temp1),5);
264        IDELEMS(temp1)+=5;
265      }
266      temp1->m[j] = q;
267      j++;
268      while (p!=NULL)
269      {
270        pp = pNext(p);
271        Free((ADDRESS)p,sizeofpoly);
272        p = pp;
273      }
274    }
275  }
276  idDelete(&temp2);
277  Free((ADDRESS) wv, ordersize*sizeof(short **));
278  idSkipZeroes(temp1);
279  return temp1;
280}
281
282void maFindPerm(char **preim_names, int preim_n, char **preim_par, int preim_p,
283                char **names,       int n,       char **par,       int nop,
284                int * perm, int *par_perm)
285{
286  int i,j;
287  /* find correspondig vars */
288  for (i=0; i<preim_n; i++)
289  {
290    for(j=0; j<n; j++)
291    {
292      if (strcmp(preim_names[i],names[j])==0)
293      {
294        if (BVERBOSE(V_IMAP))
295          Print("// var %s: nr %d -> nr %d\n",preim_names[i],i+1,j+1);
296        /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
297        perm[i+1]=j+1;
298        break;
299      }
300    }
301    if ((perm[i+1]==0)&&(par!=NULL))
302    {
303      for(j=0; j<nop; j++)
304      {
305        if (strcmp(preim_names[i],par[j])==0)
306        {
307          if (BVERBOSE(V_IMAP))
308            Print("// var %s: nr %d -> par %d\n",preim_names[i],i+1,j+1);
309          /* var i+1 from preimage ring is par j+1 (index j) from image ring */
310          perm[i+1]=-(j+1);
311        }
312      }
313    }
314  }
315  if (par_perm!=NULL)
316  {
317    for (i=0; i<preim_p; i++)
318    {
319      for(j=0; j<n; j++)
320      {
321        if (strcmp(preim_par[i],names[j])==0)
322        {
323          if (BVERBOSE(V_IMAP))
324            Print("// par %s: par %d -> nr %d\n",preim_par[i],i+1,j+1);
325          /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
326          par_perm[i]=j+1;
327          break;
328        }
329      }
330      if ((par!=NULL) && (par_perm[i]==0))
331      {
332        for(j=0; j<nop; j++)
333        {
334          if (strcmp(preim_par[i],par[j])==0)
335          {
336            if (BVERBOSE(V_IMAP))
337              Print("// par %s: nr %d -> par %d\n",preim_par[i],i+1,j+1);
338            /* var i+1 from preimage ring is par j+1 (index j) from image ring */
339            par_perm[i]=-(j+1);
340          }
341        }
342      }
343    }
344  }
345}
346
347/*2
348* embeds poly p from the subring r into the current ring
349*/
350poly maIMap(ring r, poly p)
351{
352  /* the simplest case:*/
353  if(r==currRing) return pCopy(p);
354  nSetMap(r->ch,r->parameter,r->P,r->minpoly);
355  int *perm=(int *)Alloc0((r->N+1)*sizeof(int));
356  //int *par_perm=(int *)Alloc0(rPar(r)*sizeof(int));
357  maFindPerm(r->names,r->N, r->parameter, r->P,
358             currRing->names,currRing->N,currRing->parameter, currRing->P,
359             perm,NULL/*par_perm*/);
360  poly res=pPermPoly(p,perm,r/*,par_perm,rPar(r)*/);
361  Free((ADDRESS)perm,(r->N+1)*sizeof(int));
362  //Free((ADDRESS)par_perm,rPar(r)*sizeof(int));
363  return res;
364}
365
366/*3
367* find the max. degree in one variable, but not larger than MAX_MAP_DEG
368*/
369static int maMaxDeg_Ma(ideal a,ring preimage_r)
370{
371  int i,j;
372  int N = preimage_r->N;
373  poly p;
374  int *m=(int *)Alloc0(N*sizeof(int));
375
376  for (i=MATROWS(a)*MATCOLS(a)-1;i>=0;i--)
377  {
378    p=a->m[i];
379    //pTest(p); // cannot test p because it is from another ring
380    while(p!=NULL)
381    {
382      for(j=N-1;j>=0;j--)
383      {
384        m[j]=max(m[j],pRingGetExp(preimage_r, p,j+1));
385        if (m[j]>=MAX_MAP_DEG)
386        {
387          i=MAX_MAP_DEG;
388          goto max_deg_fertig_id;
389        }
390      }
391      pIter(p);
392    }
393  }
394  i=m[0];
395  for(j=N-1;j>0;j--)
396  {
397    i=max(i,m[j]);
398  }
399max_deg_fertig_id:
400  Free((ADDRESS)m,N*sizeof(int));
401  return i;
402}
403
404/*3
405* find the max. degree in one variable, but not larger than MAX_MAP_DEG
406*/
407static int maMaxDeg_P(poly p,ring preimage_r)
408{
409  int i,j;
410  int N = preimage_r->N;
411  int *m=(int *)Alloc0(N*sizeof(int));
412
413//  pTest(p);
414  while(p!=NULL)
415  {
416    for(j=N-1;j>=0;j--)
417    {
418      m[j]=max(m[j],pRingGetExp(preimage_r,p,j+1));
419      if (m[j]>=MAX_MAP_DEG)
420      {
421        i=MAX_MAP_DEG;
422        goto max_deg_fertig_p;
423      }
424    }
425    pIter(p);
426  }
427  i=m[0];
428  for(j=N-1;j>0;j--)
429  {
430    i=max(i,m[j]);
431  }
432max_deg_fertig_p:
433  Free((ADDRESS)m,N*sizeof(int));
434  return i;
435}
436
437/*2
438* maps the expression w to res,
439* switch what: MAP_CMD: use theMap for mapping, N for preimage ring
440*              FETCH_CMD: use pOrdPoly for mapping
441*              IMAP_CMD: use perm for mapping, N for preimage ring
442*              default: map only poly-structures,
443*                       use perm and par_perm, N and P,
444*/
445BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w, ring preimage_r,
446                     int *perm, int *par_perm, int P)
447{
448  int i;
449  int N = preimage_r->N;
450  //Print("N=%d ",N);
451  //if (perm!=NULL) for(i=1;i<=N;i++) Print("%d -> %d ",i,perm[i]);
452  //PrintS("\n");
453  //Print("P=%d ",P);
454  //if (par_perm!=NULL) for(i=0;i<P;i++) Print("%d -> %d ",i,par_perm[i]);
455  //PrintS("\n");
456  void *data=w->Data();
457  res->rtyp = w->rtyp;
458  switch (w->rtyp)
459  {
460    case NUMBER_CMD:
461      if (P!=0)
462      {
463        res->data=(void *)naPermNumber((number)data,par_perm,P);
464        res->rtyp=POLY_CMD;
465        if (currRing->minpoly!=NULL)
466          res->data=(void *)pMult((poly)res->data,pOne());
467      }
468      else
469      {
470        res->data=(void *)nMap((number)data);
471        if (currRing->minpoly!=NULL)
472        {
473          number a=(number)res->data;
474          number b=nInit(1);
475          number c=nMult(a,b);
476          nDelete(&a);
477          nDelete(&b);
478          res->data=(void *)c;
479        }
480      }
481      break;
482    case POLY_CMD:
483    case VECTOR_CMD:
484      if (what==FETCH_CMD)
485        res->data=(void *)pFetchCopy(preimage_r, (poly)data);
486      else if (what==IMAP_CMD)
487        res->data=(void *)pPermPoly((poly)data,perm,preimage_r,par_perm,P);
488      else /*if (what==MAP_CMD)*/
489      {
490        matrix s=mpNew(N,maMaxDeg_P((poly)data, preimage_r));
491        res->data=(void *)maEval(theMap,(poly)data,preimage_r,s);
492        idDelete((ideal *)&s);
493      }
494      if (currRing->minpoly!=NULL)
495        res->data=(void *)pMult((poly)res->data,pOne());
496      pTest((poly)res->data);
497      break;
498    case MODUL_CMD:
499    case MATRIX_CMD:
500    case IDEAL_CMD:
501    case MAP_CMD:
502    {
503      int C=((matrix)data)->cols();
504      int R;
505      if (w->rtyp==MAP_CMD) R=1;
506      else R=((matrix)data)->rows();
507      matrix m=mpNew(R,C);
508      char *tmpR=NULL;
509      if(w->rtyp==MAP_CMD)
510      {
511        tmpR=((map)data)->preimage;
512        ((matrix)data)->rank=((matrix)data)->rows();
513      }
514      if (what==FETCH_CMD)
515      {
516        for (i=R*C-1;i>=0;i--)
517        {
518          m->m[i]=pFetchCopy(preimage_r,((ideal)data)->m[i]);
519          pTest(m->m[i]);
520        }
521      }
522      else if (what==IMAP_CMD)
523      {
524        for (i=R*C-1;i>=0;i--)
525        {
526          m->m[i]=pPermPoly(((ideal)data)->m[i],perm,preimage_r,par_perm,P);
527          pTest(m->m[i]);
528        }
529      }
530      else /* if(what==MAP_CMD) */
531      {
532        matrix s=mpNew(N,maMaxDeg_Ma((ideal)data,preimage_r));
533        for (i=R*C-1;i>=0;i--)
534        {
535          m->m[i]=maEval(theMap,((ideal)data)->m[i],preimage_r,s);
536          pTest(m->m[i]);
537        }
538        idDelete((ideal *)&s);
539      }
540      if (currRing->minpoly!=NULL)
541      {
542        for (i=R*C-1;i>=0;i--)
543        {
544          m->m[i]=pMult(m->m[i],pOne());
545          pTest(m->m[i]);
546        }
547      }
548      if(w->rtyp==MAP_CMD)
549      {
550        ((map)data)->preimage=tmpR;
551        ((map)m)->preimage=mstrdup(tmpR);
552      }
553      else
554      {
555        m->rank=((matrix)data)->rank;
556      }
557      res->data=(char *)m;
558      break;
559    }
560    case LIST_CMD:
561    {
562      lists l=(lists)data;
563      lists ml=(lists)Alloc(sizeof(slists));
564      ml->Init(l->nr+1);
565      for(i=0;i<=l->nr;i++)
566      {
567        if (((l->m[i].rtyp>BEGIN_RING)&&(l->m[i].rtyp<END_RING))
568        ||(l->m[i].rtyp==LIST_CMD))
569        {
570          if (maApplyFetch(what,theMap,&ml->m[i],&l->m[i],
571                           preimage_r,perm,par_perm,P))
572          {
573            ml->Clean();
574            Free((ADDRESS)ml,sizeof(slists));
575            res->rtyp=0;
576            return TRUE;
577          }
578        }
579        else
580        {
581          ml->m[i].Copy(&l->m[i]);
582        }
583      }
584      res->data=(char *)ml;
585      break;
586    }
587    default:
588    {
589      return TRUE;
590    }
591  }
592  return FALSE;
593}
594
Note: See TracBrowser for help on using the repository browser.