source: git/kernel/clapconv.cc @ f9d26b4

spielwiese
Last change on this file since f9d26b4 was f9d26b4, checked in by Hans Schönemann <hannes@…>, 14 years ago
*hannes: fix chinrem for bigint git-svn-id: file:///usr/local/Singular/svn/trunk@12306 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.1 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id$
6/*
7* ABSTRACT: convert data between Singular and factory
8*/
9
10
11#include "mod2.h"
12#ifdef HAVE_FACTORY
13#include "omalloc.h"
14#include "structs.h"
15#define SI_DONT_HAVE_GLOBAL_VARS
16#include "clapconv.h"
17#include "numbers.h"
18#include "modulop.h"
19#include "longalg.h"
20#include "polys.h"
21#include "febase.h"
22#include "ring.h"
23#include "sbuckets.h"
24#include "ffields.h"
25void out_cf(char *s1,const CanonicalForm &f,char *s2);
26
27static void convRec( const CanonicalForm & f, int * exp, poly & result );
28
29static void convRecAlg( const CanonicalForm & f, int * exp, napoly & result );
30
31static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r );
32
33static void convRecTrP ( const CanonicalForm & f, int * exp, poly & result, int offs, const ring r );
34
35static void convRecGFGF ( const CanonicalForm & f, int * exp, poly & result );
36
37static number convFactoryNSingAN( const CanonicalForm &f, const ring r);
38
39CanonicalForm convSingNFactoryN( number n, const ring r )
40{
41  CanonicalForm term;
42  /* does only work for Zp, Q */
43  if ( getCharacteristic() != 0 )
44  {
45    term = npInt( n,r );
46  }
47  else
48  {
49    if ( SR_HDL(n) & SR_INT )
50    {
51      term = SR_TO_INT(n);
52    }
53    else
54    {
55      if ( n->s == 3 )
56      {
57        MP_INT dummy;
58        mpz_init_set( &dummy, &(n->z) );
59        term = make_cf( dummy );
60      }
61      else
62      {
63        // assume s==0 or s==1
64        MP_INT num, den;
65        On(SW_RATIONAL);
66        mpz_init_set( &num, &(n->z) );
67        mpz_init_set( &den, &(n->n) );
68        term = make_cf( num, den, ( n->s != 1 ));
69      }
70    }
71  }
72  return term;
73}
74
75number convFactoryNSingN( const CanonicalForm & n)
76{
77  if (n.isImm())
78    return nInit(n.intval());
79  else
80  {
81    number z=(number)omAllocBin(rnumber_bin);
82#if defined(LDEBUG)
83    z->debug=123456;
84#endif
85    z->z = gmp_numerator( n );
86    if ( n.den().isOne() )
87      z->s = 3;
88    else
89    {
90      z->n = gmp_denominator( n );
91      z->s = 0;
92    }
93    return z;
94  }
95}
96
97poly convFactoryPSingP ( const CanonicalForm & f, const ring r )
98{
99//    cerr << " f = " << f << endl;
100  int n = rVar(r)+1;
101  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
102  int * exp = (int*)omAlloc0(n*sizeof(int));
103  sBucket_pt result_bucket=sBucketCreate(r);
104  conv_RecPP( f, exp, result_bucket, r );
105  poly result; int dummy;
106  sBucketDestroyMerge(result_bucket,&result,&dummy);
107  omFreeSize((ADDRESS)exp,n*sizeof(int));
108  return result;
109}
110
111static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r )
112{
113  if (f.isZero())
114    return;
115  if ( ! f.inCoeffDomain() )
116  {
117    int l = f.level();
118    for ( CFIterator i = f; i.hasTerms(); i++ )
119    {
120      exp[l] = i.exp();
121      conv_RecPP( i.coeff(), exp, result, r );
122    }
123    exp[l] = 0;
124  }
125  else
126  {
127    poly term = p_Init(r);
128    pNext( term ) = NULL;
129    for ( int i = 1; i <= r->N; i++ )
130      p_SetExp( term, i, exp[i], r);
131    //if (rRing_has_Comp(r)) p_SetComp(term, 0, r); // done by p_Init
132    if ( f.isImm() )
133      pGetCoeff( term ) = n_Init( f.intval(), r );
134    else
135    {
136      number z=(number)omAllocBin(rnumber_bin);
137#if defined(LDEBUG)
138      z->debug=123456;
139#endif
140      z->z = gmp_numerator( f );
141      if ( f.den().isOne() )
142        z->s = 3;
143      else
144      {
145        z->n = gmp_denominator( f );
146        z->s = 0;
147        nlNormalize(z);
148      }
149      pGetCoeff( term ) = z;
150    }
151    p_Setm( term, r );
152    if ( n_IsZero(pGetCoeff(term), r) )
153    {
154      p_Delete(&term,r);
155    }
156    else
157    {
158      sBucket_Merge_p(result,term,1);
159    }
160  }
161}
162
163
164CanonicalForm convSingPFactoryP( poly p, const ring r )
165{
166  CanonicalForm result = 0;
167  int e, n = rVar(r);
168
169  while ( p!=NULL)
170  {
171    CanonicalForm term;
172    /* does only work for finite fields */
173    if ( rField_is_Zp(r) )
174    {
175      term = npInt( pGetCoeff( p ),r );
176    }
177    else if (rField_is_Q(r))
178    {
179      if ( SR_HDL(pGetCoeff( p )) & SR_INT )
180        term = SR_TO_INT( pGetCoeff( p ) );
181      else
182      {
183        if ( pGetCoeff( p )->s == 3 )
184        {
185          MP_INT dummy;
186          mpz_init_set( &dummy, &(pGetCoeff( p )->z) );
187          term = make_cf( dummy );
188        }
189        else
190        {
191          // assume s==0 or s==1
192          MP_INT num, den;
193          On(SW_RATIONAL);
194          mpz_init_set( &num, &(pGetCoeff( p )->z) );
195          mpz_init_set( &den, &(pGetCoeff( p )->n) );
196          term = make_cf( num, den, ( pGetCoeff( p )->s != 1 ));
197        }
198      }
199    }
200    else
201    {
202      WerrorS("conversion error");
203      return result;
204    }
205    for ( int i = n; i >0; i-- )
206    {
207      if ( (e = p_GetExp( p, i, r)) != 0 )
208        term *= power( Variable( i ), e );
209    }
210    result += term;
211    pIter( p );
212  }
213  return result;
214}
215
216CanonicalForm convSingAPFactoryAP ( poly p , const Variable & a, const ring r)
217{
218  CanonicalForm result = 0;
219  int e, n = pVariables;
220  int off=rPar(currRing);
221
222  On(SW_RATIONAL);
223  while ( p!=NULL)
224  {
225    CanonicalForm term=convSingAFactoryA(((lnumber)pGetCoeff(p))->z,a, r);
226    for ( int i = 1; i <= n; i++ )
227    {
228      if ( (e = pGetExp( p, i )) != 0 )
229        term *= power( Variable( i + off), e );
230    }
231    result += term;
232    pIter( p );
233  }
234  return result;
235}
236
237static void
238convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start, const ring r) ;
239
240poly convFactoryAPSingAP_R ( const CanonicalForm & f, int par_start, int var_start, const ring r )
241{
242  int n = rVar(r)+rPar(r)+1;
243  int * exp = (int *)omAlloc0(n*sizeof(int));
244  poly result = NULL;
245  convRecAP_R( f, exp, result,par_start, var_start, r );
246  omFreeSize((ADDRESS)exp,n*sizeof(int));
247  return result;
248}
249
250poly convFactoryAPSingAP ( const CanonicalForm & f, const ring r )
251{
252  return convFactoryAPSingAP_R(f,0,rPar(r),r);
253}
254
255static void convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start, const ring r )
256{
257  if (f.isZero())
258    return;
259  if ( ! f.inCoeffDomain() )
260  {
261    int l = f.level();
262    for ( CFIterator i = f; i.hasTerms(); i++ )
263    {
264      exp[l] = i.exp();
265      convRecAP_R( i.coeff(), exp, result, par_start, var_start, r);
266    }
267    exp[l] = 0;
268  }
269  else
270  {
271    napoly z=(napoly)convFactoryASingA( f,r );
272    if (z!=NULL)
273    {
274      poly term = p_Init(r);
275      pNext( term ) = NULL;
276      int i;
277      for ( i = rVar(r); i>0 ; i-- )
278        p_SetExp( term, i , exp[i+var_start],r);
279      //if (rRing_has_Comp(currRing->algring)) p_SetComp(term, 0, currRing->algring); // done by pInit
280      if (par_start==0)
281      {
282        for ( i = 1; i <= var_start; i++ )
283        //z->e[i-1]+=exp[i];
284          p_AddExp(z,i,exp[i],r->algring);
285      }
286      else
287      {
288        for ( i = par_start+1; i <= var_start+rPar(currRing); i++ )
289        //z->e[i-1]+=exp[i];
290          p_AddExp(z,i,exp[i-par_start],r->algring);
291      }
292      pGetCoeff(term)=(number)omAlloc0Bin(rnumber_bin);
293      ((lnumber)pGetCoeff(term))->z=z;
294      p_Setm( term,r );
295      result = p_Add_q( result, term, r );
296    }
297  }
298}
299
300CanonicalForm convSingAFactoryA ( napoly p , const Variable & a, const ring r )
301{
302  CanonicalForm result = 0;
303  int e;
304
305  while ( p!=NULL )
306  {
307    CanonicalForm term;
308    /* does only work for finite fields:Z/p */
309    if ( rField_is_Zp_a() )
310    {
311      term = npInt( napGetCoeff( p ),r );
312    }
313    else
314    {
315      if ( SR_HDL(napGetCoeff( p )) & SR_INT )
316        term = SR_TO_INT(napGetCoeff( p )) ;
317      else
318      {
319        if ( napGetCoeff( p )->s == 3 )
320        {
321          MP_INT dummy;
322          mpz_init_set( &dummy, &(napGetCoeff( p )->z) );
323          term = make_cf( dummy );
324        }
325        else
326        {
327          // assume s==0 or s==1
328          MP_INT num, den;
329          On(SW_RATIONAL);
330          mpz_init_set( &num, &(napGetCoeff( p )->z) );
331          mpz_init_set( &den, &(napGetCoeff( p )->n) );
332          term = make_cf( num, den, ( napGetCoeff( p )->s != 1 ));
333        }
334      }
335    }
336    if ( (e = p_GetExp( p, 1, r->algring )) != 0 )
337      term *= power( a , e );
338    result += term;
339    p = pNext( p );
340  }
341  return result;
342}
343
344static number convFactoryNSingAN( const CanonicalForm &f, const ring r)
345{
346  if ( f.isImm() )
347    return n_Init( f.intval(), r->algring );
348  else
349  {
350    number z=(number)omAllocBin(rnumber_bin);
351#if defined(LDEBUG)
352    z->debug=123456;
353#endif
354    z->z = gmp_numerator( f );
355    if ( f.den().isOne() )
356    {
357      z->s = 3;
358    }
359    else
360    {
361      z->n = gmp_denominator( f );
362      z->s = 0;
363      nlNormalize(z);
364    }
365    #ifdef LDEBUG
366    nlDBTest(z,__FILE__,__LINE__);
367    #endif
368    return z;
369  }
370}
371
372napoly convFactoryASingA ( const CanonicalForm & f, const ring r )
373{
374  poly a=NULL;
375  poly t;
376  for( CFIterator i=f; i.hasTerms(); i++)
377  {
378    t=napNew();
379    // pNext( t ) = NULL; //already done by napNew
380    pGetCoeff(t)=convFactoryNSingAN( i.coeff(), r );
381    if (n_IsZero(napGetCoeff(t),r->algring))
382    {
383      p_Delete(&t,r->algring);
384    }
385    else
386    {
387      p_SetExp(t,1,i.exp(),r->algring);
388      a=p_Add_q(a,t,r->algring);
389    }
390  }
391  if (a!=NULL)
392  {
393    if (r->minpoly!=NULL)
394    {
395      lnumber l=(lnumber)r->minpoly;
396      if (p_GetExp(a,1,r->algring) >= p_GetExp(l->z,1,r->algring))
397        a = napRemainder( a, l->z);
398    }
399  }
400  return a;
401}
402
403CanonicalForm convSingTrPFactoryP ( poly p, const ring r )
404{
405  CanonicalForm result = 0;
406  int e, n = rVar(r);
407  int offs = rPar(r);
408
409  while ( p!=NULL )
410  {
411    n_Normalize(pGetCoeff(p),r);
412    CanonicalForm term=convSingPFactoryP(((lnumber)pGetCoeff(p))->z,r->algring);
413
414    if ((((lnumber)pGetCoeff(p))->n!=NULL)
415    && (!errorreported))
416    {
417      WerrorS("conversion error: denominator!= 1");
418    }
419
420    for ( int i = n; i > 0; i-- )
421    {
422      if ( (e = p_GetExp( p, i,r )) != 0 )
423        term = term * power( Variable( i + offs ), e );
424    }
425    result += term;
426    p = pNext( p );
427  }
428  return result;
429}
430
431poly convFactoryPSingTrP ( const CanonicalForm & f, const ring r )
432{
433  int n = rVar(r)+1;
434  int * exp = (int*)omAlloc0(n*sizeof(int));
435  poly result = NULL;
436  convRecTrP( f, exp, result , rPar(r), r );
437  omFreeSize((ADDRESS)exp,n*sizeof(int));
438  return result;
439}
440
441static void
442convRecTrP ( const CanonicalForm & f, int * exp, poly & result , int offs, const ring r)
443{
444  if (f.isZero())
445    return;
446  if ( f.level() > offs )
447  {
448    int l = f.level();
449    for ( CFIterator i = f; i.hasTerms(); i++ )
450    {
451      exp[l-offs] = i.exp();
452      convRecTrP( i.coeff(), exp, result, offs, r );
453    }
454    exp[l-offs] = 0;
455  }
456  else
457  {
458    poly term = p_Init(r);
459    pNext( term ) = NULL;
460    for ( int i = rVar(r); i>0; i-- )
461      p_SetExp( term, i ,exp[i], r);
462    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
463    pGetCoeff(term)=(number)omAlloc0Bin(rnumber_bin);
464    ((lnumber)pGetCoeff(term))->z=convFactoryPSingP( f, r->algring );
465    p_Setm( term,r );
466    result = p_Add_q( result, term,r );
467  }
468}
469
470number   nlChineseRemainder(number *x, number *q,int rl)
471// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
472{
473#ifdef HAVE_FACTORY
474  CFArray X(rl), Q(rl);
475  int i;
476  for(i=rl-1;i>=0;i--)
477  {
478    X[i]=CanonicalForm(nlInt(x[i],currRing)); // always < MAX_INT
479    Q[i]=convSingNFactoryN(q[i],currRing); // may be larger MAX_INT
480  }
481  CanonicalForm xnew,qnew;
482  chineseRemainder(X,Q,xnew,qnew);
483  number n=convFactoryNSingN(xnew);
484  number p=convFactoryNSingN(qnew);
485  number p2=nlIntDiv(p,nlInit(2, currRing));
486  if (nlGreater(n,p2))
487  {
488     number n2=nlSub(n,p);
489     nlDelete(&n,currRing);
490     n=n2;
491  }
492  nlDelete(&p,currRing);
493  nlDelete(&p2,currRing);
494  return n;
495#else
496  WerrorS("not implemented");
497  return nlInit(0);
498#endif
499}
500
501CanonicalForm
502convSingGFFactoryGF( poly p )
503{
504  CanonicalForm result=CanonicalForm(0);
505  int e, n = pVariables;
506
507  while ( p != NULL )
508  {
509    CanonicalForm term;
510    term = make_cf_from_gf( (int)(long)pGetCoeff( p ) );
511    //int * A=(int *)&term;
512    //Print("term=%x, == 0 ?: %d\n",*A, term.isZero());
513    for ( int i = 1; i <= n; i++ )
514    {
515      if ( (e = pGetExp( p, i )) != 0 )
516         term *= power( Variable( i ), e );
517    }
518    result += term;
519    p = pNext( p );
520  }
521  return result;
522}
523
524poly
525convFactoryGFSingGF ( const CanonicalForm & f )
526{
527//    cerr << " f = " << f << endl;
528  int n = pVariables+1;
529  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
530  int * exp = (int*)omAlloc0(n*sizeof(int));
531  poly result = NULL;
532  convRecGFGF( f, exp, result );
533  omFreeSize((ADDRESS)exp,n*sizeof(int));
534  return result;
535}
536
537static void
538convRecGFGF ( const CanonicalForm & f, int * exp, poly & result )
539{
540  if (f.isZero())
541    return;
542  if ( ! f.inCoeffDomain() )
543  {
544    int l = f.level();
545    for ( CFIterator i = f; i.hasTerms(); i++ )
546    {
547      exp[l] = i.exp();
548      convRecGFGF( i.coeff(), exp, result );
549    }
550    exp[l] = 0;
551  }
552  else
553  {
554    poly term = pInit();
555    pNext( term ) = NULL;
556    for ( int i = 1; i <= pVariables; i++ )
557      pSetExp( term, i, exp[i]);
558    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
559    pGetCoeff( term ) = (number) gf_value (f);
560    pSetm( term );
561    result = pAdd( result, term );
562  }
563}
564
565int convFactoryISingI( const CanonicalForm & f)
566{
567  if (!f.isImm()) WerrorS("int overflow in det");
568  return f.intval();
569}
570#endif
Note: See TracBrowser for help on using the repository browser.