source: git/factory/ffreval.cc @ 359d742

fieker-DuValspielwiese
Last change on this file since 359d742 was 1e6de6, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: some optimizations(gcd) git-svn-id: file:///usr/local/Singular/svn/trunk@10489 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.0 KB
Line 
1#include <config.h>
2
3#include "assert.h"
4#include "debug.h"
5
6#include "cf_defs.h"
7#include "canonicalform.h"
8#include "fac_util.h"
9#include "cf_algorithm.h"
10#include "cf_reval.h"
11#include "cf_random.h"
12#include "cf_primes.h"
13#include "fac_distrib.h"
14#include "ftmpl_functions.h"
15#include "ffreval.h"
16
17void FFREvaluation::init()
18{
19  int n = values.max();
20
21  for( int i=values.min(); i<=n; i++ )
22  {
23    CanonicalForm tmp=gen->generate();
24    values[i] = tmp; // generate random point
25    offset[i] = tmp; // generate random point
26  }
27}
28
29bool FFREvaluation::step()
30{
31  // enumerates the points stored in values
32  int n = values.max();
33  int p = getCharacteristic();
34
35  int i;
36  for(i=values.min(); i<=n; i++ )
37  {
38    if( values[i] != p-1 )
39    {
40      values[i] += 1;
41      break;
42    }
43    values[i] += 1; // becomes 0
44  }
45  for(i=values.min();i<=n;i++)
46  {
47    if(values[i]!=offset[i]) return true;
48  }
49  return false;
50}
51
52FFREvaluation& FFREvaluation::operator= ( const FFREvaluation & e )
53{
54  if( this != &e )
55  {
56    if( gen != NULL )
57      delete gen;
58    values = e.values;
59    offset = e.offset;
60    if( e.gen == NULL )
61      gen = NULL;
62    else
63      gen = e.gen->clone();
64  }
65  return *this;
66}
67
68/* ------------------------------------------------------------------------ */
69/* forward declarations: fin_ezgcd stuff*/
70static CanonicalForm fin_ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG, FFREvaluation & b, bool internal );
71static bool fin_findeval( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, FFREvaluation & b, int delta, int degF, int degG );
72static CanonicalForm fin_ezgcd_specialcase ( const CanonicalForm & F, const CanonicalForm & G, FFREvaluation & b, const modpk & bound );
73
74CanonicalForm fin_ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG )
75{
76    FFREvaluation b;
77    return fin_ezgcd( FF, GG, b, false );
78}
79
80static CanonicalForm fin_ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG, FFREvaluation & b, bool internal )
81{
82    CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG, lcD;
83    CFArray DD( 1, 2 ), lcDD( 1, 2 );
84    int degF, degG, delta, t;
85    FFREvaluation bt;
86    bool gcdfound = false;
87    Variable x = Variable(1);
88    modpk p = modpk(getCharacteristic(), 1); // k = 1
89    DEBINCLEVEL( cerr, "fin_ezgcd" );
90    DEBOUTLN( cerr, "FF = " << FF );
91    DEBOUTLN( cerr, "GG = " << GG );
92    f = content( FF, x ); g = content( GG, x ); d = gcd( f, g );
93    DEBOUTLN( cerr, "f = " << f );
94    DEBOUTLN( cerr, "g = " << g );
95    F = FF / f; G = GG / g;
96    if ( F.isUnivariate() && G.isUnivariate() )
97    {
98        DEBDECLEVEL( cerr, "fin_ezgcd" );
99        if(F.mvar()==G.mvar())
100          d*=gcd_poly(F,G);
101        return d;
102    }
103    else  if ( gcd_test_one( F, G, false ) )
104    {
105        DEBDECLEVEL( cerr, "fin_ezgcd" );
106        return d;
107    }
108    lcF = LC( F, x ); lcG = LC( G, x );
109    lcD = gcd( lcF, lcG );
110    delta = 0;
111    degF = degree( F, x ); degG = degree( G, x );
112    t = tmax( F.level(), G.level() );
113    if ( ! internal )
114    {
115        b = FFREvaluation( 2, t, FFRandom() );
116        b.init(); // choose random point
117    }
118    while ( ! gcdfound )
119    {
120        /// ---> A2
121        DEBOUTLN( cerr, "search for evaluation, delta = " << delta );
122        DEBOUTLN( cerr, "F = " << F );
123        DEBOUTLN( cerr, "G = " << G );
124        if( ! fin_findeval( F, G, Fb, Gb, Db, b, delta, degF, degG ) )
125        {
126           Off(SW_USE_EZGCD_P);
127           d *= gcd_poly(F,G);
128           On(SW_USE_EZGCD_P);
129           return d;
130        }
131
132        DEBOUTLN( cerr, "found evaluation b = " << b );
133        DEBOUTLN( cerr, "F(b) = " << Fb );
134        DEBOUTLN( cerr, "G(b) = " << Gb );
135        DEBOUTLN( cerr, "D(b) = " << Db );
136        delta = degree( Db );
137        /// ---> A3
138        if ( delta == 0 )
139        {
140          DEBDECLEVEL( cerr, "fin_ezgcd" );
141          return d;
142        }
143        /// ---> A4
144        //deltaold = delta;
145        while ( 1 )
146        {
147            bt = b;
148            if( ! fin_findeval( F, G, Fbt, Gbt, Dbt, bt, delta + 1, degF, degG ) )
149            {
150              Off(SW_USE_EZGCD_P);
151              d *= gcd_poly(F,G);
152              On(SW_USE_EZGCD_P);
153              return d;
154            }
155
156            int dd=degree( Dbt );
157            if ( dd /*degree( Dbt )*/ == 0 )
158            {
159                DEBDECLEVEL( cerr, "fin_ezgcd" );
160                return d;
161            }
162            if ( dd /*degree( Dbt )*/ == delta )
163                break;
164            else  if ( dd /*degree( Dbt )*/ < delta )
165            {
166                delta = dd /*degree( Dbt )*/;
167                b = bt;
168                Db = Dbt; Fb = Fbt; Gb = Gbt;
169            }
170        }
171        DEBOUTLN( cerr, "now after A4, delta = " << delta );
172        /// ---> A5
173        if ( degF <= degG && delta == degF && fdivides( F, G ) )
174        {
175            DEBDECLEVEL( cerr, "fin_ezgcd" );
176            return d*F;
177        }
178        if ( degG < degF && delta == degG && fdivides( G, F ) )
179        {
180            DEBDECLEVEL( cerr, "fin_ezgcd" );
181            return d*G;
182        }
183        if ( delta != degF && delta != degG )
184        {
185            bool B_is_F;
186            /// ---> A6
187            CanonicalForm xxx;
188            //if ( gcd( (DD[1] = Fb / Db), Db ) == 1 ) {
189            DD[1] = Fb / Db;
190            xxx= gcd( DD[1], Db );
191            DEBOUTLN( cerr, "gcd((Fb/Db),Db) = " << xxx );
192            DEBOUTLN( cerr, "Fb/Db = " << DD[1] );
193            DEBOUTLN( cerr, "Db = " << Db );
194            if (xxx.inCoeffDomain())
195            {
196                B = F;
197                DD[2] = Db;
198                lcDD[1] = lcF;
199                lcDD[2] = lcF;
200                B *= lcF;
201                B_is_F=true;
202            }
203            //else  if ( gcd( (DD[1] = Gb / Db), Db ) == 1 ) {
204            else
205            {
206              DD[1] = Gb / Db;
207              xxx=gcd( DD[1], Db );
208              DEBOUTLN( cerr, "gcd((Gb/Db),Db) = " << xxx );
209              DEBOUTLN( cerr, "Gb/Db = " << DD[1] );
210              DEBOUTLN( cerr, "Db = " << Db );
211              if (xxx.inCoeffDomain())
212              {
213                B = G;
214                DD[2] = Db;
215                lcDD[1] = lcG;
216                lcDD[2] = lcG;
217                B *= lcG;
218                B_is_F=false;
219              }
220              else
221              {
222#ifdef DEBUGOUTPUT
223                CanonicalForm dummyres = d * fin_ezgcd_specialcase( F, G, b, p );
224                DEBDECLEVEL( cerr, "fin_ezgcd" );
225                return dummyres;
226#else
227                return d * fin_ezgcd_specialcase( F, G, b, p );
228#endif
229              }
230            }
231            /// ---> A7
232            DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) );
233            DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) );
234            DEBOUTLN( cerr, "(hensel) B    = " << B );
235            DEBOUTLN( cerr, "(hensel) lcB  = " << LC( B, Variable(1) ) );
236            DEBOUTLN( cerr, "(hensel) b(B) = " << b(B) );
237            DEBOUTLN( cerr, "(hensel) DD   = " << DD );
238            DEBOUTLN( cerr, "(hensel) lcDD = " << lcDD );
239            gcdfound = Hensel( B, DD, lcDD, b, p, x );
240            DEBOUTLN( cerr, "(hensel finished) DD   = " << DD );
241            if (gcdfound)
242            {
243              CanonicalForm xxx=content(DD[2],Variable(1));
244              CanonicalForm cand=DD[2] / xxx; //content(DD[2],Variable(1));
245#if 0
246              gcdfound= fdivides(cand,G) &&  fdivides(cand,F);
247#else
248              if (B_is_F /*B==F*lcF*/)
249              {
250                DEBOUTLN( cerr, "(test) G: "<<G<<" % gcd:"<<cand<<" -> " << G%cand );
251                gcdfound= fdivides(cand,G);
252              }
253              else
254              {
255                DEBOUTLN( cerr, "(test) F: "<<F<<" % gcd:"<<cand<<" -> " << F%cand);
256                gcdfound= fdivides(cand,F);
257              }
258#endif
259            }
260            /// ---> A8 (gcdfound)
261        }
262        delta++;
263    }
264    /// ---> A9
265    DEBDECLEVEL( cerr, "fin_ezgcd" );
266    return d * DD[2] / content(DD[2],Variable(1));
267}
268
269static CanonicalForm fin_ezgcd_specialcase ( const CanonicalForm & F, const CanonicalForm & G, FFREvaluation & b, const modpk & bound )
270{
271    CanonicalForm d;
272    Off(SW_USE_EZGCD_P);
273    d=gcd_poly( F, G );
274    On(SW_USE_EZGCD_P);
275    return d;
276}
277
278static bool fin_findeval( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, FFREvaluation & b, int delta, int degF, int degG )
279{
280    int i;
281    bool ok;
282    DEBOUTLN( cerr, "fin_ezgcd: (fin_findeval) F = " << F  <<", G="<< G);
283    DEBOUTLN( cerr, "fin_ezgcd: (fin_findeval) degF = " << degF << ", degG="<<degG );
284    while(1)
285    {
286        DEBOUTLN( cerr, "fin_ezgcd: (fin_findeval) b = " << b );
287        Fb = b( F );
288        ok = degree( Fb ) == degF;
289        if ( ok )
290        {
291            Gb = b( G );
292            ok = degree( Gb ) == degG;
293        }
294        if ( ok )
295        {
296            Db = gcd( Fb, Gb );
297            if ( delta > 0 )
298              ok = degree( Db ) < delta;
299        }
300        if ( ok )
301            break;
302
303        if( b.step() ) // can choose valid point
304           continue;
305
306        return false;
307    }
308    return true;
309}
Note: See TracBrowser for help on using the repository browser.