1 | /* emacs edit mode for this file is -*- C++ -*- */ |
---|
2 | /* $Id: cf_chinese.cc,v 1.6 1997-09-09 07:31:18 schmidt Exp $ */ |
---|
3 | |
---|
4 | //{{{ docu |
---|
5 | // |
---|
6 | // cf_chinese.cc - algorithms for chinese remaindering. |
---|
7 | // |
---|
8 | // Used by: cf_gcd.cc, cf_linsys.cc, sm_util.cc |
---|
9 | // |
---|
10 | // Header file: cf_algorithm.h |
---|
11 | // |
---|
12 | //}}} |
---|
13 | |
---|
14 | #include <config.h> |
---|
15 | |
---|
16 | #include "assert.h" |
---|
17 | |
---|
18 | #include "canonicalform.h" |
---|
19 | |
---|
20 | //{{{ void chineseRemainder ( const CanonicalForm x1, const CanonicalForm q1, const CanonicalForm x2, const CanonicalForm q2, CanonicalForm & xnew, CanonicalForm & qnew ) |
---|
21 | //{{{ docu |
---|
22 | // |
---|
23 | // chineseRemainder - integer chinese remaindering. |
---|
24 | // |
---|
25 | // Calculate xnew such that xnew=x1 (mod q1) and xnew=x2 (mod q2) |
---|
26 | // and qnew = q1*q2. q1 and q2 should be positive integers, |
---|
27 | // pairwise prime, x1 and x2 should be polynomials with integer |
---|
28 | // coefficients. If x1 and x2 are polynomials with positive |
---|
29 | // coefficients, the result is guaranteed to have positive |
---|
30 | // coefficients, too. |
---|
31 | // |
---|
32 | // This is a standard algorithm. See, for example, |
---|
33 | // Geddes/Czapor/Labahn - 'Alogorithms for Computer Algebra', |
---|
34 | // par. 5.6 and 5.8. |
---|
35 | // |
---|
36 | // Note: be sure you are calculating in Z, and not in Q! |
---|
37 | // |
---|
38 | //}}} |
---|
39 | void |
---|
40 | chineseRemainder ( const CanonicalForm x1, const CanonicalForm q1, const CanonicalForm x2, const CanonicalForm q2, CanonicalForm & xnew, CanonicalForm & qnew ) |
---|
41 | { |
---|
42 | CanonicalForm a1, a2; |
---|
43 | (void)iextgcd( q1, q2, a1, a2 ); |
---|
44 | qnew = q1 * q2; |
---|
45 | xnew = mod( q1*a1*x2 + q2*a2*x1, qnew ); |
---|
46 | } |
---|
47 | //}}} |
---|
48 | |
---|
49 | //{{{ void chineseRemainder ( const CFArray & x, const CFArray & q, CanonicalForm & xnew, CanonicalForm & qnew ) |
---|
50 | //{{{ docu |
---|
51 | // |
---|
52 | // chineseRemainder - integer chinese remaindering. |
---|
53 | // |
---|
54 | // Calculate xnew such that xnew=x[i] (mod q[i]) and qnew is the |
---|
55 | // product of all q[i]. q[i] should be positive integers, |
---|
56 | // pairwise prime. x[i] should be polynomials with integer |
---|
57 | // coefficients. If all coefficients of all x[i] are positive |
---|
58 | // integers, the result is guaranteed to have positive |
---|
59 | // coefficients, too. |
---|
60 | // |
---|
61 | // Note: be sure you are calculating in Z, and not in Q! |
---|
62 | // |
---|
63 | //}}} |
---|
64 | void |
---|
65 | chineseRemainder ( const CFArray & x, const CFArray & q, CanonicalForm & xnew, CanonicalForm & qnew ) |
---|
66 | { |
---|
67 | ASSERT( x.min() == q.min() && x.size() == q.size(), "incompatible arrays" ); |
---|
68 | CFArray X(x), Q(q); |
---|
69 | int i, j, n = x.size(); |
---|
70 | |
---|
71 | while ( n != 1 ) { |
---|
72 | i = j = x.min(); |
---|
73 | while ( i < x.min() + n - 1 ) { |
---|
74 | chineseRemainder( X[i], Q[i], X[i+1], Q[i+1], X[j], Q[j] ); |
---|
75 | i += 2; |
---|
76 | j++; |
---|
77 | } |
---|
78 | if ( n & 1 ) { |
---|
79 | X[j] = X[i]; |
---|
80 | Q[j] = Q[i]; |
---|
81 | } |
---|
82 | n = ( n + 1) / 2; |
---|
83 | } |
---|
84 | xnew = X[x.min()]; |
---|
85 | qnew = Q[q.min()]; |
---|
86 | } |
---|
87 | //}}} |
---|