source: git/factory/cf_ops.cc @ e1a1ca

spielwiese
Last change on this file since e1a1ca was e1a1ca, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* cf_ops.cc (resultant): function moved to cf_resultant.cc * cf_ops.cc (psr): returns f now if deg(f) < deg(g) git-svn-id: file:///usr/local/Singular/svn/trunk@649 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.5 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: cf_ops.cc,v 1.6 1997-09-01 09:06:19 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_iter.h"
11
12CanonicalForm
13psr( const CanonicalForm &f, const CanonicalForm &g, const Variable & x )
14{
15    int m = f.degree( x );
16    int n = g.degree( x );
17    if ( m < n )
18        return f;
19    else
20        return ( power( LC(g,x), m-n+1 ) * f ) % g;
21}
22
23CanonicalForm
24psq( const CanonicalForm &f, const CanonicalForm &g, const Variable & x )
25{
26    return ( power( LC(g,x), degree(f,x)-degree(g,x)+1 ) * f ) / g;
27}
28
29void
30psqr( const CanonicalForm &f, const CanonicalForm &g, CanonicalForm &q, CanonicalForm &r, const Variable& x )
31{
32    divrem( power( LC(g,x), degree(f,x)-degree(g,x)+1 ) * f, g, q, r );
33}
34
35static void swapvar_rec ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term );
36
37static void swapvar_between ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term, int expx2 );
38
39static Variable sv_x1, sv_x2;
40
41CanonicalForm
42swapvar ( const CanonicalForm &f, const Variable &x1, const Variable &x2 )
43{
44    ASSERT( x1.level() > 0 && x2.level() > 0, "cannot swap algebraic Variables" );
45    if ( f.inCoeffDomain() || x1 == x2 || ( x1 > f.mvar() && x2 > f.mvar() ) )
46        return f;
47    else {
48        CanonicalForm result = 0;
49        if ( x1 > x2 ) {
50            sv_x1 = x2; sv_x2 = x1;
51        }
52        else {
53            sv_x1 = x1; sv_x2 = x2;
54        }
55        if ( f.mvar() < sv_x2 )
56            swapvar_between( f, result, 1, 0 );
57        else
58            swapvar_rec( f, result, 1 );
59        return result;
60    }
61}
62
63void
64swapvar_rec ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term )
65{
66    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
67        result += term * f;
68    else  if ( f.mvar() == sv_x2 )
69        for ( CFIterator i = f; i.hasTerms(); i++ )
70            swapvar_between( i.coeff(), result, term, i.exp() );
71    else  if ( f.mvar() < sv_x2 )
72        swapvar_between( f, result, term, 0 );
73    else
74        for ( CFIterator i = f; i.hasTerms(); i++ )
75            swapvar_rec( i.coeff(), result, term*power( f.mvar(), i.exp() ) );
76}
77
78void
79swapvar_between ( const CanonicalForm &f, CanonicalForm &result, const CanonicalForm &term, int expx2 )
80{
81    if ( f.inCoeffDomain() || f.mvar() < sv_x1 )
82        result += term * power( sv_x1, expx2 ) * f;
83    else  if ( f.mvar() == sv_x1 )
84        for ( CFIterator i = f; i.hasTerms(); i++ )
85            result += power( sv_x2, i.exp() ) * term * i.coeff() * power( sv_x1, expx2 );
86    else
87        for ( CFIterator i = f; i.hasTerms(); i++ )
88            swapvar_between( i.coeff(), result, term*power( f.mvar(), i.exp() ), expx2 );
89}
90
91CanonicalForm
92apply ( const CanonicalForm & f, void (*mf)( CanonicalForm &, int & ) )
93{
94    if ( f.inCoeffDomain() ) {
95        int exp = 0;
96        CanonicalForm result;
97        mf( result, exp );
98        ASSERT( exp == 0, "illegal result, do not know what variable to use" );
99        return result;
100    }
101    else {
102        CanonicalForm result, coeff;
103        CFIterator i;
104        int exp;
105        Variable x = f.mvar();
106        for ( i = f; i.hasTerms(); i++ ) {
107            coeff = i.coeff();
108            exp = i.exp();
109            mf( coeff, exp );
110            if ( ! coeff.isZero() )
111                result += power( x, exp ) * coeff;
112        }
113        return result;
114    }
115}
116
117//{{{ static void degreesRec ( const CanonicalForm & f, int * degs )
118//{{{ docu
119//
120// degreesRec() - recursively get degrees of f.
121//
122//}}}
123static void
124degreesRec ( const CanonicalForm & f, int * degs )
125{
126    if ( ! f.inCoeffDomain() ) {
127        int level = f.level();
128        int deg = f.degree();
129        // calculate the maximum degree of all coefficients which
130        // are in the same level
131        if ( degs[level] < deg )
132            degs[level] = f.degree();
133        for ( CFIterator i = f; i.hasTerms(); i++ )
134            degreesRec( i.coeff(), degs );
135    }
136}
137//}}}
138
139//{{{ int * degrees ( const CanonicalForm & f, int * degs )
140//{{{ docu
141//
142// degress() - return the degrees of all polynomial variables in f.
143//
144// Returns 0 if f is in a coefficient domain, the degrees of f in
145// all its polynomial variables in an array of int otherwise:
146//
147//   degrees( f, 0 )[i] = degree( f, Variable(i) )
148//
149// If degs is not the zero pointer the degrees are stored in this
150// array.  In this case degs should be larger than the level of
151// f.  If degs is the zero pointer, an array of sufficient size
152// is allocated automatically.
153//
154//}}}
155int *
156degrees ( const CanonicalForm & f, int * degs )
157{
158    if ( f.inCoeffDomain() )
159        return 0;
160    else {
161        int level = f.level();
162        if ( degs == 0 )
163            degs = new int[level+1];
164        for ( int i = 0; i <= level; i++ )
165            degs[i] = 0;
166        degreesRec( f, degs );
167        return degs;
168    }
169}
170//}}}
171
172//{{{ CanonicalForm mapdomain ( const CanonicalForm & f, CanonicalForm (*mf)( const CanonicalForm & ) )
173//{{{ docu
174//
175// mapdomain() - map all coefficients of f through mf.
176//
177// Recursively descends down through f to the coefficients which
178// are in a coefficient domain mapping each such coefficient
179// through mf and returns the result.
180//
181//}}}
182CanonicalForm
183mapdomain ( const CanonicalForm & f, CanonicalForm (*mf)( const CanonicalForm & ) )
184{
185    if ( f.inCoeffDomain() )
186        return mf( f );
187    else {
188        CanonicalForm result = 0;
189        CFIterator i;
190        Variable x = f.mvar();
191        for ( i = f; i.hasTerms(); i++ )
192            result += power( x, i.exp() ) * mapdomain( i.coeff(), mf );
193        return result;
194    }
195}
196//}}}
197
198//{{{ int totaldegree ( const CanonicalForm & f )
199//{{{ docu
200//
201// totaldegree() - return the total degree of f.
202//
203// If f is zero, return -1.  If f is in a coefficient domain,
204// return 0.  Otherwise return the total degree of f in all
205// polynomial variables.
206//
207//}}}
208int
209totaldegree ( const CanonicalForm & f )
210{
211    if ( f.isZero() )
212        return -1;
213    else if ( f.inCoeffDomain() )
214        return 0;
215    else {
216        CFIterator i;
217        int cdeg = 0, dummy;
218        // calculate maximum over all coefficients of f, taking
219        // in account our own exponent
220        for ( i = f; i.hasTerms(); i++ )
221            if ( (dummy = totaldegree( i.coeff() ) + i.exp()) > cdeg )
222                cdeg = dummy;
223        return cdeg;
224    }
225}
226//}}}
227
228//{{{ int totaldegree ( const CanonicalForm & f, const Variable & v1, const Variable & v2 )
229//{{{ docu
230//
231// totaldegree() - return the total degree of f as a polynomial
232//   in the polynomial variables between v1 and v2 (inclusively).
233//
234// If f is zero, return -1.  If f is in a coefficient domain,
235// return 0.  Also, return 0 if v1 > v2.  Otherwise, take f to be
236// a polynomial in the polynomial variables between v1 and v2 and
237// return its total degree.
238//
239//}}}
240int
241totaldegree ( const CanonicalForm & f, const Variable & v1, const Variable & v2 )
242{
243    if ( f.isZero() )
244        return -1;
245    else if ( v1 > v2 )
246        return 0;
247    else if ( f.inCoeffDomain() )
248        return 0;
249    else if ( f.mvar() < v1 )
250        return 0;
251    else if ( f.mvar() == v1 )
252        return f.degree();
253    else if ( f.mvar() > v2 ) {
254        // v2's level is larger than f's level, descend down
255        CFIterator i;
256        int cdeg = 0, dummy;
257        // calculate maximum over all coefficients of f
258        for ( i = f; i.hasTerms(); i++ )
259            if ( (dummy = totaldegree( i.coeff(), v1, v2 )) > cdeg )
260                cdeg = dummy;
261        return cdeg;
262    }
263    else {
264        // v1 < f.mvar() <= v2
265        CFIterator i;
266        int cdeg = 0, dummy;
267        // calculate maximum over all coefficients of f, taking
268        // in account our own exponent
269        for ( i = f; i.hasTerms(); i++ )
270            if ( (dummy = totaldegree( i.coeff(), v1, v2 ) + i.exp()) > cdeg )
271                cdeg = dummy;
272        return cdeg;
273    }
274}
275//}}}
276
277//{{{ static void fillVarsRec ( const CanonicalForm & f, int * vars )
278//{{{ docu
279//
280// fillVarsRec - fill array describing occurences of variables in f.
281//
282// Only polynomial variables are looked up.  The information is
283// stored in the arrary vars.  vars should be large enough to
284// hold all information, i.e. larger than the level of f.
285//
286//}}}
287static void
288fillVarsRec ( const CanonicalForm & f, int * vars )
289{
290    int n;
291    if ( (n = f.level()) > 0 ) {
292        vars[n] = 1;
293        CFIterator i;
294        for ( i = f; i.hasTerms(); ++i )
295            fillVarsRec( i.coeff(), vars );
296    }
297}
298//}}}
299
300//{{{ int getNumVars( const CanonicalForm & f )
301//{{{ docu
302//
303// getNumVars() - get number of polynomial variables in f.
304//
305//}}}
306int
307getNumVars( const CanonicalForm & f )
308{
309    int n;
310    if ( f.inCoeffDomain() )
311        return 0;
312    else  if ( (n = f.level()) == 1 )
313        return 1;
314    else {
315        int * vars = new int[ n+1 ];
316        int i;
317        for ( i = 0; i < n; i++ ) vars[i] = 0;
318
319        // look for variables
320        for ( CFIterator I = f; I.hasTerms(); ++I )
321            fillVarsRec( I.coeff(), vars );
322
323        // count them
324        int m = 0;
325        for ( i = 1; i < n; i++ )
326            if ( vars[i] != 0 ) m++;
327
328        delete [] vars;
329        // do not forget to count our own variable
330        return m+1;
331    }
332}
333//}}}
334
335//{{{ CanonicalForm getVars( const CanonicalForm & f )
336//{{{ docu
337//
338// getVars() - get polynomial variables of f.
339//
340// Return the product of all of them, 1 if there are not any.
341//
342//}}}
343CanonicalForm
344getVars( const CanonicalForm & f )
345{
346    int n;
347    if ( f.inCoeffDomain() )
348        return 1;
349    else  if ( (n = f.level()) == 1 )
350        return Variable( 1 );
351    else {
352        int * vars = new int[ n+1 ];
353        int i;
354        for ( i = 0; i <= n; i++ ) vars[i] = 0;
355
356        // look for variables
357        for ( CFIterator I = f; I.hasTerms(); ++I )
358            fillVarsRec( I.coeff(), vars );
359
360        // multiply them all
361        CanonicalForm result = 1;
362        for ( i = n; i > 0; i-- )
363            if ( vars[i] != 0 ) result *= Variable( i );
364
365        delete [] vars;
366        // do not forget our own variable
367        return f.mvar() * result;
368    }
369}
370//}}}
371
372static CanonicalForm
373cden ( const CanonicalForm & f )
374{
375    if ( f.inCoeffDomain() )
376        return f.den();
377    else {
378        CFIterator i;
379        CanonicalForm cd = 1;
380        for ( i = f; i.hasTerms(); i++ )
381            cd = lcm( cd, cden( i.coeff() ) );
382        return cd;
383    }
384}
385
386CanonicalForm
387common_den ( const CanonicalForm & f )
388{
389    if ( getCharacteristic() == 0 && isOn( SW_RATIONAL ) ) {
390        Off( SW_RATIONAL );
391        CanonicalForm cd = cden( f );
392        On( SW_RATIONAL );
393        return cd;
394    }
395    else
396        return 1;
397}
Note: See TracBrowser for help on using the repository browser.