source: git/Singular/maps.cc @ 811826

spielwiese
Last change on this file since 811826 was 811826, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* maFindPerm: no permutation from Fq parameter to other vars/parameter (if they have the same name) -- r->ch new argument to maFindPerm. git-svn-id: file:///usr/local/Singular/svn/trunk@2894 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.14 1999-03-09 12:28:49 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 **) 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, int ch)
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        // do not consider par of Fq
302         && (ch < 2))
303    {
304      for(j=0; j<nop; j++)
305      {
306        if (strcmp(preim_names[i],par[j])==0)
307        {
308          if (BVERBOSE(V_IMAP))
309            Print("// var %s: nr %d -> par %d\n",preim_names[i],i+1,j+1);
310          /* var i+1 from preimage ring is par j+1 (index j) from image ring */
311          perm[i+1]=-(j+1);
312        }
313      }
314    }
315  }
316  if (par_perm!=NULL)
317  {
318    for (i=0; i<preim_p; i++)
319    {
320      for(j=0; j<n; j++)
321      {
322        if (strcmp(preim_par[i],names[j])==0)
323        {
324          if (BVERBOSE(V_IMAP))
325            Print("// par %s: par %d -> nr %d\n",preim_par[i],i+1,j+1);
326          /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
327          par_perm[i]=j+1;
328          break;
329        }
330      }
331      if ((par!=NULL) && (par_perm[i]==0))
332      {
333        for(j=0; j<nop; j++)
334        {
335          if (strcmp(preim_par[i],par[j])==0)
336          {
337            if (BVERBOSE(V_IMAP))
338              Print("// par %s: nr %d -> par %d\n",preim_par[i],i+1,j+1);
339            /* var i+1 from preimage ring is par j+1 (index j) from image ring */
340            par_perm[i]=-(j+1);
341          }
342        }
343      }
344    }
345  }
346}
347
348/*2
349* embeds poly p from the subring r into the current ring
350*/
351poly maIMap(ring r, poly p)
352{
353  /* the simplest case:*/
354  if(r==currRing) return pCopy(p);
355  nSetMap(rInternalChar(r),r->parameter,rPar(r),r->minpoly);
356  int *perm=(int *)Alloc0((r->N+1)*sizeof(int));
357  //int *par_perm=(int *)Alloc0(rPar(r)*sizeof(int));
358  maFindPerm(r->names,r->N, r->parameter, r->P,
359             currRing->names,currRing->N,currRing->parameter, currRing->P,
360             perm,NULL, currRing->ch);
361  poly res=pPermPoly(p,perm,r/*,par_perm,rPar(r)*/);
362  Free((ADDRESS)perm,(r->N+1)*sizeof(int));
363  //Free((ADDRESS)par_perm,rPar(r)*sizeof(int));
364  return res;
365}
366
367/*3
368* find the max. degree in one variable, but not larger than MAX_MAP_DEG
369*/
370static int maMaxDeg_Ma(ideal a,ring preimage_r)
371{
372  int i,j;
373  int N = preimage_r->N;
374  poly p;
375  int *m=(int *)Alloc0(N*sizeof(int));
376
377  for (i=MATROWS(a)*MATCOLS(a)-1;i>=0;i--)
378  {
379    p=a->m[i];
380    //pTest(p); // cannot test p because it is from another ring
381    while(p!=NULL)
382    {
383      for(j=N-1;j>=0;j--)
384      {
385        m[j]=max(m[j],pRingGetExp(preimage_r, p,j+1));
386        if (m[j]>=MAX_MAP_DEG)
387        {
388          i=MAX_MAP_DEG;
389          goto max_deg_fertig_id;
390        }
391      }
392      pIter(p);
393    }
394  }
395  i=m[0];
396  for(j=N-1;j>0;j--)
397  {
398    i=max(i,m[j]);
399  }
400max_deg_fertig_id:
401  Free((ADDRESS)m,N*sizeof(int));
402  return i;
403}
404
405/*3
406* find the max. degree in one variable, but not larger than MAX_MAP_DEG
407*/
408static int maMaxDeg_P(poly p,ring preimage_r)
409{
410  int i,j;
411  int N = preimage_r->N;
412  int *m=(int *)Alloc0(N*sizeof(int));
413
414//  pTest(p);
415  while(p!=NULL)
416  {
417    for(j=N-1;j>=0;j--)
418    {
419      m[j]=max(m[j],pRingGetExp(preimage_r,p,j+1));
420      if (m[j]>=MAX_MAP_DEG)
421      {
422        i=MAX_MAP_DEG;
423        goto max_deg_fertig_p;
424      }
425    }
426    pIter(p);
427  }
428  i=m[0];
429  for(j=N-1;j>0;j--)
430  {
431    i=max(i,m[j]);
432  }
433max_deg_fertig_p:
434  Free((ADDRESS)m,N*sizeof(int));
435  return i;
436}
437
438/*2
439* maps the expression w to res,
440* switch what: MAP_CMD: use theMap for mapping, N for preimage ring
441*              FETCH_CMD: use pOrdPoly for mapping
442*              IMAP_CMD: use perm for mapping, N for preimage ring
443*              default: map only poly-structures,
444*                       use perm and par_perm, N and P,
445*/
446BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w, ring preimage_r,
447                     int *perm, int *par_perm, int P)
448{
449  int i;
450  int N = preimage_r->N;
451  //Print("N=%d ",N);
452  //if (perm!=NULL) for(i=1;i<=N;i++) Print("%d -> %d ",i,perm[i]);
453  //PrintS("\n");
454  //Print("P=%d ",P);
455  //if (par_perm!=NULL) for(i=0;i<P;i++) Print("%d -> %d ",i,par_perm[i]);
456  //PrintS("\n");
457  void *data=w->Data();
458  res->rtyp = w->rtyp;
459  switch (w->rtyp)
460  {
461    case NUMBER_CMD:
462      if (P!=0)
463      {
464        res->data=(void *)naPermNumber((number)data,par_perm,P);
465        res->rtyp=POLY_CMD;
466        if (currRing->minpoly!=NULL)
467          res->data=(void *)pMult((poly)res->data,pOne());
468      }
469      else
470      {
471        res->data=(void *)nMap((number)data);
472        if (currRing->minpoly!=NULL)
473        {
474          number a=(number)res->data;
475          number b=nInit(1);
476          number c=nMult(a,b);
477          nDelete(&a);
478          nDelete(&b);
479          res->data=(void *)c;
480        }
481      }
482      break;
483    case POLY_CMD:
484    case VECTOR_CMD:
485      if (what==FETCH_CMD)
486        res->data=(void *)pFetchCopy(preimage_r, (poly)data);
487      else if (what==IMAP_CMD)
488        res->data=(void *)pPermPoly((poly)data,perm,preimage_r,par_perm,P);
489      else /*if (what==MAP_CMD)*/
490      {
491        matrix s=mpNew(N,maMaxDeg_P((poly)data, preimage_r));
492        res->data=(void *)maEval(theMap,(poly)data,preimage_r,s);
493        idDelete((ideal *)&s);
494      }
495      if (currRing->minpoly!=NULL)
496        res->data=(void *)pMult((poly)res->data,pOne());
497      pTest((poly)res->data);
498      break;
499    case MODUL_CMD:
500    case MATRIX_CMD:
501    case IDEAL_CMD:
502    case MAP_CMD:
503    {
504      int C=((matrix)data)->cols();
505      int R;
506      if (w->rtyp==MAP_CMD) R=1;
507      else R=((matrix)data)->rows();
508      matrix m=mpNew(R,C);
509      char *tmpR=NULL;
510      if(w->rtyp==MAP_CMD)
511      {
512        tmpR=((map)data)->preimage;
513        ((matrix)data)->rank=((matrix)data)->rows();
514      }
515      if (what==FETCH_CMD)
516      {
517        for (i=R*C-1;i>=0;i--)
518        {
519          m->m[i]=pFetchCopy(preimage_r,((ideal)data)->m[i]);
520          pTest(m->m[i]);
521        }
522      }
523      else if (what==IMAP_CMD)
524      {
525        for (i=R*C-1;i>=0;i--)
526        {
527          m->m[i]=pPermPoly(((ideal)data)->m[i],perm,preimage_r,par_perm,P);
528          pTest(m->m[i]);
529        }
530      }
531      else /* if(what==MAP_CMD) */
532      {
533        matrix s=mpNew(N,maMaxDeg_Ma((ideal)data,preimage_r));
534        for (i=R*C-1;i>=0;i--)
535        {
536          m->m[i]=maEval(theMap,((ideal)data)->m[i],preimage_r,s);
537          pTest(m->m[i]);
538        }
539        idDelete((ideal *)&s);
540      }
541      if (currRing->minpoly!=NULL)
542      {
543        for (i=R*C-1;i>=0;i--)
544        {
545          m->m[i]=pMult(m->m[i],pOne());
546          pTest(m->m[i]);
547        }
548      }
549      if(w->rtyp==MAP_CMD)
550      {
551        ((map)data)->preimage=tmpR;
552        ((map)m)->preimage=mstrdup(tmpR);
553      }
554      else
555      {
556        m->rank=((matrix)data)->rank;
557      }
558      res->data=(char *)m;
559      break;
560    }
561    case LIST_CMD:
562    {
563      lists l=(lists)data;
564      lists ml=(lists)Alloc(sizeof(slists));
565      ml->Init(l->nr+1);
566      for(i=0;i<=l->nr;i++)
567      {
568        if (((l->m[i].rtyp>BEGIN_RING)&&(l->m[i].rtyp<END_RING))
569        ||(l->m[i].rtyp==LIST_CMD))
570        {
571          if (maApplyFetch(what,theMap,&ml->m[i],&l->m[i],
572                           preimage_r,perm,par_perm,P))
573          {
574            ml->Clean();
575            Free((ADDRESS)ml,sizeof(slists));
576            res->rtyp=0;
577            return TRUE;
578          }
579        }
580        else
581        {
582          ml->m[i].Copy(&l->m[i]);
583        }
584      }
585      res->data=(char *)ml;
586      break;
587    }
588    default:
589    {
590      return TRUE;
591    }
592  }
593  return FALSE;
594}
595
Note: See TracBrowser for help on using the repository browser.