source: git/factory/cf_ops.cc @ b973c0

spielwiese
Last change on this file since b973c0 was b973c0, checked in by Jens Schmidt <schmidt@…>, 27 years ago
#include <config.h> added git-svn-id: file:///usr/local/Singular/svn/trunk@136 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.6 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2// $Id: cf_ops.cc,v 1.1 1997-04-07 16:04:13 schmidt Exp $
3
4/*
5$Log: not supported by cvs2svn $
6Revision 1.0  1996/05/17 11:56:37  stobbe
7Initial revision
8
9*/
10
11#include <config.h>
12
13#include "assert.h"
14
15#include "cf_defs.h"
16#include "canonicalform.h"
17#include "cf_iter.h"
18
19CanonicalForm
20psr( const CanonicalForm &f, const CanonicalForm &g, const Variable & x )
21{
22    return ( power( LC(g,x), degree(f,x)-degree(g,x)+1 ) * f ) % g;
23}
24
25CanonicalForm
26psq( const CanonicalForm &f, const CanonicalForm &g, const Variable & x )
27{
28    return ( power( LC(g,x), degree(f,x)-degree(g,x)+1 ) * f ) / g;
29}
30
31void
32psqr( const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r, const Variable& x )
33{
34    divrem( power( LC(g,x), degree(f,x)-degree(g,x)+1 ) * f, g, q, r );
35}
36
37static void swapvar_rec ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term );
38
39static void swapvar_between ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term, int expx2 );
40
41static Variable sv_x1, sv_x2;
42
43CanonicalForm
44swapvar ( const CanonicalForm &f, const Variable &x1, const Variable &x2 )
45{
46    ASSERT( x1.level() > 0 && x2.level() > 0, "cannot swap algebraic Variables" );
47    if ( f.inCoeffDomain() || x1 == x2 || ( x1 > f.mvar() && x2 > f.mvar() ) )
48        return f;
49    else {
50        CanonicalForm result = 0;
51        if ( x1 > x2 ) {
52            sv_x1 = x2; sv_x2 = x1;
53        }
54        else {
55            sv_x1 = x1; sv_x2 = x2;
56        }
57        if ( f.mvar() < sv_x2 )
58            swapvar_between( f, result, 1, 0 );
59        else
60            swapvar_rec( f, result, 1 );
61        return result;
62    }
63}
64
65void
66swapvar_rec ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term )
67{
68    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
69        result += term * f;
70    else  if ( f.mvar() == sv_x2 )
71        for ( CFIterator i = f; i.hasTerms(); i++ )
72            swapvar_between( i.coeff(), result, term, i.exp() );
73    else  if ( f.mvar() < sv_x2 )
74        swapvar_between( f, result, term, 0 );
75    else
76        for ( CFIterator i = f; i.hasTerms(); i++ )
77            swapvar_rec( i.coeff(), result, term*power( f.mvar(), i.exp() ) );
78}
79
80void
81swapvar_between ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term, int expx2 )
82{
83    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
84        result += term * power( sv_x1, expx2 ) * f;
85    else  if ( f.mvar() == sv_x1 )
86        for ( CFIterator i = f; i.hasTerms(); i++ )
87            result += power( sv_x2, i.exp() ) * term * i.coeff() * power( sv_x1, expx2 );
88    else
89        for ( CFIterator i = f; i.hasTerms(); i++ )
90            swapvar_between( i.coeff(), result, term*power( f.mvar(), i.exp() ), expx2 );
91}
92
93CanonicalForm
94apply ( const CanonicalForm & f, void (*mf)( CanonicalForm &, int & ) )
95{
96    if ( f.inCoeffDomain() ) {
97        int exp = 0;
98        CanonicalForm result;
99        mf( result, exp );
100        ASSERT( exp == 0, "illegal result, do not know what variable to use" );
101        return result;
102    }
103    else {
104        CanonicalForm result, coeff;
105        CFIterator i;
106        int exp;
107        Variable x = f.mvar();
108        for ( i = f; i.hasTerms(); i++ ) {
109            coeff = i.coeff();
110            exp = i.exp();
111            mf( coeff, exp );
112            if ( ! coeff.isZero() )
113                result += power( x, exp ) * coeff;
114        }
115        return result;
116    }
117}
118
119void
120degreesRec ( const CanonicalForm & f, int * degs )
121{
122    if ( ! f.inCoeffDomain() ) {
123        int level = f.level();
124        int deg = f.degree();
125        if ( degs[level] < deg )
126            degs[level] = f.degree();
127        for ( CFIterator i = f; i.hasTerms(); i++ )
128            degreesRec( i.coeff(), degs );
129    }
130}
131
132int *
133degrees ( const CanonicalForm & f, int * degs )
134{
135    if ( f.inCoeffDomain() )
136        return 0;
137    else {
138        int level = f.level();
139        if ( degs == 0 )
140            degs = new int[level+1];
141        for ( int i = 0; i <= level; i++ )
142            degs[i] = 0;
143        degreesRec( f, degs );
144        return degs;
145    }
146}
147
148CanonicalForm
149mapdomain ( const CanonicalForm & f, CanonicalForm (*mf)( const CanonicalForm & ) )
150{
151    if ( f.inCoeffDomain() )
152        return mf( f );
153    else {
154        CanonicalForm result = 0;
155        CFIterator i;
156        Variable x = f.mvar();
157        for ( i = f; i.hasTerms(); i++ )
158            result += power( x, i.exp() ) * mapdomain( i.coeff(), mf );
159        return result;
160    }
161}
162
163int
164totaldegree ( const CanonicalForm & f )
165{
166    if ( f.isZero() )
167        return -1;
168    else if ( f.inCoeffDomain() )
169        return 0;
170    else {
171        CFIterator i;
172        int cdeg = 0, dummy;
173        for ( i = f; i.hasTerms(); i++ )
174            if ( (dummy = totaldegree( i.coeff() ) + i.exp()) > cdeg )
175                cdeg = dummy;
176        return cdeg;
177    }
178}
179
180
181int
182totaldegree ( const CanonicalForm & f, const Variable & v1, const Variable & v2 )
183{
184    if ( f.isZero() )
185        return -1;
186    else if ( v1 > v2 )
187        return 0;
188    else if ( f.inCoeffDomain() )
189        return 0;
190    else if ( f.mvar() < v1 )
191        return 0;
192    else if ( f.mvar() == v1 )
193        return f.degree();
194    else if ( f.mvar() > v2 ) {
195        CFIterator i;
196        int cdeg = 0, dummy;
197        for ( i = f; i.hasTerms(); i++ )
198            if ( (dummy = totaldegree( i.coeff(), v1, v2 )) > cdeg )
199                cdeg = dummy;
200        return cdeg;
201    }
202    else {
203        CFIterator i;
204        int cdeg = 0, dummy;
205        for ( i = f; i.hasTerms(); i++ )
206            if ( (dummy = totaldegree( i.coeff(), v1, v2 ) + i.exp()) > cdeg )
207                cdeg = dummy;
208        return cdeg;
209    }
210}
211
212CanonicalForm
213resultant( const CanonicalForm & f, const CanonicalForm& g, const Variable & x )
214{
215    CanonicalForm Hi, bi, pi, pi1, pi2, F, G;
216    int delta;
217    Variable v = f.mvar();
218
219    if ( f.mvar() < x || g.mvar() < x )
220        return 1;
221
222    if ( f.mvar() > x || g.mvar() > x ) {
223        if ( f.mvar() > g.mvar() )
224            v = f.mvar();
225        else
226            v = g.mvar();
227        F = swapvar( f, v, x );
228        G = swapvar( g, v, x );
229    }
230    else {
231        v = x;
232        F = f;
233        G = g;
234    }
235    if ( F.degree( v ) < 1 || G.degree( v ) < 1 )
236        return 1;
237
238    if ( f.degree( v ) >= g.degree( v ) ) {
239        pi = F; pi1 = G;
240    }
241    else {
242        pi = G; pi1 = F;
243    }
244    delta = degree( pi, v ) - degree( pi1, v );
245    Hi = power( LC( pi1, v ), delta );
246    if ( (delta+1) % 2 )
247        bi = 1;
248    else
249        bi = -1;
250    while ( degree( pi1, v ) >= 0 ) {
251        pi2 = psr( pi, pi1, v );
252        pi2 = pi2 / bi;
253        pi = pi1; pi1 = pi2;
254        if ( degree( pi1, v ) >= 0 ) {
255            delta = degree( pi, v ) - degree( pi1, v );
256            if ( (delta+1) % 2 )
257                bi = LC( pi, v ) * power( Hi, delta );
258            else
259                bi = -LC( pi, v ) * power( Hi, delta );
260            Hi = power( LC( pi1, v ), delta ) / power( Hi, delta-1 );
261        }
262    }
263    if ( v == x )
264        return Hi;
265    else
266        return swapvar( Hi, v, x );
267}
268
269
270static CanonicalForm
271cden ( const CanonicalForm & f )
272{
273    if ( f.inCoeffDomain() )
274        return f.den();
275    else {
276        CFIterator i;
277        CanonicalForm cd = 1;
278        for ( i = f; i.hasTerms(); i++ )
279            cd = lcm( cd, cden( i.coeff() ) );
280        return cd;
281    }
282}
283
284CanonicalForm
285common_den ( const CanonicalForm & f )
286{
287    if ( getCharacteristic() == 0 && isOn( SW_RATIONAL ) ) {
288        Off( SW_RATIONAL );
289        CanonicalForm cd = cden( f );
290        On( SW_RATIONAL );
291        return cd;
292    }
293    else
294        return 1;
295}
Note: See TracBrowser for help on using the repository browser.