source: git/factory/sm_util.cc @ 7a1151

spielwiese
Last change on this file since 7a1151 was ee668e, checked in by Jan Engelhardt <jengelh@…>, 12 years ago
factory/build: restore out-of-tree build support When attempting an OOT build, it fails to find <factory/cplusplus.h>, because cplusplus.h is always (even in in-tree builds) produced in "${builddir}", and not "${top_srcdir}/../factory". Furthermore, one must not rely on the basename of ${top_srcdir}, and going above ${top_srcdir} is undefined and may lead to spurious build failures. (Consider a hypothetical chroot on ${top_srcdir}). Therefore, create a directory include/factory and use -Iinclude such that <factory/*> yields a buildable state, move all exported header files there. Previous OOT build log: 17:22 seven:../factory/obj > make CXX cplusplus.o CXXLD cplusplus ./cplusplus > ./cplusplus.h ../bin/makeheader ../factory.template factory.h ../bin/makeheader ../factoryconf.template factoryconf.h YACC readcf.cc make all-am make[1]: Entering directory `/home/jengelh/obs/zu/home/jengelh/science/singsource/factory/obj' CXX libfactory_a-algext.o CXX libfactory_a-canonicalform.o In file included from ../cf_factory.h:12:0, from ../canonicalform.cc:7: ../../factory/cf_gmp.h:14:33: fatal error: factory/cplusplus.h: Ingen slik fil eller filkatalog compilation terminated. make[1]: *** [libfactory_a-canonicalform.o] Error 1 make[1]: Leaving directory `/home/jengelh/obs/zu/home/jengelh/science/singsource/factory/obj' make: *** [all] Error 2
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id$ */
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 "cf_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#include <factory/templates/ftmpl_array.h>
26
27//{{{ static CanonicalForm fmonome( const CanonicalForm & f  )
28//{{{ docu
29//
30// fmonome() - return the leading monomial of a poly.
31//
32// As in Leitkoeffizient(), the leading monomial is calculated
33// with respect to inCoeffDomain().  The leading monomial is
34// returned with coefficient 1.
35//
36//}}}
37static CanonicalForm
38fmonome( const CanonicalForm & f  )
39{
40  if ( f.inCoeffDomain() )
41    {
42      return 1;
43    }
44  else
45    {
46      CFIterator J = f;
47      CanonicalForm  result;
48      result = power( f.mvar() , J.exp() ) * fmonome( J.coeff() );
49      return result;
50    }
51}
52//}}}
53
54//{{{ static CanonicalForm interpol( const CFArray & values, const CanonicalForm & point, const CFArray & points, const Variable & x, int d, int CHAR )
55//{{{ docu
56//
57// interpol() - Newton interpolation.
58//
59// Calculate f in x such that f(point) = values[1],
60// f(points[i]) = values[i], i=2, ..., d+1.
61// Make sure that you are calculating in a field.
62//
63// alpha: the values at the interpolation points (= values)
64// punkte: the point at which we interpolate (= (point, points))
65//
66//}}}
67static CanonicalForm
68interpol( const CFArray & values, const CanonicalForm & point, const CFArray & points, const Variable & x, int d, int /*CHAR*/ )
69{
70  CFArray alpha( 1, d+1 );
71  int i;
72  for ( i = 1 ; i <= d+1 ; i++ )
73    {
74      alpha[i] = values[i];
75    }
76
77  int k, j;
78  CFArray punkte( 1 , d+1 );
79  for ( i = 1 ; i <= d+1 ; i++ )
80    {
81      if ( i == 1 )
82        {
83          punkte[i] = point;
84        }
85      else
86        {
87          punkte[i] = points[i-1];
88        }
89    }
90
91  // calculate Newton coefficients alpha[i]
92  for ( k = 2 ; k <= d+1 ; k++ )
93    {
94      for ( j = d+1 ; j >= k ; j-- )
95        {
96          alpha[j] = (alpha[j] - alpha[j-1]) / (punkte[j] - punkte[j-k+1]);
97        }
98    }
99
100  // calculate f from Newton coefficients
101  CanonicalForm f = alpha [1], produkt = 1;
102  for ( i = 1 ; i <= d ; i++ )
103    {
104      produkt *= ( x - punkte[i] );
105      f += ( alpha[i+1] * produkt ) ;
106    }
107
108  return f;
109}
110//}}}
111
112//{{{ int countmonome( const CanonicalForm & f )
113//{{{ docu
114//
115// countmonome() - count the number of monomials in a poly.
116//
117// As in Leitkoeffizient(), the number of monomials is calculated
118// with respect to inCoeffDomain().
119//
120//}}}
121int
122countmonome( const CanonicalForm & f )
123{
124  if ( f.inCoeffDomain() )
125    {
126      return 1;
127    }
128  else
129    {
130      CFIterator I = f;
131      int result = 0;
132
133      while ( I.hasTerms() )
134        {
135          result += countmonome( I.coeff() );
136          I++;
137        }
138      return result;
139    }
140}
141//}}}
142
143//{{{ CanonicalForm Leitkoeffizient( const CanonicalForm & f )
144//{{{ docu
145//
146// Leitkoeffizient() - get the leading coefficient of a poly.
147//
148// In contrary to the method lc(), the leading coefficient is calculated
149// with respect to to the method inCoeffDomain(), so that a poly over an
150// algebraic extension will have a leading coefficient in this algebraic
151// extension (and *not* in its groundfield).
152//
153//}}}
154CanonicalForm
155Leitkoeffizient( const CanonicalForm & f )
156{
157  if ( f.inCoeffDomain() )
158    return f;
159  else
160    {
161      CFIterator J = f;
162      CanonicalForm result;
163      result = Leitkoeffizient( J.coeff() );
164      return result;
165    }
166}
167//}}}
168
169//{{{ void ChinesePoly( int arraylength, const CFArray & Polys, const CFArray & primes, CanonicalForm & result )
170//{{{ docu
171//
172// ChinesePoly - chinese remaindering mod p.
173//
174// Given n=arraylength polynomials Polys[1] (mod primes[1]), ...,
175// Polys[n] (mod primes[n]), we calculate result such that
176// result = Polys[i] (mod primes[i]) for all i.
177//
178// Note: We assume that all monomials which occure in Polys[2],
179// ..., Polys[n] also occure in Polys[1].
180//
181// bound: number of monomials of Polys[1]
182// mono: array of monomials of Polys[1].  For each monomial, we
183//   get the coefficients of this monomial in all Polys, store them
184//   in koeffi and do chinese remaindering over these coeffcients.
185//   The resulting polynomial is constructed monomial-wise from
186//   the results.
187// polis: used to trace through monomials of Polys
188// h: result of remaindering of koeffi[1], ..., koeffi[n]
189// Primes: do we need that?
190//
191//}}}
192void
193ChinesePoly( int arraylength, const CFArray & Polys, const CFArray & primes, CanonicalForm & result )
194{
195  DEBINCLEVEL( cerr, "ChinesePoly" );
196
197  CFArray koeffi( 1, arraylength ), polis( 1, arraylength );
198  CFArray Primes( 1, arraylength );
199  int bound = countmonome( Polys[1] );
200  CFArray mono( 1, bound );
201  int i, j;
202  CanonicalForm h, unnecessaryforme;
203
204  DEBOUTLN( cerr, "Interpolating " << Polys );
205  DEBOUTLN( cerr, "modulo" << primes );
206  for ( i = 1 ; i <= arraylength ; i++ )
207    {
208      polis[i]  = Polys[i];
209      Primes[i] = primes[i];
210    }
211
212  for ( i = 1 ; i <= bound ; i++ )
213    {
214      mono[i] = fmonome( polis[1] );
215      koeffi[1] = lc( polis[1] );                // maybe better use Leitkoeffizient ??
216      polis[1] -= mono[i] * koeffi[1];
217      for ( j = 2 ; j <= arraylength ; j++ )
218        {
219          koeffi[j] = lc( polis[j] );                // see above
220          polis[j] -= mono[i] * koeffi[j];
221        }
222
223      // calculate interpolating poly for each monomial
224      chineseRemainder( koeffi, Primes, h, unnecessaryforme );
225      result += h * mono[i];
226    }
227  DEBOUTLN( cerr, "result = " << result );
228
229  DEBDECLEVEL( cerr, "ChinesePoly" );
230}
231//}}}
232
233//{{{ CanonicalForm dinterpol( int d, const CanonicalForm & gi, const CFArray & zwischen, const REvaluation & alpha, int s, const CFArray & beta, int ni, int CHAR )
234//{{{ docu
235//
236// dinterpol() - calculate interpolating poly (???).
237//
238// Calculate f such that f is congruent to gi mod (x_s - alpha_s) and
239// congruent to zwischen[i] mod (x_s - beta[i]) for all i.
240//
241//}}}
242CanonicalForm
243dinterpol( int d, const CanonicalForm & gi, const CFArray & zwischen, const REvaluation & alpha, int s, const CFArray & beta, int ni, int CHAR )
244{
245  int i, j, lev = s;
246  Variable x( lev );
247
248  CFArray polis( 1, d+1 );
249  polis[1] = gi;
250  for ( i = 2 ; i <= d+1 ; i++ )
251    {
252      polis[i] = zwischen[i-1];
253    }
254
255  CFArray mono( 1, ni ), koeffi( 1, d+1 );
256  CanonicalForm h , f = 0;
257
258  for ( i = 1 ; i <= ni ; i++ )
259    {
260      mono[i] = fmonome( polis[1] );
261
262      koeffi[1] = Leitkoeffizient( polis[1] );
263      polis[1] -= mono[i] * koeffi[1];
264
265      for ( j = 2 ; j <= d+1 ; j++ )
266        {
267          koeffi[j] = Leitkoeffizient( polis[j] );
268          polis[j] -= mono[i] * koeffi[j];
269        }
270
271      // calculate interpolating poly for each monomial
272      h = interpol( koeffi, alpha[s] , beta, x , d , CHAR );
273
274      f += h * mono[i];
275    }
276
277  return f;
278}
279//}}}
280
281//{{{ CanonicalForm sinterpol( const CanonicalForm & gi, const Array<REvaluation> & xi, CanonicalForm* zwischen, int n )
282//{{{ docu
283//
284// sinterpol - sparse interpolation (???).
285//
286// Loese Gleichungssystem:
287// x[1], .., x[q]( Tupel ) eingesetzt fuer die Variablen in gi ergibt
288// zwischen[1], .., zwischen[q]
289//
290//}}}
291CanonicalForm
292sinterpol( const CanonicalForm & gi, const Array<REvaluation> & xi, CanonicalForm* zwischen, int n )
293{
294  CanonicalForm f = gi;
295  int i, j;
296  CFArray mono( 1 , n );
297
298  //  mono[i] is the i'th monomial
299  for ( i = 1 ; i <= n ; i++ )
300    {
301      mono[i] = fmonome( f );
302      f -= mono[i]*Leitkoeffizient(f);
303    }
304
305  //  fill up matrix a
306  CFMatrix a( n , n + 1 );
307  for ( i = 1 ; i <= n ; i++ )
308    for ( j = 1 ; j <= n + 1 ; j++ )
309      {
310        if ( j == n+1 )
311          {
312            a[i][j] = zwischen[i];
313          }
314        else
315          {
316            a[i][j] = xi[i]( mono[j] );
317          }
318      }
319
320  // sove a*y=zwischen and get soultions y1, .., yn mod p
321  linearSystemSolve( a );
322
323  for ( i = 1 ; i <= n ; i++ )
324    f += a[i][n+1] * mono[i];
325
326  return f;
327}
328//}}}
Note: See TracBrowser for help on using the repository browser.