source: git/factory/cf_algorithm.cc @ 194f5e5

spielwiese
Last change on this file since 194f5e5 was 9719434, checked in by Jens Schmidt <schmidt@…>, 26 years ago
* cf_algorithm.cc (divides): slightly speeded up. * cf_algorithm.cc (cden, common_den): renamed to `internalBCommonDen()' and `bCommonDen()', resp. Declarations adapted. All references changed. * cf_algorithm.cc (maxNorm, euclideanNorm): new functions. Declarations added. * cf_algorithm.cc (internalBCommonDen): uses `blcm()' instead of `lcm()' git-svn-id: file:///usr/local/Singular/svn/trunk@1214 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.2 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: cf_algorithm.cc,v 1.6 1998-03-12 10:26:14 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, fac_distrib.cc,
16//   fac_ezgcd.cc, fac_util.cc, sm_sparsemod.cc
17//
18//}}}
19
20#include <config.h>
21
22#include "assert.h"
23
24#include "cf_defs.h"
25#include "canonicalform.h"
26#include "cf_algorithm.h"
27#include "variable.h"
28#include "cf_iter.h"
29
30//{{{ CanonicalForm psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
31//{{{ docu
32//
33// psr() - calculate pseudo remainder of `f' and `g' with respect
34//   to `x'.
35//
36// `x' should be a polynomial variable, `g' must not equal zero.
37//
38// For f and g in R[x], R an integral domain, g != 0, there is a
39// unique representation
40//
41//   lc(g)^s*f = g*q + r
42//
43// with r = 0 or deg(r) < deg(g) and s = 0 if f = 0 or
44// s = max( 0, deg(f)-deg(g)+1 ) otherwise.
45// Then r = psr(f, g) and q = psq(f, g) are called pseudo
46// remainder and pseudo quotient, resp.
47//
48// See H.-J. Reiffen/G. Scheja/U. Vetter - 'Algebra', 2nd ed.,
49// par. 15 for a reference.
50//
51//}}}
52CanonicalForm
53psr ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
54{
55    ASSERT( x.level() > 0, "illegal variable" );
56    ASSERT( g != 0, "division by zero" );
57
58    int m = degree( f, x );
59    int n = degree( g, x );
60    if ( m < 0 || m < n )
61        return f;
62    else
63        return ( power( LC( g, x ), m-n+1 ) * f ) % g;
64}
65//}}}
66
67//{{{ CanonicalForm psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
68//{{{ docu
69//
70// psq() - calculate pseudo quotient of `f' and `g' with respect
71//   to `x'.
72//
73// `x' should be a polynomial variable, `g' must not equal zero.
74// See `psr()' for more detailed information.
75//
76//}}}
77CanonicalForm
78psq ( const CanonicalForm & f, const CanonicalForm & g, const Variable & x )
79{
80    ASSERT( x.level() > 0, "illegal variable" );
81    ASSERT( g != 0, "division by zero" );
82
83    int m = degree( f, x );
84    int n = degree( g, x );
85    if ( m < 0 || m < n )
86        return 0;
87    else
88        return ( power( LC( g, x ), m-n+1 ) * f ) / g;
89}
90//}}}
91
92//{{{ void psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable & x )
93//{{{ docu
94//
95// psqr() - calculate pseudo quotient and remainder of `f' and
96//   `g' with respect to `x'.
97//
98// `x' should be a polynomial variable, `g' must not equal zero.
99// See `psr()' for more detailed information.
100//
101//}}}
102void
103psqr ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r, const Variable& x )
104{
105    ASSERT( x.level() > 0, "illegal variable" );
106    ASSERT( g != 0, "division by zero" );
107
108    int m = degree( f, x );
109    int n = degree( g, x );
110    if ( m < 0 || m < n ) {
111        q = 0; r = f;
112    }
113    else
114        divrem( power( LC( g, x ), m-n+1 ) * f, g, q, r );
115}
116//}}}
117
118//{{{ static CanonicalForm internalBCommonDen ( const CanonicalForm & f )
119//{{{ docu
120//
121// internalBCommonDen() - recursively calculate multivariate
122//   common denominator of coefficients of `f'.
123//
124// Used by: bCommonDen()
125//
126//}}}
127static CanonicalForm
128internalBCommonDen ( const CanonicalForm & f )
129{
130    if ( f.inBaseDomain() )
131        return f.den();
132    else {
133        CanonicalForm result = 1;
134        for ( CFIterator i = f; i.hasTerms(); i++ )
135            result = blcm( result, internalBCommonDen( i.coeff() ) );
136        return result;
137    }
138}
139//}}}
140
141//{{{ CanonicalForm bCommonDen ( const CanonicalForm & f )
142//{{{ docu
143//
144// bCommonDen() - calculate multivariate common denominator of
145//   coefficients of `f'.
146//
147// The common denominator is calculated with respect to all
148// coefficients of `f' which are in a base domain.  In other
149// words, common_den( `f' ) * `f' is guaranteed to have integer
150// coefficients only.  The common denominator of zero equals is
151// one.
152//
153// Returns something non-trivial iff the current domain is Q.
154//
155//}}}
156CanonicalForm
157bCommonDen ( const CanonicalForm & f )
158{
159    if ( getCharacteristic() == 0 && isOn( SW_RATIONAL ) ) {
160        // otherwise `bgcd()' returns one
161        Off( SW_RATIONAL );
162        CanonicalForm result = internalBCommonDen( f );
163        On( SW_RATIONAL );
164        return result;
165    } else
166        return CanonicalForm( 1 );
167}
168//}}}
169
170//{{{ bool divides ( const CanonicalForm & f, const CanonicalForm & g )
171//{{{ docu
172//
173// divides() - check whether `f' divides `g'.
174//
175// Uses some extra checks to avoid polynomial division.
176//
177//}}}
178bool
179divides ( const CanonicalForm & f, const CanonicalForm & g )
180{
181    if ( g.level() > 0 && g.level() == f.level() )
182        if ( divides( f.tailcoeff(), g.tailcoeff() ) && divides( f.LC(), g.LC() ) ) {
183            CanonicalForm q, r;
184            bool ok = divremt( g, f, q, r );
185            return ok && r.isZero();
186        }
187        else
188            return false;
189    else {
190        CanonicalForm q, r;
191        bool ok = divremt( g, f, q, r );
192        return ok && r.isZero();
193    }
194}
195//}}}
196
197//{{{ CanonicalForm maxNorm ( const CanonicalForm & f )
198//{{{ docu
199//
200// maxNorm() - get maximum norm of `f'.
201//
202// That is, the base coefficient of `f' with the largest absolute
203// value.
204//
205// Valid for arbitrary polynomials over arbitrary domains, but
206// most useful for multivariate polynomials over Z.
207//
208//}}}
209CanonicalForm
210maxNorm ( const CanonicalForm & f )
211{
212    if ( f.inBaseDomain() )
213        return abs( f );
214    else {
215        CanonicalForm result = 0;
216        for ( CFIterator i = f; i.hasTerms(); i++ ) {
217            CanonicalForm coeffMaxNorm = maxNorm( i.coeff() );
218            if ( coeffMaxNorm > result )
219                result = coeffMaxNorm;
220        }
221        return result;
222    }
223}
224//}}}
225
226//{{{ CanonicalForm euclideanNorm ( const CanonicalForm & f )
227//{{{ docu
228//
229// euclideanNorm() - get euclidean norm of `f'.
230//
231// That is, returns the largest integer smaller or equal
232// norm(`f') = sqrt(sum( `f'[i]^2 )).  `f' should be an
233// univariate polynomial over Z.
234//
235//}}}
236CanonicalForm
237euclideanNorm ( const CanonicalForm & f )
238{
239    ASSERT( (f.inBaseDomain() || f.isUnivariate()) && f.LC().inZ(),
240            "illegal polynomial" );
241
242    CanonicalForm result = 0;
243    for ( CFIterator i = f; i.hasTerms(); i++ ) {
244        CanonicalForm coeff = i.coeff();
245        result += coeff*coeff;
246    }
247    return sqrt( result );
248}
249//}}}
Note: See TracBrowser for help on using the repository browser.