source: git/factory/fac_multivar.cc @ bba835

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