source: git/Singular/maps_ip.cc @ 95585d3

spielwiese
Last change on this file since 95585d3 was 95585d3, checked in by Karim Abou Zeid <karim23697@…>, 5 years ago
Add subst() support for Letterplace
  • Property mode set to 100644
File size: 11.6 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT - the mapping of polynomials to other rings
6*/
7#define TRANSEXT_PRIVATES
8
9#include "kernel/mod2.h"
10
11#include "coeffs/numbers.h"
12#include "coeffs/coeffs.h"
13
14#include "polys/monomials/ring.h"
15#include "polys/monomials/maps.h"
16#include "polys/matpol.h"
17#include "polys/prCopy.h"
18#include "polys/ext_fields/transext.h"
19
20//#include "polys/ext_fields/longtrans.h"
21// #include "kernel/longalg.h"
22
23#include "misc/options.h"
24#include "kernel/GBEngine/kstd1.h"
25#include "kernel/maps/gen_maps.h"
26
27#include "maps_ip.h"
28#include "ipid.h"
29
30
31#include "lists.h"
32#include "tok.h"
33
34/* debug output: Tok2Cmdname in maApplyFetch*/
35#include "ipshell.h"
36
37/*2
38* maps the expression w to res,
39* switch what: MAP_CMD: use theMap for mapping, N for preimage ring
40*              //FETCH_CMD: use pOrdPoly for mapping
41*              IMAP_CMD: use perm for mapping, N for preimage ring
42*              default: map only poly-structures,
43*                       use perm and par_perm, N and P,
44*/
45BOOLEAN maApplyFetch(int what,map theMap,leftv res, leftv w, ring preimage_r,
46                     int *perm, int *par_perm, int P, nMapFunc nMap)
47{
48  BOOLEAN use_mult=FALSE;
49#ifdef HAVE_PLURAL
50  if ((what==IMAP_CMD)
51  && rIsPluralRing(currRing)
52  && rIsPluralRing(preimage_r))
53  {
54    assume(perm!=NULL);
55    int i=1;
56    while((i<currRing->N)&&(perm[i]==0)) i++;
57    if (i<currRing->N)
58    {
59      int prev_nonnull=i;
60      i++;
61      for(;i<=currRing->N;i++)
62      {
63        if (perm[prev_nonnull] > perm[i])
64        {
65          if (TEST_V_ALLWARN)
66          {
67            Warn("imap not usable for permuting variables, use map (%s <-> %s)",currRing->names[prev_nonnull-1],currRing->names[i-1]);
68          }
69          use_mult=TRUE;
70          break;
71        }
72        else
73          prev_nonnull=i;
74      }
75    }
76  }
77#endif
78  int i;
79  int N = preimage_r->N;
80#if 0
81  Print("N=%d what=%s ",N,Tok2Cmdname(what));
82  if (perm!=NULL) for(i=1;i<=N;i++) Print("%d -> %d ",i,perm[i]);
83  PrintS("\n");
84  Print("P=%d ",P);
85  if (par_perm!=NULL) for(i=0;i<P;i++) Print("%d -> %d ",i,par_perm[i]);
86  PrintS("\n");
87#endif
88
89  void *data=w->Data();
90  res->rtyp = w->rtyp;
91  switch (w->rtyp)
92  {
93    case NUMBER_CMD:
94      if (P!=0)
95      {
96// poly n_PermNumber(const number z, const int *par_perm, const int OldPar, const ring src, const ring dst);
97        res->data= (void *) n_PermNumber((number)data, par_perm, P, preimage_r, currRing);
98        res->rtyp=POLY_CMD;
99        if (nCoeff_is_algExt(currRing->cf))
100          res->data=(void *)p_MinPolyNormalize((poly)res->data, currRing);
101        pTest((poly) res->data);
102      }
103      else
104      {
105        assume( nMap != NULL );
106        number a = nMap((number)data, preimage_r->cf, currRing->cf);
107        if (nCoeff_is_Extension(currRing->cf))
108        {
109          n_Normalize(a, currRing->cf);
110/*
111          number a = (number)res->data;
112          number one = nInit(1);
113          number product = nMult(a, one );
114          nDelete(&one);
115          nDelete(&a);
116          res->data=(void *)product;
117 */
118        }
119        #ifdef LDEBUG
120        n_Test(a, currRing->cf);
121        #endif
122        res->data=(void *)a;
123
124      }
125      break;
126    case BUCKET_CMD:
127      if ((what==FETCH_CMD)&& (preimage_r->cf==currRing->cf))
128        res->data=(void *)prCopyR(sBucketPeek((sBucket_pt)data), preimage_r, currRing);
129      else
130        if ( (what==IMAP_CMD) || /*(*/ (what==FETCH_CMD) /*)*/) /* && (nMap!=nCopy)*/
131        res->data=(void *)p_PermPoly(sBucketPeek((sBucket_pt)data),perm,preimage_r,currRing, nMap,par_perm,P,use_mult);
132      else /*if (what==MAP_CMD)*/
133      {
134        res->data=(void*)maMapPoly(sBucketPeek((sBucket_pt)data),preimage_r,(ideal)theMap,currRing,nMap);
135      }
136      if (nCoeff_is_Extension(currRing->cf))
137        res->data=(void *)p_MinPolyNormalize(sBucketPeek((sBucket_pt)data), currRing);
138      break;
139    case POLY_CMD:
140    case VECTOR_CMD:
141      if ((what==FETCH_CMD)&& (preimage_r->cf==currRing->cf))
142        res->data=(void *)prCopyR( (poly)data, preimage_r, currRing);
143      else
144        if ( (what==IMAP_CMD) || /*(*/ (what==FETCH_CMD) /*)*/) /* && (nMap!=nCopy)*/
145        res->data=(void *)p_PermPoly((poly)data,perm,preimage_r,currRing, nMap,par_perm,P,use_mult);
146      else /*if (what==MAP_CMD)*/
147      {
148        p_Test((poly)data,preimage_r);
149        res->data=(void*)maMapPoly((poly)data,preimage_r,(ideal)theMap,currRing,nMap);
150      }
151      if (nCoeff_is_Extension(currRing->cf))
152        res->data=(void *)p_MinPolyNormalize((poly)res->data, currRing);
153      pTest((poly)res->data);
154      break;
155    case MODUL_CMD:
156    case MATRIX_CMD:
157    case IDEAL_CMD:
158    case MAP_CMD:
159    {
160      int C=((matrix)data)->cols();
161      int R;
162      if (w->rtyp==MAP_CMD) R=1;
163      else R=((matrix)data)->rows();
164      matrix m=mpNew(R,C);
165      char *tmpR=NULL;
166      if(w->rtyp==MAP_CMD)
167      {
168        tmpR=((map)data)->preimage;
169        ((matrix)data)->rank=((matrix)data)->rows();
170      }
171      if ((what==FETCH_CMD)&& (preimage_r->cf == currRing->cf))
172      {
173        for (i=R*C-1;i>=0;i--)
174        {
175          m->m[i]=prCopyR(((ideal)data)->m[i], preimage_r, currRing);
176          pTest(m->m[i]);
177        }
178      }
179      else if ((what==IMAP_CMD) || (what==FETCH_CMD))
180      {
181        for (i=R*C-1;i>=0;i--)
182        {
183          m->m[i]=p_PermPoly(((ideal)data)->m[i],perm,preimage_r,currRing,
184                          nMap,par_perm,P,use_mult);
185          pTest(m->m[i]);
186        }
187      }
188      else /* (what==MAP_CMD) */
189      {
190        assume(what==MAP_CMD);
191        matrix s=mpNew(N,maMaxDeg_Ma((ideal)data,preimage_r));
192        for (i=R*C-1;i>=0;i--)
193        {
194          m->m[i]=maEval(theMap, ((ideal)data)->m[i], preimage_r, nMap, (ideal)s, currRing);
195          pTest(m->m[i]);
196        }
197        idDelete((ideal *)&s);
198      }
199      if (nCoeff_is_algExt(currRing->cf))
200      {
201        for (i=R*C-1;i>=0;i--)
202        {
203          m->m[i]=p_MinPolyNormalize(m->m[i], currRing);
204          pTest(m->m[i]);
205        }
206      }
207      if(w->rtyp==MAP_CMD)
208      {
209        ((map)data)->preimage=tmpR;
210        ((map)m)->preimage=omStrDup(tmpR);
211      }
212      else
213      {
214        m->rank=((matrix)data)->rank;
215      }
216      res->data=(char *)m;
217      idTest((ideal) m);
218      break;
219    }
220
221    case LIST_CMD:
222    {
223      lists l=(lists)data;
224      lists ml=(lists)omAllocBin(slists_bin);
225      ml->Init(l->nr+1);
226      for(i=0;i<=l->nr;i++)
227      {
228        if (((l->m[i].rtyp>BEGIN_RING)&&(l->m[i].rtyp<END_RING))
229        ||(l->m[i].rtyp==LIST_CMD))
230        {
231          if (maApplyFetch(what,theMap,&ml->m[i],&l->m[i],
232                           preimage_r,perm,par_perm,P,nMap))
233          {
234            ml->Clean();
235            omFreeBin((ADDRESS)ml, slists_bin);
236            res->rtyp=0;
237            return TRUE;
238          }
239        }
240        else
241        {
242          ml->m[i].Copy(&l->m[i]);
243        }
244      }
245      res->data=(char *)ml;
246      break;
247    }
248    default:
249    {
250      return TRUE;
251    }
252  }
253  return FALSE;
254}
255
256/*2
257* substitutes the parameter par (from 1..N) by image,
258* does not destroy p and  image
259*/
260poly pSubstPar(poly p, int par, poly image)
261{
262  const ring R = currRing->cf->extRing;
263  ideal theMapI = idInit(rPar(currRing),1);
264  nMapFunc nMap = n_SetMap(R->cf, currRing->cf);
265  int i;
266  for(i = rPar(currRing);i>0;i--)
267  {
268    if (i != par)
269      theMapI->m[i-1]= p_NSet(n_Param(i, currRing), currRing);
270    else
271      theMapI->m[i-1] = p_Copy(image, currRing);
272    p_Test(theMapI->m[i-1],currRing);
273  }
274  //iiWriteMatrix((matrix)theMapI,"map:",1,currRing,0);
275
276  map theMap=(map)theMapI;
277  theMap->preimage=NULL;
278
279  leftv v=(leftv)omAllocBin(sleftv_bin);
280  sleftv tmpW;
281  poly res=NULL;
282
283  p_Normalize(p,currRing);
284  if (currRing->cf->rep==n_rep_rat_fct )
285  {
286    while (p!=NULL)
287    {
288      memset(v,0,sizeof(sleftv));
289
290      number d = n_GetDenom(pGetCoeff(p), currRing->cf);
291      p_Test((poly)NUM((fraction)d), R);
292
293      if ( n_IsOne (d, currRing->cf) )
294      {
295        n_Delete(&d, currRing->cf); d = NULL;
296      }
297      else if (!p_IsConstant((poly)NUM((fraction)d), R))
298      {
299        WarnS("ignoring denominators of coefficients...");
300        n_Delete(&d, currRing->cf); d = NULL;
301      }
302
303      number num = n_GetNumerator(pGetCoeff(p), currRing->cf);
304      memset(&tmpW,0,sizeof(sleftv));
305      tmpW.rtyp = POLY_CMD;
306      p_Test((poly)NUM((fraction)num), R);
307
308      tmpW.data = NUM ((fraction)num); // a copy of this poly will be used
309
310      p_Normalize(NUM((fraction)num),R);
311      if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,R,NULL,NULL,0,nMap))
312      {
313        WerrorS("map failed");
314        v->data=NULL;
315      }
316      n_Delete(&num, currRing->cf);
317      //TODO check for memory leaks
318      poly pp = pHead(p);
319      //PrintS("map:");pWrite(pp);
320      if( d != NULL )
321      {
322        pSetCoeff(pp, n_Invers(d, currRing->cf));
323        n_Delete(&d, currRing->cf); // d = NULL;
324      }
325      else
326        pSetCoeff(pp, nInit(1));
327
328      //PrintS("->");pWrite((poly)(v->data));
329      poly ppp = pMult((poly)(v->data),pp);
330      //PrintS("->");pWrite(ppp);
331      res=pAdd(res,ppp);
332      pIter(p);
333    }
334  }
335  else if (currRing->cf->rep==n_rep_poly )
336  {
337    while (p!=NULL)
338    {
339      memset(v,0,sizeof(sleftv));
340
341      number num = n_GetNumerator(pGetCoeff(p), currRing->cf);
342      memset(&tmpW,0,sizeof(sleftv));
343      tmpW.rtyp = POLY_CMD;
344      p_Test((poly)num, R);
345
346
347      p_Normalize((poly)num,R);
348      if (num==NULL) num=(number)R->qideal->m[0];
349      tmpW.data = num; // a copy of this poly will be used
350      if (maApplyFetch(MAP_CMD,theMap,v,&tmpW,R,NULL,NULL,0,nMap))
351      {
352        WerrorS("map failed");
353        v->data=NULL;
354      }
355      if (num!=(number)R->qideal->m[0]) n_Delete(&num, currRing->cf);
356      //TODO check for memory leaks
357      poly pp = pHead(p);
358      //PrintS("map:");pWrite(pp);
359      pSetCoeff(pp,n_Init(1,currRing->cf));
360      //PrintS("cf->");pWrite((poly)(v->data));
361      poly ppp = pMult((poly)(v->data),pp);
362      //PrintS("->");pWrite(ppp);
363      res=pAdd(res,ppp);
364      pIter(p);
365    }
366  }
367  else
368  {
369    WerrorS("cannot apply subst for these coeffcients");
370  }
371  idDelete((ideal *)(&theMap));
372  omFreeBin((ADDRESS)v, sleftv_bin);
373  return res;
374}
375
376/*2
377* substitute the n-th parameter by the poly e in id
378* does not destroy id and e
379*/
380ideal  idSubstPar(ideal id, int n, poly e)
381{
382  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
383  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
384
385  res->rank = id->rank;
386  for(k--;k>=0;k--)
387  {
388    res->m[k]=pSubstPar(id->m[k],n,e);
389  }
390  return res;
391}
392
393/*2
394* substitutes the variable var (from 1..N) by image,
395* does not destroy p and  image
396*/
397poly pSubstPoly(poly p, int var, poly image)
398{
399  if (p==NULL) return NULL;
400#ifdef HAVE_PLURAL
401  if (rIsPluralRing(currRing))
402  {
403    return pSubst(pCopy(p),var,image);
404  }
405#endif
406#ifdef HAVE_SHIFTBBA
407  if (rIsLPRing(currRing))
408  {
409    return pSubst(pCopy(p),var,image);
410  }
411#endif
412  return p_SubstPoly(p,var,image,currRing,currRing,ndCopyMap);
413}
414
415/*2
416* substitute the n-th variable by the poly e in id
417* does not destroy id and e
418*/
419ideal  idSubstPoly(ideal id, int n, poly e)
420{
421
422#ifdef HAVE_PLURAL
423  if (rIsPluralRing(currRing))
424  {
425    int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
426    ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
427    res->rank = id->rank;
428    for(k--;k>=0;k--)
429    {
430      res->m[k]=pSubst(pCopy(id->m[k]),n,e);
431    }
432    return res;
433  }
434#endif
435#ifdef HAVE_SHIFTBBA
436  if (rIsLPRing(currRing))
437  {
438    int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
439    ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
440    res->rank = id->rank;
441    for(k--;k>=0;k--)
442    {
443      res->m[k]=pSubst(pCopy(id->m[k]),n,e);
444    }
445    return res;
446  }
447#endif
448  return id_SubstPoly(id,n,e,currRing,currRing,ndCopyMap);
449}
Note: See TracBrowser for help on using the repository browser.