source: git/Singular/clapsing.cc @ 28e0ac8

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