source: git/libpolys/polys/clapconv.cc @ 8fb2225

fieker-DuValspielwiese
Last change on this file since 8fb2225 was d65075, checked in by Hans Schoenemann <hannes@…>, 3 years ago
compiler warnings: signed etc.
  • Property mode set to 100644
File size: 11.5 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/*
6* ABSTRACT: convert data between Singular and factory
7*/
8
9
10
11
12
13#include "misc/auxiliary.h"
14
15#include "factory/factory.h"
16
17#include "coeffs/coeffs.h"
18
19#include "coeffs/longrat.h" // snumber is necessary
20
21#include "polys/monomials/p_polys.h"
22#include "polys/sbuckets.h"
23#include "polys/clapconv.h"
24
25#include "simpleideals.h"
26
27#define TRANSEXT_PRIVATES
28#include "polys/ext_fields/transext.h"
29
30void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
31
32static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r );
33
34static void convRecTrP ( const CanonicalForm & f, int * exp, poly & result, int offs, const ring r );
35
36//static void convRecGFGF ( const CanonicalForm & f, int * exp, poly & result );
37
38static number convFactoryNSingAN( const CanonicalForm &f, const ring r);
39
40poly convFactoryPSingP ( const CanonicalForm & f, const ring r )
41{
42  if (f.isZero()) return NULL;
43  int n = rVar(r)+1;
44  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
45  int * exp = (int*)omAlloc0(n*sizeof(int));
46  sBucket_pt result_bucket=sBucketCreate(r);
47  conv_RecPP( f, exp, result_bucket, r );
48  poly result; int dummy;
49  sBucketDestroyMerge(result_bucket,&result,&dummy);
50  omFreeSize((ADDRESS)exp,n*sizeof(int));
51  return result;
52}
53
54static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r )
55{
56  // assume f!=0
57  if ( ! f.inCoeffDomain() )
58  {
59    int l = f.level();
60    for ( CFIterator i = f; i.hasTerms(); i++ )
61    {
62      exp[l] = i.exp();
63      conv_RecPP( i.coeff(), exp, result, r );
64    }
65    exp[l] = 0;
66  }
67  else
68  {
69    number n=r->cf->convFactoryNSingN(f, r->cf);
70    if ( n_IsZero(n, r->cf) )
71    {
72      n_Delete(&n,r->cf);
73    }
74    else
75    {
76      poly term = p_Init(r);
77      //pNext( term ) = NULL; // done by p_Init
78      pGetCoeff(term)=n;
79      p_SetExpV(term,exp,r);
80      sBucket_Merge_m(result,term);
81    }
82  }
83}
84
85static inline void convPhalf(poly p,int l,poly &p1,poly &p2)
86{
87  p1=p;
88  l=l/2;
89  while(l>1) { p=pNext(p); l--; }
90  p2=pNext(p);
91  pNext(p)=NULL;
92}
93
94static inline poly convPunhalf(poly p1,poly p2)
95{
96  poly p=p1;
97  while(pNext(p1)!=NULL) { p1=pNext(p1);}
98  pNext(p1)=p2;
99  return p;
100}
101
102#define MIN_CONV_LEN 7
103static CanonicalForm convSingPFactoryP_intern( poly p, int l, BOOLEAN & setChar,const ring r )
104{
105  CanonicalForm result = 0;
106  int e, n = rVar(r);
107  assume(l==(int)pLength(p));
108
109  if (l>MIN_CONV_LEN)
110  {
111    poly p1,p2;
112    convPhalf(p,l,p1,p2);
113    CanonicalForm P=convSingPFactoryP_intern(p1,l/2,setChar,r);
114    P+=convSingPFactoryP_intern(p2,l-l/2,setChar,r);
115    convPunhalf(p1,p2);
116    return P;
117  }
118  BOOLEAN setChar_loc=setChar;
119  setChar=FALSE;
120  while ( p!=NULL )
121  {
122    CanonicalForm term=r->cf->convSingNFactoryN(pGetCoeff( p ),setChar_loc, r->cf);
123    if (errorreported) break;
124    setChar_loc=FALSE;
125    for ( int i = 1; i <=n; i++ )
126    {
127      if ( (e = p_GetExp( p, i, r)) != 0 )
128        term *= CanonicalForm( Variable( i ), e );
129    }
130    result += term;
131    pIter( p );
132 }
133 return result;
134}
135
136CanonicalForm convSingPFactoryP( poly p, const ring r )
137{
138  BOOLEAN setChar=TRUE;
139  return convSingPFactoryP_intern(p,pLength(p),setChar,r);
140}
141
142int convFactoryISingI( const CanonicalForm & f)
143{
144  if (!f.isImm()) WerrorS("int overflow in det");
145  return f.intval();
146}
147
148CanonicalForm convSingAPFactoryAP ( poly p , const Variable & a, const ring r)
149{
150  CanonicalForm result = 0;
151  int e, n = r-> N;
152  int off=rPar(r);
153
154  if (!rField_is_Zp_a(r))
155    On(SW_RATIONAL);
156  while ( p!=NULL)
157  {
158    CanonicalForm term=convSingAFactoryA(((poly)p_GetCoeff(p, r->cf->extRing)),a, r);
159    for ( int i = 1; i <= n; i++ )
160    {
161      if ( (e = p_GetExp( p, i, r )) != 0 )
162        term *= CanonicalForm( Variable( i + off), e );
163    }
164    result += term;
165    pIter( p );
166  }
167  return result;
168}
169
170static void
171convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start, const ring r) ;
172
173poly convFactoryAPSingAP_R ( const CanonicalForm & f, int par_start, int var_start, const ring r )
174{
175  if (f.isZero()) return NULL;
176  int n = rVar(r)+rPar(r)+1;
177  int * exp = (int *)omAlloc0(n*sizeof(int));
178  poly result = NULL;
179  convRecAP_R( f, exp, result,par_start, var_start, r );
180  omFreeSize((ADDRESS)exp,n*sizeof(int));
181  return result;
182}
183
184poly convFactoryAPSingAP ( const CanonicalForm & f, const ring r )
185{
186  return convFactoryAPSingAP_R(f,0,rPar(r),r);
187}
188
189static void convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start, const ring r )
190{
191  // assume f!=0
192  if ( ! f.inCoeffDomain() )
193  {
194    int l = f.level();
195    for ( CFIterator i = f; i.hasTerms(); i++ )
196    {
197      exp[l] = i.exp();
198      convRecAP_R( i.coeff(), exp, result, par_start, var_start, r);
199    }
200    exp[l] = 0;
201  }
202  else
203  {
204    poly z=(poly)convFactoryASingA( f,r );
205    if (z!=NULL)
206    {
207      poly term = p_Init(r);
208      //pNext( term ) = NULL; // done by p_Init
209      int i;
210      for ( i = rVar(r); i>0 ; i-- )
211        p_SetExp( term, i , exp[i+var_start],r);
212      //if (rRing_has_Comp(currRing->extRing)) p_SetComp(term, 0, currRing->extRing); // done by pInit
213      if (par_start==0)
214      {
215        for ( i = 1; i <= var_start; i++ )
216        //z->e[i-1]+=exp[i];
217          p_AddExp(z,i,exp[i],r->cf->extRing);
218      }
219      else
220      {
221        for ( i = par_start+1; i <= var_start+rPar(r); i++ )
222        //z->e[i-1]+=exp[i];
223          p_AddExp(z,i,exp[i-par_start],r->cf->extRing);
224      }
225      p_GetCoeff(term, r->cf->extRing)=(number) z;
226      p_Setm( term,r );
227      result = p_Add_q( result, term, r );
228    }
229  }
230}
231
232CanonicalForm convSingAFactoryA ( poly p , const Variable & a, const ring r )
233{
234  CanonicalForm result = 0;
235  int e;
236
237  while ( p!=NULL )
238  {
239    CanonicalForm term;
240    if ( rField_is_Zp_a(r) )
241    {
242      term = n_Int( p_GetCoeff( p, r->cf->extRing ), r->cf->extRing->cf );
243    }
244    else
245    {
246      if ( SR_HDL(p_GetCoeff( p, r->cf->extRing )) & SR_INT )
247        term = SR_TO_INT(p_GetCoeff( p, r->cf->extRing )) ;
248      else
249      {
250        if ( p_GetCoeff( p, r->cf->extRing )->s == 3 )
251        {
252          mpz_t dummy;
253          mpz_init_set( dummy, (p_GetCoeff( p,r->cf->extRing )->z) );
254          term = make_cf( dummy );
255        }
256        else
257        {
258          // assume s==0 or s==1
259          mpz_t num, den;
260          On(SW_RATIONAL);
261          mpz_init_set( num, (p_GetCoeff( p, r->cf->extRing )->z) );
262          mpz_init_set( den, (p_GetCoeff( p, r->cf->extRing )->n) );
263          term = make_cf( num, den, ( p_GetCoeff( p, r->cf->extRing )->s != 1 ));
264        }
265      }
266    }
267    if ( (e = p_GetExp( p, 1, r->cf->extRing )) != 0 )
268      term *= power( a , e );
269    result += term;
270    p = pNext( p );
271  }
272  return result;
273}
274
275static number convFactoryNSingAN( const CanonicalForm &f, const ring r)
276{
277  assume (r != NULL);
278  assume (r->cf != NULL);
279  assume (r->cf->extRing != NULL);
280  // r->cf->extRing->cf has to be Q or Z/p (the supported types of factory)
281  return n_convFactoryNSingN( f, r->cf->extRing->cf );
282}
283
284poly convFactoryASingA ( const CanonicalForm & f, const ring r )
285{
286  poly a=NULL;
287  for( CFIterator i=f; i.hasTerms(); i++)
288  {
289    number n= convFactoryNSingAN( i.coeff(), r );
290    if (n_IsZero(n,r->cf->extRing->cf))
291    {
292      n_Delete(&n,r->cf->extRing->cf);
293    }
294    else
295    {
296      poly t= p_Init (r->cf->extRing);
297      pGetCoeff(t)=n;
298      p_SetExp(t,1,i.exp(),r->cf->extRing);
299      //p_Setm(t,r->cf->extRing);// not needed for rings with 1 variable
300      a=p_Add_q(a,t,r->cf->extRing);
301    }
302  }
303  if (a!=NULL)
304  {
305    if( r->cf->extRing != NULL )
306      if (r->cf->extRing->qideal->m[0]!=NULL)
307      {
308        poly l=r->cf->extRing->qideal->m[0];
309        if (p_GetExp(a,1,r->cf->extRing) >= p_GetExp(l,1,r->cf->extRing))
310          a = p_PolyDiv (a, l, FALSE, r->cf->extRing); // ???
311      }
312  }
313  return a;
314}
315
316CanonicalForm convSingTrPFactoryP ( poly p, const ring r )
317{
318  CanonicalForm result = 0;
319  int e, n = rVar(r);
320  int offs = rPar(r);
321
322  while ( p!=NULL )
323  {
324    //n_Normalize(p_GetCoeff(p, r), r->cf);
325
326    // test if denominator is constant
327    if (!errorreported && !p_IsConstant(DEN ((fraction)p_GetCoeff (p,r)),r->cf->extRing))
328      WerrorS("conversion error: denominator!= 1");
329
330    CanonicalForm term=convSingPFactoryP(NUM ((fraction)p_GetCoeff(p, r)),r->cf->extRing);
331
332    // if denominator is not NULL it should be a constant at this point
333    if (DEN ((fraction)p_GetCoeff(p,r)) != NULL)
334    {
335      CanonicalForm den= convSingPFactoryP(DEN ((fraction)p_GetCoeff(p, r)),r->cf->extRing);
336      if (rChar (r) == 0)
337        On (SW_RATIONAL);
338      term /= den;
339    }
340
341    for ( int i = n; i > 0; i-- )
342    {
343      if ( (e = p_GetExp( p, i,r )) != 0 )
344        term = term * power( Variable( i + offs ), e );
345    }
346    result += term;
347    p = pNext( p );
348  }
349  return result;
350}
351
352BOOLEAN convSingTrP(poly p, const ring r )
353{
354  while ( p!=NULL )
355  {
356    n_Normalize(p_GetCoeff(p, r), r->cf);
357
358    // test if denominator is constant
359    if (!p_IsConstant(DEN ((fraction)p_GetCoeff (p,r)),r->cf->extRing))
360      return FALSE;
361    pIter(p);
362  }
363  return TRUE;
364}
365
366poly convFactoryPSingTrP ( const CanonicalForm & f, const ring r )
367{
368  if (f.isZero()) return NULL;
369  int n = rVar(r)+1;
370  int * exp = (int*)omAlloc0(n*sizeof(int));
371  poly result = NULL;
372  convRecTrP( f, exp, result , rPar(r), r );
373  omFreeSize((ADDRESS)exp,n*sizeof(int));
374  return result;
375}
376
377static void
378convRecTrP ( const CanonicalForm & f, int * exp, poly & result , int offs, const ring r)
379{
380  // assume f!= 0
381  if ( f.level() > offs )
382  {
383    int l = f.level();
384    for ( CFIterator i = f; i.hasTerms(); i++ )
385    {
386      exp[l-offs] = i.exp();
387      convRecTrP( i.coeff(), exp, result, offs, r );
388    }
389    exp[l-offs] = 0;
390  }
391  else
392  {
393    poly term = p_Init(r);
394    //pNext( term ) = NULL; // done by p_Init
395    for ( int i = rVar(r); i>0; i-- )
396      p_SetExp( term, i ,exp[i], r);
397    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
398    pGetCoeff(term)=ntInit(convFactoryPSingP( f, r->cf->extRing ), r->cf);
399    p_Setm( term,r );
400    result = p_Add_q( result, term,r );
401  }
402}
403
404#if 0
405CanonicalForm
406convSingGFFactoryGF( poly p )
407{
408  CanonicalForm result=CanonicalForm(0);
409  int e, n = pVariables;
410
411  while ( p != NULL )
412  {
413    CanonicalForm term;
414    term = make_cf_from_gf( (int)(long)pGetCoeff( p ) );
415    //int * A=(int *)&term;
416    //Print("term=%x, == 0 ?: %d\n",*A, term.isZero());
417    for ( int i = 1; i <= n; i++ )
418    {
419      if ( (e = pGetExp( p, i )) != 0 )
420         term *= power( Variable( i ), e );
421    }
422    result += term;
423    p = pNext( p );
424  }
425  return result;
426}
427
428poly
429convFactoryGFSingGF ( const CanonicalForm & f )
430{
431//    cerr << " f = " << f << endl;
432  int n = pVariables+1;
433  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
434  int * exp = (int*)omAlloc0(n*sizeof(int));
435  poly result = NULL;
436  convRecGFGF( f, exp, result );
437  omFreeSize((ADDRESS)exp,n*sizeof(int));
438  return result;
439}
440
441static void
442convRecGFGF ( const CanonicalForm & f, int * exp, poly & result )
443{
444  if (f.isZero())
445    return;
446  if ( ! f.inCoeffDomain() )
447  {
448    int l = f.level();
449    for ( CFIterator i = f; i.hasTerms(); i++ )
450    {
451      exp[l] = i.exp();
452      convRecGFGF( i.coeff(), exp, result );
453    }
454    exp[l] = 0;
455  }
456  else
457  {
458    poly term = pInit();
459    pNext( term ) = NULL;
460    for ( int i = 1; i <= pVariables; i++ )
461      pSetExp( term, i, exp[i]);
462    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
463    pGetCoeff( term ) = (number) gf_value (f);
464    pSetm( term );
465    result = pAdd( result, term );
466  }
467}
468
469#endif
Note: See TracBrowser for help on using the repository browser.