source: git/kernel/maps.cc @ 936551

spielwiese
Last change on this file since 936551 was 86016d, checked in by Motsak Oleksandr <motsak@…>, 17 years ago
*motsak: !+!: factors of SCA, debug print for SCA, "kill squares" in std. * : ncRingType, naming, formatting, unified NC setup. git-svn-id: file:///usr/local/Singular/svn/trunk@9792 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: maps.cc,v 1.6 2007-01-31 23:51:24 motsak Exp $ */
5/*
6* ABSTRACT - the mapping of polynomials to other rings
7*/
8
9#include "mod2.h"
10#include "structs.h"
11#include "febase.h"
12#include "polys.h"
13#include "numbers.h"
14#include "ring.h"
15#include "ideals.h"
16#include "matpol.h"
17#include "omalloc.h"
18#include "kstd1.h"
19#include "longalg.h"
20#include "maps.h"
21#include "prCopy.h"
22
23// This is a very dirty way to "normalize" numbers w.r.t. a
24// MinPoly
25
26/* debug output: Tok2Cmdname in maApplyFetch*/
27//#include "ipshell.h"
28
29#define MAX_MAP_DEG 128
30
31/*2
32* copy a map
33*/
34map maCopy(map theMap)
35{
36  int i;
37  map m=(map)idInit(IDELEMS(theMap),0);
38  for (i=IDELEMS(theMap)-1; i>=0; i--)
39      m->m[i] = pCopy(theMap->m[i]);
40  m->preimage=omStrDup(theMap->preimage);
41  return m;
42}
43
44
45/*2
46* return the image of var(v)^pExp, where var(v) maps to p
47*/
48poly maEvalVariable(poly p, int v,int pExp,matrix s)
49{
50  if (pExp==1)
51    return pCopy(p);
52
53  poly res;
54
55  if((s!=NULL)&&(pExp<MAX_MAP_DEG))
56  {
57    int j=2;
58    poly p0=p;
59    // find starting point
60    if(MATELEM(s,v,1)==NULL)
61    {
62      MATELEM(s,v,1)=pCopy(p/*theMap->m[v-1]*/);
63    }
64    else
65    {
66      while((j<=pExp)&&(MATELEM(s,v,j)!=NULL))
67      {
68        j++;
69      }
70      p0=MATELEM(s,v,j-1);
71    }
72    // multiply
73    for(;j<=pExp;j++)
74    {
75      p0=MATELEM(s,v,j)=ppMult_qq(p0, p);
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
87static poly maEvalMonom(map theMap, poly p,ring preimage_r,matrix s, nMapFunc nMap)
88{
89    poly q=pNSet(nMap(pGetCoeff(p)));
90
91    int i;
92    for(i=1;i<=preimage_r->N; i++)
93    {
94      int pExp=p_GetExp( p,i,preimage_r);
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 = p_GetComp( p,preimage_r);
111    if (q!=NULL) pSetCompP(q,modulComp);
112  return q;
113}
114
115poly maEval(map theMap, poly p,ring preimage_r,nMapFunc nMap,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*) omAlloc(l*sizeof(poly));
137
138      for (i=0; i<l; i++)
139      {
140        monoms[i]=maEvalMonom(theMap,p,preimage_r,s, nMap);
141        pIter(p);
142      }
143    }
144    result=maEvalMonom(theMap,p,preimage_r,s, nMap);
145    if (l>0)
146    {
147      for(i = l-1; i>=0; i--)
148      {
149        result=pAdd(result, monoms[i]);
150      }
151      omFreeSize((ADDRESS)monoms,l*sizeof(poly));
152    }
153    if (currRing->minpoly!=NULL) result=pMinPolyNormalize(result);
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,p_GetExp(p,i,p_ring));
177    pSetComp(resultWorkP,p_GetComp(p,p_ring));
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* (assumes) that both ring have the same coeff.field
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*) omAlloc0(sizeof(int)*(ordersize));
205  int *block0 = (int*) omAlloc0(sizeof(int)*(ordersize));
206  int *block1 = (int*) omAlloc0(sizeof(int)*(ordersize));
207  int **wv = (int **) omAlloc0(ordersize * sizeof(int *));
208
209  int imagepvariables = theImageRing->N;
210  ring sourcering = currRing;
211  int N = pVariables+imagepvariables;
212  char** names = (char**) omAlloc0(N*sizeof(char*));
213
214  memcpy(names, currRing->names, currRing->N*sizeof(char*));
215  memcpy(&(names[currRing->N]), theImageRing->names,
216          (theImageRing->N*sizeof(char*)));
217  sip_sring tmpR;
218
219  //if (theImageRing->OrdSgn == 1)s
220     orders[0] = ringorder_dp;
221  //else orders[0] = ringorder_ls;
222  block1[0] = imagepvariables;
223  block0[0] = 1;
224  /*
225  *if (sourcering->order[blockmax])
226  *{
227  *  if (sourcering->OrdSgn == 1) orders[1] = ringorder_dp;
228  *  else orders[1] = ringorder_ls;
229  *  block1[1] = N;
230  *}
231  *else
232  */
233  for (i=0; i<ordersize - 1; i++)
234  {
235    orders[i+1] = sourcering->order[i];
236    block0[i+1] = sourcering->block0[i]+imagepvariables;
237    block1[i+1] = sourcering->block1[i]+imagepvariables;
238    wv[i+1] = sourcering->wvhdl[i];
239  }
240  tmpR = *currRing;
241  tmpR.N = N;
242  tmpR.order = orders;
243  tmpR.block0 = block0;
244  tmpR.block1 = block1;
245  tmpR.wvhdl = wv;
246  tmpR.names = names;
247  rComplete(&tmpR, 1);
248  rTest(&tmpR);
249
250#ifdef HAVE_PLURAL
251  if (rIsPluralRing(theImageRing))
252  {
253    rUnComplete(&tmpR);
254    omFreeSize(orders, sizeof(int)*(ordersize));orders=NULL;
255    omFreeSize(block0, sizeof(int)*(ordersize));block0=NULL;
256    omFreeSize(block1, sizeof(int)*(ordersize));block1=NULL;
257    omFreeSize(wv, sizeof(int*)*(ordersize)); wv=NULL;
258    omFreeSize(names, (currRing->N)*sizeof(char*)); names=NULL;
259    memset(&tmpR,0,sizeof(tmpR));
260    if ((rIsPluralRing(sourcering)) && (ncRingType(sourcering)!=nc_comm)) 
261    {
262      Werror("Sorry, not yet implemented for noncomm. rings");
263      return NULL;
264    }   
265    ring tmpR_ptr;
266    if ( rSum(theImageRing, sourcering, tmpR_ptr ) !=1 )
267    {
268      /* something is wrong with the rings... */
269      Werror("Error in rSum");
270      return NULL;
271    }
272    memcpy(&tmpR,tmpR_ptr,sizeof(tmpR));
273    // Action!
274  }
275  if (nSetMap(theImageRing) != nCopy)
276  {
277    Werror("Coefficient fields must be equal");
278    return NULL;
279  }
280#endif
281
282  // change to new ring
283  rChangeCurrRing(&tmpR);
284  if (id==NULL)
285    j = 0;
286  else
287    j = IDELEMS(id);
288  int j0=j;
289  if (theImageRing->qideal!=NULL) j+=IDELEMS(theImageRing->qideal);
290  temp1 = idInit(sourcering->N+j,1);
291  for (i=0;i<sourcering->N;i++)
292  {
293    q = pISet(-1);
294    pSetExp(q,i+1+imagepvariables,1);
295    pSetm(q);
296    if ((i<IDELEMS(theMap)) && (theMap->m[i]!=NULL))
297    {
298      p = pSort(pChangeSizeOfPoly(theImageRing,theMap->m[i],1,imagepvariables));
299      p=pAdd(p,q);
300    }
301    else
302    {
303      p = q;
304    }
305    temp1->m[i] = p;
306  }
307  idTest(temp1);
308  for (i=sourcering->N;i<sourcering->N+j0;i++)
309  {
310    temp1->m[i] = pSort(pChangeSizeOfPoly(theImageRing,
311                                    id->m[i-sourcering->N],1,imagepvariables));
312  }
313  for (i=sourcering->N+j0;i<sourcering->N+j;i++)
314  {
315    temp1->m[i] = pSort(pChangeSizeOfPoly(theImageRing,
316                                    theImageRing->qideal->m[i-sourcering->N-j0],
317                                    1,imagepvariables));
318  }
319  // we ignore here homogenity - may be changed later:
320  temp2 = kStd(temp1,NULL,isNotHomog,NULL);
321  idDelete(&temp1);
322  for (i=0;i<IDELEMS(temp2);i++)
323  {
324    if (pLowVar(temp2->m[i])<imagepvariables) pDelete(&(temp2->m[i]));
325  }
326
327  // let's get back to the original ring
328  rChangeCurrRing(sourcering);
329  temp1 = idInit(5,1);
330  j = 0;
331  for (i=0;i<IDELEMS(temp2);i++)
332  {
333    p = temp2->m[i];
334    if (p!=NULL)
335    {
336      q = pChangeSizeOfPoly(&tmpR, p,imagepvariables+1,N);
337      if (j>=IDELEMS(temp1))
338      {
339        pEnlargeSet(&(temp1->m),IDELEMS(temp1),5);
340        IDELEMS(temp1)+=5;
341      }
342      temp1->m[j] = q;
343      j++;
344    }
345  }
346  id_Delete(&temp2, &tmpR);
347  idSkipZeroes(temp1);
348  rUnComplete(&tmpR);
349  if (orders!=NULL)
350  {
351    omFreeSize(orders, sizeof(int)*(ordersize));
352    omFreeSize(block0, sizeof(int)*(ordersize));
353    omFreeSize(block1, sizeof(int)*(ordersize));
354    omFreeSize(wv, sizeof(int*)*(ordersize));
355    omFreeSize(names, (currRing->N)*sizeof(char*));
356  }
357  return temp1;
358}
359
360void maFindPerm(char **preim_names, int preim_n, char **preim_par, int preim_p,
361                char **names,       int n,       char **par,       int nop,
362                int * perm, int *par_perm, int ch)
363{
364  int i,j;
365  /* find correspondig vars */
366  for (i=0; i<preim_n; i++)
367  {
368    for(j=0; j<n; j++)
369    {
370      if (strcmp(preim_names[i],names[j])==0)
371      {
372        if (BVERBOSE(V_IMAP))
373          Print("// var %s: nr %d -> nr %d\n",preim_names[i],i+1,j+1);
374        /* var i+1 from preimage ring is var j+1  (index j+1) from image ring */
375        perm[i+1]=j+1;
376        break;
377      }
378    }
379    if ((perm[i+1]==0)&&(par!=NULL)
380        // do not consider par of Fq
381         && (ch < 2))
382    {
383      for(j=0; j<nop; j++)
384      {
385        if (strcmp(preim_names[i],par[j])==0)
386        {
387          if (BVERBOSE(V_IMAP))
388            Print("// var %s: nr %d -> par %d\n",preim_names[i],i+1,j+1);
389          /* var i+1 from preimage ring is par j+1 (index j) from image ring */
390          perm[i+1]=-(j+1);
391        }
392      }
393    }
394  }
395  if (par_perm!=NULL)
396  {
397    for (i=0; i<preim_p; i++)
398    {
399      for(j=0; j<n; j++)
400      {
401        if (strcmp(preim_par[i],names[j])==0)
402        {
403          if (BVERBOSE(V_IMAP))
404            Print("// par %s: par %d -> nr %d\n",preim_par[i],i+1,j+1);
405          /*par i+1 from preimage ring is var j+1  (index j+1) from image ring*/
406          par_perm[i]=j+1;
407          break;
408        }
409      }
410      if ((par!=NULL) && (par_perm[i]==0))
411      {
412        for(j=0; j<nop; j++)
413        {
414          if (strcmp(preim_par[i],par[j])==0)
415          {
416            if (BVERBOSE(V_IMAP))
417              Print("// par %s: nr %d -> par %d\n",preim_par[i],i+1,j+1);
418            /*par i+1 from preimage ring is par j+1 (index j) from image ring */
419            par_perm[i]=-(j+1);
420          }
421        }
422      }
423    }
424  }
425}
426
427/*2
428* embeds poly p from the subring r into the current ring
429*/
430poly maIMap(ring r, poly p)
431{
432  /* the simplest case:*/
433  if(r==currRing) return pCopy(p);
434  nMapFunc nMap=nSetMap(r);
435  int *perm=(int *)omAlloc0((r->N+1)*sizeof(int));
436  //int *par_perm=(int *)omAlloc0(rPar(r)*sizeof(int));
437  maFindPerm(r->names,r->N, r->parameter, r->P,
438             currRing->names,currRing->N,currRing->parameter, currRing->P,
439             perm,NULL, currRing->ch);
440  poly res=pPermPoly(p,perm,r, nMap /*,par_perm,rPar(r)*/);
441  omFreeSize((ADDRESS)perm,(r->N+1)*sizeof(int));
442  //omFreeSize((ADDRESS)par_perm,rPar(r)*sizeof(int));
443  return res;
444}
445
446/*3
447* find the max. degree in one variable, but not larger than MAX_MAP_DEG
448*/
449int maMaxDeg_Ma(ideal a,ring preimage_r)
450{
451  int i,j;
452  int N = preimage_r->N;
453  poly p;
454  int *m=(int *)omAlloc0(N*sizeof(int));
455
456  for (i=MATROWS(a)*MATCOLS(a)-1;i>=0;i--)
457  {
458    p=a->m[i];
459    //pTest(p); // cannot test p because it is from another ring
460    while(p!=NULL)
461    {
462      for(j=N-1;j>=0;j--)
463      {
464        m[j]=si_max(m[j],p_GetExp( p,j+1,preimage_r));
465        if (m[j]>=MAX_MAP_DEG)
466        {
467          i=MAX_MAP_DEG;
468          goto max_deg_fertig_id;
469        }
470      }
471      pIter(p);
472    }
473  }
474  i=m[0];
475  for(j=N-1;j>0;j--)
476  {
477    i=si_max(i,m[j]);
478  }
479max_deg_fertig_id:
480  omFreeSize((ADDRESS)m,N*sizeof(int));
481  return i;
482}
483
484/*3
485* find the max. degree in one variable, but not larger than MAX_MAP_DEG
486*/
487int maMaxDeg_P(poly p,ring preimage_r)
488{
489  int i,j;
490  int N = preimage_r->N;
491  int *m=(int *)omAlloc0(N*sizeof(int));
492
493//  pTest(p);
494  while(p!=NULL)
495  {
496    for(j=N-1;j>=0;j--)
497    {
498      m[j]=si_max(m[j],p_GetExp(p,j+1,preimage_r));
499      if (m[j]>=MAX_MAP_DEG)
500      {
501        i=MAX_MAP_DEG;
502        goto max_deg_fertig_p;
503      }
504    }
505    pIter(p);
506  }
507  i=m[0];
508  for(j=N-1;j>0;j--)
509  {
510    i=si_max(i,m[j]);
511  }
512max_deg_fertig_p:
513  omFreeSize((ADDRESS)m,N*sizeof(int));
514  return i;
515}
516
517// This is a very dirty way to cancel monoms whose number equals the
518// MinPoly
519poly pMinPolyNormalize(poly p)
520{
521  number one = nInit(1);
522  spolyrec rp;
523
524  poly q = &rp;
525
526  while (p != NULL)
527  {
528    // this returns 0, if p == MinPoly
529    number product = nMult(pGetCoeff(p), one);
530    if (product == NULL)
531    {
532      pDeleteLm(&p);
533    }
534    else
535    {
536      pSetCoeff(p, product);
537      pNext(q) = p;
538      q = p;
539      p = pNext(p);
540    }
541  }
542  pNext(q) = NULL;
543  return rp.next;
544}
Note: See TracBrowser for help on using the repository browser.