source: git/factory/cf_ops.cc @ ac7e53

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