source: git/libpolys/polys/clapsing.cc @ 7f7808

spielwiese
Last change on this file since 7f7808 was 7f7808, checked in by Hans Schoenemann <hannes@…>, 9 years ago
minor optimizations for numbers
  • Property mode set to 100644
File size: 41.4 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5/*
6* ABSTRACT: interface between Singular and factory
7*/
8
9//#define FACTORIZE2_DEBUG
10
11
12
13
14
15
16
17#include <misc/auxiliary.h>
18#include "clapsing.h"
19
20#include <factory/factory.h>
21
22#include <omalloc/omalloc.h>
23#include <coeffs/numbers.h>
24#include <coeffs/coeffs.h>
25#include <coeffs/bigintmat.h>
26
27// #include <kernel/ffields.h>
28
29#include "monomials/ring.h"
30#include "simpleideals.h"
31
32
33//#include "polys.h"
34#define TRANSEXT_PRIVATES
35
36#include "ext_fields/transext.h"
37
38
39#include "clapconv.h"
40// #include <kernel/clapconv.h>
41
42#include <polys/monomials/p_polys.h>
43#include <polys/monomials/ring.h>
44#include <polys/simpleideals.h>
45#include <misc/intvec.h>
46#include <polys/matpol.h>
47#include <coeffs/bigintmat.h>
48
49
50void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
51
52poly singclap_gcd_r ( poly f, poly g, const ring r )
53{
54  poly res=NULL;
55
56  assume(f!=NULL);
57  assume(g!=NULL);
58
59  if(pNext(f)==NULL && pNext(g)==NULL)
60  {
61    poly p=p_One(r);
62    for(int i=rVar(r);i>0;i--)
63      p_SetExp(p,i,si_min(p_GetExp(f,i,r),p_GetExp(g,i,r)),r);
64    if (rField_is_Ring(r))
65    {
66      number c = p_GetCoeff(f,r);
67      number d = p_GetCoeff(g,r);
68      p_SetCoeff(p,n_Gcd(c,d,r->cf),r);
69    }
70    p_Setm(p,r);
71    return p;
72#if 0
73    else
74    {
75      poly h=g;
76      for(int i=rVar(r);i>0;i--)
77        p_SetExp(p,i,p_GetExp(f,i,r),r);
78      while(h!=NULL)
79      {
80        for(int i=rVar(r);i>0;i--)
81          p_SetExp(p,i,si_min(p_GetExp(p,i,r),p_GetExp(h,i,r)),r);
82        pIter(h);
83      }
84      p_Setm(p,r);
85      return p;
86    }
87#endif
88  }
89#if 0
90  else if (pNext(g)==NULL)
91  {
92    poly p=p_One(r);
93    poly h=f;
94    for(int i=rVar(r);i>0;i--)
95      p_SetExp(p,i,p_GetExp(g,i,r),r);
96    if (rField_is_Ring(r))
97    {
98      number c = p_GetCoeff(f,r);
99      number d = p_GetCoeff(g,r);
100      p_SetCoeff(p,n_Gcd(c,d,r->cf),r);
101    }
102    while(h!=NULL)
103    {
104      for(int i=rVar(r);i>0;i--)
105        p_SetExp(p,i,si_min(p_GetExp(p,i,r),p_GetExp(h,i,r)),r);
106      pIter(h);
107    }
108    p_Setm(p,r);
109    return p;
110  }
111#endif
112
113  Off(SW_RATIONAL);
114  if (rField_is_Q(r) || rField_is_Zp(r) || rField_is_Ring_Z(r))
115  {
116    setCharacteristic( rChar(r) );
117    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g, r ) );
118    res=convFactoryPSingP( gcd( F, G ) , r);
119  }
120  // and over Q(a) / Fp(a)
121  else if ( r->cf->extRing!=NULL )
122  {
123    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
124    else                   setCharacteristic( rChar(r) );
125    if (r->cf->extRing->qideal!=NULL)
126    {
127      bool b1=isOn(SW_USE_QGCD);
128      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
129      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
130                                           r->cf->extRing);
131      Variable a=rootOf(mipo);
132      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
133                    G( convSingAPFactoryAP( g,a,r ) );
134      res= convFactoryAPSingAP( gcd( F, G ),r );
135      prune (a);
136      if (!b1) Off(SW_USE_QGCD);
137    }
138    else
139    {
140      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
141      res= convFactoryPSingTrP( gcd( F, G ),r );
142    }
143  }
144  else
145    WerrorS( feNotImplemented );
146  Off(SW_RATIONAL);
147  return res;
148}
149
150poly singclap_gcd_and_divide ( poly& f, poly& g, const ring r)
151{
152  poly res=NULL;
153
154  if (g == NULL)
155  {
156    res= f;
157    f=p_One (r);
158    return res;
159  }
160  if (f==NULL)
161  {
162    res= g;
163    g=p_One (r);
164    return res;
165  }
166
167  Off(SW_RATIONAL);
168  CanonicalForm F,G,GCD;
169  if (rField_is_Q(r) || (rField_is_Zp(r)))
170  {
171    bool b1=isOn(SW_USE_EZGCD_P);
172    F=convSingPFactoryP( f,r );
173    G=convSingPFactoryP( g,r );
174    GCD=gcd(F,G);
175    if (!GCD.isOne())
176    {
177      p_Delete(&f,r);
178      p_Delete(&g,r);
179      if (getCharacteristic() == 0)
180        On (SW_RATIONAL);
181      F /= GCD;
182      G /= GCD;
183      if (getCharacteristic() == 0)
184      {
185        CanonicalForm denF= bCommonDen (F);
186        CanonicalForm denG= bCommonDen (G);
187        G *= denG;
188        F *= denF;
189        Off (SW_RATIONAL);
190        CanonicalForm gcddenFdenG= gcd (denG, denF);
191        denG /= gcddenFdenG;
192        denF /= gcddenFdenG;
193        On (SW_RATIONAL);
194        G *= denF;
195        F *= denG;
196      }
197      f=convFactoryPSingP( F, r);
198      g=convFactoryPSingP( G, r);
199    }
200    res=convFactoryPSingP( GCD , r);
201    if (!b1) Off (SW_USE_EZGCD_P);
202  }
203  // and over Q(a) / Fp(a)
204  else if ( r->cf->extRing )
205  {
206    if ( rField_is_Q_a(r)) setCharacteristic( 0 );
207    else                   setCharacteristic( rChar(r) );
208    if (r->cf->extRing->qideal!=NULL)
209    {
210      bool b1=isOn(SW_USE_QGCD);
211      if ( rField_is_Q_a(r) ) On(SW_USE_QGCD);
212      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
213                                           r->cf->extRing);
214      Variable a=rootOf(mipo);
215      F=( convSingAPFactoryAP( f,a,r ) );
216      G=( convSingAPFactoryAP( g,a,r ) );
217      GCD=gcd(F,G);
218      if (!GCD.isOne())
219      {
220        p_Delete(&f,r);
221        p_Delete(&g,r);
222        if (getCharacteristic() == 0)
223          On (SW_RATIONAL);
224        F /= GCD;
225        G /= GCD;
226        if (getCharacteristic() == 0)
227        {
228          CanonicalForm denF= bCommonDen (F);
229          CanonicalForm denG= bCommonDen (G);
230          G *= denG;
231          F *= denF;
232          Off (SW_RATIONAL);
233          CanonicalForm gcddenFdenG= gcd (denG, denF);
234          denG /= gcddenFdenG;
235          denF /= gcddenFdenG;
236          On (SW_RATIONAL);
237          G *= denF;
238          F *= denG;
239        }
240        f= convFactoryAPSingAP( F,r );
241        g= convFactoryAPSingAP( G,r );
242      }
243      res= convFactoryAPSingAP( GCD,r );
244      prune (a);
245      if (!b1) Off(SW_USE_QGCD);
246    }
247    else
248    {
249      F=( convSingTrPFactoryP( f,r ) );
250      G=( convSingTrPFactoryP( g,r ) );
251      GCD=gcd(F,G);
252      if (!GCD.isOne())
253      {
254        p_Delete(&f,r);
255        p_Delete(&g,r);
256        if (getCharacteristic() == 0)
257          On (SW_RATIONAL);
258        F /= GCD;
259        G /= GCD;
260        if (getCharacteristic() == 0)
261        {
262          CanonicalForm denF= bCommonDen (F);
263          CanonicalForm denG= bCommonDen (G);
264          G *= denG;
265          F *= denF;
266          Off (SW_RATIONAL);
267          CanonicalForm gcddenFdenG= gcd (denG, denF);
268          denG /= gcddenFdenG;
269          denF /= gcddenFdenG;
270          On (SW_RATIONAL);
271          G *= denF;
272          F *= denG;
273        }
274        f= convFactoryPSingTrP( F,r );
275        g= convFactoryPSingTrP( G,r );
276      }
277      res= convFactoryPSingTrP( GCD,r );
278    }
279  }
280  else
281    WerrorS( feNotImplemented );
282  Off(SW_RATIONAL);
283  return res;
284}
285
286poly singclap_gcd ( poly f, poly g, const ring r)
287{
288  poly res=NULL;
289
290  if (f!=NULL) p_Cleardenom(f, r);
291  if (g!=NULL) p_Cleardenom(g, r);
292  else         return f; // g==0 => gcd=f (but do a p_Cleardenom)
293  if (f==NULL) return g; // f==0 => gcd=g (but do a p_Cleardenom)
294
295  res=singclap_gcd_r(f,g,r);
296  p_Delete(&f, r);
297  p_Delete(&g, r);
298  return res;
299}
300
301/*2 find the maximal exponent of var(i) in poly p*/
302int pGetExp_Var(poly p, int i, const ring r)
303{
304  int m=0;
305  int mm;
306  while (p!=NULL)
307  {
308    mm=p_GetExp(p,i,r);
309    if (mm>m) m=mm;
310    pIter(p);
311  }
312  return m;
313}
314
315// destroys f,g,x
316poly singclap_resultant ( poly f, poly g , poly x, const ring r)
317{
318  poly res=NULL;
319  int i=p_IsPurePower(x, r);
320  if (i==0)
321  {
322    WerrorS("3rd argument must be a ring variable");
323    goto resultant_returns_res;
324  }
325  if ((f==NULL) || (g==NULL))
326    goto resultant_returns_res;
327  // for now there is only the possibility to handle polynomials over
328  // Q and Fp ...
329  if (rField_is_Zp(r) || rField_is_Q(r))
330  {
331    Variable X(i);
332    setCharacteristic( rChar(r) );
333    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
334    res=convFactoryPSingP( resultant( F, G, X),r );
335    Off(SW_RATIONAL);
336    goto resultant_returns_res;
337  }
338  // and over Q(a) / Fp(a)
339  else if (r->cf->extRing!=NULL)
340  {
341    if (rField_is_Q_a(r)) setCharacteristic( 0 );
342    else               setCharacteristic( rChar(r) );
343    Variable X(i+rPar(r));
344    if (r->cf->extRing->qideal!=NULL)
345    {
346      //Variable X(i);
347      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
348                                           r->cf->extRing);
349      Variable a=rootOf(mipo);
350      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
351                    G( convSingAPFactoryAP( g,a,r ) );
352      res= convFactoryAPSingAP( resultant( F, G, X ),r );
353      prune (a);
354    }
355    else
356    {
357      //Variable X(i+rPar(currRing));
358      number nf,ng;
359      p_Cleardenom_n(f,r,nf);p_Cleardenom_n(g,r,ng);
360      int ef,eg;
361      ef=pGetExp_Var(f,i,r);
362      eg=pGetExp_Var(g,i,r);
363      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
364      res= convFactoryPSingTrP( resultant( F, G, X ),r );
365      if ((nf!=NULL)&&(!n_IsOne(nf,r->cf)))
366      {
367        number n=n_Invers(nf,r->cf);
368        while(eg>0)
369        {
370          res=p_Mult_nn(res,n,r);
371          eg--;
372        }
373        n_Delete(&n,r->cf);
374      }
375      n_Delete(&nf,r->cf);
376      if ((ng!=NULL)&&(!n_IsOne(ng,r->cf)))
377      {
378        number n=n_Invers(ng,r->cf);
379        while(ef>0)
380        {
381          res=p_Mult_nn(res,n,r);
382          ef--;
383        }
384        n_Delete(&n,r->cf);
385      }
386      n_Delete(&ng,r->cf);
387    }
388    Off(SW_RATIONAL);
389    goto resultant_returns_res;
390  }
391  else
392    WerrorS( feNotImplemented );
393resultant_returns_res:
394  p_Delete(&f,r);
395  p_Delete(&g,r);
396  p_Delete(&x,r);
397  return res;
398}
399//poly singclap_resultant ( poly f, poly g , poly x)
400//{
401//  int i=pVar(x);
402//  if (i==0)
403//  {
404//    WerrorS("ringvar expected");
405//    return NULL;
406//  }
407//  ideal I=idInit(1,1);
408//
409//  // get the coeffs von f wrt. x:
410//  I->m[0]=pCopy(f);
411//  matrix ffi=mpCoeffs(I,i);
412//  ffi->rank=1;
413//  ffi->ncols=ffi->nrows;
414//  ffi->nrows=1;
415//  ideal fi=(ideal)ffi;
416//
417//  // get the coeffs von g wrt. x:
418//  I->m[0]=pCopy(g);
419//  matrix ggi=mpCoeffs(I,i);
420//  ggi->rank=1;
421//  ggi->ncols=ggi->nrows;
422//  ggi->nrows=1;
423//  ideal gi=(ideal)ggi;
424//
425//  // contruct the matrix:
426//  int fn=IDELEMS(fi); //= deg(f,x)+1
427//  int gn=IDELEMS(gi); //= deg(g,x)+1
428//  matrix m=mpNew(fn+gn-2,fn+gn-2);
429//  if(m==NULL)
430//  {
431//    return NULL;
432//  }
433//
434//  // enter the coeffs into m:
435//  int j;
436//  for(i=0;i<gn-1;i++)
437//  {
438//    for(j=0;j<fn;j++)
439//    {
440//      MATELEM(m,i+1,fn-j+i)=pCopy(fi->m[j]);
441//    }
442//  }
443//  for(i=0;i<fn-1;i++)
444//  {
445//    for(j=0;j<gn;j++)
446//    {
447//      MATELEM(m,gn+i,gn-j+i)=pCopy(gi->m[j]);
448//    }
449//  }
450//
451//  poly r=mpDet(m);
452//
453//  idDelete(&fi);
454//  idDelete(&gi);
455//  idDelete((ideal *)&m);
456//  return r;
457//}
458
459BOOLEAN singclap_extgcd ( poly f, poly g, poly &res, poly &pa, poly &pb , const ring r)
460{
461  // for now there is only the possibility to handle univariate
462  // polynomials over
463  // Q and Fp ...
464  res=NULL;pa=NULL;pb=NULL;
465  On(SW_SYMMETRIC_FF);
466  if ( rField_is_Q(r) || rField_is_Zp(r) )
467  {
468    setCharacteristic( rChar(r) );
469    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r) );
470    CanonicalForm FpG=F+G;
471    if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
472    //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
473    {
474      Off(SW_RATIONAL);
475      WerrorS("not univariate");
476      return TRUE;
477    }
478    CanonicalForm Fa,Gb;
479    On(SW_RATIONAL);
480    res=convFactoryPSingP( extgcd( F, G, Fa, Gb ),r );
481    pa=convFactoryPSingP(Fa,r);
482    pb=convFactoryPSingP(Gb,r);
483    Off(SW_RATIONAL);
484  }
485  // and over Q(a) / Fp(a)
486  else if ( r->cf->extRing!=NULL )
487  {
488    if (rField_is_Q_a(r)) setCharacteristic( 0 );
489    else                 setCharacteristic( rChar(r) );
490    CanonicalForm Fa,Gb;
491    if (r->cf->extRing->qideal!=NULL)
492    {
493      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
494                                           r->cf->extRing);
495      Variable a=rootOf(mipo);
496      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
497                    G( convSingAPFactoryAP( g,a,r ) );
498      CanonicalForm FpG=F+G;
499      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
500      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
501      {
502        WerrorS("not univariate");
503        return TRUE;
504      }
505      res= convFactoryAPSingAP( extgcd( F, G, Fa, Gb ),r );
506      pa=convFactoryAPSingAP(Fa,r);
507      pb=convFactoryAPSingAP(Gb,r);
508      prune (a);
509    }
510    else
511    {
512      CanonicalForm F( convSingTrPFactoryP( f, r ) ), G( convSingTrPFactoryP( g, r ) );
513      CanonicalForm FpG=F+G;
514      if (!(FpG.isUnivariate()|| FpG.inCoeffDomain()))
515      //if (!F.isUnivariate() || !G.isUnivariate() || F.mvar()!=G.mvar())
516      {
517        Off(SW_RATIONAL);
518        WerrorS("not univariate");
519        return TRUE;
520      }
521      res= convFactoryPSingTrP( extgcd( F, G, Fa, Gb ), r );
522      pa=convFactoryPSingTrP(Fa, r);
523      pb=convFactoryPSingTrP(Gb, r);
524    }
525    Off(SW_RATIONAL);
526  }
527  else
528  {
529    WerrorS( feNotImplemented );
530    return TRUE;
531  }
532#ifndef SING_NDEBUG
533  // checking the result of extgcd:
534  poly dummy;
535  dummy=p_Sub(p_Add_q(pp_Mult_qq(f,pa,r),pp_Mult_qq(g,pb,r),r),p_Copy(res,r),r);
536  if (dummy!=NULL)
537  {
538    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
539    PrintS("extgcd( ");p_Write(f,r);p_Write0(g,r);PrintS(" )\n");
540    p_Delete(&dummy,r);
541  }
542#endif
543  return FALSE;
544}
545
546poly singclap_pdivide ( poly f, poly g, const ring r )
547{
548  poly res=NULL;
549  On(SW_RATIONAL);
550  if (rField_is_Zp(r) || rField_is_Q(r))
551  {
552    setCharacteristic( rChar(r) );
553    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
554    res = convFactoryPSingP( F / G,r );
555  }
556  else if (rField_is_Ring_Z(r))
557  {
558    Off(SW_RATIONAL);
559    setCharacteristic( rChar(r) );
560    CanonicalForm F( convSingPFactoryP( f,r ) ), G( convSingPFactoryP( g,r ) );
561    res = convFactoryPSingP( F / G,r );
562  }
563  else if (r->cf->extRing!=NULL)
564  {
565    if (rField_is_Q_a(r)) setCharacteristic( 0 );
566    else               setCharacteristic( rChar(r) );
567    if (r->cf->extRing->qideal!=NULL)
568    {
569      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
570                                                 r->cf->extRing);
571      Variable a=rootOf(mipo);
572      CanonicalForm F( convSingAPFactoryAP( f,a,r ) ),
573                    G( convSingAPFactoryAP( g,a,r ) );
574      res= convFactoryAPSingAP(  F / G, r  );
575      prune (a);
576    }
577    else
578    {
579      CanonicalForm F( convSingTrPFactoryP( f,r ) ), G( convSingTrPFactoryP( g,r ) );
580      res= convFactoryPSingTrP(  F / G,);
581    }
582  }
583#if 0 // not yet working
584  else if (rField_is_GF())
585  {
586    //Print("GF(%d^%d)\n",nfCharP,nfMinPoly[0]);
587    setCharacteristic( nfCharP,nfMinPoly[0], currRing->parameter[0][0] );
588    CanonicalForm F( convSingGFFactoryGF( f ) ), G( convSingGFFactoryGF( g ) );
589    res = convFactoryGFSingGF( F / G );
590  }
591#endif
592  else
593    WerrorS( feNotImplemented );
594  Off(SW_RATIONAL);
595  return res;
596}
597
598void singclap_divide_content ( poly f, const ring r )
599{
600  if ( f==NULL )
601  {
602    return;
603  }
604  else  if ( pNext( f ) == NULL )
605  {
606    p_SetCoeff( f, n_Init( 1, r->cf ), r );
607    return;
608  }
609  else
610  {
611    if ( rField_is_Q_a(r) )
612      setCharacteristic( 0 );
613    else  if ( rField_is_Zp_a(r) )
614      setCharacteristic( -rChar(r) );
615    else
616      return; /* not implemented*/
617
618    CFList L;
619    CanonicalForm g, h;
620    poly p = pNext(f);
621
622    // first attemp: find 2 smallest g:
623
624    number g1=pGetCoeff(f);
625    number g2=pGetCoeff(p); // p==pNext(f);
626    pIter(p);
627    int sz1=n_Size(g1, r->cf);
628    int sz2=n_Size(g2, r->cf);
629    if (sz1>sz2)
630    {
631      number gg=g1;
632      g1=g2; g2=gg;
633      int sz=sz1;
634      sz1=sz2; sz2=sz;
635    }
636    while (p!=NULL)
637    {
638      int n_sz=n_Size(pGetCoeff(p),r->cf);
639      if (n_sz<sz1)
640      {
641        sz2=sz1;
642        g2=g1;
643        g1=pGetCoeff(p);
644        sz1=n_sz;
645        if (sz1<=3) break;
646      }
647      else if(n_sz<sz2)
648      {
649        sz2=n_sz;
650        g2=pGetCoeff(p);
651        sz2=n_sz;
652      }
653      pIter(p);
654    }
655    g = convSingPFactoryP( NUM(((fraction)g1)), r->cf->extRing );
656    g = gcd( g, convSingPFactoryP( NUM(((fraction)g2)) , r->cf->extRing));
657
658    // second run: gcd's
659
660    p = f;
661    while ( (p != NULL) && (g != 1)  && ( g != 0))
662    {
663      h = convSingPFactoryP( NUM(((fraction)pGetCoeff(p))), r->cf->extRing );
664      pIter( p );
665
666      g = gcd( g, h );
667
668      L.append( h );
669    }
670    if (( g == 1 ) || (g == 0))
671    {
672      // pTest(f);
673      return;
674    }
675    else
676    {
677      CFListIterator i;
678      for ( i = L, p = f; i.hasItem(); i++, p=pNext(p) )
679      {
680        fraction c=(fraction)pGetCoeff(p);
681        p_Delete(&(NUM(c)),r->cf->extRing); // 2nd arg used to be nacRing
682        NUM(c)=convFactoryPSingP( i.getItem() / g, r->cf->extRing );
683        //nTest((number)c);
684        //#ifdef LDEBUG
685        //number cn=(number)c;
686        //StringSetS(""); nWrite(nt); StringAppend(" ==> ");
687        //nWrite(cn);PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
688        //#endif
689      }
690    }
691    // pTest(f);
692  }
693}
694
695BOOLEAN count_Factors(ideal I, intvec *v,int j, poly &f, poly fac, const ring r)
696{
697  p_Test(f,r);
698  p_Test(fac,r);
699  int e=0;
700  if (!p_IsConstantPoly(fac,r))
701  {
702#ifdef FACTORIZE2_DEBUG
703    printf("start count_Factors(%d), Fdeg=%d, factor deg=%d\n",j,p_Totaldegree(f,r),p_Totaldegree(fac,r));
704    p_wrp(fac,r);PrintLn();
705#endif
706    On(SW_RATIONAL);
707    CanonicalForm F, FAC,Q,R;
708    Variable a;
709    if (rField_is_Zp(r) || rField_is_Q(r))
710    {
711      F=convSingPFactoryP( f,r );
712      FAC=convSingPFactoryP( fac,r );
713    }
714    else if (r->cf->extRing!=NULL)
715    {
716      if (r->cf->extRing->qideal!=NULL)
717      {
718        CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
719                                    r->cf->extRing);
720        a=rootOf(mipo);
721        F=convSingAPFactoryAP( f,a,r );
722        FAC=convSingAPFactoryAP( fac,a,r );
723      }
724      else
725      {
726        F=convSingTrPFactoryP( f,r );
727        FAC=convSingTrPFactoryP( fac,r );
728      }
729    }
730    else
731      WerrorS( feNotImplemented );
732
733    poly q;
734    loop
735    {
736      Q=F;
737      Q/=FAC;
738      R=Q;
739      R*=FAC;
740      R-=F;
741      if (R.isZero())
742      {
743        if (rField_is_Zp(r) || rField_is_Q(r))
744        {
745          q = convFactoryPSingP( Q,r );
746        }
747        else if (r->cf->extRing!=NULL)
748        {
749          if (r->cf->extRing->qideal!=NULL)
750          {
751            q= convFactoryAPSingAP( Q,r );
752          }
753          else
754          {
755            q= convFactoryPSingTrP( Q,r );
756          }
757        }
758        e++; p_Delete(&f,r); f=q; q=NULL; F=Q;
759      }
760      else
761      {
762        break;
763      }
764    }
765    if (r->cf->extRing!=NULL)
766      if (r->cf->extRing->qideal!=NULL)
767        prune (a);
768    if (e==0)
769    {
770      Off(SW_RATIONAL);
771      return FALSE;
772    }
773  }
774  else e=1;
775  I->m[j]=fac;
776  if (v!=NULL) (*v)[j]=e;
777  Off(SW_RATIONAL);
778  return TRUE;
779}
780
781int singclap_factorize_retry;
782
783ideal singclap_factorize ( poly f, intvec ** v , int with_exps, const ring r)
784/* destroys f, sets *v */
785{
786  p_Test(f,r);
787#ifdef FACTORIZE2_DEBUG
788  printf("singclap_factorize, degree %ld\n",p_Totaldegree(f,r));
789#endif
790  // with_exps: 3,1 return only true factors, no exponents
791  //            2 return true factors and exponents
792  //            0 return coeff, factors and exponents
793  BOOLEAN save_errorreported=errorreported;
794
795  ideal res=NULL;
796
797  // handle factorize(0) =========================================
798  if (f==NULL)
799  {
800    res=idInit(1,1);
801    if (with_exps!=1)
802    {
803      (*v)=new intvec(1);
804      (**v)[0]=1;
805    }
806    return res;
807  }
808  // handle factorize(mon) =========================================
809  if (pNext(f)==NULL)
810  {
811    int i=0;
812    int n=0;
813    int e;
814    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
815    if (with_exps==0) n++; // with coeff
816    res=idInit(si_max(n,1),1);
817    switch(with_exps)
818    {
819      case 0: // with coef & exp.
820        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
821        // no break
822      case 2: // with exp.
823        (*v)=new intvec(si_max(1,n));
824        (**v)[0]=1;
825        // no break
826      case 1: ;
827#ifdef TEST
828      default: ;
829#endif
830    }
831    if (n==0)
832    {
833      res->m[0]=p_One(r);
834      // (**v)[0]=1; is already done
835    }
836    else
837    {
838      for(i=rVar(r);i>0;i--)
839      {
840        e=p_GetExp(f,i,r);
841        if(e!=0)
842        {
843          n--;
844          poly p=p_One(r);
845          p_SetExp(p,i,1,r);
846          p_Setm(p,r);
847          res->m[n]=p;
848          if (with_exps!=1) (**v)[n]=e;
849        }
850      }
851    }
852    p_Delete(&f,r);
853    return res;
854  }
855  //PrintS("S:");p_Write(f,r);PrintLn();
856  // use factory/libfac in general ==============================
857  Off(SW_RATIONAL);
858  On(SW_SYMMETRIC_FF);
859  CFFList L;
860  number N=NULL;
861  number NN=NULL;
862  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
863
864  Variable a;
865  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
866  {
867    //if (f!=NULL) // already tested at start of routine
868    {
869      number n0=n_Copy(pGetCoeff(f),r->cf);
870      if (with_exps==0)
871        N=n_Copy(n0,r->cf);
872      p_Cleardenom(f, r);
873      //after here f should not have a denominator!!
874      //PrintS("S:");p_Write(f,r);PrintLn();
875      NN=n_Div(n0,pGetCoeff(f),r->cf);
876      n_Delete(&n0,r->cf);
877      if (with_exps==0)
878      {
879        n_Delete(&N,r->cf);
880        N=n_Copy(NN,r->cf);
881      }
882    }
883  }
884  else if (rField_is_Zp_a(r))
885  {
886    //if (f!=NULL) // already tested at start of routine
887    if (singclap_factorize_retry==0)
888    {
889      number n0=n_Copy(pGetCoeff(f),r->cf);
890      if (with_exps==0)
891        N=n_Copy(n0,r->cf);
892      p_Norm(f,r);
893      p_Cleardenom(f, r);
894      NN=n_Div(n0,pGetCoeff(f),r->cf);
895      n_Delete(&n0,r->cf);
896      if (with_exps==0)
897      {
898        n_Delete(&N,r->cf);
899        N=n_Copy(NN,r->cf);
900      }
901    }
902  }
903  if (rField_is_Q(r) || rField_is_Zp(r))
904  {
905    setCharacteristic( rChar(r) );
906    CanonicalForm F( convSingPFactoryP( f,r ) );
907    L = factorize( F );
908  }
909  // and over Q(a) / Fp(a)
910  else if (r->cf->extRing!=NULL)
911  {
912    if (rField_is_Q_a (r)) setCharacteristic (0);
913    else                   setCharacteristic( rChar(r) );
914    if (r->cf->extRing->qideal!=NULL)
915    {
916      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
917                                           r->cf->extRing);
918      a=rootOf(mipo);
919      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
920      if (rField_is_Zp_a(r))
921      {
922        L = factorize( F, a );
923      }
924      else
925      {
926        //  over Q(a)
927        L= factorize (F, a);
928      }
929    }
930    else
931    {
932      CanonicalForm F( convSingTrPFactoryP( f,r ) );
933      L = factorize( F );
934    }
935  }
936  else
937  {
938    goto notImpl;
939  }
940  {
941    poly ff=p_Copy(f,r); // a copy for the retry stuff
942    // the first factor should be a constant
943    if ( ! L.getFirst().factor().inCoeffDomain() )
944      L.insert(CFFactor(1,1));
945    // convert into ideal
946    int n = L.length();
947    if (n==0) n=1;
948    CFFListIterator J=L;
949    int j=0;
950    if (with_exps!=1)
951    {
952      if ((with_exps==2)&&(n>1))
953      {
954        n--;
955        J++;
956      }
957      *v = new intvec( n );
958    }
959    res = idInit( n ,1);
960    for ( ; J.hasItem(); J++, j++ )
961    {
962      if (with_exps!=1) (**v)[j] = J.getItem().exp();
963      if (rField_is_Zp(r) || rField_is_Q(r))           /* Q, Fp */
964      {
965        //count_Factors(res,*v,f, j, convFactoryPSingP( J.getItem().factor() );
966        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
967      }
968#if 0
969      else if (rField_is_GF())
970        res->m[j] = convFactoryGFSingGF( J.getItem().factor() );
971#endif
972      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
973      {
974#ifndef SING_NDEBUG
975        intvec *w=NULL;
976        if (v!=NULL) w=*v;
977#endif
978        if (r->cf->extRing->qideal==NULL)
979        {
980#ifdef SING_NDEBUG
981          res->m[j]= convFactoryPSingTrP( J.getItem().factor(),r );
982#else
983          if(!count_Factors(res,w,j,ff,convFactoryPSingTrP( J.getItem().factor(),r ),r))
984          {
985            if (w!=NULL)
986              (*w)[j]=1;
987            res->m[j]=p_One(r);
988          }
989#endif
990        }
991        else
992        {
993#ifdef SING_NDEBUG
994          res->m[j]= convFactoryAPSingAP( J.getItem().factor(),r );
995#else
996          if (!count_Factors(res,w,j,ff,convFactoryAPSingAP( J.getItem().factor(),r ),r))
997          {
998            if (w!=NULL)
999              (*w)[j]=1;
1000            res->m[j]=p_One(r);
1001          }
1002#endif
1003        }
1004      }
1005    }
1006    if (r->cf->extRing!=NULL)
1007      if (r->cf->extRing->qideal!=NULL)
1008        prune (a);
1009#ifndef SING_NDEBUG
1010    if ((r->cf->extRing!=NULL) && (!p_IsConstantPoly(ff,r)))
1011    {
1012      singclap_factorize_retry++;
1013      if (singclap_factorize_retry<3)
1014      {
1015        int jj;
1016#ifdef FACTORIZE2_DEBUG
1017        printf("factorize_retry\n");
1018#endif
1019        intvec *ww=NULL;
1020        id_Test(res,r);
1021        ideal h=singclap_factorize ( ff, &ww , with_exps, r );
1022        id_Test(h,r);
1023        int l=(*v)->length();
1024        (*v)->resize(l+ww->length());
1025        for(jj=0;jj<ww->length();jj++)
1026          (**v)[jj+l]=(*ww)[jj];
1027        delete ww;
1028        ideal hh=idInit(IDELEMS(res)+IDELEMS(h),1);
1029        for(jj=IDELEMS(res)-1;jj>=0;jj--)
1030        {
1031          hh->m[jj]=res->m[jj];
1032          res->m[jj]=NULL;
1033        }
1034        for(jj=IDELEMS(h)-1;jj>=0;jj--)
1035        {
1036          hh->m[jj+IDELEMS(res)]=h->m[jj];
1037          h->m[jj]=NULL;
1038        }
1039        id_Delete(&res,r);
1040        id_Delete(&h,r);
1041        res=hh;
1042        id_Test(res,r);
1043        ff=NULL;
1044      }
1045      else
1046      {
1047        WarnS("problem with factorize");
1048#if 0
1049        pWrite(ff);
1050        idShow(res);
1051#endif
1052        id_Delete(&res,r);
1053        res=idInit(2,1);
1054        res->m[0]=p_One(r);
1055        res->m[1]=ff; ff=NULL;
1056      }
1057    }
1058#endif
1059    p_Delete(&ff,r);
1060    if (N!=NULL)
1061    {
1062      p_Mult_nn(res->m[0],N,r);
1063      n_Delete(&N,r->cf);
1064      N=NULL;
1065    }
1066    // delete constants
1067    if (res!=NULL)
1068    {
1069      int i=IDELEMS(res)-1;
1070      int j=0;
1071      for(;i>=0;i--)
1072      {
1073        if ((res->m[i]!=NULL)
1074        && (pNext(res->m[i])==NULL)
1075        && (p_IsConstant(res->m[i],r)))
1076        {
1077          if (with_exps!=0)
1078          {
1079            p_Delete(&(res->m[i]),r);
1080            if ((v!=NULL) && ((*v)!=NULL))
1081              (**v)[i]=0;
1082            j++;
1083          }
1084          else if (i!=0)
1085          {
1086            while ((v!=NULL) && ((*v)!=NULL) && ((**v)[i]>1))
1087            {
1088              res->m[0]=p_Mult_q(res->m[0],p_Copy(res->m[i],r),r);
1089              (**v)[i]--;
1090            }
1091            res->m[0]=p_Mult_q(res->m[0],res->m[i],r);
1092            res->m[i]=NULL;
1093            if ((v!=NULL) && ((*v)!=NULL))
1094              (**v)[i]=1;
1095            j++;
1096          }
1097        }
1098      }
1099      if (j>0)
1100      {
1101        idSkipZeroes(res);
1102        if ((v!=NULL) && ((*v)!=NULL))
1103        {
1104          intvec *w=*v;
1105          int len=IDELEMS(res);
1106          *v = new intvec( len );
1107          for (i=0,j=0;i<si_min(w->length(),len);i++)
1108          {
1109            if((*w)[i]!=0)
1110            {
1111              (**v)[j]=(*w)[i]; j++;
1112            }
1113          }
1114          delete w;
1115        }
1116      }
1117      if (res->m[0]==NULL)
1118      {
1119        res->m[0]=p_One(r);
1120      }
1121    }
1122  }
1123  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
1124  {
1125    int i=IDELEMS(res)-1;
1126    int stop=1;
1127    if (with_exps!=0) stop=0;
1128    for(;i>=stop;i--)
1129    {
1130      p_Norm(res->m[i],r);
1131    }
1132    if (with_exps==0) p_SetCoeff(res->m[0],old_lead_coeff,r);
1133    else n_Delete(&old_lead_coeff,r->cf);
1134  }
1135  else
1136    n_Delete(&old_lead_coeff,r->cf);
1137  errorreported=save_errorreported;
1138notImpl:
1139  if (res==NULL)
1140    WerrorS( feNotImplemented );
1141  if (NN!=NULL)
1142  {
1143    n_Delete(&NN,r->cf);
1144  }
1145  if (N!=NULL)
1146  {
1147    n_Delete(&N,r->cf);
1148  }
1149  if (f!=NULL) p_Delete(&f,r);
1150  //PrintS("......S\n");
1151  return res;
1152}
1153
1154ideal singclap_sqrfree ( poly f, intvec ** v , int with_exps, const ring r)
1155{
1156  p_Test(f,r);
1157#ifdef FACTORIZE2_DEBUG
1158  printf("singclap_sqrfree, degree %d\n",pTotaldegree(f));
1159#endif
1160  // with_exps: 3,1 return only true factors, no exponents
1161  //            2 return true factors and exponents
1162  //            0 return coeff, factors and exponents
1163  BOOLEAN save_errorreported=errorreported;
1164
1165  ideal res=NULL;
1166
1167  // handle factorize(0) =========================================
1168  if (f==NULL)
1169  {
1170    res=idInit(1,1);
1171    if (with_exps!=1 && with_exps!=3)
1172    {
1173      (*v)=new intvec(1);
1174      (**v)[0]=1;
1175    }
1176    return res;
1177  }
1178  // handle factorize(mon) =========================================
1179  if (pNext(f)==NULL)
1180  {
1181    int i=0;
1182    int n=0;
1183    int e;
1184    for(i=rVar(r);i>0;i--) if(p_GetExp(f,i,r)!=0) n++;
1185    if (with_exps==0 || with_exps==3) n++; // with coeff
1186    res=idInit(si_max(n,1),1);
1187    switch(with_exps)
1188    {
1189      case 0: // with coef & exp.
1190        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
1191        // no break
1192      case 3: // with coef & exp.
1193        res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
1194        // no break
1195      case 2: // with exp.
1196        (*v)=new intvec(si_max(1,n));
1197        (**v)[0]=1;
1198        // no break
1199      case 1: ;
1200      #ifdef TEST
1201      default: ;
1202      #endif
1203    }
1204    res->m[0]=p_NSet(n_Copy(pGetCoeff(f),r->cf),r);
1205    if (n==0)
1206    {
1207      res->m[0]=p_One(r);
1208      // (**v)[0]=1; is already done
1209    }
1210    else
1211    {
1212      for(i=rVar(r);i>0;i--)
1213      {
1214        e=p_GetExp(f,i,r);
1215        if(e!=0)
1216        {
1217          n--;
1218          poly p=p_One(r);
1219          p_SetExp(p,i,1,r);
1220          p_Setm(p,r);
1221          res->m[n]=p;
1222          if (with_exps!=1) (**v)[n]=e;
1223        }
1224      }
1225    }
1226    p_Delete(&f,r);
1227    return res;
1228  }
1229  //PrintS("S:");pWrite(f);PrintLn();
1230  // use factory/libfac in general ==============================
1231  Off(SW_RATIONAL);
1232  On(SW_SYMMETRIC_FF);
1233  CFFList L;
1234  number N=NULL;
1235  number NN=NULL;
1236  number old_lead_coeff=n_Copy(pGetCoeff(f), r->cf);
1237  Variable a;
1238
1239  if (!rField_is_Zp(r) && !rField_is_Zp_a(r)) /* Q, Q(a) */
1240  {
1241    //if (f!=NULL) // already tested at start of routine
1242    number n0=n_Copy(pGetCoeff(f),r->cf);
1243    if (with_exps==0 || with_exps==3)
1244      N=n_Copy(n0,r->cf);
1245    p_Cleardenom(f, r);
1246    //after here f should not have a denominator!!
1247    //PrintS("S:");p_Write(f,r);PrintLn();
1248    NN=n_Div(n0,pGetCoeff(f),r->cf);
1249    n_Delete(&n0,r->cf);
1250    if (with_exps==0 || with_exps==3)
1251    {
1252      n_Delete(&N,r->cf);
1253      N=n_Copy(NN,r->cf);
1254    }
1255  }
1256  else if (rField_is_Zp_a(r))
1257  {
1258    //if (f!=NULL) // already tested at start of routine
1259    if (singclap_factorize_retry==0)
1260    {
1261      number n0=n_Copy(pGetCoeff(f),r->cf);
1262      if (with_exps==0 || with_exps==3)
1263        N=n_Copy(n0,r->cf);
1264      p_Norm(f,r);
1265      p_Cleardenom(f, r);
1266      NN=n_Div(n0,pGetCoeff(f),r->cf);
1267      n_Delete(&n0,r->cf);
1268      if (with_exps==0 || with_exps==3)
1269      {
1270        n_Delete(&N,r->cf);
1271        N=n_Copy(NN,r->cf);
1272      }
1273    }
1274  }
1275  if (rField_is_Q(r) || rField_is_Zp(r))
1276  {
1277    setCharacteristic( rChar(r) );
1278    CanonicalForm F( convSingPFactoryP( f,r ) );
1279    L = sqrFree( F );
1280  }
1281  else if (r->cf->extRing!=NULL)
1282  {
1283    if (rField_is_Q_a (r)) setCharacteristic (0);
1284    else                   setCharacteristic( rChar(r) );
1285    if (r->cf->extRing->qideal!=NULL)
1286    {
1287      CanonicalForm mipo=convSingPFactoryP(r->cf->extRing->qideal->m[0],
1288                                           r->cf->extRing);
1289      a=rootOf(mipo);
1290      CanonicalForm F( convSingAPFactoryAP( f, a, r ) );
1291      L= sqrFree (F);
1292    }
1293    else
1294    {
1295      CanonicalForm F( convSingTrPFactoryP( f,r ) );
1296      L = sqrFree( F );
1297    }
1298  }
1299  #if 0
1300  else if (rField_is_GF())
1301  {
1302    int c=rChar(r);
1303    setCharacteristic( c, primepower(c) );
1304    CanonicalForm F( convSingGFFactoryGF( f ) );
1305    if (F.isUnivariate())
1306    {
1307      L = factorize( F );
1308    }
1309    else
1310    {
1311      goto notImpl;
1312    }
1313  }
1314  #endif
1315  else
1316  {
1317    goto notImpl;
1318  }
1319  {
1320    // convert into ideal
1321    int n = L.length();
1322    if (n==0) n=1;
1323    CFFListIterator J=L;
1324    int j=0;
1325    if (with_exps!=1)
1326    {
1327      if ((with_exps==2)&&(n>1))
1328      {
1329        n--;
1330        J++;
1331      }
1332      *v = new intvec( n );
1333    }
1334    else if (L.getFirst().factor().inCoeffDomain() && with_exps!=3)
1335    {
1336      n--;
1337      J++;
1338    }
1339    res = idInit( n ,1);
1340    for ( ; J.hasItem(); J++, j++ )
1341    {
1342      if (with_exps!=1 && with_exps!=3) (**v)[j] = J.getItem().exp();
1343      if (rField_is_Zp(r) || rField_is_Q(r))
1344        res->m[j] = convFactoryPSingP( J.getItem().factor(),r );
1345      else if (r->cf->extRing!=NULL)     /* Q(a), Fp(a) */
1346      {
1347        if (r->cf->extRing->qideal==NULL)
1348          res->m[j]=convFactoryPSingTrP( J.getItem().factor(),r );
1349        else
1350          res->m[j]=convFactoryAPSingAP( J.getItem().factor(),r );
1351      }
1352    }
1353    if (res->m[0]==NULL)
1354    {
1355      res->m[0]=p_One(r);
1356    }
1357    if (N!=NULL)
1358    {
1359      p_Mult_nn(res->m[0],N,r);
1360      n_Delete(&N,r->cf);
1361      N=NULL;
1362    }
1363  }
1364  if (r->cf->extRing!=NULL)
1365    if (r->cf->extRing->qideal!=NULL)
1366      prune (a);
1367  if (rField_is_Q_a(r) && (r->cf->extRing->qideal!=NULL))
1368  {
1369    int i=IDELEMS(res)-1;
1370    int stop=1;
1371    if (with_exps!=0 || with_exps==3) stop=0;
1372    for(;i>=stop;i--)
1373    {
1374      p_Norm(res->m[i],r);
1375    }
1376    if (with_exps==0 || with_exps==3) p_SetCoeff(res->m[0],old_lead_coeff,r);
1377    else n_Delete(&old_lead_coeff,r->cf);
1378  }
1379  else
1380    n_Delete(&old_lead_coeff,r->cf);
1381  p_Delete(&f,r);
1382  errorreported=save_errorreported;
1383notImpl:
1384  if (res==NULL)
1385    WerrorS( feNotImplemented );
1386  if (NN!=NULL)
1387  {
1388    n_Delete(&NN,r->cf);
1389  }
1390  if (N!=NULL)
1391  {
1392    n_Delete(&N,r->cf);
1393  }
1394  return res;
1395}
1396
1397matrix singclap_irrCharSeries ( ideal I, const ring r)
1398{
1399  if (idIs0(I)) return mpNew(1,1);
1400
1401  // for now there is only the possibility to handle polynomials over
1402  // Q and Fp ...
1403  matrix res=NULL;
1404  int i;
1405  Off(SW_RATIONAL);
1406  On(SW_SYMMETRIC_FF);
1407  CFList L;
1408  ListCFList LL;
1409  if (rField_is_Q(r) || rField_is_Zp(r))
1410  {
1411    setCharacteristic( rChar(r) );
1412    for(i=0;i<IDELEMS(I);i++)
1413    {
1414      poly p=I->m[i];
1415      if (p!=NULL)
1416      {
1417        p=p_Copy(p,r);
1418        p_Cleardenom(p, r);
1419        L.append(convSingPFactoryP(p,r));
1420      }
1421    }
1422  }
1423  // and over Q(a) / Fp(a)
1424  else if (nCoeff_is_transExt (r->cf))
1425  {
1426    setCharacteristic( rChar(r) );
1427    for(i=0;i<IDELEMS(I);i++)
1428    {
1429      poly p=I->m[i];
1430      if (p!=NULL)
1431      {
1432        p=p_Copy(p,r);
1433        p_Cleardenom(p, r);
1434        L.append(convSingTrPFactoryP(p,r));
1435      }
1436    }
1437  }
1438  else
1439  {
1440    WerrorS( feNotImplemented );
1441    return res;
1442  }
1443
1444  // a very bad work-around --- FIX IT in libfac
1445  // should be fixed as of 2001/6/27
1446  int tries=0;
1447  int m,n;
1448  ListIterator<CFList> LLi;
1449  loop
1450  {
1451    LL=irrCharSeries(L);
1452    m= LL.length(); // Anzahl Zeilen
1453    n=0;
1454    for ( LLi = LL; LLi.hasItem(); LLi++ )
1455    {
1456      n = si_max(LLi.getItem().length(),n);
1457    }
1458    if ((m!=0) && (n!=0)) break;
1459    tries++;
1460    if (tries>=5) break;
1461  }
1462  if ((m==0) || (n==0))
1463  {
1464    Warn("char_series returns %d x %d matrix from %d input polys (%d)",
1465      m,n,IDELEMS(I)+1,LL.length());
1466    iiWriteMatrix((matrix)I,"I",2,r,0);
1467    m=si_max(m,1);
1468    n=si_max(n,1);
1469  }
1470  res=mpNew(m,n);
1471  CFListIterator Li;
1472  for ( m=1, LLi = LL; LLi.hasItem(); LLi++, m++ )
1473  {
1474    for (n=1, Li = LLi.getItem(); Li.hasItem(); Li++, n++)
1475    {
1476      if (rField_is_Q(r) || rField_is_Zp(r))
1477        MATELEM(res,m,n)=convFactoryPSingP(Li.getItem(),r);
1478      else
1479        MATELEM(res,m,n)=convFactoryPSingTrP(Li.getItem(),r);
1480    }
1481  }
1482  Off(SW_RATIONAL);
1483  return res;
1484}
1485
1486char* singclap_neworder ( ideal I, const ring r)
1487{
1488  int i;
1489  Off(SW_RATIONAL);
1490  On(SW_SYMMETRIC_FF);
1491  CFList L;
1492  if (rField_is_Q(r) || rField_is_Zp(r))
1493  {
1494    setCharacteristic( rChar(r) );
1495    for(i=0;i<IDELEMS(I);i++)
1496    {
1497      poly p=I->m[i];
1498      if (p!=NULL)
1499      {
1500        p=p_Copy(p,r);
1501        p_Cleardenom(p, r);
1502        L.append(convSingPFactoryP(p,r));
1503      }
1504    }
1505  }
1506  // and over Q(a) / Fp(a)
1507  else if (nCoeff_is_transExt (r->cf))
1508  {
1509    setCharacteristic( rChar(r) );
1510    for(i=0;i<IDELEMS(I);i++)
1511    {
1512      poly p=I->m[i];
1513      if (p!=NULL)
1514      {
1515        p=p_Copy(p,r);
1516        p_Cleardenom(p, r);
1517        L.append(convSingTrPFactoryP(p,r));
1518      }
1519    }
1520  }
1521  else
1522  {
1523    WerrorS( feNotImplemented );
1524    return NULL;
1525  }
1526
1527  List<int> IL=neworderint(L);
1528  ListIterator<int> Li;
1529  StringSetS("");
1530  Li = IL;
1531  int offs=rPar(r);
1532  int* mark=(int*)omAlloc0((rVar(r)+offs)*sizeof(int));
1533  int cnt=rVar(r)+offs;
1534  loop
1535  {
1536    if(! Li.hasItem()) break;
1537    BOOLEAN done=TRUE;
1538    i=Li.getItem()-1;
1539    mark[i]=1;
1540    if (i<offs)
1541    {
1542      done=FALSE;
1543      //StringAppendS(r->parameter[i]);
1544    }
1545    else
1546    {
1547      StringAppendS(r->names[i-offs]);
1548    }
1549    Li++;
1550    cnt--;
1551    if(cnt==0) break;
1552    if (done) StringAppendS(",");
1553  }
1554  for(i=0;i<rVar(r)+offs;i++)
1555  {
1556    BOOLEAN done=TRUE;
1557    if(mark[i]==0)
1558    {
1559      if (i<offs)
1560      {
1561        done=FALSE;
1562        //StringAppendS(r->parameter[i]);
1563      }
1564      else
1565      {
1566        StringAppendS(r->names[i-offs]);
1567      }
1568      cnt--;
1569      if(cnt==0) break;
1570      if (done) StringAppendS(",");
1571    }
1572  }
1573  char * s=StringEndS();
1574  if (s[strlen(s)-1]==',') s[strlen(s)-1]='\0';
1575  return s;
1576}
1577
1578poly singclap_det( const matrix m, const ring s )
1579{
1580  int r=m->rows();
1581  if (r!=m->cols())
1582  {
1583    Werror("det of %d x %d matrix",r,m->cols());
1584    return NULL;
1585  }
1586  poly res=NULL;
1587  CFMatrix M(r,r);
1588  int i,j;
1589  for(i=r;i>0;i--)
1590  {
1591    for(j=r;j>0;j--)
1592    {
1593      M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1594    }
1595  }
1596  res= convFactoryPSingP( determinant(M,r),s ) ;
1597  Off(SW_RATIONAL);
1598  return res;
1599}
1600
1601int singclap_det_i( intvec * m, const ring /*r*/)
1602{
1603//  assume( r == currRing ); // Anything else is not guaranted to work!
1604
1605  setCharacteristic( 0 ); // ?
1606  CFMatrix M(m->rows(),m->cols());
1607  int i,j;
1608  for(i=m->rows();i>0;i--)
1609  {
1610    for(j=m->cols();j>0;j--)
1611    {
1612      M(i,j)=IMATELEM(*m,i,j);
1613    }
1614  }
1615  int res= convFactoryISingI( determinant(M,m->rows()) ) ;
1616  return res;
1617}
1618
1619number singclap_det_bi( bigintmat * m, const coeffs cf)
1620{
1621  assume(m->basecoeffs()==cf);
1622  CFMatrix M(m->rows(),m->cols());
1623  int i,j;
1624  BOOLEAN setchar=TRUE;
1625  for(i=m->rows();i>0;i--)
1626  {
1627    for(j=m->cols();j>0;j--)
1628    {
1629      M(i,j)=n_convSingNFactoryN(BIMATELEM(*m,i,j),setchar,cf);
1630      setchar=FALSE;
1631    }
1632  }
1633  number res=n_convFactoryNSingN( determinant(M,m->rows()),cf ) ;
1634  return res;
1635}
1636
1637#ifdef HAVE_NTL
1638#if 1
1639matrix singntl_HNF(matrix  m, const ring s )
1640{
1641  int r=m->rows();
1642  if (r!=m->cols())
1643  {
1644    Werror("HNF of %d x %d matrix",r,m->cols());
1645    return NULL;
1646  }
1647
1648  matrix res=mp_New(r,r);
1649
1650  if (rField_is_Q(s))
1651  {
1652
1653    CFMatrix M(r,r);
1654    int i,j;
1655    for(i=r;i>0;i--)
1656    {
1657      for(j=r;j>0;j--)
1658      {
1659        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s );
1660      }
1661    }
1662    CFMatrix *MM=cf_HNF(M);
1663    for(i=r;i>0;i--)
1664    {
1665      for(j=r;j>0;j--)
1666      {
1667        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1668      }
1669    }
1670    delete MM;
1671  }
1672  return res;
1673}
1674
1675intvec* singntl_HNF(intvec*  m)
1676{
1677  int r=m->rows();
1678  if (r!=m->cols())
1679  {
1680    Werror("HNF of %d x %d matrix",r,m->cols());
1681    return NULL;
1682  }
1683  setCharacteristic( 0 );
1684  CFMatrix M(r,r);
1685  int i,j;
1686  for(i=r;i>0;i--)
1687  {
1688    for(j=r;j>0;j--)
1689    {
1690      M(i,j)=IMATELEM(*m,i,j);
1691    }
1692  }
1693  CFMatrix *MM=cf_HNF(M);
1694  intvec *mm=ivCopy(m);
1695  for(i=r;i>0;i--)
1696  {
1697    for(j=r;j>0;j--)
1698    {
1699      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1700    }
1701  }
1702  delete MM;
1703  return mm;
1704}
1705
1706matrix singntl_LLL(matrix  m, const ring s )
1707{
1708  int r=m->rows();
1709  int c=m->cols();
1710  matrix res=mp_New(r,c);
1711  if (rField_is_Q(s))
1712  {
1713    CFMatrix M(r,c);
1714    int i,j;
1715    for(i=r;i>0;i--)
1716    {
1717      for(j=c;j>0;j--)
1718      {
1719        M(i,j)=convSingPFactoryP(MATELEM(m,i,j),s);
1720      }
1721    }
1722    CFMatrix *MM=cf_LLL(M);
1723    for(i=r;i>0;i--)
1724    {
1725      for(j=c;j>0;j--)
1726      {
1727        MATELEM(res,i,j)=convFactoryPSingP((*MM)(i,j),s);
1728      }
1729    }
1730    delete MM;
1731  }
1732  return res;
1733}
1734
1735intvec* singntl_LLL(intvec*  m)
1736{
1737  int r=m->rows();
1738  int c=m->cols();
1739  setCharacteristic( 0 );
1740  CFMatrix M(r,c);
1741  int i,j;
1742  for(i=r;i>0;i--)
1743  {
1744    for(j=c;j>0;j--)
1745    {
1746      M(i,j)=IMATELEM(*m,i,j);
1747    }
1748  }
1749  CFMatrix *MM=cf_LLL(M);
1750  intvec *mm=ivCopy(m);
1751  for(i=r;i>0;i--)
1752  {
1753    for(j=c;j>0;j--)
1754    {
1755      IMATELEM(*mm,i,j)=convFactoryISingI((*MM)(i,j));
1756    }
1757  }
1758  delete MM;
1759  return mm;
1760}
1761
1762ideal singclap_absFactorize ( poly f, ideal & mipos, intvec ** exps, int & numFactors, const ring r)
1763{
1764  p_Test(f, r);
1765
1766  ideal res=NULL;
1767
1768  int offs = rPar(r);
1769  if (f==NULL)
1770  {
1771    res= idInit (1, 1);
1772    mipos= idInit (1, 1);
1773    mipos->m[0]= convFactoryPSingTrP (Variable (offs), r); //overkill
1774    (*exps)=new intvec (1);
1775    (**exps)[0]= 1;
1776    numFactors= 0;
1777    return res;
1778  }
1779  CanonicalForm F( convSingTrPFactoryP( f, r) );
1780
1781  bool isRat= isOn (SW_RATIONAL);
1782  if (!isRat)
1783    On (SW_RATIONAL);
1784
1785  CFAFList absFactors= absFactorize (F);
1786
1787  int n= absFactors.length();
1788  *exps=new intvec (n);
1789
1790  res= idInit (n, 1);
1791
1792  mipos= idInit (n, 1);
1793
1794  Variable x= Variable (offs);
1795  Variable alpha;
1796  int i= 0;
1797  numFactors= 0;
1798  int count;
1799  CFAFListIterator iter= absFactors;
1800  CanonicalForm lead= iter.getItem().factor();
1801  if (iter.getItem().factor().inCoeffDomain())
1802  {
1803    i++;
1804    iter++;
1805  }
1806  for (; iter.hasItem(); iter++, i++)
1807  {
1808    (**exps)[i]= iter.getItem().exp();
1809    alpha= iter.getItem().minpoly().mvar();
1810    if (iter.getItem().minpoly().isOne())
1811      lead /= power (bCommonDen (iter.getItem().factor()), iter.getItem().exp());
1812    else
1813      lead /= power (power (bCommonDen (iter.getItem().factor()), degree (iter.getItem().minpoly())), iter.getItem().exp());
1814    res->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().factor()*bCommonDen (iter.getItem().factor()), alpha, x), r);
1815    if (iter.getItem().minpoly().isOne())
1816    {
1817      count= iter.getItem().exp();
1818      mipos->m[i]= convFactoryPSingTrP (x,r);
1819    }
1820    else
1821    {
1822      count= iter.getItem().exp()*degree (iter.getItem().minpoly());
1823      mipos->m[i]= convFactoryPSingTrP (replacevar (iter.getItem().minpoly(), alpha, x), r);
1824    }
1825    if (!iter.getItem().minpoly().isOne())
1826      prune (alpha);
1827    numFactors += count;
1828  }
1829  if (!isRat)
1830    Off (SW_RATIONAL);
1831
1832  (**exps)[0]= 1;
1833  res->m[0]= convFactoryPSingTrP (lead, r);
1834  mipos->m[0]= convFactoryPSingTrP (x, r);
1835  return res;
1836}
1837
1838#endif
1839#endif /* HAVE_NTL */
1840
Note: See TracBrowser for help on using the repository browser.