1 | /* emacs edit mode for this file is -*- C++ -*- */ |
---|
2 | /* $Id: cf_algorithm.cc,v 1.2 1997-09-08 16:02:02 schmidt Exp $ */ |
---|
3 | |
---|
4 | //{{{ docu |
---|
5 | // |
---|
6 | // cf_algorithm.cc - simple mathematical algorithms. |
---|
7 | // |
---|
8 | // A 'mathematical' algorithm is an algorithm which calculates |
---|
9 | // some mathematical function in contrast to a 'structural' |
---|
10 | // algorithm which gives structural information on polynomials. |
---|
11 | // |
---|
12 | // Compare these functions to the functions in cf_ops.cc, which are |
---|
13 | // structural algorithms. |
---|
14 | // |
---|
15 | // Used by: cf_gcd.cc, cf_resultant.cc |
---|
16 | // |
---|
17 | //}}} |
---|
18 | |
---|
19 | #include <config.h> |
---|
20 | |
---|
21 | #include "assert.h" |
---|
22 | |
---|
23 | #include "cf_defs.h" |
---|
24 | #include "canonicalform.h" |
---|
25 | #include "variable.h" |
---|
26 | #include "cf_iter.h" |
---|
27 | |
---|
28 | //{{{ CanonicalForm psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x ) |
---|
29 | //{{{ docu |
---|
30 | // |
---|
31 | // psr() - calculate pseudo remainder of f and g with respect to x. |
---|
32 | // |
---|
33 | // x should be a polynomial variable. |
---|
34 | // |
---|
35 | // For f and g in R[x], R an integral domain, g != 0, there is a |
---|
36 | // unique representation |
---|
37 | // |
---|
38 | // lc(g)^s*f = g*q + r |
---|
39 | // |
---|
40 | // with r = 0 or deg(r) < deg(g) and s = 0 if f = 0 or |
---|
41 | // s = max( 0, deg(f)-deg(g)+1 ) otherwise. |
---|
42 | // Then r = psr(f, g) and q = psq(f, g) are called pseudo |
---|
43 | // remainder and pseudo quotient, resp. |
---|
44 | // |
---|
45 | // See H.-J. Reiffen/G. Scheja/U. Vetter - 'Algebra', 2nd ed., |
---|
46 | // par. 15 for a reference. |
---|
47 | // |
---|
48 | //}}} |
---|
49 | CanonicalForm |
---|
50 | psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x ) |
---|
51 | { |
---|
52 | ASSERT( x.level() > 0, "cannot calculate pseudo remainder/quotient with respect to algebraic variables" ); |
---|
53 | ASSERT( g != 0, "division by zero" ); |
---|
54 | |
---|
55 | int m = degree( f, x ); |
---|
56 | int n = degree( g, x ); |
---|
57 | if ( m < 0 || m < n ) |
---|
58 | return f; |
---|
59 | else |
---|
60 | return ( power( LC( g, x ), m-n+1 ) * f ) % g; |
---|
61 | } |
---|
62 | //}}} |
---|
63 | |
---|
64 | //{{{ CanonicalForm psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x ) |
---|
65 | //{{{ docu |
---|
66 | // |
---|
67 | // psq() - calculate pseudo quotient of f and g with respect to x. |
---|
68 | // |
---|
69 | // x should be a polynomial variable. See psr() for more |
---|
70 | // detailed information. |
---|
71 | // |
---|
72 | //}}} |
---|
73 | CanonicalForm |
---|
74 | psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x ) |
---|
75 | { |
---|
76 | ASSERT( x.level() > 0, "cannot calculate pseudo remainder/quotient with respect to algebraic variables" ); |
---|
77 | ASSERT( g != 0, "division by zero" ); |
---|
78 | |
---|
79 | int m = degree( f, x ); |
---|
80 | int n = degree( g, x ); |
---|
81 | if ( m < 0 || m < n ) |
---|
82 | return 0; |
---|
83 | else |
---|
84 | return ( power( LC( g, x ), m-n+1 ) * f ) / g; |
---|
85 | } |
---|
86 | //}}} |
---|
87 | |
---|
88 | //{{{ void psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable & x ) |
---|
89 | //{{{ docu |
---|
90 | // |
---|
91 | // psqr() - calculate pseudo quotient and remainder of f and g with respect to x. |
---|
92 | // |
---|
93 | // x should be a polynomial variable. See psr() for more |
---|
94 | // detailed information. |
---|
95 | // |
---|
96 | //}}} |
---|
97 | void |
---|
98 | psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable& x ) |
---|
99 | { |
---|
100 | ASSERT( x.level() > 0, "cannot calculate pseudo remainder/quotient with respect to algebraic variables" ); |
---|
101 | ASSERT( g != 0, "division by zero" ); |
---|
102 | |
---|
103 | int m = degree( f, x ); |
---|
104 | int n = degree( g, x ); |
---|
105 | if ( m < 0 || m < n ) { |
---|
106 | q = 0; r = f; |
---|
107 | } |
---|
108 | else |
---|
109 | divrem( power( LC( g, x ), m-n+1 ) * f, g, q, r ); |
---|
110 | } |
---|
111 | //}}} |
---|
112 | |
---|
113 | //{{{ static CanonicalForm cden ( const CanonicalForm & f ) |
---|
114 | //{{{ docu |
---|
115 | // |
---|
116 | // cden() - recursively calculate multivariate common denominator |
---|
117 | // of coefficients of f. |
---|
118 | // |
---|
119 | // Used by: common_den() |
---|
120 | // |
---|
121 | //}}} |
---|
122 | static CanonicalForm |
---|
123 | cden ( const CanonicalForm & f ) |
---|
124 | { |
---|
125 | if ( f.inBaseDomain() ) |
---|
126 | return f.den(); |
---|
127 | else { |
---|
128 | CFIterator i; |
---|
129 | CanonicalForm cd = 1; |
---|
130 | for ( i = f; i.hasTerms(); i++ ) |
---|
131 | cd = lcm( cd, cden( i.coeff() ) ); |
---|
132 | return cd; |
---|
133 | } |
---|
134 | } |
---|
135 | //}}} |
---|
136 | |
---|
137 | //{{{ CanonicalForm common_den ( const CanonicalForm & f ) |
---|
138 | //{{{ docu |
---|
139 | // |
---|
140 | // common_den() - calculate multivariate common denominator of |
---|
141 | // coefficients of f. |
---|
142 | // |
---|
143 | // The common denominator is calculated with respect to all |
---|
144 | // coefficients of f which are in a base domain. In other words, |
---|
145 | // common_den( f ) * f is guaranteed to have integer |
---|
146 | // coefficients only. |
---|
147 | // |
---|
148 | // Returns one for domains other than Q. |
---|
149 | // |
---|
150 | //}}} |
---|
151 | CanonicalForm |
---|
152 | common_den ( const CanonicalForm & f ) |
---|
153 | { |
---|
154 | if ( getCharacteristic() == 0 && isOn( SW_RATIONAL ) ) { |
---|
155 | // switch to Z so lcm() will work correctly |
---|
156 | Off( SW_RATIONAL ); |
---|
157 | CanonicalForm cd = cden( f ); |
---|
158 | On( SW_RATIONAL ); |
---|
159 | return cd; |
---|
160 | } |
---|
161 | else |
---|
162 | return 1; |
---|
163 | } |
---|
164 | //}}} |
---|