source: git/kernel/clapconv.cc @ 3d6c38

spielwiese
Last change on this file since 3d6c38 was 3d6c38, checked in by Hans Schönemann <hannes@…>, 15 years ago
*hannes: code cleanup (longalg.h) git-svn-id: file:///usr/local/Singular/svn/trunk@12045 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.7 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id: clapconv.cc,v 1.13 2009-08-05 17:28:16 Singular Exp $
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 convRecPTr ( const CanonicalForm & f, int * exp, napoly & result );
34
35static void convRecTrP ( const CanonicalForm & f, int * exp, poly & result, int offs );
36
37static void convRecGFGF ( const CanonicalForm & f, int * exp, poly & result );
38
39static number convFactoryNSingAN( const CanonicalForm &f);
40
41CanonicalForm convSingNFactoryN( number n )
42{
43  CanonicalForm term;
44  /* does only work for Zp, Q */
45  if ( getCharacteristic() != 0 )
46  {
47    term = npInt( n );
48  }
49  else
50  {
51    if ( SR_HDL(n) & SR_INT )
52    {
53      term = SR_TO_INT(n);
54    }
55    else
56    {
57      if ( n->s == 3 )
58      {
59        MP_INT dummy;
60        mpz_init_set( &dummy, &(n->z) );
61        term = make_cf( dummy );
62      }
63      else
64      {
65        // assume s==0 or s==1
66        MP_INT num, den;
67        On(SW_RATIONAL);
68        mpz_init_set( &num, &(n->z) );
69        mpz_init_set( &den, &(n->n) );
70        term = make_cf( num, den, ( n->s != 1 ));
71      }
72    }
73  }
74  return term;
75}
76
77number convFactoryNSingN( const CanonicalForm & n)
78{
79  if (n.isImm())
80    return nInit(n.intval());
81  else
82  {
83    number z=(number)omAllocBin(rnumber_bin);
84#if defined(LDEBUG)
85    z->debug=123456;
86#endif
87    z->z = gmp_numerator( n );
88    if ( n.den().isOne() )
89      z->s = 3;
90    else
91    {
92      z->n = gmp_denominator( n );
93      z->s = 0;
94    }
95    return z;
96  }
97}
98
99CanonicalForm conv_SingPFactoryP( poly p, ring r )
100{
101  CanonicalForm result = 0;
102  int e, n = r->N;
103  assume( rPar(r)==0);
104
105  if ( getCharacteristic() != 0 )
106  {
107    /* does only work for finite fields Z/p*/
108    while ( p != NULL )
109    {
110      CanonicalForm term = npInt( pGetCoeff( p ) );
111      for ( int i = n; i >0; i-- )
112      {
113        if ( (e = p_GetExp( p, i, r )) != 0 )
114           term *= power( Variable( i ), e );
115      }
116      result += term;
117      pIter( p );
118    }
119  }
120  else
121  {
122    while ( p != NULL )
123    {
124      CanonicalForm term;
125      if ( SR_HDL(pGetCoeff( p )) & SR_INT )
126      {
127        term = SR_TO_INT( pGetCoeff( p ) );
128      }
129      else
130      {
131        if ( pGetCoeff( p )->s == 3 )
132        {
133          MP_INT dummy;
134          mpz_init_set( &dummy, &(pGetCoeff( p )->z) );
135          term = make_cf( dummy );
136        }
137        else
138        {
139          // assume s==1 or s==0
140          MP_INT num, den;
141          On(SW_RATIONAL);
142          mpz_init_set( &num, &(pGetCoeff( p )->z) );
143          mpz_init_set( &den, &(pGetCoeff( p )->n) );
144          term = make_cf( num, den, ( pGetCoeff( p )->s != 1 ));
145        }
146      }
147      for ( int i = n; i >0; i-- )
148      {
149        if ( (e = p_GetExp( p, i, r )) != 0 )
150           term *= power( Variable( i ), e );
151      }
152      result += term;
153      pIter( p );
154    }
155  }
156  return result;
157}
158
159poly conv_FactoryPSingP ( const CanonicalForm & f, ring r )
160{
161//    cerr << " f = " << f << endl;
162  int n = r->N+1;
163  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
164  int * exp = (int*)omAlloc0(n*sizeof(int));
165  sBucket_pt result_bucket=sBucketCreate(r);
166  conv_RecPP( f, exp, result_bucket, r );
167  poly result; int dummy;
168  sBucketDestroyMerge(result_bucket,&result,&dummy);
169  omFreeSize((ADDRESS)exp,n*sizeof(int));
170  return result;
171}
172
173static void conv_RecPP ( const CanonicalForm & f, int * exp, sBucket_pt result, ring r )
174{
175  if (f.isZero())
176    return;
177  if ( ! f.inCoeffDomain() )
178  {
179    int l = f.level();
180    for ( CFIterator i = f; i.hasTerms(); i++ )
181    {
182      exp[l] = i.exp();
183      conv_RecPP( i.coeff(), exp, result, r );
184    }
185    exp[l] = 0;
186  }
187  else
188  {
189    poly term = p_Init(r);
190    pNext( term ) = NULL;
191    for ( int i = 1; i <= r->N; i++ )
192      p_SetExp( term, i, exp[i], r);
193    //if (rRing_has_Comp(r)) p_SetComp(term, 0, r); // done by p_Init
194    if ( f.isImm() )
195      pGetCoeff( term ) = n_Init( f.intval(), r );
196    else
197    {
198      number z=(number)omAllocBin(rnumber_bin);
199#if defined(LDEBUG)
200      z->debug=123456;
201#endif
202      z->z = gmp_numerator( f );
203      if ( f.den().isOne() )
204        z->s = 3;
205      else
206      {
207        z->n = gmp_denominator( f );
208        z->s = 0;
209        nlNormalize(z);
210      }
211      pGetCoeff( term ) = z;
212    }
213    p_Setm( term, r );
214    if ( n_IsZero(pGetCoeff(term), r) )
215    {
216      p_Delete(&term,r);
217    }
218    else
219    {
220      sBucket_Merge_p(result,term,1);
221    }
222  }
223}
224
225
226CanonicalForm convSingTrFactoryP( napoly p )
227{
228  CanonicalForm result = 0;
229  int e, n = rPar(currRing);
230
231  while ( p!=NULL)
232  {
233    CanonicalForm term;
234    /* does only work for finite fields */
235    if ( getCharacteristic() != 0 )
236    {
237      term = npInt( pGetCoeff( p ) );
238    }
239    else
240    {
241      if ( SR_HDL(pGetCoeff( p )) & SR_INT )
242        term = SR_TO_INT( pGetCoeff( p ) );
243      else
244      {
245        if ( pGetCoeff( p )->s == 3 )
246        {
247          MP_INT dummy;
248          mpz_init_set( &dummy, &(pGetCoeff( p )->z) );
249          term = make_cf( dummy );
250        }
251        else
252        {
253          // assume s==0 or s==1
254          MP_INT num, den;
255          On(SW_RATIONAL);
256          mpz_init_set( &num, &(pGetCoeff( p )->z) );
257          mpz_init_set( &den, &(pGetCoeff( p )->n) );
258          term = make_cf( num, den, ( pGetCoeff( p )->s != 1 ));
259        }
260      }
261    }
262    for ( int i = n; i >0; i-- )
263    {
264      if ( (e = p_GetExp( p, i, currRing->algring )) != 0 )
265        term *= power( Variable( i ), e );
266    }
267    result += term;
268    pIter( p );
269  }
270  return result;
271}
272
273napoly convFactoryPSingTr ( const CanonicalForm & f )
274{
275//    cerr << " f = " << f << endl;
276  int n = rPar(currRing)+1;
277  /* ASSERT( level( f ) <= rPar(currRing), "illegal number of variables" ); */
278  int * exp = (int *)omAlloc0(n*sizeof(int));
279  napoly result = NULL;
280  convRecPTr( f, exp, result );
281  omFreeSize((ADDRESS)exp,n*sizeof(int));
282  return result;
283}
284
285static void convRecPTr ( const CanonicalForm & f, int * exp, napoly & result )
286{
287  if (f.isZero())
288    return;
289  if ( ! f.inCoeffDomain() )
290  {
291    int l = f.level();
292    for ( CFIterator i = f; i.hasTerms(); i++ )
293    {
294        exp[l] = i.exp();
295        convRecPTr( i.coeff(), exp, result );
296    }
297    exp[l] = 0;
298  }
299  else
300  {
301    napoly term = napNew();
302    // napNext( term ) = NULL; //already done by napNew
303    for ( int i = rPar(currRing); i>=1; i-- )
304      p_SetExp( term, i , exp[i],currRing->algring);
305    p_Setm(term, currRing->algring);
306    if ( f.isImm() )
307      pGetCoeff( term ) = n_Init( f.intval(), currRing->algring );
308    else
309    {
310      number z=(number)omAllocBin(rnumber_bin);
311#if defined(LDEBUG)
312      z->debug=123456;
313#endif
314      z->z = gmp_numerator( f );
315      if ( f.den().isOne() )
316      {
317        z->s = 3;
318      }
319      else
320      {
321        z->n = gmp_denominator( f );
322        if (mpz_cmp_si(&z->n,(long)1)==0)
323        {
324          mpz_clear(&z->n);
325          z->s=3;
326        }
327        else
328        {
329          z->s = 0;
330          n_Normalize(z,currRing->algring);
331        }
332      }
333      pGetCoeff( term ) = z;
334    }
335    if (n_IsZero(pGetCoeff(term),currRing->algring))
336    {
337      napDelete(&term);
338    }
339    else
340    {
341      result = napAdd( result, term );
342    }
343  }
344}
345
346CanonicalForm convSingAPFactoryAP ( poly p , const Variable & a)
347{
348  CanonicalForm result = 0;
349  int e, n = pVariables;
350  int off=rPar(currRing);
351
352  On(SW_RATIONAL);
353  while ( p!=NULL)
354  {
355    CanonicalForm term=convSingAFactoryA(((lnumber)pGetCoeff(p))->z,a);
356    for ( int i = 1; i <= n; i++ )
357    {
358      if ( (e = pGetExp( p, i )) != 0 )
359        term *= power( Variable( i + off), e );
360    }
361    result += term;
362    pIter( p );
363  }
364  return result;
365}
366
367static void
368convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start) ;
369
370poly convFactoryAPSingAP_R ( const CanonicalForm & f, int par_start, int var_start )
371{
372  int n = pVariables+1+rPar(currRing);
373  int * exp = (int *)omAlloc0(n*sizeof(int));
374  poly result = NULL;
375  convRecAP_R( f, exp, result,par_start, var_start );
376  omFreeSize((ADDRESS)exp,n*sizeof(int));
377  return result;
378}
379
380poly convFactoryAPSingAP ( const CanonicalForm & f )
381{
382  return convFactoryAPSingAP_R(f,0,rPar(currRing));
383}
384
385static void convRecAP_R ( const CanonicalForm & f, int * exp, poly & result, int par_start, int var_start )
386{
387  if (f.isZero())
388    return;
389  if ( ! f.inCoeffDomain() )
390  {
391    int l = f.level();
392    for ( CFIterator i = f; i.hasTerms(); i++ )
393    {
394      exp[l] = i.exp();
395      convRecAP_R( i.coeff(), exp, result, par_start, var_start );
396    }
397    exp[l] = 0;
398  }
399  else
400  {
401    napoly z=(napoly)convFactoryASingA( f );
402    if (z!=NULL)
403    {
404      poly term = pInit();
405      pNext( term ) = NULL;
406      int i;
407      for ( i = 1; i <= pVariables; i++ )
408        pSetExp( term, i , exp[i+var_start]);
409      //if (rRing_has_Comp(currRing->algring)) p_SetComp(term, 0, currRing->algring); // done by pInit
410      if (par_start==0)
411      {
412        for ( i = 1; i <= var_start; i++ )
413        //z->e[i-1]+=exp[i];
414          napAddExp(z,i,exp[i]);
415      }
416      else
417      {
418        for ( i = par_start+1; i <= var_start+rPar(currRing); i++ )
419        //z->e[i-1]+=exp[i];
420          napAddExp(z,i,exp[i-par_start]);
421      }
422      pGetCoeff(term)=(number)omAlloc0Bin(rnumber_bin);
423      ((lnumber)pGetCoeff(term))->z=z;
424      pSetm( term );
425      result = pAdd( result, term );
426    }
427  }
428}
429
430CanonicalForm convSingAFactoryA ( napoly p , const Variable & a )
431{
432  CanonicalForm result = 0;
433  int e;
434
435  while ( p!=NULL )
436  {
437    CanonicalForm term;
438    /* does only work for finite fields:Z/p */
439    if ( rField_is_Zp_a() )
440    {
441      term = npInt( napGetCoeff( p ) );
442    }
443    else
444    {
445      if ( SR_HDL(napGetCoeff( p )) & SR_INT )
446        term = SR_TO_INT(napGetCoeff( p )) ;
447      else
448      {
449        if ( napGetCoeff( p )->s == 3 )
450        {
451          MP_INT dummy;
452          mpz_init_set( &dummy, &(napGetCoeff( p )->z) );
453          term = make_cf( dummy );
454        }
455        else
456        {
457          // assume s==0 or s==1
458          MP_INT num, den;
459          On(SW_RATIONAL);
460          mpz_init_set( &num, &(napGetCoeff( p )->z) );
461          mpz_init_set( &den, &(napGetCoeff( p )->n) );
462          term = make_cf( num, den, ( napGetCoeff( p )->s != 1 ));
463        }
464      }
465    }
466    if ( (e = napGetExp( p, 1 )) != 0 )
467      term *= power( a , e );
468    result += term;
469    p = napNext( p );
470  }
471  return result;
472}
473
474static number convFactoryNSingAN( const CanonicalForm &f)
475{
476  if ( f.isImm() )
477    return n_Init( f.intval(), currRing->algring );
478  else
479  {
480    number z=(number)omAllocBin(rnumber_bin);
481#if defined(LDEBUG)
482    z->debug=123456;
483#endif
484    z->z = gmp_numerator( f );
485    if ( f.den().isOne() )
486    {
487      z->s = 3;
488    }
489    else
490    {
491      z->n = gmp_denominator( f );
492      z->s = 0;
493      nlNormalize(z);
494    }
495    #ifdef LDEBUG
496    nlDBTest(z,__FILE__,__LINE__);
497    #endif
498    return z;
499  }
500}
501
502napoly convFactoryASingA ( const CanonicalForm & f )
503{
504  napoly a=NULL;
505  napoly t;
506  for( CFIterator i=f; i.hasTerms(); i++)
507  {
508    t=napNew();
509    // napNext( t ) = NULL; //already done by napNew
510    napGetCoeff(t)=convFactoryNSingAN( i.coeff() );
511    if (n_IsZero(napGetCoeff(t),currRing->algring))
512    {
513      napDelete(&t);
514    }
515    else
516    {
517      napSetExp(t,1,i.exp());
518      a=napAdd(a,t);
519    }
520  }
521  if (a!=NULL)
522  {
523    if (naMinimalPoly!=NULL)
524    {
525      if (napGetExp(a,1) >= napGetExp(naMinimalPoly,1))
526        a = napRemainder( a, naMinimalPoly);
527    }
528  }
529  return a;
530}
531
532CanonicalForm convSingTrPFactoryP ( poly p )
533{
534  CanonicalForm result = 0;
535  int e, n = pVariables;
536  int offs = rPar(currRing);
537
538  while ( p!=NULL )
539  {
540    nNormalize(pGetCoeff(p));
541    CanonicalForm term=convSingTrFactoryP(((lnumber)pGetCoeff(p))->z);
542
543    if ((((lnumber)pGetCoeff(p))->n!=NULL)
544    && (!errorreported))
545    {
546      WerrorS("conversion error: denominator!= 1");
547    }
548
549    for ( int i = n; i > 0; i-- )
550    {
551      if ( (e = pGetExp( p, i )) != 0 )
552        term = term * power( Variable( i + offs ), e );
553    }
554    result += term;
555    p = pNext( p );
556  }
557  return result;
558}
559
560poly convFactoryPSingTrP ( const CanonicalForm & f )
561{
562  int n = pVariables+1;
563  int * exp = (int*)omAlloc0(n*sizeof(int));
564  poly result = NULL;
565  convRecTrP( f, exp, result , rPar(currRing) );
566  omFreeSize((ADDRESS)exp,n*sizeof(int));
567  return result;
568}
569
570static void
571convRecTrP ( const CanonicalForm & f, int * exp, poly & result , int offs)
572{
573  if (f.isZero())
574    return;
575  if ( f.level() > offs )
576  {
577    int l = f.level();
578    for ( CFIterator i = f; i.hasTerms(); i++ )
579    {
580      exp[l-offs] = i.exp();
581      convRecTrP( i.coeff(), exp, result, offs );
582    }
583    exp[l-offs] = 0;
584  }
585  else
586  {
587    poly term = pInit();
588    pNext( term ) = NULL;
589    for ( int i = 1; i <= pVariables; i++ )
590      pSetExp( term, i ,exp[i]);
591    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
592    pGetCoeff(term)=(number)omAlloc0Bin(rnumber_bin);
593    ((lnumber)pGetCoeff(term))->z=convFactoryPSingTr( f );
594    pSetm( term );
595    result = pAdd( result, term );
596  }
597}
598
599number   nlChineseRemainder(number *x, number *q,int rl)
600// elemenst in the array are x[0..(rl-1)], q[0..(rl-1)]
601{
602#ifdef HAVE_FACTORY
603  CFArray X(rl), Q(rl);
604  int i;
605  for(i=rl-1;i>=0;i--)
606  {
607    X[i]=CanonicalForm(nlInt(x[i]));
608    Q[i]=CanonicalForm(nlInt(q[i]));
609  }
610  CanonicalForm xnew,qnew;
611  chineseRemainder(X,Q,xnew,qnew);
612  number n=convFactoryNSingN(xnew);
613  number p=convFactoryNSingN(qnew);
614  number p2=nlIntDiv(p,nlInit(2));
615  if (nlGreater(n,p2))
616  {
617     number n2=nlSub(n,p);
618     nlDelete(&n,currRing);
619     n=n2;
620  }
621  nlDelete(&p,currRing);
622  nlDelete(&p2,currRing);
623  return n;
624#else
625  WerrorS("not implemented");
626  return nlInit(0);
627#endif
628}
629
630CanonicalForm
631convSingGFFactoryGF( poly p )
632{
633  CanonicalForm result=CanonicalForm(0);
634  int e, n = pVariables;
635
636  while ( p != NULL )
637  {
638    CanonicalForm term;
639    term = make_cf_from_gf( (int)(long)pGetCoeff( p ) );
640    //int * A=(int *)&term;
641    //Print("term=%x, == 0 ?: %d\n",*A, term.isZero());
642    for ( int i = 1; i <= n; i++ )
643    {
644      if ( (e = pGetExp( p, i )) != 0 )
645         term *= power( Variable( i ), e );
646    }
647    result += term;
648    p = pNext( p );
649  }
650  return result;
651}
652
653poly
654convFactoryGFSingGF ( const CanonicalForm & f )
655{
656//    cerr << " f = " << f << endl;
657  int n = pVariables+1;
658  /* ASSERT( level( f ) <= pVariables, "illegal number of variables" ); */
659  int * exp = (int*)omAlloc0(n*sizeof(int));
660  poly result = NULL;
661  convRecGFGF( f, exp, result );
662  omFreeSize((ADDRESS)exp,n*sizeof(int));
663  return result;
664}
665
666static void
667convRecGFGF ( const CanonicalForm & f, int * exp, poly & result )
668{
669  if (f.isZero())
670    return;
671  if ( ! f.inCoeffDomain() )
672  {
673    int l = f.level();
674    for ( CFIterator i = f; i.hasTerms(); i++ )
675    {
676      exp[l] = i.exp();
677      convRecGFGF( i.coeff(), exp, result );
678    }
679    exp[l] = 0;
680  }
681  else
682  {
683    poly term = pInit();
684    pNext( term ) = NULL;
685    for ( int i = 1; i <= pVariables; i++ )
686      pSetExp( term, i, exp[i]);
687    //if (rRing_has_Comp(currRing)) p_SetComp(term, 0, currRing); // done by pInit
688    pGetCoeff( term ) = (number) gf_value (f);
689    pSetm( term );
690    result = pAdd( result, term );
691  }
692}
693
694int convFactoryISingI( const CanonicalForm & f)
695{
696  if (!f.isImm()) WerrorS("int overflow in det");
697  return f.intval();
698}
699#endif
Note: See TracBrowser for help on using the repository browser.