source: git/factory/fac_multivar.cc @ 68a3479

fieker-DuValspielwiese
Last change on this file since 68a3479 was f78374, checked in by Martin Lee <martinlee84@…>, 12 years ago
chg: more changes of squarefree decomposition according to master
  • Property mode set to 100644
File size: 11.0 KB
RevLine 
[493c477]1/* emacs edit mode for this file is -*- C++ -*- */
[341696]2/* $Id$ */
[2dd068]3
[e4fe2b]4#include "config.h"
[173e86]5
[650f2d8]6#include "cf_assert.h"
[043814]7#include "debug.h"
[125195]8#include "timing.h"
[2dd068]9
10#include "cf_defs.h"
[f58e95]11#include "cf_algorithm.h"
[2dd068]12#include "fac_multivar.h"
13#include "fac_univar.h"
14#include "cf_reval.h"
15#include "cf_map.h"
16#include "fac_util.h"
17#include "cf_binom.h"
18#include "cf_iter.h"
[cae0b6]19#include "cf_primes.h"
[e074407]20#include "fac_distrib.h"
[2dd068]21
[3a7ee74]22void out_cf(const char *s1,const CanonicalForm &f,const char *s2);
[c6d3744]23void out_cff(CFFList &L);
[2dd068]24
[e76d7a6]25TIMING_DEFINE_PRINT(fac_content)
26TIMING_DEFINE_PRINT(fac_findeval)
27TIMING_DEFINE_PRINT(fac_distrib)
28TIMING_DEFINE_PRINT(fac_hensel)
[2dd068]29
30static CFArray
31conv_to_factor_array( const CFFList & L )
32{
33    int n;
34    CFFListIterator I = L;
[125195]35    bool negate = false;
36
[2dd068]37    if ( ! I.hasItem() )
[cae0b6]38        n = 0;
[2dd068]39    else  if ( I.getItem().factor().inBaseDomain() ) {
[cae0b6]40        negate = I.getItem().factor().sign() < 0;
41        I++;
42        n = L.length();
[2dd068]43    }
44    else
[cae0b6]45        n = L.length() + 1;
[2dd068]46    CFFListIterator J = I;
47    while ( J.hasItem() ) {
[cae0b6]48        n += J.getItem().exp() - 1;
49        J++;
[2dd068]50    }
51    CFArray result( 1, n-1 );
52    int i, j, k;
53    i = 1;
54    while ( I.hasItem() ) {
[cae0b6]55        k = I.getItem().exp();
56        for ( j = 1; j <= k; j++ ) {
57            result[i] = I.getItem().factor();
58            i++;
59        }
60        I++;
[2dd068]61    }
[125195]62    if ( negate )
[cae0b6]63        result[1] = -result[1];
[2dd068]64    return result;
65}
66
[125195]67static modpk
[2dd068]68coeffBound ( const CanonicalForm & f, int p )
69{
70    int * degs = degrees( f );
71    int M = 0, i, k = f.level();
72    for ( i = 1; i <= k; i++ )
[cae0b6]73        M += degs[i];
[c6caf1]74    CanonicalForm b = 2 * maxNorm( f ) * power( CanonicalForm( 3 ), M );
[2dd068]75    CanonicalForm B = p;
76    k = 1;
77    while ( B < b ) {
[cae0b6]78        B *= p;
79        k++;
[2dd068]80    }
81    return modpk( p, k );
82}
83
[e074407]84// static bool
85// nonDivisors ( CanonicalForm omega, CanonicalForm delta, const CFArray & F, CFArray & d )
86// {
[d81ed62]87//     DEBOUTLN( cerr, "nondivisors omega = " << omega );
88//     DEBOUTLN( cerr, "nondivisors delta = " << delta );
89//     DEBOUTLN( cerr, "nondivisors F = " << F );
[e074407]90//     CanonicalForm q, r;
91//     int k = F.size();
92//     d = CFArray( 0, k );
93//     d[0] = delta * omega;
94//     for ( int i = 1; i <= k; i++ ) {
[cae0b6]95//         q = abs(F[i]);
96//         for ( int j = i-1; j >= 0; j-- ) {
97//             r = d[j];
98//             do {
99//                 r = gcd( r, q );
100//                 q = q / r;
101//             } while ( r != 1 );
102//             if ( q == 1 )
103//                 return false;
104//         }
105//         d[i] = q;
[e074407]106//     }
107//     return true;
108// }
[2dd068]109
110static void
[125195]111findEvaluation ( const CanonicalForm & U, const CanonicalForm & V, const CanonicalForm & omega, const CFFList & F, Evaluation & A, CanonicalForm & U0, CanonicalForm & delta, CFArray & D, int r )
[2dd068]112{
[e074407]113    DEBINCLEVEL( cerr, "findEvaluation" );
[2dd068]114    CanonicalForm Vn;
115    CFFListIterator I;
116    int j;
117    bool found = false;
[125195]118    CFArray FF = CFArray( 1, F.length() );
[2dd068]119    if ( r > 0 )
[cae0b6]120        A.nextpoint();
[c6d3744]121    while ( ! found )
122    {
[cae0b6]123        Vn = A( V );
[c6d3744]124        if ( Vn != 0 )
125        {
[cae0b6]126            U0 = A( U );
127            DEBOUTLN( cerr, "U0 = " << U0 );
[c6d3744]128            if ( isSqrFree( U0 ) )
129            {
[cae0b6]130                delta = content( U0 );
131                DEBOUTLN( cerr, "content( U0 ) = " << delta );
132                for ( I = F, j = 1; I.hasItem(); I++, j++ )
133                    FF[j] = A( I.getItem().factor() );
134                found = nonDivisors( omega, delta, FF, D );
135            }
[c6d3744]136            else
137            {
[cae0b6]138                DEBOUTLN( cerr, "not sqrfree : " << sqrFree( U0 ) );
139            }
140        }
141        if ( ! found )
142            A.nextpoint();
[2dd068]143    }
[e074407]144    DEBDECLEVEL( cerr, "findEvaluation" );
[2dd068]145}
146
[cae0b6]147#ifdef HAVE_NTL
148int prime_number=0;
[77f483]149void find_good_prime(const CanonicalForm &f, int &start)
[cae0b6]150{
151  if (! f.inBaseDomain() )
152  {
[77f483]153    CFIterator i = f;
154    for(;;)
[cae0b6]155    {
[77f483]156      if  ( i.hasTerms() )
[ec989c]157      {
[77f483]158        find_good_prime(i.coeff(),start);
[493225]159        if (0==cf_getSmallPrime(start)) return;
[77f483]160        if((i.exp()!=0) && ((i.exp() % cf_getSmallPrime(start))==0))
161        {
162          start++;
163          i=f;
164        }
165        else  i++;
[ec989c]166      }
[77f483]167      else break;
[cae0b6]168    }
169  }
170  else
171  {
[77f483]172    if (f.inZ())
[cae0b6]173    {
[493225]174      if (0==cf_getSmallPrime(start)) return;
175      while((!f.isZero()) && (mod(f,cf_getSmallPrime(start))==0))
[77f483]176      {
177        start++;
[493225]178        if (0==cf_getSmallPrime(start)) return;
[77f483]179      }
[cae0b6]180    }
[77f483]181/* should not happen!
182    else if (f.inQ())
183    {
184      while((f.den()!=0) && (mod(f.den(),cf_getSmallPrime(start))==0))
185      {
186        start++;
187      }
188      while((f.num()!=0) && (mod(f.num(),cf_getSmallPrime(start))==0))
189      {
190        start++;
191      }
192    }
193    else
194          cout <<"??"<< f <<"\n";
195*/
[cae0b6]196  }
197}
198#endif
199
[c6d3744]200static CFArray ZFactorizeMulti ( const CanonicalForm & arg )
[2dd068]201{
[e074407]202    DEBINCLEVEL( cerr, "ZFactorizeMulti" );
[2dd068]203    CFMap M;
204    CanonicalForm UU, U = compress( arg, M );
205    CanonicalForm delta, omega, V = LC( U, 1 );
206    int t = U.level();
207    CFFList F = factorize( V );
208    CFFListIterator I, J;
[125195]209    CFArray G, lcG, D;
[01e8874]210    int i, j, r, maxdeg;
[afd067]211    REvaluation A( 2, t, IntRandom( 50 ) );
[2dd068]212    CanonicalForm U0;
213    CanonicalForm ft, ut, gt, d;
214    modpk b;
215    bool negate = false;
216
[d81ed62]217    DEBOUTLN( cerr, "-----------------------------------------------------" );
218    DEBOUTLN( cerr, "trying to factorize U = " << U );
219    DEBOUTLN( cerr, "U is a polynomial of level = " << arg.level() );
220    DEBOUTLN( cerr, "U will be factorized with respect to variable " << Variable(1) );
221    DEBOUTLN( cerr, "the leading coefficient of U with respect to that variable is " << V );
222    DEBOUTLN( cerr, "which is factorized as " << F );
[e074407]223
[2dd068]224    maxdeg = 0;
[c6d3744]225    for ( i = 2; i <= t; i++ )
226    {
[cae0b6]227        j = U.degree( Variable( i ) );
228        if ( j > maxdeg ) maxdeg = j;
[2dd068]229    }
230
[c6d3744]231    if ( F.getFirst().factor().inCoeffDomain() )
232    {
[cae0b6]233        omega = F.getFirst().factor();
234        F.removeFirst();
[c6d3744]235        if ( omega < 0 )
236        {
[cae0b6]237            negate = true;
238            omega = -omega;
239            U = -U;
240        }
[2dd068]241    }
242    else
[cae0b6]243        omega = 1;
[2dd068]244
245    bool goodeval = false;
246    r = 0;
247
248//    for ( i = 0; i < 10*t; i++ )
[cae0b6]249//        A.nextpoint();
[2dd068]250
[c6d3744]251    while ( ! goodeval )
252    {
[cae0b6]253        TIMING_START(fac_findeval);
254        findEvaluation( U, V, omega, F, A, U0, delta, D, r );
255        TIMING_END(fac_findeval);
256        DEBOUTLN( cerr, "the evaluation point to reduce to an univariate problem is " << A );
257        DEBOUTLN( cerr, "corresponding delta = " << delta );
258        DEBOUTLN( cerr, "              omega = " << omega );
259        DEBOUTLN( cerr, "              D     = " << D );
260        DEBOUTLN( cerr, "now factorize the univariate polynomial " << U0 );
261        G = conv_to_factor_array( factorize( U0, false ) );
262        DEBOUTLN( cerr, "which factorizes into " << G );
263        #ifdef HAVE_NTL
264        {
265          int i=prime_number;
[c6d3744]266          find_good_prime(arg,i);
267          find_good_prime(U0,i);
268          find_good_prime(U,i);
269          int p=cf_getSmallPrime(i);
270          //printf("found:p=%d (%d)\n",p,i);
[493225]271          if (p==0)
[32c11f]272          {
273            return conv_to_factor_array(CFFactor(arg,1));
274            //printf("out of primes - switch ot non-NTL\n");
[493225]275          }
[32c11f]276          else if (((i==0)||(i!=prime_number)))
[c6d3744]277          {
[cae0b6]278            b = coeffBound( U, p );
[c6d3744]279            prime_number=i;
280          }
[32c11f]281          // p!=0:
282          modpk bb=coeffBound(U0,p);
283          if (bb.getk() > b.getk() ) b=bb;
284          bb=coeffBound(arg,p);
285          if (bb.getk() > b.getk() ) b=bb;
[cae0b6]286        }
287        #else
288        b = coeffBound( U, getZFacModulus().getp() );
289        if ( getZFacModulus().getpk() > b.getpk() )
290            b = getZFacModulus();
291        #endif
[c6d3744]292        //printf("p=%d, k=%d\n",b.getp(),b.getk());
[cae0b6]293        DEBOUTLN( cerr, "the coefficient bound of the factors of U is " << b.getpk() );
[e074407]294
[cae0b6]295        r = G.size();
296        lcG = CFArray( 1, r );
297        UU = U;
298        DEBOUTLN( cerr, "now trying to distribute the leading coefficients ..." );
299        TIMING_START(fac_distrib);
300        goodeval = distributeLeadingCoeffs( UU, G, lcG, F, D, delta, omega, A, r );
301        TIMING_END(fac_distrib);
[e074407]302#ifdef DEBUGOUTPUT
[c6d3744]303        if ( goodeval )
304        {
[cae0b6]305            DEBOUTLN( cerr, "the univariate factors after distribution are " << G );
306            DEBOUTLN( cerr, "the distributed leading coeffs are " << lcG );
307            DEBOUTLN( cerr, "U may have changed and is now " << UU );
308            DEBOUTLN( cerr, "which has leading coefficient " << LC( UU, Variable(1) ) );
[e074407]309
[c6d3744]310            if ( LC( UU, Variable(1) ) != prod( lcG ) || A(UU) != prod( G ) )
311            {
[cae0b6]312                DEBOUTLN( cerr, "!!! distribution was not correct !!!" );
313                DEBOUTLN( cerr, "product of leading coeffs is " << prod( lcG ) );
314                DEBOUTLN( cerr, "product of univariate factors is " << prod( G ) );
315                DEBOUTLN( cerr, "the new U is evaluated as " << A(UU) );
316            }
317            else
318                DEBOUTLN( cerr, "leading coeffs correct" );
319        }
[c6d3744]320        else
321        {
[cae0b6]322            DEBOUTLN( cerr, "we have found a bad evaluation point" );
323        }
[e074407]324#endif
[c6d3744]325        if ( goodeval )
326        {
[cae0b6]327            TIMING_START(fac_hensel);
328            goodeval = Hensel( UU, G, lcG, A, b, Variable(1) );
329            TIMING_END(fac_hensel);
330        }
[2dd068]331    }
[c6d3744]332    for ( i = 1; i <= r; i++ )
333    {
[cae0b6]334        G[i] /= icontent( G[i] );
335        G[i] = M(G[i]);
[e074407]336    }
[2dd068]337    // negate noch beachten !
338    if ( negate )
[cae0b6]339        G[1] = -G[1];
[e074407]340    DEBDECLEVEL( cerr, "ZFactorMulti" );
[2dd068]341    return G;
342}
343
[c6d3744]344CFFList ZFactorizeMultivariate ( const CanonicalForm & f, bool issqrfree )
[2dd068]345{
346    CFFList G, F, R;
347    CFArray GG;
348    CFFListIterator i, j;
349    CFMap M;
350    CanonicalForm g, cont;
351    Variable v1, vm;
352    int k, m, n;
353
354    v1 = Variable(1);
355    if ( issqrfree )
[cae0b6]356        F = CFFactor( f, 1 );
[2dd068]357    else
[e89e56]358        F = sqrFree( f );
[2dd068]359
[c6d3744]360    for ( i = F; i.hasItem(); i++ )
361    {
362        if ( i.getItem().factor().inCoeffDomain() )
[f78374]363            R.append( CFFactor( i.getItem().factor(), i.getItem().exp() ) );
[c6d3744]364        else
365        {
[cae0b6]366            TIMING_START(fac_content);
367            g = compress( i.getItem().factor(), M );
368            // now after compress g contains Variable(1)
369            vm = g.mvar();
370            g = swapvar( g, v1, vm );
371            cont = content( g );
372            g = swapvar( g / cont, v1, vm );
373            cont = swapvar( cont, v1, vm );
374            n = i.getItem().exp();
375            TIMING_END(fac_content);
376            DEBOUTLN( cerr, "now after content ..." );
[c6d3744]377            if ( g.isUnivariate() )
378            {
[cae0b6]379                G = factorize( g, true );
380                for ( j = G; j.hasItem(); j++ )
381                    if ( ! j.getItem().factor().isOne() )
382                        R.append( CFFactor( M( j.getItem().factor() ), n ) );
383            }
[c6d3744]384            else
385            {
[cae0b6]386                GG = ZFactorizeMulti( g );
387                m = GG.max();
388                for ( k = GG.min(); k <= m; k++ )
389                    if ( ! GG[k].isOne() )
390                        R.append( CFFactor( M( GG[k] ), n ) );
391            }
392            G = factorize( cont, true );
393            for ( j = G; j.hasItem(); j++ )
394                if ( ! j.getItem().factor().isOne() )
395                    R.append( CFFactor( M( j.getItem().factor() ), n ) );
396        }
[2dd068]397    }
398    return R;
399}
Note: See TracBrowser for help on using the repository browser.