source: git/kernel/clapconv.cc @ f2b6f0b

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