source: git/factory/sm_util.cc @ 22743e

fieker-DuValspielwiese
Last change on this file since 22743e was fbefc9, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* cf_chinese.h: declarations moved to cf_algorithm.h. cf_chinese.h removed. All #include statements changed. git-svn-id: file:///usr/local/Singular/svn/trunk@634 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.9 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: sm_util.cc,v 1.3 1997-08-29 07:26:46 schmidt Exp $ */
3
4//{{{ docu
5//
6// sm_util.cc - utlities for sparse modular gcd.
7//
8// Dependencies: Routines used by and only by sm_sparsemod.cc.
9//
10// Contributed by Marion Bruder <bruder@math.uni-sb.de>.
11//
12//}}}
13
14#include <config.h>
15
16#include "assert.h"
17#include "debug.h"
18
19#include "cf_defs.h"
20#include "cf_algorithm.h"
21#include "cf_iter.h"
22#include "cf_reval.h"
23#include "canonicalform.h"
24#include "variable.h"
25#ifdef macintosh
26#include <::templates:ftmpl_array.h>
27#else
28#include "templates/ftmpl_array.h"
29#endif
30
31//{{{ static CanonicalForm fmonome( const CanonicalForm & f  )
32//{{{ docu
33//
34// fmonome() - return the leading monomial of a poly.
35//
36// As in Leitkoeffizient(), the leading monomial is calculated
37// with respect to inCoeffDomain().  The leading monomial is
38// returned with coefficient 1.
39//
40//}}}
41static CanonicalForm
42fmonome( const CanonicalForm & f  )
43{
44  if ( f.inCoeffDomain() )
45    {
46      return 1;
47    }
48  else
49    {
50      CFIterator J = f;
51      CanonicalForm  result;
52      result = power( f.mvar() , J.exp() ) * fmonome( J.coeff() );
53      return result;
54    }
55}
56//}}}
57
58//{{{ static CanonicalForm interpol( const CFArray & values, const CanonicalForm & point, const CFArray & points, const Variable & x, int d, int CHAR )
59//{{{ docu
60//
61// interpol() - Newton interpolation.
62//
63// Calculate f in x such that f(point) = values[1],
64// f(points[i]) = values[i], i=2, ..., d+1.
65// Make sure that you are calculating in a field.
66//
67// alpha: the values at the interpolation points (= values)
68// punkte: the point at which we interpolate (= (point, points))
69//
70//}}}
71static CanonicalForm
72interpol( const CFArray & values, const CanonicalForm & point, const CFArray & points, const Variable & x, int d, int CHAR )
73{
74  CFArray alpha( 1, d+1 );
75  int i;
76  for ( i = 1 ; i <= d+1 ; i++ )
77    {
78      alpha[i] = values[i];
79    }
80
81  int k, j;
82  CFArray punkte( 1 , d+1 );
83  for ( i = 1 ; i <= d+1 ; i++ )
84    {
85      if ( i == 1 )
86        {
87          punkte[i] = point;
88        }
89      else
90        {
91          punkte[i] = points[i-1];
92        }
93    }
94
95  // calculate Newton coefficients alpha[i]
96  for ( k = 2 ; k <= d+1 ; k++ )
97    {
98      for ( j = d+1 ; j >= k ; j-- )
99        {
100          alpha[j] = (alpha[j] - alpha[j-1]) / (punkte[j] - punkte[j-k+1]);
101        }
102    }
103
104  // calculate f from Newton coefficients
105  CanonicalForm f = alpha [1], produkt = 1;
106  for ( i = 1 ; i <= d ; i++ )
107    {
108      produkt *= ( x - punkte[i] );
109      f += ( alpha[i+1] * produkt ) ;
110    }
111
112  return f;
113}
114//}}}
115
116//{{{ int countmonome( const CanonicalForm & f )
117//{{{ docu
118//
119// countmonome() - count the number of monomials in a poly.
120//
121// As in Leitkoeffizient(), the number of monomials is calculated
122// with respect to inCoeffDomain().
123//
124//}}}
125int
126countmonome( const CanonicalForm & f )
127{
128  if ( f.inCoeffDomain() )
129    {
130      return 1;
131    }
132  else
133    {
134      CFIterator I = f;
135      int result = 0;
136
137      while ( I.hasTerms() )
138        {
139          result += countmonome( I.coeff() );
140          I++;
141        }
142      return result;
143    }
144}
145//}}}
146
147//{{{ CanonicalForm Leitkoeffizient( const CanonicalForm & f )
148//{{{ docu
149//
150// Leitkoeffizient() - get the leading coefficient of a poly.
151//
152// In contrary to the method lc(), the leading coefficient is calculated
153// with respect to to the method inCoeffDomain(), so that a poly over an
154// algebraic extension will have a leading coefficient in this algebraic
155// extension (and *not* in its groundfield).
156//
157//}}}
158CanonicalForm
159Leitkoeffizient( const CanonicalForm & f )
160{
161  if ( f.inCoeffDomain() )
162    return f;
163  else
164    {
165      CFIterator J = f;
166      CanonicalForm result;
167      result = Leitkoeffizient( J.coeff() );
168      return result;
169    }
170}
171//}}}
172
173//{{{ void ChinesePoly( int arraylength, const CFArray & Polys, const CFArray & primes, CanonicalForm & result )
174//{{{ docu
175//
176// ChinesePoly - chinese remaindering mod p.
177//
178// Given n=arraylength polynomials Polys[1] (mod primes[1]), ...,
179// Polys[n] (mod primes[n]), we calculate result such that
180// result = Polys[i] (mod primes[i]) for all i.
181//
182// Note: We assume that all monomials which occure in Polys[2],
183// ..., Polys[n] also occure in Polys[1].
184//
185// bound: number of monomials of Polys[1]
186// mono: array of monomials of Polys[1].  For each monomial, we
187//   get the coefficients of this monomial in all Polys, store them
188//   in koeffi and do chinese remaindering over these coeffcients.
189//   The resulting polynomial is constructed monomial-wise from
190//   the results.
191// polis: used to trace through monomials of Polys
192// h: result of remaindering of koeffi[1], ..., koeffi[n]
193// Primes: do we need that?
194//
195//}}}
196void
197ChinesePoly( int arraylength, const CFArray & Polys, const CFArray & primes, CanonicalForm & result )
198{
199  DEBINCLEVEL( cerr, "ChinesePoly" );
200
201  CFArray koeffi( 1, arraylength ), polis( 1, arraylength );
202  CFArray Primes( 1, arraylength );
203  int bound = countmonome( Polys[1] );
204  CFArray mono( 1, bound );
205  int i, j;
206  CanonicalForm h, unnecessaryforme;
207
208  DEBOUTLN( cerr, "Interpolating " << Polys );
209  DEBOUTLN( cerr, "modulo" << primes );
210  for ( i = 1 ; i <= arraylength ; i++ )
211    {
212      polis[i]  = Polys[i];
213      Primes[i] = primes[i];
214    }
215
216  for ( i = 1 ; i <= bound ; i++ )
217    {
218      mono[i] = fmonome( polis[1] );
219      koeffi[1] = lc( polis[1] );               // maybe better use Leitkoeffizient ??
220      polis[1] -= mono[i] * koeffi[1];
221      for ( j = 2 ; j <= arraylength ; j++ )
222        {
223          koeffi[j] = lc( polis[j] );           // see above
224          polis[j] -= mono[i] * koeffi[j];
225        }
226
227      // calculate interpolating poly for each monomial
228      chineseRemainder( koeffi, Primes, h, unnecessaryforme );
229      result += h * mono[i];
230    }
231  DEBOUTLN( cerr, "result = " << result );
232
233  DEBDECLEVEL( cerr, "ChinesePoly" );
234}
235//}}}
236
237//{{{ CanonicalForm dinterpol( int d, const CanonicalForm & gi, const CFArray & zwischen, const REvaluation & alpha, int s, const CFArray & beta, int ni, int CHAR )
238//{{{ docu
239//
240// dinterpol() - calculate interpolating poly (???).
241//
242// Calculate f such that f is congruent to gi mod (x_s - alpha_s) and
243// congruent to zwischen[i] mod (x_s - beta[i]) for all i.
244//
245//}}}
246CanonicalForm
247dinterpol( int d, const CanonicalForm & gi, const CFArray & zwischen, const REvaluation & alpha, int s, const CFArray & beta, int ni, int CHAR )
248{
249  int i, j, lev = s;
250  Variable x( lev );
251
252  CFArray polis( 1, d+1 );
253  polis[1] = gi;
254  for ( i = 2 ; i <= d+1 ; i++ )
255    {
256      polis[i] = zwischen[i-1];
257    }
258
259  CFArray mono( 1, ni ), koeffi( 1, d+1 );
260  CanonicalForm h , f = 0; 
261
262  for ( i = 1 ; i <= ni ; i++ )
263    {
264      mono[i] = fmonome( polis[1] );
265
266      koeffi[1] = Leitkoeffizient( polis[1] );
267      polis[1] -= mono[i] * koeffi[1];
268
269      for ( j = 2 ; j <= d+1 ; j++ )
270        {
271          koeffi[j] = Leitkoeffizient( polis[j] );
272          polis[j] -= mono[i] * koeffi[j];
273        }
274
275      // calculate interpolating poly for each monomial
276      h = interpol( koeffi, alpha[s] , beta, x , d , CHAR );
277
278      f += h * mono[i];
279    }
280
281  return f;
282}
283//}}}
284
285//{{{ CanonicalForm sinterpol( const CanonicalForm & gi, const Array<REvaluation> & xi, CanonicalForm* zwischen, int n )
286//{{{ docu
287//
288// sinterpol - sparse interpolation (???).
289//
290// Loese Gleichungssystem:
291// x[1], .., x[q]( Tupel ) eingesetzt fuer die Variablen in gi ergibt
292// zwischen[1], .., zwischen[q]
293//
294//}}}
295CanonicalForm
296sinterpol( const CanonicalForm & gi, const Array<REvaluation> & xi, CanonicalForm* zwischen, int n )
297{
298  CanonicalForm f = gi;
299  int i, j;
300  CFArray mono( 1 , n );
301
302  //  mono[i] is the i'th monomial
303  for ( i = 1 ; i <= n ; i++ )
304    {
305      mono[i] = fmonome( f );
306      f -= mono[i]*Leitkoeffizient(f);
307    }
308
309  //  fill up matrix a
310  CFMatrix a( n , n + 1 );
311  for ( i = 1 ; i <= n ; i++ )
312    for ( j = 1 ; j <= n + 1 ; j++ )
313      {
314        if ( j == n+1 )
315          {
316            a[i][j] = zwischen[i];
317          }
318        else
319          {
320            a[i][j] = xi[i]( mono[j] );
321          }
322      }
323
324  // sove a*y=zwischen and get soultions y1, .., yn mod p
325  linearSystemSolve( a );
326
327  for ( i = 1 ; i <= n ; i++ )
328    f += a[i][n+1] * mono[i];
329
330  return f;
331}
332//}}}
Note: See TracBrowser for help on using the repository browser.