source: git/kernel/clapconv.cc @ 593f81

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