source: git/factory/fac_util.cc @ 84250a6

spielwiese
Last change on this file since 84250a6 was 173e86, checked in by Jens Schmidt <schmidt@…>, 27 years ago
#include <config.h> added git-svn-id: file:///usr/local/Singular/svn/trunk@138 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.0 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2// $Id: fac_util.cc,v 1.5 1997-04-08 10:37:42 schmidt Exp $
3
4/*
5$Log: not supported by cvs2svn $
6Revision 1.4  1997/03/27 09:56:58  schmidt
7error check changed to ASSERT
8
9Revision 1.3  1996/07/16 12:26:05  stobbe
10"New functions prod, crossprod ans sum for CFArrays, since these functions
11are no longer contained in the template specification of Array.
12"
13
14Revision 1.2  1996/07/08 08:22:02  stobbe
15"New organization of the factorization stuff. Some functions moved from
16fac_diophand.cc which no longer exists.
17"
18
19Revision 1.1  1996/06/27 11:34:24  stobbe
20"New function dviremainder.
21"
22
23Revision 1.0  1996/05/17 10:59:46  stobbe
24Initial revision
25
26*/
27
28#include <config.h>
29
30#include "assert.h"
31
32#include "cf_defs.h"
33#include "canonicalform.h"
34#include "cf_iter.h"
35#include "fac_util.h"
36
37static CanonicalForm PK, PKHALF;
38
39static CanonicalForm mappk ( const CanonicalForm& );
40
41static CanonicalForm mappksymmetric ( const CanonicalForm& );
42
43
44modpk::modpk()
45{
46    p = 3;
47    k = 1;
48    pk = power( CanonicalForm( p ), k );
49    pkhalf = pk / 2;
50}
51
52modpk::modpk( int q, int l )
53{
54    p = q;
55    k = l;
56    pk = power( CanonicalForm( p ), k );
57    pkhalf = pk / 2;
58}
59
60modpk::modpk( const modpk & m )
61{
62    p = m.p;
63    k = m.k;
64    pk = m.pk;
65    pkhalf = m.pkhalf;
66}
67
68modpk&
69modpk::operator= ( const modpk & m )
70{
71    if ( this != &m ) {
72        p = m.p;
73        k = m.k;
74        pk = m.pk;
75        pkhalf = m.pkhalf;
76    }
77    return *this;
78}
79
80CanonicalForm
81modpk::inverse( const CanonicalForm & f, bool symmetric ) const
82{
83    CanonicalForm u, r0 = this->operator()( f, false ), r1 = pk, q0 = 1, q1 = 0;
84    while ( ( r0 > 0 ) && ( r1 > 0 ) ) {
85        u = r0 / r1;
86        r0 = r0 % r1;
87        q0 = u*q1 + q0;
88        if ( r0 > 0 ) {
89            u = r1 / r0;
90            r1 = r1 % r0;
91            q1 = u*q0 + q1;
92        }
93    }
94    if ( r0 == 0 )
95        return this->operator()( pk-q1, symmetric );
96    else
97        return this->operator()( q0, symmetric );
98}
99
100CanonicalForm
101modpk::operator() ( const CanonicalForm & f, bool symmetric ) const
102{
103    PKHALF = pkhalf;
104    PK = pk;
105    if ( symmetric )
106        return mapdomain( f, mappksymmetric );
107    else
108        return mapdomain( f, mappk );
109};
110
111CanonicalForm
112replaceLc( const CanonicalForm & f, const CanonicalForm & c )
113{
114    if ( f.inCoeffDomain() )
115        return c;
116    else
117        return f + ( c - LC( f ) ) * power( f.mvar(), degree( f ) );
118}
119
120CanonicalForm
121remainder( const CanonicalForm & f, const CanonicalForm & g, const modpk & pk )
122{
123    ASSERT( (f.inCoeffDomain() || f.isUnivariate()) && (g.inCoeffDomain() || g.isUnivariate()) && (f.inCoeffDomain() || g.inCoeffDomain() || f.mvar() == g.mvar()), "can not build remainder" );
124    if ( f.inCoeffDomain() )
125        if ( g.inCoeffDomain() )
126            return pk( f % g );
127        else
128            return pk( f );
129    else {
130        Variable x = f.mvar();
131        CanonicalForm invlcg = pk.inverse( g.lc() );
132        CanonicalForm result = f;
133        int degg = g.degree();
134        while ( result.degree() >= degg ) {
135            result = pk( result - lc( result ) * invlcg * g * power( x, result.degree() - degg ) );
136        }
137        return result;
138    }
139}
140
141void
142divremainder( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & quot, CanonicalForm & rem, const modpk & pk )
143{
144    ASSERT( (f.inCoeffDomain() || f.isUnivariate()) && (g.inCoeffDomain() || g.isUnivariate()) && (f.inCoeffDomain() || g.inCoeffDomain() || f.mvar() == g.mvar()), "can not build remainder" );
145    if ( f.inCoeffDomain() )
146        if ( g.inCoeffDomain() ) {
147            divrem( f, g, quot, rem );
148            quot = pk( quot );
149            rem = pk( rem );
150        }
151        else {
152            quot = 0;
153            rem = pk( f );
154        }
155    else {
156        Variable x = f.mvar();
157        CanonicalForm invlcg = pk.inverse( g.lc() );
158        rem = f;
159        int degg = g.degree();
160        while ( rem.degree() >= degg ) {
161            quot += pk( lc( rem ) * invlcg ) * power( x, rem.degree() - degg );
162            rem = pk( rem - lc( rem ) * invlcg * g * power( x, rem.degree() - degg ) );
163        }
164    }
165}
166
167CanonicalForm
168maxCoeff( const CanonicalForm & f )
169{
170    if ( f.inCoeffDomain() )
171        return abs( f );
172    else {
173        CanonicalForm M = 0, m;
174        for ( CFIterator i = f; i.hasTerms(); i++ )
175            if ( (m = maxCoeff( i.coeff() )) > M )
176                M = m;
177        return M;
178    }
179}
180
181
182CanonicalForm
183mappksymmetric ( const CanonicalForm & f )
184{
185    CanonicalForm result = mod( f, PK );
186    if ( result > PKHALF )
187        return result - PK;
188    else
189        return result;
190}
191
192CanonicalForm
193mappk ( const CanonicalForm & f )
194{
195    return mod( f, PK );
196}
197
198void
199extgcd ( const CanonicalForm & a, const CanonicalForm & b, CanonicalForm & S, CanonicalForm & T, const modpk & pk )
200{
201    int p = pk.getp(), k = pk.getk(), j;
202    CanonicalForm amodp, bmodp, smodp, tmodp, s, t, sigma, tau, e;
203    CanonicalForm modulus = p, sigmat, taut, q;
204
205    setCharacteristic( p );
206    {
207        amodp = mapinto( a ); bmodp = mapinto( b );
208        (void)extgcd( amodp, bmodp, smodp, tmodp );
209    }
210    setCharacteristic( 0 );
211    s = mapinto( smodp ); t = mapinto( tmodp );
212
213    for ( j = 1; j < k; j++ ) {
214        e = ( 1 - s * a - t * b ) / modulus;
215        setCharacteristic( p );
216        {
217            e = mapinto( e );
218            sigmat = smodp * e;
219            taut = tmodp * e;
220            divrem( sigmat, bmodp, q, sigma );
221            tau = taut + q * amodp;
222        }
223        setCharacteristic( 0 );
224        s += mapinto( sigma ) * modulus;
225        t += mapinto( tau ) * modulus;
226        modulus *= p;
227    }
228    S = s; T = t;
229}
230
231CanonicalForm
232sum ( const CFArray & a, int f, int l )
233{
234    if ( f < a.min() ) f = a.min();
235    if ( l > a.max() ) l = a.max();
236    CanonicalForm s = 0;
237    for ( int i = f; i <= l; i++ )
238        s += a[i];
239    return s;
240}
241
242CanonicalForm
243prod ( const CFArray & a, int f, int l )
244{
245    if ( f < a.min() ) f = a.min();
246    if ( l > a.max() ) l = a.max();
247    CanonicalForm p = 1;
248    for ( int i = f; i <= l; i++ )
249        p *= a[i];
250    return p;
251}
252
253CanonicalForm
254sum ( const CFArray & a )
255{
256    return sum( a, a.min(), a.max() );
257}
258
259CanonicalForm
260prod ( const CFArray & a )
261{
262    return prod( a, a.min(), a.max() );
263}
264
265CanonicalForm
266crossprod ( const CFArray & a, const CFArray & b )
267{
268    ASSERT( a.size() == b.size(), "array size mismatch" );
269    CanonicalForm s = 0;
270    int fa = a.min();
271    int fb = b.min();
272    int n = a.max();
273    for ( ; fa <= n; fa++, fb++ )
274        s += a[fa] * b[fb];
275    return s;
276}
Note: See TracBrowser for help on using the repository browser.