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

spielwiese
Last change on this file since 82716e was a1c44e, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: renamed std to kStd, stdfac to kStdfac git-svn-id: file:///usr/local/Singular/svn/trunk@1761 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.10 1998-05-14 13:04:20 Singular 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 **) Alloc0(ordersize * sizeof(short **));
202  for (i--;i!=0 ;i--) wv[i+1] = sourcering->wvhdl[i];
203  tmpR = *currRing;
204  tmpR.N = N;
205  tmpR.order = orders;
206  tmpR.block0 = block0;
207  tmpR.block1 = block1;
208  tmpR.wvhdl = wv;
209  rComplete(&tmpR);
210
211  // change to new ring
212  rChangeCurrRing(&tmpR, FALSE);
213  sizeofpoly = mmGetSpecSize();
214  if (id==NULL)
215    j = 0;
216  else
217    j = IDELEMS(id);
218  temp1 = idInit(sourcering->N+j,1);
219  for (i=0;i<sourcering->N;i++)
220  {
221    if ((i<IDELEMS(theMap)) && (theMap->m[i]!=NULL))
222    {
223      p = pChangeSizeOfPoly(theImageRing, theMap->m[i],1,imagepvariables);
224      q = p;
225      while (pNext(q)) pIter(q);
226      pNext(q) = pOne();
227      pIter(q);
228    }
229    else
230      q = p = pOne();
231    pGetCoeff(q)=nNeg(pGetCoeff(q));
232    pSetExp(q,i+1+imagepvariables,1);
233    pSetm(q);
234    temp1->m[i] = p;
235  }
236  for (i=sourcering->N;i<sourcering->N+j;i++)
237  {
238    temp1->m[i] = pChangeSizeOfPoly(theImageRing,
239                                    id->m[i-sourcering->N],1,imagepvariables);
240  }
241  // we ignore here homogenity - may be changed later:
242  temp2 = kStd(temp1,NULL,isNotHomog,NULL);
243  idDelete(&temp1);
244  for (i=0;i<IDELEMS(temp2);i++)
245  {
246    if (pLowVar(temp2->m[i])<imagepvariables) pDelete(&(temp2->m[i]));
247  }
248
249  // let's get back to the original ring
250  rChangeCurrRing(sourcering, FALSE);
251  temp1 = idInit(5,1);
252  j = 0;
253  for (i=0;i<IDELEMS(temp2);i++)
254  {
255    p = temp2->m[i];
256    temp2->m[i]=NULL;
257    if (p!=NULL)
258    {
259      q = pChangeSizeOfPoly(&tmpR, p,imagepvariables+1,N);
260      if (j>=IDELEMS(temp1))
261      {
262        pEnlargeSet(&(temp1->m),IDELEMS(temp1),5);
263        IDELEMS(temp1)+=5;
264      }
265      temp1->m[j] = q;
266      j++;
267      while (p!=NULL)
268      {
269        pp = pNext(p);
270        Free((ADDRESS)p,sizeofpoly);
271        p = pp;
272      }
273    }
274  }
275  idDelete(&temp2);
276  Free((ADDRESS) wv, ordersize*sizeof(short **));
277  idSkipZeroes(temp1);
278  return temp1;
279}
280
281void maFindPerm(char **preim_names, int preim_n, char **preim_par, int preim_p,
282                char **names,       int n,       char **par,       int nop,
283                int * perm, int *par_perm)
284{
285  int i,j;
286  /* find correspondig vars */
287  for (i=0; i<preim_n; i++)
288  {
289    for(j=0; j<n; j++)
290    {
291      if (strcmp(preim_names[i],names[j])==0)
292      {
293        if (BVERBOSE(V_IMAP))
294          Print("// var %s: nr %d -> nr %d\n",preim_names[i],i+1,j+1);
295        /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
296        perm[i+1]=j+1;
297        break;
298      }
299    }
300    if ((perm[i+1]==0)&&(par!=NULL))
301    {
302      for(j=0; j<nop; j++)
303      {
304        if (strcmp(preim_names[i],par[j])==0)
305        {
306          if (BVERBOSE(V_IMAP))
307            Print("// var %s: nr %d -> par %d\n",preim_names[i],i+1,j+1);
308          /* var i+1 from preimage ring is par j+1 (index j) from image ring */
309          perm[i+1]=-(j+1);
310        }
311      }
312    }
313  }
314  if (par_perm!=NULL)
315  {
316    for (i=0; i<preim_p; i++)
317    {
318      for(j=0; j<n; j++)
319      {
320        if (strcmp(preim_par[i],names[j])==0)
321        {
322          if (BVERBOSE(V_IMAP))
323            Print("// par %s: par %d -> nr %d\n",preim_par[i],i+1,j+1);
324          /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
325          par_perm[i]=j+1;
326          break;
327        }
328      }
329      if ((par!=NULL) && (par_perm[i]==0))
330      {
331        for(j=0; j<nop; j++)
332        {
333          if (strcmp(preim_par[i],par[j])==0)
334          {
335            if (BVERBOSE(V_IMAP))
336              Print("// par %s: nr %d -> par %d\n",preim_par[i],i+1,j+1);
337            /* var i+1 from preimage ring is par j+1 (index j) from image ring */
338            par_perm[i]=-(j+1);
339          }
340        }
341      }
342    }
343  }
344}
345
346/*2
347* embeds poly p from the subring r into the current ring
348*/
349poly maIMap(ring r, poly p)
350{
351  /* the simplest case:*/
352  if(r==currRing) return pCopy(p);
353  nSetMap(r->ch,r->parameter,r->P,r->minpoly);
354  int *perm=(int *)Alloc0((r->N+1)*sizeof(int));
355  //int *par_perm=(int *)Alloc0(rPar(r)*sizeof(int));
356  maFindPerm(r->names,r->N, r->parameter, r->P,
357             currRing->names,currRing->N,currRing->parameter, currRing->P,
358             perm,NULL/*par_perm*/);
359  poly res=pPermPoly(p,perm,r/*,par_perm,rPar(r)*/);
360  Free((ADDRESS)perm,(r->N+1)*sizeof(int));
361  //Free((ADDRESS)par_perm,rPar(r)*sizeof(int));
362  return res;
363}
364
365/*3
366* find the max. degree in one variable, but not larger than MAX_MAP_DEG
367*/
368static int maMaxDeg_Ma(ideal a,ring preimage_r)
369{
370  int i,j;
371  int N = preimage_r->N;
372  poly p;
373  int *m=(int *)Alloc0(N*sizeof(int));
374
375  for (i=MATROWS(a)*MATCOLS(a)-1;i>=0;i--)
376  {
377    p=a->m[i];
378    //pTest(p); // cannot test p because it is from another ring
379    while(p!=NULL)
380    {
381      for(j=N-1;j>=0;j--)
382      {
383        m[j]=max(m[j],pRingGetExp(preimage_r, p,j+1));
384        if (m[j]>=MAX_MAP_DEG)
385        {
386          i=MAX_MAP_DEG;
387          goto max_deg_fertig_id;
388        }
389      }
390      pIter(p);
391    }
392  }
393  i=m[0];
394  for(j=N-1;j>0;j--)
395  {
396    i=max(i,m[j]);
397  }
398max_deg_fertig_id:
399  Free((ADDRESS)m,N*sizeof(int));
400  return i;
401}
402
403/*3
404* find the max. degree in one variable, but not larger than MAX_MAP_DEG
405*/
406static int maMaxDeg_P(poly p,ring preimage_r)
407{
408  int i,j;
409  int N = preimage_r->N;
410  int *m=(int *)Alloc0(N*sizeof(int));
411
412//  pTest(p);
413  while(p!=NULL)
414  {
415    for(j=N-1;j>=0;j--)
416    {
417      m[j]=max(m[j],pRingGetExp(preimage_r,p,j+1));
418      if (m[j]>=MAX_MAP_DEG)
419      {
420        i=MAX_MAP_DEG;
421        goto max_deg_fertig_p;
422      }
423    }
424    pIter(p);
425  }
426  i=m[0];
427  for(j=N-1;j>0;j--)
428  {
429    i=max(i,m[j]);
430  }
431max_deg_fertig_p:
432  Free((ADDRESS)m,N*sizeof(int));
433  return i;
434}
435
436/*2
437* maps the expression w to res,
438* switch what: MAP_CMD: use theMap for mapping, N for preimage ring
439*              FETCH_CMD: use pOrdPoly for mapping
440*              IMAP_CMD: use perm for mapping, N for preimage ring
441*              default: map only poly-structures,
442*                       use perm and par_perm, N and P,
443*/
444BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w, ring preimage_r,
445                     int *perm, int *par_perm, int P)
446{
447  int i;
448  int N = preimage_r->N;
449  //Print("N=%d ",N);
450  //if (perm!=NULL) for(i=1;i<=N;i++) Print("%d -> %d ",i,perm[i]);
451  //PrintS("\n");
452  //Print("P=%d ",P);
453  //if (par_perm!=NULL) for(i=0;i<P;i++) Print("%d -> %d ",i,par_perm[i]);
454  //PrintS("\n");
455  void *data=w->Data();
456  res->rtyp = w->rtyp;
457  switch (w->rtyp)
458  {
459    case NUMBER_CMD:
460      if (P!=0)
461      {
462        res->data=(void *)naPermNumber((number)data,par_perm,P);
463        res->rtyp=POLY_CMD;
464        if (currRing->minpoly!=NULL)
465          res->data=(void *)pMult((poly)res->data,pOne());
466      }
467      else
468      {
469        res->data=(void *)nMap((number)data);
470        if (currRing->minpoly!=NULL)
471        {
472          number a=(number)res->data;
473          number b=nInit(1);
474          number c=nMult(a,b);
475          nDelete(&a);
476          nDelete(&b);
477          res->data=(void *)c;
478        }
479      }
480      break;
481    case POLY_CMD:
482    case VECTOR_CMD:
483      if (what==FETCH_CMD)
484        res->data=(void *)pFetchCopy(preimage_r, (poly)data);
485      else if (what==IMAP_CMD)
486        res->data=(void *)pPermPoly((poly)data,perm,preimage_r,par_perm,P);
487      else /*if (what==MAP_CMD)*/
488      {
489        matrix s=mpNew(N,maMaxDeg_P((poly)data, preimage_r));
490        res->data=(void *)maEval(theMap,(poly)data,preimage_r,s);
491        idDelete((ideal *)&s);
492      }
493      if (currRing->minpoly!=NULL)
494        res->data=(void *)pMult((poly)res->data,pOne());
495      pTest((poly)res->data);
496      break;
497    case MODUL_CMD:
498    case MATRIX_CMD:
499    case IDEAL_CMD:
500    case MAP_CMD:
501    {
502      int C=((matrix)data)->cols();
503      int R;
504      if (w->rtyp==MAP_CMD) R=1;
505      else R=((matrix)data)->rows();
506      matrix m=mpNew(R,C);
507      char *tmpR=NULL;
508      if(w->rtyp==MAP_CMD)
509      {
510        tmpR=((map)data)->preimage;
511        ((matrix)data)->rank=((matrix)data)->rows();
512      }
513      if (what==FETCH_CMD)
514      {
515        for (i=R*C-1;i>=0;i--)
516        {
517          m->m[i]=pFetchCopy(preimage_r,((ideal)data)->m[i]);
518          pTest(m->m[i]);
519        }
520      }
521      else if (what==IMAP_CMD)
522      {
523        for (i=R*C-1;i>=0;i--)
524        {
525          m->m[i]=pPermPoly(((ideal)data)->m[i],perm,preimage_r,par_perm,P);
526          pTest(m->m[i]);
527        }
528      }
529      else /* if(what==MAP_CMD) */
530      {
531        matrix s=mpNew(N,maMaxDeg_Ma((ideal)data,preimage_r));
532        for (i=R*C-1;i>=0;i--)
533        {
534          m->m[i]=maEval(theMap,((ideal)data)->m[i],preimage_r,s);
535          pTest(m->m[i]);
536        }
537        idDelete((ideal *)&s);
538      }
539      if (currRing->minpoly!=NULL)
540      {
541        for (i=R*C-1;i>=0;i--)
542        {
543          m->m[i]=pMult(m->m[i],pOne());
544          pTest(m->m[i]);
545        }
546      }
547      if(w->rtyp==MAP_CMD)
548      {
549        ((map)data)->preimage=tmpR;
550        ((map)m)->preimage=mstrdup(tmpR);
551      }
552      else
553      {
554        m->rank=((matrix)data)->rank;
555      }
556      res->data=(char *)m;
557      break;
558    }
559    case LIST_CMD:
560    {
561      lists l=(lists)data;
562      lists ml=(lists)Alloc(sizeof(slists));
563      ml->Init(l->nr+1);
564      for(i=0;i<=l->nr;i++)
565      {
566        if (((l->m[i].rtyp>BEGIN_RING)&&(l->m[i].rtyp<END_RING))
567        ||(l->m[i].rtyp==LIST_CMD))
568        {
569          if (maApplyFetch(what,theMap,&ml->m[i],&l->m[i],
570                           preimage_r,perm,par_perm,P))
571          {
572            ml->Clean();
573            Free((ADDRESS)ml,sizeof(slists));
574            res->rtyp=0;
575            return TRUE;
576          }
577        }
578        else
579        {
580          ml->m[i].Copy(&l->m[i]);
581        }
582      }
583      res->data=(char *)ml;
584      break;
585    }
586    default:
587    {
588      return TRUE;
589    }
590  }
591  return FALSE;
592}
593
Note: See TracBrowser for help on using the repository browser.