source: git/Singular/maps.cc @ e20214

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