source: git/Singular/maps.cc @ fdc537

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