source: git/Singular/clapsing.cc @ 50cbdc

spielwiese
Last change on this file since 50cbdc was 50cbdc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merge-2-0-2 git-svn-id: file:///usr/local/Singular/svn/trunk@5619 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 34.2 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5// $Id: clapsing.cc,v 1.78 2001-08-27 14:46:49 Singular Exp $
6/*
7* ABSTRACT: interface between Singular and factory
8*/
9
10#include "mod2.h"
11#include "omalloc.h"
12#ifdef HAVE_FACTORY
13#define SI_DONT_HAVE_GLOBAL_VARS
14#include "tok.h"
15#include "clapsing.h"
16#include "ipid.h"
17#include "numbers.h"
18#include "subexpr.h"
19#include "ipshell.h"
20#include "ring.h"
21#include <factory.h>
22#include "clapconv.h"
23#ifdef HAVE_LIBFAC_P
24#include <factor.h>
25#endif
26#include "ring.h"
27
28//
29// FACTORY_GCD_TEST: use new gcd instead of old one.  Does not work
30//   without new gcd-implementation which is not publicly available.
31//
32// FACTORY_GCD_STAT: print statistics on polynomials.  Works only
33//   with the file `gcd_stat.cc' and `gcd_stat.h which may be found
34//   in the repository, module `factory-devel'.
35//   Overall statistics may printed using `system("gcdstat");'.
36//
37// FACTORY_GCD_TIMING: accumulate time used for gcd calculations.
38//   Time may be printed (and reset) with `system("gcdtime");'.
39//   For this define, `timing.h' from the factory source directory
40//   has to be copied to the Singular source directory.
41//   Note: for better readability, the macros `TIMING_START()' and
42//   `TIMING_END()' are used in any case.  However, they expand to
43//   nothing if `FACTORY_GCD_TIMING' is off.
44//
45// FACTORY_GCD_DEBOUT: print polynomials involved in gcd calculations.
46//   The polynomials are printed by means of the macros
47//   `FACTORY_*OUT_POLY' which are defined to be empty if
48//   `FACTORY_GCD_DEBOUT' is off.
49//
50// FACTORY_GCD_DEBOUT_PATTERN: print degree patterns of polynomials
51//   involved in gcd calculations.
52//   The patterns are printed by means of the macros
53//   `FACTORY_*OUT_PAT' which are defined to be empty if
54//   `FACTORY_GCD_DEBOUT_PATTERN' is off.
55//
56//   A degree pattern looks like this:
57//
58//   totDeg  size    deg(v1) deg(v2) ...
59//
60//   where "totDeg" means total degree, "size" the number of terms,
61//   and "deg(vi)" is the degree with respect to variable i.
62//   In univariate case, the "deg(vi)" are missing.  For this feature
63//   you need the files `gcd_stat.cc' and `gcd_stat.h'.
64//
65//
66// And here is what the functions print if `FACTORY_GCD_DEBOUT' (1),
67// `FACTORY_GCD_STAT' (2), or `FACTORY_GCD_DEBOUT_PATTERN' (3) is on:
68//
69// sinclap_divide_content:
70// (1) G = <firstCoeff>
71// (3) G#= <firstCoeff, pattern>
72// (1) h = <nextCoeff>
73// (3) h#= <nextCoeff, pattern>
74// (2) gcnt: <statistics on gcd as explained above>
75// (1) g = <intermediateResult>
76// (3) g#= <intermediateResult, pattern>
77// (1) h = <nextCoeff>
78// (3) h#= <nextCoeff, pattern>
79// (2) gcnt: <statistics on gcd as explained above>
80//  ...
81// (1) h = <lastCoeff>
82// (3) h#= <lastCoeff, pattern>
83// (1) g = <finalResult>
84// (3) g#= <finalResult, pattern>
85// (2) gcnt: <statistics on gcd as explained above>
86// (2) cont: <statistics on content as explained above>
87//
88// singclap_alglcm:
89// (1) f = <inputPolyF>
90// (3) f#= <inputPolyF, pattern>
91// (1) g = <inputPolyG>
92// (3) g#= <inputPolyG, pattern>
93// (1) d = <its gcd>
94// (3) d#= <its gcd, pattern>
95// (2) alcm: <statistics as explained above>
96//
97// singclap_algdividecontent:
98// (1) f = <inputPolyF>
99// (3) f#= <inputPolyF, pattern>
100// (1) g = <inputPolyG>
101// (3) g#= <inputPolyG, pattern>
102// (1) d = <its gcd>
103// (3) d#= <its gcd, pattern>
104// (2) acnt: <statistics as explained above>
105//
106
107#ifdef FACTORY_GCD_STAT
108#include "gcd_stat.h"
109#define FACTORY_GCDSTAT( tag, f, g, d ) \
110  printGcdStat( tag, f, g, d )
111#define FACTORY_CONTSTAT( tag, f ) \
112  printContStat( tag, f )
113#else
114#define FACTORY_GCDSTAT( tag, f, g, d )
115#define FACTORY_CONTSTAT( tag, f )
116#endif
117
118#ifdef FACTORY_GCD_TIMING
119#define TIMING
120#include "timing.h"
121TIMING_DEFINE_PRINT( contentTimer );
122TIMING_DEFINE_PRINT( algContentTimer );
123TIMING_DEFINE_PRINT( algLcmTimer );
124#else
125#define TIMING_START( timer )
126#define TIMING_END( timer )
127#endif
128
129#ifdef FACTORY_GCD_DEBOUT
130#include "longalg.h"
131#include "febase.h"
132// napoly f
133#define FACTORY_ALGOUT_POLY( tag, f ) \
134  StringSetS( tag ); \
135  napWrite( f ); \
136  pRINtS(StringAppendS("\n"));
137// CanonicalForm f, represents transcendent extension
138#define FACTORY_CFTROUT_POLY( tag, f ) \
139  { \
140    napoly F=convClapPSingTr( f ); \
141    StringSetS( tag ); \
142    napWrite( F ); \
143    PrintS(StringAppendS("\n")); \
144    napDelete(&F); \
145  }
146// CanonicalForm f, represents algebraic extension
147#define FACTORY_CFAOUT_POLY( tag, f ) \
148  { \
149    napoly F=convClapASingA( f ); \
150    StringSetS( tag ); \
151    napWrite( F ); \
152    PrintS(StringAppendS("\n")); \
153    napDelete(&F); \
154  }
155#else /* ! FACTORY_GCD_DEBOUT */
156#define FACTORY_ALGOUT_POLY( tag, f )
157#define FACTORY_CFTROUT_POLY( tag, f )
158#define FACTORY_CFAOUT_POLY( tag, f )
159#endif /* ! FACTORY_GCD_DEBOUT */
160
161#ifdef FACTORY_GCD_DEBOUT_PATTERN
162// napoly f
163#define FACTORY_ALGOUT_PAT( tag, f ) \
164  if (currRing->minpoly!=NULL) \
165  { \
166    CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z); \
167    Variable a=rootOf(mipo); \
168    printPolyPattern( tag, convSingAClapA( f,a ), rPar( currRing ) ); \
169  } \
170  else \
171  { \
172    printPolyPattern( tag, convSingTrClapP( f ), rPar( currRing ) ); \
173  }
174// CanonicalForm f, represents transcendent extension
175#define FACTORY_CFTROUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
176// CanonicalForm f, represents algebraic extension
177#define FACTORY_CFAOUT_PAT( tag, f ) printPolyPattern( tag, f, rPar( currRing ) )
178#else /* ! FACTORY_GCD_DEBOUT_PATTERN */
179#define FACTORY_ALGOUT_PAT( tag, f )
180#define FACTORY_CFTROUT_PAT( tag, f )
181#define FACTORY_CFAOUT_PAT( tag, f )
182#endif /* ! FACTORY_GCD_DEBOUT_PATTERN */
183
184// these macors combine both print macros
185#define FACTORY_ALGOUT( tag, f ) \
186  FACTORY_ALGOUT_POLY( tag " = ", f ); \
187  FACTORY_ALGOUT_PAT( tag "#= ", f )
188#define FACTORY_CFTROUT( tag, f ) \
189  FACTORY_CFTROUT_POLY( tag " = ", f ); \
190  FACTORY_CFTROUT_PAT( tag "#= ", f )
191#define FACTORY_CFAOUT( tag, f ) \
192  FACTORY_CFAOUT_POLY( tag " = ", f ); \
193  FACTORY_CFAOUT_PAT( tag "#= ", f )
194
195
196
197
198
199poly singclap_gcd ( poly f, poly g )
200{
201  poly res=NULL;
202
203  if (f!=NULL) pCleardenom(f);
204  if (g!=NULL) pCleardenom(g);
205  else         return pCopy(f); // g==0 => gcd=f (but do a pCleardenom)
206  if (f==NULL) return pCopy(g); // f==0 => gcd=g (but do a pCleardenom)
207
208  // for now there is only the possibility to handle polynomials over
209  // Q and Fp ...
210  if (( nGetChar() == 0 || nGetChar() > 1 )
211  && (currRing->parameter==NULL))
212  {
213    setCharacteristic( nGetChar() );
214    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
215    res=convClapPSingP( gcd( F, G ) );
216    Off(SW_RATIONAL);
217  }
218  // and over Q(a) / Fp(a)
219  else if (( nGetChar()==1 ) /* Q(a) */
220  || (nGetChar() <-1))       /* Fp(a) */
221  {
222    if (nGetChar()==1) setCharacteristic( 0 );
223    else               setCharacteristic( -nGetChar() );
224    if (currRing->minpoly!=NULL)
225    {
226      if ( nGetChar()==1 ) /* Q(a) */
227      {
228        WerrorS( feNotImplemented );
229      }
230      else
231      {
232        CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
233        Variable a=rootOf(mipo);
234        CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
235        res= convClapAPSingAP( gcd( F, G ) );
236      }
237    }
238    else
239    {
240      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
241      res= convClapPSingTrP( gcd( F, G ) );
242    }
243    Off(SW_RATIONAL);
244  }
245  #if 0
246  else if (( nGetChar()>1 )&&(currRing->parameter!=NULL)) /* GF(q) */
247  {
248    int p=rChar(currRing);
249    int n=2;
250    int t=p*p;
251    while (t!=nChar) { t*=p;n++; }
252    setCharacteristic(p,n,'a');
253    CanonicalForm F( convSingGFClapGF( f ) ), G( convSingGFClapGF( g ) );
254    res= convClapGFSingGF( gcd( F, G ) );
255  }
256  #endif
257  else
258    WerrorS( feNotImplemented );
259
260  pDelete(&f);
261  pDelete(&g);
262  pTest(res);
263  return res;
264}
265
266poly singclap_resultant ( poly f, poly g , poly x)
267{
268  int i=pIsPurePower(x);
269  if (i==0)
270  {
271    WerrorS("3rd argument must be a ring variable");
272    return NULL;
273  }
274  if ((f==NULL) || (g==NULL))
275    return NULL;
276  // for now there is only the possibility to handle polynomials over
277  // Q and Fp ...
278  if (( nGetChar() == 0 || nGetChar() > 1 )
279  && (currRing->parameter==NULL))
280  {
281    Variable X(i);
282    setCharacteristic( nGetChar() );
283    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
284    poly res=convClapPSingP( resultant( F, G, X ) );
285    Off(SW_RATIONAL);
286    return res;
287  }
288  // and over Q(a) / Fp(a)
289  else if (( nGetChar()==1 ) /* Q(a) */
290  || (nGetChar() <-1))       /* Fp(a) */
291  {
292    if (nGetChar()==1) setCharacteristic( 0 );
293    else               setCharacteristic( -nGetChar() );
294    poly res;
295    if (currRing->minpoly!=NULL)
296    {
297      Variable X(i);
298      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
299      Variable a=rootOf(mipo);
300      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
301      res= convClapAPSingAP( resultant( F, G, X ) );
302    }
303    else
304    {
305      Variable X(i+rPar(currRing));
306      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
307      res= convClapPSingTrP( resultant( F, G, X ) );
308    }
309    Off(SW_RATIONAL);
310    return res;
311  }
312  else
313    WerrorS( feNotImplemented );
314  return NULL;
315}
316//poly singclap_resultant ( poly f, poly g , poly x)
317//{
318//  int i=pVar(x);
319//  if (i==0)
320//  {
321//    WerrorS("ringvar expected");
322//    return NULL;
323//  }
324//  ideal I=idInit(1,1);
325//
326//  // get the coeffs von f wrt. x:
327//  I->m[0]=pCopy(f);
328//  matrix ffi=mpCoeffs(I,i);
329//  ffi->rank=1;
330//  ffi->ncols=ffi->nrows;
331//  ffi->nrows=1;
332//  ideal fi=(ideal)ffi;
333//
334//  // get the coeffs von g wrt. x:
335//  I->m[0]=pCopy(g);
336//  matrix ggi=mpCoeffs(I,i);
337//  ggi->rank=1;
338//  ggi->ncols=ggi->nrows;
339//  ggi->nrows=1;
340//  ideal gi=(ideal)ggi;
341//
342//  // contruct the matrix:
343//  int fn=IDELEMS(fi); //= deg(f,x)+1
344//  int gn=IDELEMS(gi); //= deg(g,x)+1
345//  matrix m=mpNew(fn+gn-2,fn+gn-2);
346//  if(m==NULL)
347//  {
348//    return NULL;
349//  }
350//
351//  // enter the coeffs into m:
352//  int j;
353//  for(i=0;i<gn-1;i++)
354//  {
355//    for(j=0;j<fn;j++)
356//    {
357//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
358//    }
359//  }
360//  for(i=0;i<fn-1;i++)
361//  {
362//    for(j=0;j<gn;j++)
363//    {
364//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
365//    }
366//  }
367//
368//  poly r=mpDet(m);
369//
370//  idDelete(&fi);
371//  idDelete(&gi);
372//  idDelete((ideal *)&m);
373//  return r;
374//}
375
376lists singclap_extgcd ( poly f, poly g )
377{
378  // for now there is only the possibility to handle univariate
379  // polynomials over
380  // Q and Fp ...
381  poly res=NULL,pa=NULL,pb=NULL;
382  On(SW_SYMMETRIC_FF);
383  if (( nGetChar() == 0 || nGetChar() > 1 )
384  && (currRing->parameter==NULL))
385  {
386    setCharacteristic( nGetChar() );
387    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
388    if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
389    {
390      Off(SW_RATIONAL);
391      WerrorS("not univariate");
392      return NULL;
393    }
394    CanonicalForm Fa,Gb;
395    On(SW_RATIONAL);
396    res=convClapPSingP( extgcd( F, G, Fa, Gb ) );
397    pa=convClapPSingP(Fa);
398    pb=convClapPSingP(Gb);
399    Off(SW_RATIONAL);
400  }
401  // and over Q(a) / Fp(a)
402  else if (( nGetChar()==1 ) /* Q(a) */
403  || (nGetChar() <-1))       /* Fp(a) */
404  {
405    if (nGetChar()==1) setCharacteristic( 0 );
406    else               setCharacteristic( -nGetChar() );
407    CanonicalForm Fa,Gb;
408    if (currRing->minpoly!=NULL)
409    {
410      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
411      Variable a=rootOf(mipo);
412      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
413      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
414      {
415        WerrorS("not univariate");
416        return NULL;
417      }
418      res= convClapAPSingAP( extgcd( F, G, Fa, Gb ) );
419      pa=convClapAPSingAP(Fa);
420      pb=convClapAPSingAP(Gb);
421    }
422    else
423    {
424      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
425      if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
426      {
427        Off(SW_RATIONAL);
428        WerrorS("not univariate");
429        return NULL;
430      }
431      res= convClapPSingTrP( extgcd( F, G, Fa, Gb ) );
432      pa=convClapPSingTrP(Fa);
433      pb=convClapPSingTrP(Gb);
434    }
435    Off(SW_RATIONAL);
436  }
437  else
438  {
439    WerrorS( feNotImplemented );
440    return NULL;
441  }
442  lists L=(lists)omAllocBin(slists_bin);
443  L->Init(3);
444  L->m[0].rtyp=POLY_CMD;
445  L->m[0].data=(void *)res;
446  L->m[1].rtyp=POLY_CMD;
447  L->m[1].data=(void *)pa;
448  L->m[2].rtyp=POLY_CMD;
449  L->m[2].data=(void *)pb;
450  return L;
451}
452
453poly singclap_pdivide ( poly f, poly g )
454{
455  // for now there is only the possibility to handle polynomials over
456  // Q and Fp ...
457  poly res=NULL;
458  On(SW_RATIONAL);
459  if (( nGetChar() == 0 || nGetChar() > 1 )
460  && (currRing->parameter==NULL))
461  {
462    setCharacteristic( nGetChar() );
463    CanonicalForm F( convSingPClapP( f ) ), G( convSingPClapP( g ) );
464    res = convClapPSingP( F / G );
465  }
466  // and over Q(a) / Fp(a)
467  else if (( nGetChar()==1 ) /* Q(a) */
468  || (nGetChar() <-1))       /* Fp(a) */
469  {
470    if (nGetChar()==1) setCharacteristic( 0 );
471    else               setCharacteristic( -nGetChar() );
472    if (currRing->minpoly!=NULL)
473    {
474      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
475      Variable a=rootOf(mipo);
476      CanonicalForm F( convSingAPClapAP( f,a ) ), G( convSingAPClapAP( g,a ) );
477      res= convClapAPSingAP(  F / G  );
478    }
479    else
480    {
481      CanonicalForm F( convSingTrPClapP( f ) ), G( convSingTrPClapP( g ) );
482      res= convClapPSingTrP(  F / G  );
483    }
484  }
485  else
486    WerrorS( feNotImplemented );
487  Off(SW_RATIONAL);
488  return res;
489}
490
491void singclap_divide_content ( poly f )
492{
493  if ( f==NULL )
494  {
495    return;
496  }
497  else  if ( pNext( f ) == NULL )
498  {
499    pSetCoeff( f, nInit( 1 ) );
500    return;
501  }
502  else
503  {
504    if ( nGetChar() == 1 )
505      setCharacteristic( 0 );
506    else  if ( nGetChar() == -1 )
507      return; /* not implemented for R */
508    else  if ( nGetChar() < 0 )
509      setCharacteristic( -nGetChar() );
510    else if (currRing->parameter==NULL) /* not GF(q) */
511      setCharacteristic( nGetChar() );
512    else
513      return; /* not implemented*/
514
515    CFList L;
516    CanonicalForm g, h;
517    poly p = pNext(f);
518
519    // first attemp: find 2 smallest g:
520
521    number g1=pGetCoeff(f);
522    number g2=pGetCoeff(p); // p==pNext(f);
523    pIter(p);
524    int sz1=nSize(g1);
525    int sz2=nSize(g2);
526    if (sz1>sz2)
527    {
528      number gg=g1;
529      g1=g2; g2=gg;
530      int sz=sz1;
531      sz1=sz2; sz2=sz;
532    }
533    while (p!=NULL)
534    {
535      int n_sz=nSize(pGetCoeff(p));
536      if (n_sz<sz1)
537      {
538        sz2=sz1;
539        g2=g1;
540        g1=pGetCoeff(p);
541        sz1=n_sz;
542        if (sz1<=3) break;
543      }
544      else if(n_sz<sz2)
545      {
546        sz2=n_sz;
547        g2=pGetCoeff(p);
548        sz2=n_sz;
549      }
550      pIter(p);
551    }
552    FACTORY_ALGOUT( "G", ((lnumber)g1)->z );
553    g = convSingTrClapP( ((lnumber)g1)->z );
554    g = gcd( g, convSingTrClapP( ((lnumber)g2)->z ));
555
556    // second run: gcd's
557
558    p = f;
559    TIMING_START( contentTimer );
560    while ( (p != NULL) && (g != 1)  && ( g != 0))
561    {
562      FACTORY_ALGOUT( "h", (((lnumber)pGetCoeff(p))->z) );
563      h = convSingTrClapP( ((lnumber)pGetCoeff(p))->z );
564      pIter( p );
565#ifdef FACTORY_GCD_STAT
566      // save g
567      CanonicalForm gOld = g;
568#endif
569
570#ifdef FACTORY_GCD_TEST
571      g = CFPrimitiveGcdUtil::gcd( g, h );
572#else
573      g = gcd( g, h );
574#endif
575
576      FACTORY_GCDSTAT( "gcnt:", gOld, h, g );
577      FACTORY_CFTROUT( "g", g );
578      L.append( h );
579    }
580    TIMING_END( contentTimer );
581    FACTORY_CONTSTAT( "cont:", g );
582    if (( g == 1 ) || (g == 0))
583    {
584      // pTest(f);
585      return;
586    }
587    else
588    {
589      CFListIterator i;
590      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
591      {
592        lnumber c=(lnumber)pGetCoeff(p);
593        napDelete(&c->z);
594        c->z=convClapPSingTr( i.getItem() / g );
595        //nTest((number)c);
596        //#ifdef LDEBUG
597        //number cn=(number)c;
598        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
599        //nWrite(cn);PrintS(StringAppend("\n"));
600        //#endif
601      }
602    }
603    // pTest(f);
604  }
605}
606
607static int primepower(int c)
608{
609  int p=1;
610  int cc=c;
611  while(cc!= rInternalChar(currRing)) { cc*=c; p++; }
612  return p;
613}
614
615ideal singclap_factorize ( poly f, intvec ** v , int with_exps)
616{
617  // with_exps: 3,1 return only true factors, no exponents
618  //            2 return true factors and exponents
619  //            0 return coeff, factors and exponents
620
621  ideal res=NULL;
622
623  // handle factorize(0) =========================================
624  if (f==NULL)
625  {
626    res=idInit(1,1);
627    if (with_exps!=1)
628    {
629      (*v)=new intvec(1);
630      (**v)[0]=1;
631    }
632    return res;
633  }
634  // handle factorize(mon) =========================================
635  if (pNext(f)==NULL)
636  {
637    int i=0;
638    int n=0;
639    int e;
640    for(i=pVariables;i>0;i--) if(pGetExp(f,i)!=0) n++;
641    if (with_exps==0) n++; // with coeff
642    res=idInit(max(n,1),1);
643    switch(with_exps)
644    {
645      case 0: // with coef & exp.
646        res->m[0]=pOne();
647        pSetCoeff(res->m[0],nCopy(pGetCoeff(f)));
648        // no break
649      case 2: // with exp.
650        (*v)=new intvec(n);
651        (**v)[0]=1;
652        // no break
653      case 1: ;
654      #ifdef TEST
655      default: ;
656      #endif
657    }
658    if (n==0)
659    {
660      res->m[0]=pOne();
661      // (**v)[0]=1; is already done
662      return res;
663    }
664    for(i=pVariables;i>0;i--)
665    {
666      e=pGetExp(f,i);
667      if(e!=0)
668      {
669        n--;
670        poly p=pOne();
671        pSetExp(p,i,1);
672        pSetm(p);
673        res->m[n]=p;
674        if (with_exps!=1) (**v)[n]=e;
675      }
676    }
677    return res;
678  }
679  // use factory/libfac in general ==============================
680  Off(SW_RATIONAL);
681  On(SW_SYMMETRIC_FF);
682  CFFList L;
683  number N=NULL;
684  number NN=NULL;
685  number old_lead_coeff=nCopy(pGetCoeff(f));
686
687  if (rField_is_Q() || rField_is_Zp())
688  {
689    setCharacteristic( nGetChar() );
690    if (nGetChar()==0) /* Q */
691    {
692      //if (f!=NULL) // already tested at start of routine
693      {
694        number n0=nCopy(pGetCoeff(f));
695        if (with_exps==0)
696          N=nCopy(n0);
697        pCleardenom(f);
698        NN=nDiv(n0,pGetCoeff(f));
699        nDelete(&n0);
700        if (with_exps==0)
701        {
702          nDelete(&N);
703          N=nCopy(NN);
704        }
705      }
706    }
707    CanonicalForm F( convSingPClapP( f ) );
708    if (nGetChar()==0) /* Q */
709    {
710      L = factorize( F );
711    }
712    else /* Fp */
713    {
714#ifdef HAVE_LIBFAC_P
715      L = Factorize( F );
716#else
717      goto notImpl;
718#endif
719    }
720  }
721  #if 0
722  else if (rField_is_GF())
723  {
724    int c=rChar(currRing);
725    setCharacteristic( c, primepower(c) );
726    CanonicalForm F( convSingGFClapGF( f ) );
727    if (F.isUnivariate())
728    {
729      L = factorize( F );
730    }
731    else
732    {
733      goto notImpl;
734    }
735  }
736  #endif
737  // and over Q(a) / Fp(a)
738  else if (rField_is_Extension())
739  {
740    if (rField_is_Q_a()) setCharacteristic( 0 );
741    else                 setCharacteristic( -nGetChar() );
742    if ((currRing->minpoly!=NULL)
743    )
744    {
745      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
746      Variable a=rootOf(mipo);
747      CanonicalForm F( convSingAPClapAP( f,a ) );
748      L.insert(F);
749      if ((nGetChar()<(-1)) && F.isUnivariate())
750      {
751        L = factorize( F, a );
752      }
753      else
754      {
755        CanonicalForm G( convSingTrPClapP( f ) );
756#ifdef HAVE_LIBFAC_P
757        CFList as(mipo);
758        L = newfactoras( G, as, 1);
759#else
760        WarnS("complete factorization only for univariate polynomials");
761        if (nGetChar()==1) /* Q(a) */
762        {
763          L = factorize( G );
764        }
765        else
766        {
767          goto notImpl;
768        }
769#endif
770      }
771    }
772    else
773    {
774      CanonicalForm F( convSingTrPClapP( f ) );
775      if ((rField_is_Q_a())&&(currRing->minpoly!=NULL))
776      {
777        WarnS("factorization may be incomplete");
778        L = factorize( F );
779      }
780      else /* Fp(a) */
781      {
782#ifdef HAVE_LIBFAC_P
783        L = Factorize( F );
784#else
785        goto notImpl;
786#endif
787      }
788    }
789  }
790  else
791  {
792    goto notImpl;
793  }
794  {
795    // the first factor should be a constant
796    if ( ! L.getFirst().factor().inCoeffDomain() )
797      L.insert(CFFactor(1,1));
798    // convert into ideal
799    int n = L.length();
800    CFFListIterator J=L;
801    int j=0;
802    if (with_exps!=1)
803    {
804      if ((with_exps==2)&&(n>1))
805      {
806        n--;
807        J++;
808      }
809      *v = new intvec( n );
810    }
811    res = idInit( n ,1);
812    for ( ; J.hasItem(); J++, j++ )
813    {
814      if (with_exps!=1) (**v)[j] = J.getItem().exp();
815      if (rField_is_Zp() || rField_is_Q())           /* Q, Fp */
816        res->m[j] = convClapPSingP( J.getItem().factor() );
817      #if 0
818      else if (rField_is_GF())
819        res->m[j] = convClapGFSingGF( J.getItem().factor() );
820      #endif
821      else if (rField_is_Extension())     /* Q(a), Fp(a) */
822      {
823        if (currRing->minpoly==NULL)
824          res->m[j] = convClapPSingTrP( J.getItem().factor() );
825        else
826          res->m[j] = convClapAPSingAP( J.getItem().factor() );
827      }
828    }
829    if (N!=NULL)
830    {
831      pMult_nn(res->m[0],N);
832      nDelete(&N);
833      N=NULL;
834    }
835    // delete constants
836    if (res!=NULL)
837    {
838      int i=IDELEMS(res)-1;
839      int j=0;
840      for(;i>=0;i--)
841      {
842        if ((res->m[i]!=NULL)
843        && (pNext(res->m[i])==NULL)
844        && (pIsConstant(res->m[i])))
845        {
846          if (with_exps!=0)
847          {
848            pDelete(&(res->m[i]));
849            if ((v!=NULL) && ((*v)!=NULL))
850              (**v)[i]=0;
851            j++;
852          }
853          else if (i!=0)
854          {
855            res->m[0]=pMult(res->m[0],res->m[i]);
856            res->m[i]=NULL;
857            if ((v!=NULL) && ((*v)!=NULL))
858              (**v)[i]=0;
859            j++;
860          }
861        }
862      }
863      if (j>0)
864      {
865        idSkipZeroes(res);
866        if ((v!=NULL) && ((*v)!=NULL))
867        {
868          intvec *w=*v;
869          *v = new intvec( max(n-j,1) );
870          for (i=0,j=0;i<w->length();i++)
871          {
872            if((*w)[i]!=0)
873            {
874              (**v)[j]=(*w)[i]; j++;
875            }
876          }
877          delete w;
878        }
879      }
880      if (res->m[0]==NULL)
881      {
882        res->m[0]=pOne();
883      }
884    }
885  }
886  if (rField_is_Q_a() && (currRing->minpoly!=NULL))
887  {
888    int i=IDELEMS(res)-1;
889    for(;i>=1;i--)
890    {
891      pNorm(res->m[i]);
892    }
893    pSetCoeff(res->m[0],old_lead_coeff);
894  }
895  else
896    nDelete(&old_lead_coeff);
897notImpl:
898  if (res==NULL)
899    WerrorS( feNotImplemented );
900  if (NN!=NULL)
901  {
902    pMult_nn(f,NN);
903    nDelete(&NN);
904  }
905  if (N!=NULL)
906  {
907    nDelete(&N);
908  }
909  return res;
910}
911
912matrix singclap_irrCharSeries ( ideal I)
913{
914#ifdef HAVE_LIBFAC_P
915  // for now there is only the possibility to handle polynomials over
916  // Q and Fp ...
917  matrix res=NULL;
918  int i;
919  Off(SW_RATIONAL);
920  On(SW_SYMMETRIC_FF);
921  CFList L;
922  ListCFList LL;
923  if (((nGetChar() == 0) || (nGetChar() > 1) )
924  && (currRing->parameter==NULL))
925  {
926    setCharacteristic( nGetChar() );
927    for(i=0;i<IDELEMS(I);i++)
928    {
929      poly p=I->m[i];
930      if (p!=NULL)
931      {
932        p=pCopy(p);
933        pCleardenom(p);
934        L.append(convSingPClapP(p));
935      }
936    }
937  }
938  // and over Q(a) / Fp(a)
939  else if (( nGetChar()==1 ) /* Q(a) */
940  || (nGetChar() <-1))       /* Fp(a) */
941  {
942    if (nGetChar()==1) setCharacteristic( 0 );
943    else               setCharacteristic( -nGetChar() );
944    for(i=0;i<IDELEMS(I);i++)
945    {
946      poly p=I->m[i];
947      if (p!=NULL)
948      {
949        p=pCopy(p);
950        pCleardenom(p);
951        L.append(convSingTrPClapP(p));
952      }
953    }
954  }
955  else
956  {
957    WerrorS( feNotImplemented );
958    return res;
959  }
960
961  // a very bad work-around --- FIX IT in libfac
962  // should be fixed as of 2001/6/27
963  int tries=0;
964  int m,n;
965  ListIterator<CFList> LLi;
966  loop
967  {
968    LL=IrrCharSeries(L);
969    m= LL.length(); // Anzahl Zeilen
970    n=0;
971    for ( LLi = LL; LLi.hasItem(); LLi++ )
972    {
973      n = max(LLi.getItem().length(),n);
974    }
975    if ((m!=0) && (n!=0)) break;
976    tries++;
977    if (tries>=5) break;
978  }
979  if ((m==0) || (n==0))
980  {
981    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
982      m,n,IDELEMS(I)+1,LL.length());
983    iiWriteMatrix((matrix)I,"I",2,0);
984    m=max(m,1);
985    n=max(n,1);
986  }
987  res=mpNew(m,n);
988  CFListIterator Li;
989  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
990  {
991    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
992    {
993      if ( (nGetChar() == 0) || (nGetChar() > 1) )
994        MATELEM(res,m,n)=convClapPSingP(Li.getItem());
995      else
996        MATELEM(res,m,n)=convClapPSingTrP(Li.getItem());
997    }
998  }
999  Off(SW_RATIONAL);
1000  return res;
1001#else
1002  return NULL;
1003#endif
1004}
1005
1006char* singclap_neworder ( ideal I)
1007{
1008#ifdef HAVE_LIBFAC_P
1009  int i;
1010  Off(SW_RATIONAL);
1011  On(SW_SYMMETRIC_FF);
1012  CFList L;
1013  if (((nGetChar() == 0) || (nGetChar() > 1) )
1014  && (currRing->parameter==NULL))
1015  {
1016    setCharacteristic( nGetChar() );
1017    for(i=0;i<IDELEMS(I);i++)
1018    {
1019      L.append(convSingPClapP(I->m[i]));
1020    }
1021  }
1022  // and over Q(a) / Fp(a)
1023  else if (( nGetChar()==1 ) /* Q(a) */
1024  || (nGetChar() <-1))       /* Fp(a) */
1025  {
1026    if (nGetChar()==1) setCharacteristic( 0 );
1027    else               setCharacteristic( -nGetChar() );
1028    for(i=0;i<IDELEMS(I);i++)
1029    {
1030      L.append(convSingTrPClapP(I->m[i]));
1031    }
1032  }
1033  else
1034  {
1035    WerrorS( feNotImplemented );
1036    return NULL;
1037  }
1038
1039  List<int> IL=neworderint(L);
1040  ListIterator<int> Li;
1041  StringSetS("");
1042  Li = IL;
1043  int offs=rPar(currRing);
1044  int* mark=(int*)omAlloc0((pVariables+offs)*sizeof(int));
1045  int cnt=pVariables+offs;
1046  loop
1047  {
1048    i=Li.getItem()-1;
1049    mark[i]=1;
1050    if (i<offs)
1051    {
1052      StringAppendS(currRing->parameter[i]);
1053    }
1054    else
1055    {
1056      StringAppendS(currRing->names[i-offs]);
1057    }
1058    Li++;
1059    cnt--;
1060    if(cnt==0) break;
1061    StringAppendS(",");
1062    if(! Li.hasItem()) break;
1063  }
1064  for(i=0;i<pVariables+offs;i++)
1065  {
1066    if(mark[i]==0)
1067    {
1068      if (i<offs)
1069      {
1070        StringAppendS(currRing->parameter[i]);
1071      }
1072      else
1073      {
1074        StringAppendS(currRing->names[i-offs]);
1075      }
1076      cnt--;
1077      if(cnt==0) break;
1078      StringAppendS(",");
1079    }
1080  }
1081  return omStrDup(StringAppendS(""));
1082#else
1083  return NULL;
1084#endif
1085}
1086
1087BOOLEAN singclap_isSqrFree(poly f)
1088{
1089  BOOLEAN b=FALSE;
1090  Off(SW_RATIONAL);
1091  //  Q / Fp
1092  if (((nGetChar() == 0) || (nGetChar() > 1) )
1093  &&(currRing->parameter==NULL))
1094  {
1095    setCharacteristic( nGetChar() );
1096    CanonicalForm F( convSingPClapP( f ) );
1097    if((nGetChar()>1)&&(!F.isUnivariate()))
1098      goto err;
1099    b=(BOOLEAN)isSqrFree(F);
1100  }
1101  // and over Q(a) / Fp(a)
1102  else if (( nGetChar()==1 ) /* Q(a) */
1103  || (nGetChar() <-1))       /* Fp(a) */
1104  {
1105    if (nGetChar()==1) setCharacteristic( 0 );
1106    else               setCharacteristic( -nGetChar() );
1107    //if (currRing->minpoly!=NULL)
1108    //{
1109    //  CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1110    //  Variable a=rootOf(mipo);
1111    //  CanonicalForm F( convSingAPClapAP( f,a ) );
1112    //  ...
1113    //}
1114    //else
1115    {
1116      CanonicalForm F( convSingTrPClapP( f ) );
1117      b=(BOOLEAN)isSqrFree(F);
1118    }
1119    Off(SW_RATIONAL);
1120  }
1121  else
1122  {
1123err:
1124    WerrorS( feNotImplemented );
1125  }
1126  return b;
1127}
1128
1129poly singclap_det( const matrix m )
1130{
1131  int r=m->rows();
1132  if (r!=m->cols())
1133  {
1134    Werror("det of %d x %d matrix",r,m->cols());
1135    return NULL;
1136  }
1137  poly res=NULL;
1138  if (( nGetChar() == 0 || nGetChar() > 1 )
1139  && (currRing->parameter==NULL))
1140  {
1141    setCharacteristic( nGetChar() );
1142    CFMatrix M(r,r);
1143    int i,j;
1144    for(i=r;i>0;i--)
1145    {
1146      for(j=r;j>0;j--)
1147      {
1148        M(i,j)=convSingPClapP(MATELEM(m,i,j));
1149      }
1150    }
1151    res= convClapPSingP( determinant(M,r) ) ;
1152  }
1153  // and over Q(a) / Fp(a)
1154  else if (( nGetChar()==1 ) /* Q(a) */
1155  || (nGetChar() <-1))       /* Fp(a) */
1156  {
1157    if (nGetChar()==1) setCharacteristic( 0 );
1158    else               setCharacteristic( -nGetChar() );
1159    CFMatrix M(r,r);
1160    poly res;
1161    if (currRing->minpoly!=NULL)
1162    {
1163      CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1164      Variable a=rootOf(mipo);
1165      int i,j;
1166      for(i=r;i>0;i--)
1167      {
1168        for(j=r;j>0;j--)
1169        {
1170          M(i,j)=convSingAPClapAP(MATELEM(m,i,j),a);
1171        }
1172      }
1173      res= convClapAPSingAP( determinant(M,r) ) ;
1174    }
1175    else
1176    {
1177      int i,j;
1178      for(i=r;i>0;i--)
1179      {
1180        for(j=r;j>0;j--)
1181        {
1182          M(i,j)=convSingTrPClapP(MATELEM(m,i,j));
1183        }
1184      }
1185      res= convClapPSingTrP( determinant(M,r) );
1186    }
1187  }
1188  else
1189    WerrorS( feNotImplemented );
1190  Off(SW_RATIONAL);
1191  return res;
1192}
1193
1194int singclap_det_i( intvec * m )
1195{
1196  setCharacteristic( 0 );
1197  CFMatrix M(m->rows(),m->cols());
1198  int i,j;
1199  for(i=m->rows();i>0;i--)
1200  {
1201    for(j=m->cols();j>0;j--)
1202    {
1203      M(i,j)=IMATELEM(*m,i,j);
1204    }
1205  }
1206  int res= convClapISingI( determinant(M,m->rows())) ;
1207  Off(SW_RATIONAL);
1208  return res;
1209}
1210/*==============================================================*/
1211/* interpreter interface : */
1212BOOLEAN jjGCD_P(leftv res, leftv u, leftv v)
1213{
1214  res->data=(void *)singclap_gcd((poly)(u->CopyD(POLY_CMD)),
1215                                 (poly)(v->CopyD(POLY_CMD)));
1216  return FALSE;
1217}
1218
1219BOOLEAN jjFAC_P(leftv res, leftv u)
1220{
1221  intvec *v=NULL;
1222  ideal f=singclap_factorize((poly)(u->Data()), &v, 0);
1223  if (f==NULL) return TRUE;
1224  ivTest(v);
1225  lists l=(lists)omAllocBin(slists_bin);
1226  l->Init(2);
1227  l->m[0].rtyp=IDEAL_CMD;
1228  l->m[0].data=(void *)f;
1229  l->m[1].rtyp=INTVEC_CMD;
1230  l->m[1].data=(void *)v;
1231  res->data=(void *)l;
1232  return FALSE;
1233}
1234
1235BOOLEAN jjSQR_FREE_DEC(leftv res, leftv u,leftv dummy)
1236{
1237  intvec *v=NULL;
1238  int sw=(int)dummy->Data();
1239  int fac_sw=sw;
1240  if ((sw<0)||(sw>2)) fac_sw=1;
1241  ideal f=singclap_factorize((poly)(u->Data()), &v, fac_sw);
1242  if (f==NULL)
1243    return TRUE;
1244  switch(sw)
1245  {
1246    case 0:
1247    case 2:
1248    {
1249      lists l=(lists)omAllocBin(slists_bin);
1250      l->Init(2);
1251      l->m[0].rtyp=IDEAL_CMD;
1252      l->m[0].data=(void *)f;
1253      l->m[1].rtyp=INTVEC_CMD;
1254      l->m[1].data=(void *)v;
1255      res->data=(void *)l;
1256      res->rtyp=LIST_CMD;
1257      return FALSE;
1258    }
1259    case 1:
1260      res->data=(void *)f;
1261      return FALSE;
1262    case 3:
1263      {
1264        poly p=f->m[0];
1265        int i=IDELEMS(f);
1266        f->m[0]=NULL;
1267        while(i>1)
1268        {
1269          i--;
1270          p=pMult(p,f->m[i]);
1271          f->m[i]=NULL;
1272        }
1273        res->data=(void *)p;
1274        res->rtyp=POLY_CMD;
1275      }
1276      return FALSE;
1277  }
1278  WerrorS("invalid switch");
1279  return TRUE;
1280}
1281
1282#if 0
1283BOOLEAN jjIS_SQR_FREE(leftv res, leftv u)
1284{
1285  BOOLEAN b=singclap_factorize((poly)(u->Data()), &v, 0);
1286  res->data=(void *)b;
1287}
1288#endif
1289
1290BOOLEAN jjEXTGCD_P(leftv res, leftv u, leftv v)
1291{
1292  res->data=singclap_extgcd((poly)u->Data(),(poly)v->Data());
1293  return (res->data==NULL);
1294}
1295BOOLEAN jjRESULTANT(leftv res, leftv u, leftv v, leftv w)
1296{
1297  res->data=singclap_resultant((poly)u->Data(),(poly)v->Data(), (poly)w->Data());
1298  return errorreported;
1299}
1300BOOLEAN jjCHARSERIES(leftv res, leftv u)
1301{
1302  res->data=singclap_irrCharSeries((ideal)u->Data());
1303  return (res->data==NULL);
1304}
1305
1306napoly singclap_alglcm ( napoly f, napoly g )
1307{
1308 FACTORY_ALGOUT( "f", f );
1309 FACTORY_ALGOUT( "g", g );
1310
1311 // over Q(a) / Fp(a)
1312 if (nGetChar()==1) setCharacteristic( 0 );
1313 else               setCharacteristic( -nGetChar() );
1314 napoly res;
1315
1316 if (currRing->minpoly!=NULL)
1317 {
1318   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1319   Variable a=rootOf(mipo);
1320   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1321   CanonicalForm GCD;
1322
1323   TIMING_START( algLcmTimer );
1324   // calculate gcd
1325#ifdef FACTORY_GCD_TEST
1326   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1327#else
1328   GCD = gcd( F, G );
1329#endif
1330   TIMING_END( algLcmTimer );
1331
1332   FACTORY_CFAOUT( "d", GCD );
1333   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1334
1335   // calculate lcm
1336   res= convClapASingA( (F/GCD)*G );
1337 }
1338 else
1339 {
1340   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1341   CanonicalForm GCD;
1342   TIMING_START( algLcmTimer );
1343   // calculate gcd
1344#ifdef FACTORY_GCD_TEST
1345   GCD = CFPrimitiveGcdUtil::gcd( F, G );
1346#else
1347   GCD = gcd( F, G );
1348#endif
1349   TIMING_END( algLcmTimer );
1350
1351   FACTORY_CFTROUT( "d", GCD );
1352   FACTORY_GCDSTAT( "alcm:", F, G, GCD );
1353
1354   // calculate lcm
1355   res= convClapPSingTr( (F/GCD)*G );
1356 }
1357
1358 Off(SW_RATIONAL);
1359 return res;
1360}
1361
1362void singclap_algdividecontent ( napoly f, napoly g, napoly &ff, napoly &gg )
1363{
1364 FACTORY_ALGOUT( "f", f );
1365 FACTORY_ALGOUT( "g", g );
1366
1367 // over Q(a) / Fp(a)
1368 if (nGetChar()==1) setCharacteristic( 0 );
1369 else               setCharacteristic( -nGetChar() );
1370 ff=gg=NULL;
1371 On(SW_RATIONAL);
1372
1373 if (currRing->minpoly!=NULL)
1374 {
1375   CanonicalForm mipo=convSingTrClapP(((lnumber)currRing->minpoly)->z);
1376   Variable a=rootOf(mipo);
1377   CanonicalForm F( convSingAClapA( f,a ) ), G( convSingAClapA( g,a ) );
1378   CanonicalForm GCD;
1379
1380   TIMING_START( algContentTimer );
1381#ifdef FACTORY_GCD_TEST
1382   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1383#else
1384   GCD=gcd( F, G );
1385#endif
1386   TIMING_END( algContentTimer );
1387
1388   FACTORY_CFAOUT( "d", GCD );
1389   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1390
1391   if ((GCD!=1) && (GCD!=0))
1392   {
1393     ff= convClapASingA( F/ GCD );
1394     gg= convClapASingA( G/ GCD );
1395   }
1396 }
1397 else
1398 {
1399   CanonicalForm F( convSingTrClapP( f ) ), G( convSingTrClapP( g ) );
1400   CanonicalForm GCD;
1401
1402   TIMING_START( algContentTimer );
1403#ifdef FACTORY_GCD_TEST
1404   GCD=CFPrimitiveGcdUtil::gcd( F, G );
1405#else
1406   GCD=gcd( F, G );
1407#endif
1408   TIMING_END( algContentTimer );
1409
1410   FACTORY_CFTROUT( "d", GCD );
1411   FACTORY_GCDSTAT( "acnt:", F, G, GCD );
1412
1413   if ((GCD!=1) && (GCD!=0))
1414   {
1415     ff= convClapPSingTr( F/ GCD );
1416     gg= convClapPSingTr( G/ GCD );
1417   }
1418 }
1419
1420 Off(SW_RATIONAL);
1421}
1422
1423lists singclap_chineseRemainder(lists x, lists q)
1424{
1425  //assume(x->nr == q->nr);
1426  //assume(x->nr >= 0);
1427  int n=x->nr+1;
1428  if ((x->nr<0) || (x->nr!=q->nr))
1429  {
1430    WerrorS("list are empty or not of equal length");
1431    return NULL;
1432  }
1433  lists res=(lists)omAlloc0Bin(slists_bin);
1434  CFArray X(1,n), Q(1,n);
1435  int i;
1436  for(i=0; i<n; i++)
1437  {
1438    if (x->m[i-1].Typ()==INT_CMD)
1439    {
1440      X[i]=(int)x->m[i-1].Data();
1441    }
1442    else if (x->m[i-1].Typ()==NUMBER_CMD)
1443    {
1444      number N=(number)x->m[i-1].Data();
1445      X[i]=convSingNClapN(N);
1446    }
1447    else
1448    {
1449      WerrorS("illegal type in chineseRemainder");
1450      omFreeBin(res,slists_bin);
1451      return NULL;
1452    }
1453    if (q->m[i-1].Typ()==INT_CMD)
1454    {
1455      Q[i]=(int)q->m[i-1].Data();
1456    }
1457    else if (q->m[i-1].Typ()==NUMBER_CMD)
1458    {
1459      number N=(number)x->m[i-1].Data();
1460      Q[i]=convSingNClapN(N);
1461    }
1462    else
1463    {
1464      WerrorS("illegal type in chineseRemainder");
1465      omFreeBin(res,slists_bin);
1466      return NULL;
1467    }
1468  }
1469  CanonicalForm r, prod;
1470  chineseRemainder( X, Q, r, prod );
1471  res->Init(2);
1472  res->m[0].rtyp=NUMBER_CMD;
1473  res->m[1].rtyp=NUMBER_CMD;
1474  res->m[0].data=(char *)convClapNSingN( r );
1475  res->m[1].data=(char *)convClapNSingN( prod );
1476  return res;
1477}
1478#endif
Note: See TracBrowser for help on using the repository browser.