source: git/Singular/maps.cc @ 416465

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