source: git/kernel/clapconv.cc @ cafd4ff

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