source: git/factory/fac_util.cc @ e7232f

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