source: git/factory/fac_util.cc

spielwiese
Last change on this file was 9f48f5, checked in by Hans Schoenemann <hannes@…>, 11 months ago
format
  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[493c477]1/* emacs edit mode for this file is -*- C++ -*- */
[2dd068]2
[9f7665]3
[e4fe2b]4#include "config.h"
[9f7665]5
[173e86]6
[650f2d8]7#include "cf_assert.h"
[83452f]8
[2dd068]9#include "cf_defs.h"
[7b4bfe6]10#include "canonicalform.h"
11#include "cf_iter.h"
[2dd068]12#include "fac_util.h"
[564dd8]13#include "cfUnivarGcd.h"
[2dd068]14
[a3f0fea]15STATIC_INST_VAR CanonicalForm PK, PKHALF;
[2dd068]16
17static CanonicalForm mappk ( const CanonicalForm& );
18
19static CanonicalForm mappksymmetric ( const CanonicalForm& );
20
21
22modpk::modpk()
23{
[667ba1]24    p = 0;
25    k = 0;
26    pk = 1;
27    pkhalf = 0;
[2dd068]28}
29
30modpk::modpk( int q, int l )
31{
32    p = q;
33    k = l;
34    pk = power( CanonicalForm( p ), k );
35    pkhalf = pk / 2;
36}
37
38modpk::modpk( const modpk & m )
39{
40    p = m.p;
41    k = m.k;
42    pk = m.pk;
43    pkhalf = m.pkhalf;
44}
45
46modpk&
47modpk::operator= ( const modpk & m )
48{
49    if ( this != &m ) {
[412bedd]50        p = m.p;
51        k = m.k;
52        pk = m.pk;
53        pkhalf = m.pkhalf;
[2dd068]54    }
55    return *this;
56}
57
58CanonicalForm
59modpk::inverse( const CanonicalForm & f, bool symmetric ) const
60{
61    CanonicalForm u, r0 = this->operator()( f, false ), r1 = pk, q0 = 1, q1 = 0;
62    while ( ( r0 > 0 ) && ( r1 > 0 ) ) {
[412bedd]63        u = r0 / r1;
64        r0 = r0 % r1;
65        q0 = u*q1 + q0;
66        if ( r0 > 0 ) {
67            u = r1 / r0;
68            r1 = r1 % r0;
69            q1 = u*q0 + q1;
70        }
[2dd068]71    }
72    if ( r0 == 0 )
[412bedd]73        return this->operator()( pk-q1, symmetric );
[2dd068]74    else
[412bedd]75        return this->operator()( q0, symmetric );
[83452f]76}
[2dd068]77
78CanonicalForm
79modpk::operator() ( const CanonicalForm & f, bool symmetric ) const
80{
81    PKHALF = pkhalf;
82    PK = pk;
83    if ( symmetric )
[412bedd]84        return mapdomain( f, mappksymmetric );
[2dd068]85    else
[412bedd]86        return mapdomain( f, mappk );
[e76d7a6]87}
[2dd068]88
89CanonicalForm
90replaceLc( const CanonicalForm & f, const CanonicalForm & c )
91{
92    if ( f.inCoeffDomain() )
[412bedd]93        return c;
[2dd068]94    else
[412bedd]95        return f + ( c - LC( f ) ) * power( f.mvar(), degree( f ) );
[2dd068]96}
97
98CanonicalForm
99mappksymmetric ( const CanonicalForm & f )
100{
101    CanonicalForm result = mod( f, PK );
102    if ( result > PKHALF )
[412bedd]103        return result - PK;
[2dd068]104    else
[412bedd]105        return result;
[2dd068]106}
107
108CanonicalForm
109mappk ( const CanonicalForm & f )
110{
111    return mod( f, PK );
112}
[7b4bfe6]113
[564dd8]114CanonicalForm
115remainder( const CanonicalForm & f, const CanonicalForm & g, const modpk & pk )
116{
117    ASSERT( (f.inCoeffDomain() || f.isUnivariate()) && (g.inCoeffDomain() || g.isUnivariate()) && (f.inCoeffDomain() || g.inCoeffDomain() || f.mvar() == g.mvar()), "can not build remainder" );
118    if ( f.inCoeffDomain() )
119        if ( g.inCoeffDomain() )
120            return pk( f % g );
121        else
122            return pk( f );
123    else {
124        Variable x = f.mvar();
125        CanonicalForm result = f;
126        int degg = g.degree();
127        CanonicalForm invlcg = pk.inverse( g.lc() );
128        CanonicalForm gg = pk( g*invlcg );
129        if((gg.lc().isOne()))
130        {
131          while ( result.degree() >= degg )
132          {
133            result -= pk(lc( result ) * gg) * power( x, result.degree() - degg );
134            result=pk(result);
135          }
136        }
137        else
138        // no inverse found
139        {
140          CanonicalForm ic=icontent(g);
141          if (!ic.isOne())
142          {
143            gg=g/ic;
144            return remainder(f,gg,pk);
145          }
146          while ( result.degree() >= degg )
147          {
148            if (gg.lc().isZero()) return result;
149            CanonicalForm lcgf = result.lc() / gg.lc();
150            if (lcgf.inZ())
151              gg = pk( g*lcgf );
152            else
153            {
154              //printf("!\n\n");
155              return result;
156            }
157            result -=  gg * power( x, result.degree() - degg );
158            result=pk(result);
159          }
160        }
161        return result;
162    }
163}
164
165CanonicalForm
166prod ( const CFArray & a, int f, int l )
167{
168    if ( f < a.min() ) f = a.min();
169    if ( l > a.max() ) l = a.max();
170    CanonicalForm p = 1;
171    for ( int i = f; i <= l; i++ )
172        p *= a[i];
173    return p;
174}
175
176CanonicalForm
177prod ( const CFArray & a )
178{
179    return prod( a, a.min(), a.max() );
[9f48f5]180}
[564dd8]181
182void
183extgcd ( const CanonicalForm & a, const CanonicalForm & b, CanonicalForm & S, CanonicalForm & T, const modpk & pk )
184{
185    int p = pk.getp(), k = pk.getk(), j;
186    CanonicalForm amodp, bmodp, smodp, tmodp, s, t, sigma, tau, e;
187    CanonicalForm modulus = p, sigmat, taut, q;
188
189    setCharacteristic( p );
190    {
191        amodp = mapinto( a ); bmodp = mapinto( b );
192        (void)extgcd( amodp, bmodp, smodp, tmodp );
193    }
194    setCharacteristic( 0 );
195    s = mapinto( smodp ); t = mapinto( tmodp );
196
197    for ( j = 1; j < k; j++ ) {
198        e = ( 1 - s * a - t * b ) / modulus;
199        setCharacteristic( p );
200        {
201            e = mapinto( e );
202            sigmat = smodp * e;
203            taut = tmodp * e;
204            divrem( sigmat, bmodp, q, sigma );
205            tau = taut + q * amodp;
206        }
207        setCharacteristic( 0 );
208        s += mapinto( sigma ) * modulus;
209        t += mapinto( tau ) * modulus;
210        modulus *= p;
211    }
212    S = s; T = t;
213}
Note: See TracBrowser for help on using the repository browser.