source: git/Singular/interpolation.cc @ c16aa0

spielwiese
Last change on this file since c16aa0 was c16aa0, checked in by Hans Schoenemann <hannes@…>, 14 years ago
compile also without HAVE_FACTORY git-svn-id: file:///usr/local/Singular/svn/trunk@13196 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 48.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5
6#include <Singular/mod2.h>
7#include <kernel/options.h>
8#include <kernel/febase.h>
9#include <kernel/ideals.h>
10#include <kernel/intvec.h>
11#include <kernel/polys.h>
12#include <Singular/lists.h>
13#include <kernel/longrat.h>
14#include <Singular/ipid.h>
15#include <kernel/ring.h>
16#ifdef HAVE_FACTORY
17//#include <factory.h>
18#endif
19
20//memory management
21#define mdmALLOC(x) omAlloc0(x)
22#define mdmFREE(x) omFree(x)
23
24// parameters to debug
25//#define debb
26//#define shmat
27//#define checksize
28//#define writemsg
29
30// possible strategies
31#define unsortedmatrix
32//#define integerstrategy
33
34#define modp_number int
35#define exponent int
36
37modp_number myp;  // all modp computation done mod myp
38int myp_index; // index of small prime in Singular table of primes
39
40static inline modp_number modp_mul (modp_number x,modp_number y)
41{
42//    return (x*y)%myp;
43   return (modp_number)(((unsigned long)x)*((unsigned long)y)%((unsigned long)myp));
44}
45static inline modp_number modp_sub (modp_number x,modp_number y)
46{
47//   if (x>=y) return x-y; else return x+myp-y;
48     return (x+myp-y)%myp;
49}
50
51typedef exponent *mono_type;
52typedef struct {mono_type mon; unsigned int point_ref;} condition_type;
53typedef modp_number *coordinate_products;
54typedef coordinate_products *coordinates;
55
56struct mon_list_entry_struct {mono_type mon;
57                              struct mon_list_entry_struct *next;};
58typedef struct mon_list_entry_struct mon_list_entry;
59
60struct row_list_entry_struct {modp_number *row_matrix;
61                              modp_number *row_solve;
62                              int first_col;
63                              struct row_list_entry_struct *next;};
64
65typedef struct row_list_entry_struct row_list_entry;
66
67struct generator_struct {modp_number *coef;
68                         mono_type lt;
69                         modp_number ltcoef;
70                         struct generator_struct *next;};
71
72typedef struct generator_struct generator_entry;
73
74struct modp_result_struct {modp_number p;
75                           generator_entry *generator;
76                           int n_generators;
77                           struct modp_result_struct *next;
78                           struct modp_result_struct *prev;};
79
80typedef struct modp_result_struct modp_result_entry;
81
82typedef modp_number *modp_coordinates;
83typedef mpq_t *q_coordinates;
84typedef mpz_t *int_coordinates;
85typedef bool *coord_exist_table;
86
87int final_base_dim;    // dimension of the quotient space, known from the beginning
88int last_solve_column;  // last non-zero column in "solve" part of matrix, used for speed up
89int n_points;  // modp_number of ideals (points)
90int *multiplicity;  // multiplicities of points
91int variables;  // modp_number of variables
92int max_coord;  // maximal possible coordinate product used during Evaluation
93bool only_modp;  // perform only one modp computations
94
95modp_coordinates *modp_points; // coordinates of points for modp problem - used by Evaluate (this is also initial data for only modp)
96q_coordinates *q_points; // coordinates of points for rational data (not used for modp)
97int_coordinates *int_points; // coordinates of points for integer data - used to check generators (not used for modp)
98coord_exist_table *coord_exist; // checks whether all coordinates has been initialized
99mon_list_entry *check_list; // monomials to be checked in next stages
100coordinates *points; // power products of coordinates of points used in modp cycles
101condition_type *condition_list; // conditions stored in an array
102mon_list_entry *lt_list; // leading terms found so far
103mon_list_entry *base_list; // standard monomials found so far
104row_list_entry *row_list; // rows of the matrix (both parts)
105modp_number *my_row; // one special row to perform operations
106modp_number *my_solve_row; // one special row to find the linear dependence ("solve" part)
107mono_type *column_name; // monomials assigned to columns in solve_row
108
109int n_results;  // modp_number of performed modp computations (not discarded)
110modp_number modp_denom; // denominator of mod p computations
111modp_result_entry *modp_result; // list of results for various mod p calculations (used for modp - first result is the desired one)
112modp_result_entry *cur_result; // pointer to current result (as before)
113modp_number *congr; // primes used in computations (chinese remainder theorem) (not used for modp)
114modp_number *in_gamma; // inverts used in chinese remainder theorem (not used for modp)
115mpz_t bigcongr; // result, in fact, is given in mod bigcongr (not used for modp)
116
117mpz_t *polycoef; // polynomial integercoefficients (not used for modp)
118mono_type *polyexp; // polynomial exponents
119
120struct gen_list_struct {mpz_t *polycoef;
121                        mono_type *polyexp;
122                        struct gen_list_struct *next;};
123typedef struct gen_list_struct gen_list_entry;
124
125gen_list_entry *gen_list=NULL; // list of resulting generators - output data (integer version)
126
127int generic_n_generators; // modp_number of generators - should be the same for all modp comp (not used for modp)
128mono_type *generic_column_name; // monomials assigned to columns in solve_row - should be the same for all modp comp (!!! used for modp)
129mon_list_entry *generic_lt=NULL; // leading terms for ordered generators - should be the same for all modp comp (not used for modp)
130int good_primes; // modp_number of good primes so far;
131int bad_primes; // modp_number of bad primes so far;
132mpz_t common_denom; // common denominator used to force points coordinates to Z (not used for modp)
133bool denom_divisible; // common denominator is divisible by p (not used for modp)
134
135poly comparizon_p1;  //polynomials used to do comparizons by Singular
136poly comparizon_p2;
137
138modp_number *modp_Reverse; // reverses in mod p
139
140bool protocol; // true to show the protocol
141
142#ifdef checksize
143int maximal_size=0;
144#endif
145
146void WriteMono (mono_type m) // Writes a monomial on the screen - only for debug
147{
148     int i;
149     for (i=0;i<variables;i++) Print("_%d", m[i]);
150     PrintS(" ");
151}
152
153#ifdef debb
154void WriteMonoList (mon_list_entry *list)
155{
156     mon_list_entry *ptr;
157     ptr=list;
158     while (ptr!=NULL)
159     {
160           WriteMono(ptr->mon);
161           ptr=ptr->next;
162     }
163}
164
165void Info ()
166{
167     int i;
168     row_list_entry *curptr;
169     modp_number *row;
170     modp_number *solve;
171     char ch;
172     cout << endl << "quotient basis: ";
173     WriteMonoList (base_list);
174     cout << endl << "leading terms: ";
175     WriteMonoList (lt_list);
176     cout << endl << "to be checked: ";
177     WriteMonoList (check_list);
178#ifdef shmat
179     cout << endl << "Matrix:" << endl;
180     cout << "                                      ";
181     for (i=0;i<final_base_dim;i++)
182     {
183         WriteMono (column_name[i]);
184     }
185     cout << endl;
186     curptr=row_list;
187     while (curptr!=NULL)
188     {
189           row=curptr->row_matrix;
190           solve=curptr->row_solve;
191           for (i=0;i<final_base_dim;i++)
192           {
193               cout << *row << " , ";
194               row++;
195           }
196           cout << "        ";
197           for (i=0;i<final_base_dim;i++)
198           {
199               cout << *solve << " , ";
200               solve++;
201           }
202           curptr=curptr->next;
203           cout << endl;}
204     cout << "Special row:                           Solve row:" << endl;
205     row=my_row;
206     for (i=0;i<final_base_dim;i++)
207     {
208         cout << *row << " , ";
209         row++;
210     }
211     cout << "          ";
212     row=my_solve_row;
213     for (i=0;i<final_base_dim;i++)
214     {
215         cout << *row << " , ";
216         row++;
217     }
218#endif
219     cout << endl;
220     cin >> ch;
221     cout << endl << endl;
222}
223#endif
224
225modp_number OneInverse(modp_number a,modp_number p) // computes inverse of d mod p without using tables
226{
227   long  u, v, u0, u1, u2, q, r;
228   u1=1; u2=0;
229   u = a; v = p;
230   while (v != 0) {
231      q = u / v;
232      r = u % v;
233      u = v;
234      v = r;
235      u0 = u2;
236      u2 = u1 - q*u2;
237      u1 = u0;
238   }
239   if (u1 < 0) u1=u1+p;
240// now it should be ok, but for any case...
241   if ((u1<0)||((u1*a)%p!=1))
242   {
243     PrintS("?");
244     modp_number i;
245     for (i=1;i<p;i++)
246     {
247       if ((a*i)%p==1) return i;
248     }
249   }
250   return (modp_number)u1;
251}
252
253int CalcBaseDim () // returns the maximal (expected) dimension of quotient space
254{
255    int c;
256    int i,j;
257    int s=0;
258    max_coord=1;
259    for (i=0;i<n_points;i++) max_coord=max_coord+multiplicity[i];
260    for (j=0;j<n_points;j++)
261    {
262        c=1;
263        for (i=1;i<=variables;i++)
264        {
265            c=(c*(multiplicity[j]+i-1))/i;
266        }
267        s=s+c;
268    }
269    return s;
270}
271
272bool EqualMon (mono_type m1, mono_type m2)  // compares two monomials, true if equal, false otherwise
273{
274     int i;
275     for (i=0;i<variables;i++)
276         if (m1[i]!=m2[i]) return false;;
277     return true;
278}
279
280exponent MonDegree (mono_type mon)  // computes the degree of a monomial
281{
282     exponent v=0;
283     int i;
284     for (i=0;i<variables;i++) v=v+mon[i];
285     return v;
286}
287
288bool Greater (mono_type m1, mono_type m2) // true if m1 > m2, false otherwise. uses Singular comparing function
289{
290     for (int j = variables; j; j--)
291     {
292       pSetExp(comparizon_p1, j, m1[j-1]);
293       pSetExp(comparizon_p2, j, m2[j-1]);
294     }
295     pSetm(comparizon_p1);
296     pSetm(comparizon_p2);
297     bool res=(pLmCmp(comparizon_p1,comparizon_p2)>0);
298     return res;
299}
300
301mon_list_entry* MonListAdd (mon_list_entry *list, mono_type mon)  // adds one entry to the list of monomials structure
302{
303     mon_list_entry *curptr=list;
304     mon_list_entry *prevptr=NULL;
305     mon_list_entry *temp;
306
307     while (curptr!=NULL)
308     {
309           if (EqualMon (mon,(*curptr).mon)) return list;
310           if (Greater ((*curptr).mon,mon)) break;
311           prevptr=curptr;
312           curptr=curptr->next;}
313     temp=(mon_list_entry*)mdmALLOC(sizeof(mon_list_entry));
314     (*temp).next=curptr;
315     (*temp).mon=(exponent*)mdmALLOC(sizeof(exponent)*variables);
316     memcpy(temp->mon,mon,sizeof(exponent)*variables);
317     if (prevptr==NULL) return temp; else {
318          prevptr->next=temp;
319          return list;}
320}
321
322mono_type MonListElement (mon_list_entry *list, int n)  // returns ith element from list of monomials - no error checking!
323{
324     mon_list_entry *cur=list;
325     int i;
326     for (i=0;i<n;i++) cur=cur->next;
327     return cur->mon;
328}
329
330mono_type ZeroMonomial ()  // allocates memory for new monomial with all enries equal 0
331{
332     mono_type m;
333     m=(exponent*)mdmALLOC(sizeof(exponent)*variables);
334     int i;
335     for (i=0;i<variables;i++) m[i]=0;
336     return m;
337}
338
339void GeneralInit ()  // general initialization
340{
341     int i,j,k;
342     points=(coordinates*)mdmALLOC(sizeof(coordinates)*n_points);
343     for (i=0;i<n_points;i++)
344     {
345         points[i]=(coordinate_products*)mdmALLOC(sizeof(coordinate_products)*variables);
346         for (j=0;j<variables;j++) points[i][j]=(modp_number*)mdmALLOC(sizeof(modp_number)*(max_coord));
347     }
348     condition_list=(condition_type*)mdmALLOC(sizeof(condition_type)*final_base_dim);
349     for (i=0;i<final_base_dim;i++) condition_list[i].mon=(exponent*)mdmALLOC(sizeof(exponent)*variables);
350     modp_points=(modp_coordinates*)mdmALLOC(sizeof(modp_coordinates)*n_points);
351     for (i=0;i<n_points;i++) modp_points[i]=(modp_number*)mdmALLOC(sizeof(modp_number)*variables);
352     if (!only_modp)
353     {
354        q_points=(q_coordinates*)mdmALLOC(sizeof(q_coordinates)*n_points);
355        for (i=0;i<n_points;i++)
356        {
357            q_points[i]=(mpq_t*)mdmALLOC(sizeof(mpq_t)*variables);
358            for (j=0;j<variables;j++) mpq_init(q_points[i][j]);
359        }
360        int_points=(int_coordinates*)mdmALLOC(sizeof(int_coordinates)*n_points);
361        for (i=0;i<n_points;i++)
362        {
363            int_points[i]=(mpz_t*)mdmALLOC(sizeof(mpz_t)*variables);
364            for (j=0;j<variables;j++) mpz_init(int_points[i][j]);
365        }
366     }
367     coord_exist=(coord_exist_table*)mdmALLOC(sizeof(coord_exist_table)*n_points);
368     for (i=0;i<n_points;i++)
369     {
370         coord_exist[i]=(bool*)mdmALLOC(sizeof(bool)*variables);
371         for (j=0;j<variables;j++) coord_exist[i][j]=false;
372     }
373     generic_column_name=(mono_type*)mdmALLOC(sizeof(mono_type)*final_base_dim);
374     for (i=0;i<final_base_dim;i++) generic_column_name[i]=ZeroMonomial ();
375     good_primes=0;
376     bad_primes=1;
377     generic_n_generators=0;
378     if (!only_modp)
379     {
380        polycoef=(mpz_t*)mdmALLOC(sizeof(mpz_t)*(final_base_dim+1));
381        polyexp=(mono_type*)mdmALLOC(sizeof(mono_type)*(final_base_dim+1));
382        for (i=0;i<=final_base_dim;i++)
383        {
384             mpz_init(polycoef[i]);
385             polyexp[i]=ZeroMonomial ();
386        }
387        mpz_init(common_denom);
388     }
389
390// set all globally used lists to be initially empty
391     modp_result=NULL;
392     cur_result=NULL;
393     gen_list=NULL;
394     n_results=0;
395
396// creates polynomials to compare by Singular
397     comparizon_p1=pOne();
398     comparizon_p2=pOne();
399}
400
401void InitProcData ()  // initialization for procedures which do computations mod p
402{
403     int i,j;
404     check_list=MonListAdd (check_list,ZeroMonomial ());
405     my_row=(modp_number*)mdmALLOC(sizeof(modp_number)*final_base_dim);
406     my_solve_row=(modp_number*)mdmALLOC(sizeof(modp_number)*final_base_dim);
407     column_name=(mono_type*)mdmALLOC(sizeof(mono_type)*final_base_dim);
408     for (i=0;i<final_base_dim;i++) column_name[i]=ZeroMonomial ();
409     last_solve_column=0;
410     modp_number *gen_table;
411     modp_number pos_gen;
412     bool gen_ok;
413     modp_Reverse=(modp_number*)mdmALLOC(sizeof(modp_number)*myp);
414
415// produces table of modp inverts by finding a generator of (Z_myp*,*)
416     gen_table=(modp_number*)mdmALLOC(sizeof(modp_number)*myp);
417     gen_table[1]=1;
418     for (pos_gen=2;pos_gen<myp;pos_gen++)
419     {
420         gen_ok=true;
421         for (i=2;i<myp;i++)
422         {
423             gen_table[i]=modp_mul(gen_table[i-1],pos_gen);
424             if (gen_table[i]==1)
425             {
426                gen_ok=false;
427                break;
428             }
429         }
430         if (gen_ok) break;
431     }
432     for (i=2;i<myp;i++) modp_Reverse[gen_table[i]]=gen_table[myp-i+1];
433     modp_Reverse[1]=1;
434     mdmFREE(gen_table);
435}
436
437mon_list_entry* FreeMonList (mon_list_entry *list)  // destroys a list of monomials, returns NULL pointer
438{
439     mon_list_entry *ptr;
440     mon_list_entry *pptr;
441     ptr=list;
442     while (ptr!=NULL)
443     {
444           pptr=ptr->next;
445           mdmFREE(ptr->mon);
446           mdmFREE(ptr);
447           ptr=pptr;}
448     return NULL;
449}
450
451void GeneralDone ()  // to be called before exit to free memory
452{
453     int i,j,k;
454     for (i=0;i<n_points;i++)
455     {
456         for (j=0;j<variables;j++)
457         {
458             mdmFREE(points[i][j]);
459         }
460         mdmFREE(points[i]);
461     }
462     mdmFREE(points);
463     for (i=0;i<final_base_dim;i++) mdmFREE(condition_list[i].mon);
464     mdmFREE(condition_list);
465     for (i=0;i<n_points;i++) mdmFREE(modp_points[i]);
466     mdmFREE(modp_points);
467     if (!only_modp)
468     {
469        for (i=0;i<n_points;i++)
470        {
471            for (j=0;j<variables;j++) mpq_clear(q_points[i][j]);
472            mdmFREE(q_points[i]);
473        }
474        mdmFREE(q_points);
475        for (i=0;i<n_points;i++)
476        {
477            for (j=0;j<variables;j++) mpz_clear(int_points[i][j]);
478            mdmFREE(int_points[i]);
479        }
480        mdmFREE(int_points);
481        generic_lt=FreeMonList (generic_lt);
482        for (i=0;i<=final_base_dim;i++)
483        {
484            mpz_clear(polycoef[i]);
485            mdmFREE(polyexp[i]);
486        }
487        mdmFREE(polycoef);
488        mdmFREE(polyexp);
489        if (!only_modp) mpz_clear(common_denom);
490     }
491     for (i=0;i<final_base_dim;i++)
492     {
493         mdmFREE(generic_column_name[i]);
494     }
495     mdmFREE(generic_column_name);
496     for (i=0;i<n_points;i++) mdmFREE(coord_exist[i]);
497     mdmFREE(coord_exist);
498     pDelete(&comparizon_p1);
499     pDelete(&comparizon_p2);
500}
501
502void FreeProcData ()  // to be called after one modp computation to free memory
503{
504     int i;
505     row_list_entry *ptr;
506     row_list_entry *pptr;
507     check_list=FreeMonList (check_list);
508     lt_list=FreeMonList (lt_list);
509     base_list=FreeMonList (base_list);
510     mdmFREE(my_row);
511     my_row=NULL;
512     mdmFREE(my_solve_row);
513     my_solve_row=NULL;
514     ptr=row_list;
515     while (ptr!=NULL)
516     {
517           pptr=ptr->next;
518           mdmFREE(ptr->row_matrix);
519           mdmFREE(ptr->row_solve);
520           mdmFREE(ptr);
521           ptr=pptr;
522     }
523     row_list=NULL;
524     for (i=0;i<final_base_dim;i++) mdmFREE(column_name[i]);
525     mdmFREE(column_name);
526     mdmFREE(modp_Reverse);
527}
528
529void modp_Evaluate(modp_number *ev, mono_type mon, condition_type con)  // evaluates monomial on condition (modp)
530{
531    int i;
532    *ev=0;
533    for (i=0;i<variables;i++)
534        if (con.mon[i] > mon[i]) return ;;
535    *ev=1;
536    int j,k;
537    mono_type mn;
538    mn=(exponent*)mdmALLOC(sizeof(exponent)*variables);
539    memcpy(mn,mon,sizeof(exponent)*variables);
540    for (k=0;k<variables;k++)
541    {
542        for (j=1;j<=con.mon[k];j++) // this loop computes the coefficient from derivation
543        {
544            *ev=modp_mul(*ev,mn[k]);
545            mn[k]--;
546        }
547        *ev=modp_mul(*ev,points[con.point_ref][k][mn[k]]);
548    }
549    mdmFREE(mn);
550}
551
552void int_Evaluate(mpz_t ev, mono_type mon, condition_type con) // (***) evaluates monomial on condition for integer numbers
553{
554    int i;
555    mpz_set_si(ev,0);
556    for (i=0;i<variables;i++)
557        if (con.mon[i] > mon[i]) return ;;
558    mpz_set_si(ev,1);
559    mpz_t mon_conv;
560    mpz_init(mon_conv);
561    int j,k;
562    mono_type mn;
563    mn=(exponent*)mdmALLOC(sizeof(exponent)*variables);
564    memcpy(mn,mon,sizeof(exponent)*variables);
565    for (k=0;k<variables;k++)
566    {
567        for (j=1;j<=con.mon[k];j++) // this loop computes the coefficient from derivation
568        {
569            mpz_set_si(mon_conv,mn[k]); // (***)
570            mpz_mul(ev,ev,mon_conv);
571            mn[k]--;
572        }
573        for (j=1;j<=mn[k];j++) mpz_mul(ev,ev,int_points[con.point_ref][k]);  // this loop computes the product of coordinate
574    }
575    mdmFREE(mn);
576    mpz_clear(mon_conv);
577}
578
579void ProduceRow(mono_type mon)  // produces a row for monomial - first part is an evaluated part, second 0 to obtain the coefs of dependence
580{
581     modp_number *row;
582     condition_type *con;
583     int i;
584     row=my_row;
585     con=condition_list;
586     for (i=0;i<final_base_dim;i++)
587     {
588         modp_Evaluate (row, mon, *con);
589         row++;
590         con++;
591     }
592     row=my_solve_row;
593     for (i=0;i<final_base_dim;i++)
594     {
595         *row=0;
596         row++;
597     }
598}
599
600void IntegerPoints ()  // produces integer points from rationals by scaling the coordinate system
601{
602     int i,j;
603     mpz_set_si(common_denom,1); // this is common scaling factor
604     for (i=0;i<n_points;i++)
605     {
606         for (j=0;j<variables;j++)
607         {
608             mpz_lcm(common_denom,common_denom,mpq_denref(q_points[i][j]));
609         }
610     }
611     mpq_t temp;
612     mpq_init(temp);
613     mpq_t denom_q;
614     mpq_init(denom_q);
615     mpq_set_z(denom_q,common_denom);
616     for (i=0;i<n_points;i++)
617     {
618         for (j=0;j<variables;j++)
619         {
620             mpq_mul(temp,q_points[i][j],denom_q);  // multiplies by common denominator
621             mpz_set(int_points[i][j],mpq_numref(temp));  // and changes into integer
622         }
623     }
624     mpq_clear(temp);
625     mpq_clear(denom_q);
626}
627
628void int_PrepareProducts ()  // prepares coordinates of points and products for modp case (from integer coefs)
629{
630     bool ok=true;
631     int i,j,k;
632     mpz_t big_myp;
633     mpz_init(big_myp);
634     mpz_set_si(big_myp,myp);
635     mpz_t temp;
636     mpz_init(temp);
637     for (i=0;i<n_points;i++)
638     {
639         for (j=0;j<variables;j++)
640         {
641             mpz_mod(temp,int_points[i][j],big_myp);  // coordinate is now modulo myp
642             points[i][j][1]=mpz_get_ui(temp);
643             points[i][j][0]=1;
644             for (k=2;k<max_coord;k++) points[i][j][k]=modp_mul(points[i][j][k-1],points[i][j][1]);
645         }
646     }
647     mpz_mod(temp,common_denom,big_myp);  // computes the common denominator (from rational data) modulo myp
648     denom_divisible=(mpz_sgn(temp)==0);  // checks whether it is divisible by modp
649     mpz_clear(temp);
650     mpz_clear(big_myp);
651}
652
653void modp_PrepareProducts () // prepares products for modp computation from modp data
654{
655     int i,j,k;
656     for (i=0;i<n_points;i++)
657     {
658         for (j=0;j<variables;j++)
659         {
660             points[i][j][1]=modp_points[i][j];
661             points[i][j][0]=1;
662             for (k=2;k<max_coord;k++) points[i][j][k]=modp_mul(points[i][j][k-1],points[i][j][1]);
663         }
664     }
665}
666
667void MakeConditions ()  // prepares a list of conditions from list of multiplicities
668{
669     condition_type *con;
670     int n,i,k;
671     mono_type mon;
672     mon=ZeroMonomial ();
673     con=condition_list;
674     for (n=0;n<n_points;n++)
675     {
676         for (i=0;i<variables;i++) mon[i]=0;
677         while (mon[0]<multiplicity[n])
678         {
679             if (MonDegree (mon) < multiplicity[n])
680             {
681                memcpy(con->mon,mon,sizeof(exponent)*variables);
682                con->point_ref=n;
683                con++;
684             }
685             k=variables-1;
686             mon[k]++;
687             while ((k>0)&&(mon[k]>=multiplicity[n]))
688             {
689                 mon[k]=0;
690                 k--;
691                 mon[k]++;
692             }
693         }
694     }
695     mdmFREE(mon);
696}
697
698void ReduceRow ()  // reduces my_row by previous rows, does the same for solve row
699{
700     if (row_list==NULL) return ;
701     row_list_entry *row_ptr;
702     modp_number *cur_row_ptr;
703     modp_number *solve_row_ptr;
704     modp_number *my_row_ptr;
705     modp_number *my_solve_row_ptr;
706     int first_col;
707     int i;
708     modp_number red_val;
709     modp_number mul_val;
710#ifdef integerstrategy
711     modp_number *m_row_ptr;
712     modp_number prep_val;
713#endif
714     row_ptr=row_list;
715     while (row_ptr!=NULL)
716     {
717           cur_row_ptr=row_ptr->row_matrix;
718           solve_row_ptr=row_ptr->row_solve;
719           my_row_ptr=my_row;
720           my_solve_row_ptr=my_solve_row;
721           first_col=row_ptr->first_col;
722           cur_row_ptr=cur_row_ptr+first_col;  // reduction begins at first_col position
723           my_row_ptr=my_row_ptr+first_col;
724           red_val=*my_row_ptr;
725           if (red_val!=0)
726           {
727#ifdef integerstrategy
728              prep_val=*cur_row_ptr;
729              if (prep_val!=1)
730              {
731                 m_row_ptr=my_row;
732                 for (i=0;i<final_base_dim;i++)
733                 {
734                     if (*m_row_ptr!=0) *m_row_ptr=modp_mul(*m_row_ptr,prep_val);
735                     m_row_ptr++;
736                 }
737                 m_row_ptr=my_solve_row;
738                 for (i=0;i<last_solve_column;i++)
739                 {
740                     if (*m_row_ptr!=0) *m_row_ptr=modp_mul(*m_row_ptr,prep_val);
741                     m_row_ptr++;
742                 }
743              }
744#endif
745              for (i=first_col;i<final_base_dim;i++)
746              {
747                  if (*cur_row_ptr!=0)
748                  {
749                    mul_val=modp_mul(*cur_row_ptr,red_val);
750                    *my_row_ptr=modp_sub(*my_row_ptr,mul_val);
751                  }
752                  my_row_ptr++;
753                  cur_row_ptr++;
754              }
755              for (i=0;i<=last_solve_column;i++)  // last_solve_column stores the last non-enmpty entry in solve matrix
756              {
757                  if (*solve_row_ptr!=0)
758                  {
759                     mul_val=modp_mul(*solve_row_ptr,red_val);
760                     *my_solve_row_ptr=modp_sub(*my_solve_row_ptr,mul_val);
761                  }
762                  solve_row_ptr++;
763                  my_solve_row_ptr++;
764              }
765           }
766           row_ptr=row_ptr->next;
767#ifdef debb
768           PrintS("reduction by row ");
769           Info ();
770#endif
771     }
772}
773
774bool RowIsZero () // check whether a row is zero
775{
776     bool zero=1;
777     int i;
778     modp_number *row;
779     row=my_row;
780     for (i=0;i<final_base_dim;i++)
781     {
782         if (*row!=0) {zero=0; break;}
783         row++;
784     }
785     return zero;
786}
787
788bool DivisibleMon (mono_type m1, mono_type m2) // checks whether m1 is divisible by m2
789{
790     int i;
791     for (i=0;i<variables;i++)
792         if (m1[i]>m2[i]) return false;;
793     return true;
794}
795
796void ReduceCheckListByMon (mono_type m)  // from check_list monomials divisible by m are thrown out
797{
798     mon_list_entry *c_ptr;
799     mon_list_entry *p_ptr;
800     mon_list_entry *n_ptr;
801     c_ptr=check_list;
802     p_ptr=NULL;
803     while (c_ptr!=NULL)
804     {
805          if (DivisibleMon (m,c_ptr->mon))
806          {
807             if (p_ptr==NULL) 
808                check_list=c_ptr->next;
809             else
810                p_ptr->next=c_ptr->next;
811             n_ptr=c_ptr->next;
812             mdmFREE(c_ptr->mon);
813             mdmFREE(c_ptr);
814             c_ptr=n_ptr;
815          }
816          else
817          {
818              p_ptr=c_ptr;
819              c_ptr=c_ptr->next;
820          }
821     }
822}
823
824void TakeNextMonomial (mono_type mon)  // reads first monomial from check_list, then it is deleted
825{
826     mon_list_entry *n_check_list;
827     if (check_list!=NULL)
828     {
829        memcpy(mon,check_list->mon,sizeof(exponent)*variables);
830        n_check_list=check_list->next;
831        mdmFREE(check_list->mon);
832        mdmFREE(check_list);
833        check_list=n_check_list;
834     }
835}
836
837void UpdateCheckList (mono_type m) // adds all monomials which are "next" to m (divisible by m and degree +1)
838{
839     int i;
840     for (i=0;i<variables;i++)
841     {
842         m[i]++;
843         check_list=MonListAdd (check_list,m);
844         m[i]--;
845     }
846}
847
848void ReduceCheckListByLTs ()  // deletes all monomials from check_list which are divisible by one of the leading terms
849{
850     mon_list_entry *ptr;
851     ptr=lt_list;
852     while (ptr!=NULL)
853     {
854           ReduceCheckListByMon (ptr->mon);
855           ptr=ptr->next;
856     }
857}
858
859void RowListAdd (int first_col, mono_type mon) // puts a row into matrix
860{
861     row_list_entry *ptr;
862     row_list_entry *pptr;
863     row_list_entry *temp;
864     ptr=row_list;
865     pptr=NULL;
866     while (ptr!=NULL)
867     {
868#ifndef unsortedmatrix
869         if (  first_col <= ptr->first_col ) break;
870#endif
871         pptr=ptr;
872         ptr=ptr->next;
873     }
874     temp=(row_list_entry*)mdmALLOC(sizeof(row_list_entry));
875     (*temp).row_matrix=(modp_number*)mdmALLOC(sizeof(modp_number)*final_base_dim);
876     memcpy((*temp).row_matrix,my_row,sizeof(modp_number)*(final_base_dim));
877     (*temp).row_solve=(modp_number*)mdmALLOC(sizeof(modp_number)*final_base_dim);
878     memcpy((*temp).row_solve,my_solve_row,sizeof(modp_number)*(final_base_dim));
879     (*temp).first_col=first_col;
880     temp->next=ptr;
881     if (pptr==NULL) row_list=temp; else pptr->next=temp;
882     memcpy(column_name[first_col],mon,sizeof(exponent)*variables);
883}
884
885
886void PrepareRow (mono_type mon) // prepares a row and puts it into matrix
887{
888     modp_number *row;
889     int first_col=-1;
890     int col;
891     modp_number red_val=1;
892     row=my_row;
893#ifdef integerstrategy
894     for (col=0;col<final_base_dim;col++)
895     {
896         if (*row!=0)
897         {
898            first_col=col;
899            break;
900         }
901         row++;
902     }
903     my_solve_row[first_col]=1;
904     if (first_col > last_solve_column) last_solve_column=first_col;
905#else
906     for (col=0;col<final_base_dim;col++)
907     {
908         if (*row!=0)
909         {
910            first_col=col;
911            red_val=modp_Reverse[*row]; // first non-zero entry, should multiply all row by inverse to obtain 1
912            modp_denom=modp_mul(modp_denom,*row);  // remembers the divisor
913            *row=1;
914            break;
915         }
916         row++;
917     }
918     my_solve_row[first_col]=1;
919     if (first_col > last_solve_column) last_solve_column=first_col;
920     if (red_val!=1)
921     {
922        row++;
923        for (col=first_col+1;col<final_base_dim;col++)
924        {
925            if (*row!=0) *row=modp_mul(*row,red_val);
926            row++;
927        }
928        row=my_solve_row;
929        for (col=0;col<=last_solve_column;col++)
930        {
931            if (*row!=0) *row=modp_mul(*row,red_val);
932            row++;
933        }
934     }
935#endif
936     RowListAdd (first_col, mon);
937}
938
939void NewResultEntry ()  // creates an entry for new modp result
940{
941    modp_result_entry *temp;
942    int i;
943    temp=(modp_result_entry*)mdmALLOC(sizeof(modp_result_entry));
944    if (cur_result==NULL)
945    {
946       modp_result=temp;
947       temp->prev=NULL;
948    }
949    else
950    {
951       temp->prev=cur_result;
952       cur_result->next=temp;
953    }
954    cur_result=temp;
955    cur_result->next=NULL;
956    cur_result->p=myp;
957    cur_result->generator=NULL;
958    cur_result->n_generators=0;
959    n_results++;
960}
961
962void FreeResultEntry (modp_result_entry *e) // destroys the result entry, without worrying about where it is
963{
964     generator_entry *cur_gen;
965     generator_entry *next_gen;
966     cur_gen=e->generator;
967     while (cur_gen!=NULL)
968     {
969         next_gen=cur_gen->next;
970         mdmFREE(cur_gen->coef);
971         mdmFREE(cur_gen->lt);
972         mdmFREE(cur_gen);
973         cur_gen=next_gen;
974     }
975     mdmFREE(e);
976}
977
978
979void NewGenerator (mono_type mon)  // new generator in modp comp found, shoul be stored on the list
980{
981     int i;
982     generator_entry *cur_ptr;
983     generator_entry *prev_ptr;
984     generator_entry *temp;
985     cur_ptr=cur_result->generator;
986     prev_ptr=NULL;
987     while (cur_ptr!=NULL)
988     {
989         prev_ptr=cur_ptr;
990         cur_ptr=cur_ptr->next;
991     }
992     temp=(generator_entry*)mdmALLOC(sizeof(generator_entry));
993     if (prev_ptr==NULL) cur_result->generator=temp; else prev_ptr->next=temp;
994     temp->next=NULL;
995     temp->coef=(modp_number*)mdmALLOC(sizeof(modp_number)*final_base_dim);
996     memcpy(temp->coef,my_solve_row,sizeof(modp_number)*final_base_dim);
997     temp->lt=ZeroMonomial ();
998     memcpy(temp->lt,mon,sizeof(exponent)*variables);
999     temp->ltcoef=1;
1000     cur_result->n_generators++;
1001}
1002
1003void MultGenerators () // before reconstructing, all denominators must be cancelled
1004{
1005#ifndef integerstrategy
1006     int i;
1007     generator_entry *cur_ptr;
1008     cur_ptr=cur_result->generator;
1009     while (cur_ptr!=NULL)
1010     {
1011         for (i=0;i<final_base_dim;i++) 
1012             cur_ptr->coef[i]=modp_mul(cur_ptr->coef[i],modp_denom);
1013         cur_ptr->ltcoef=modp_denom;
1014         cur_ptr=cur_ptr->next;
1015     }
1016#endif
1017}
1018
1019void PresentGenerator (int i)  // only for debuging, writes a generator in its form in program
1020{
1021     int j;
1022     modp_result_entry *cur_ptr;
1023     generator_entry *cur_gen;
1024     cur_ptr=modp_result;
1025     while (cur_ptr!=NULL)
1026     {
1027        cur_gen=cur_ptr->generator;
1028        for (j=0;j<i;j++) cur_gen=cur_gen->next;
1029        for (j=0;j<final_base_dim;j++)
1030        {
1031            Print("%d;", cur_gen->coef[j]);
1032        }
1033        PrintS(" and LT = ");
1034        WriteMono (cur_gen->lt);
1035        Print(" ( %d )  prime = %d\n", cur_gen->ltcoef, cur_ptr->p);
1036        cur_ptr=cur_ptr->next;
1037     }
1038}
1039
1040modp_number TakePrime (modp_number p)  // takes "previous" (smaller) prime
1041{
1042#ifdef HAVE_FACTORY
1043    myp_index--;
1044    return cf_getSmallPrime(myp_index);
1045#else
1046    return IsPrime(p-1);
1047#endif
1048}
1049
1050void PrepareChinese (int n) // initialization for CRA
1051{
1052     int i,k;
1053     modp_result_entry *cur_ptr;
1054     cur_ptr=modp_result;
1055     modp_number *congr_ptr;
1056     modp_number prod;
1057     in_gamma=(modp_number*)mdmALLOC(sizeof(modp_number)*n);
1058     congr=(modp_number*)mdmALLOC(sizeof(modp_number)*n);
1059     congr_ptr=congr;
1060     while (cur_ptr!=NULL)
1061     {
1062        *congr_ptr=cur_ptr->p;
1063        cur_ptr=cur_ptr->next;
1064        congr_ptr++;
1065     }
1066     for (k=1;k<n;k++)
1067     {
1068         prod=congr[0]%congr[k];
1069         for (i=1;i<=k-1;i++) prod=(prod*congr[i])%congr[k];
1070         in_gamma[i]=OneInverse(prod,congr[k]);
1071     }
1072     mpz_init(bigcongr);
1073     mpz_set_ui(bigcongr,congr[0]);
1074     for (k=1;k<n;k++) mpz_mul_ui(bigcongr,bigcongr,congr[k]);
1075}
1076
1077void CloseChinese (int n) // after CRA
1078{
1079     mdmFREE(in_gamma);
1080     mdmFREE(congr);
1081     mpz_clear(bigcongr);
1082}
1083
1084void ClearGCD () // divides polynomials in basis by gcd of coefficients
1085{
1086     bool first_gcd=true;
1087     int i;
1088     mpz_t g;
1089     mpz_init(g);
1090     for (i=0;i<=final_base_dim;i++)
1091     {
1092         if (mpz_sgn(polycoef[i])!=0)
1093         {
1094            if (first_gcd)
1095            {
1096               first_gcd=false;
1097               mpz_set(g,polycoef[i]);
1098            }
1099            else
1100               mpz_gcd(g,g,polycoef[i]);
1101         }
1102     }
1103     for (i=0;i<=final_base_dim;i++) mpz_divexact(polycoef[i],polycoef[i],g);
1104     mpz_clear(g);
1105}
1106
1107void ReconstructGenerator (int ngen,int n,bool show) // recostruction of generator from various modp comp
1108{
1109     int size;
1110     int i,j,k;
1111     int coef;
1112     char *str=NULL;
1113     str=(char*)mdmALLOC(sizeof(char)*1000);
1114     modp_result_entry *cur_ptr;
1115     generator_entry *cur_gen;
1116     modp_number *u;
1117     modp_number *v;
1118     modp_number temp;
1119     mpz_t sol;
1120     mpz_t nsol;
1121     mpz_init(sol);
1122     mpz_init(nsol);
1123     u=(modp_number*)mdmALLOC(sizeof(modp_number)*n);
1124     v=(modp_number*)mdmALLOC(sizeof(modp_number)*n);
1125     for (coef=0;coef<=final_base_dim;coef++)
1126     {
1127         i=0;
1128         cur_ptr=modp_result;
1129         while (cur_ptr!=NULL)
1130         {
1131            cur_gen=cur_ptr->generator;
1132            for (j=0;j<ngen;j++) cur_gen=cur_gen->next; // we have to take jth generator
1133            if (coef<final_base_dim) u[i]=cur_gen->coef[coef]; else u[i]=cur_gen->ltcoef;
1134            cur_ptr=cur_ptr->next;
1135            i++;
1136         }
1137         v[0]=u[0]; // now CRA begins
1138         for (k=1;k<n;k++)
1139         {
1140             temp=v[k-1];
1141             for (j=k-2;j>=0;j--) temp=(temp*congr[j]+v[j])%congr[k];
1142             temp=u[k]-temp;
1143             if (temp<0) temp=temp+congr[k];
1144             v[k]=(temp*in_gamma[k])%congr[k];
1145         }
1146         mpz_set_si(sol,v[n-1]);
1147         for (k=n-2;k>=0;k--)
1148         {
1149             mpz_mul_ui(sol,sol,congr[k]);
1150             mpz_add_ui(sol,sol,v[k]);
1151         }          // now CRA ends
1152         mpz_sub(nsol,sol,bigcongr);
1153         int s=mpz_cmpabs(sol,nsol);
1154         if (s>0) mpz_set(sol,nsol); // chooses representation closer to 0
1155         mpz_set(polycoef[coef],sol);
1156         if (coef<final_base_dim)
1157            memcpy(polyexp[coef],generic_column_name[coef],sizeof(exponent)*variables);
1158         else
1159            memcpy(polyexp[coef],MonListElement (generic_lt,ngen),sizeof(exponent)*variables);
1160#ifdef checksize
1161         size=mpz_sizeinbase(sol,10);
1162         if (size>maximal_size) maximal_size=size;
1163#endif
1164     }
1165     mdmFREE(u);
1166     mdmFREE(v);
1167     mdmFREE(str);
1168     ClearGCD ();
1169     mpz_clear(sol);
1170     mpz_clear(nsol);
1171}
1172
1173void Discard ()  // some unlucky prime occures
1174{
1175     modp_result_entry *temp;
1176#ifdef writemsg
1177     Print(", prime=%d", cur_result->p);
1178#endif
1179     bad_primes++;
1180     if (good_primes>bad_primes)
1181     {
1182#ifdef writemsg
1183        Print("-discarding this comp (%dth)\n", n_results);
1184#endif
1185        temp=cur_result;
1186        cur_result=cur_result->prev;
1187        cur_result->next=NULL;
1188        n_results--;
1189        FreeResultEntry (temp);
1190     }
1191     else
1192     {
1193#ifdef writemsg
1194        PrintS("-discarding ALL.\n");
1195#endif
1196        int i;
1197        modp_result_entry *ntfree;
1198        generator_entry *cur_gen;
1199        temp=cur_result->prev;
1200        while (temp!=NULL)
1201        {
1202            ntfree=temp->prev;
1203            FreeResultEntry (temp);
1204            temp=ntfree;
1205        }
1206        modp_result=cur_result;
1207        cur_result->prev=NULL;
1208        n_results=1;
1209        good_primes=1;
1210        bad_primes=0;
1211        generic_n_generators=cur_result->n_generators;
1212        cur_gen=cur_result->generator;
1213        generic_lt=FreeMonList (generic_lt);
1214        for (i=0;i<generic_n_generators;i++)
1215        {
1216            generic_lt=MonListAdd (generic_lt,cur_gen->lt);
1217            cur_gen=cur_gen->next;
1218        }
1219        for (i=0;i<final_base_dim;i++) memcpy(generic_column_name[i],column_name[i],sizeof(exponent)*variables);
1220     }
1221}
1222
1223void modp_SetColumnNames ()  // used by modp - sets column names, the old table will be destroyed
1224{
1225    int i;
1226    for (i=0;i<final_base_dim;i++) memcpy(generic_column_name[i],column_name[i],sizeof(exponent)*variables);
1227}
1228
1229void CheckColumnSequence () // checks if scheme of computations is as generic one
1230{
1231     int i;
1232     if (cur_result->n_generators!=generic_n_generators)
1233     {
1234#ifdef writemsg
1235        PrintS("wrong number of generators occured");
1236#else
1237        if (protocol) PrintS("ng");
1238#endif
1239        Discard ();
1240        return;
1241     }
1242     if (denom_divisible)
1243     {
1244#ifdef writemsg
1245        PrintS("denom of coef divisible by p");
1246#else
1247        if (protocol) PrintS("dp");
1248#endif
1249        Discard ();
1250        return;
1251     }
1252     generator_entry *cur_gen;
1253     mon_list_entry *cur_mon;
1254     cur_gen=cur_result->generator;
1255     cur_mon=generic_lt;
1256     for (i=0;i<generic_n_generators;i++)
1257     {
1258         if (!EqualMon(cur_mon->mon,cur_gen->lt))
1259         {
1260#ifdef writemsg
1261            PrintS("wrong leading term occured");
1262#else
1263            if (protocol) PrintS("lt");
1264#endif
1265            Discard ();
1266            return;
1267         }
1268         cur_gen=cur_gen->next;
1269         cur_mon=cur_mon->next;
1270     }
1271     for (i=0;i<final_base_dim;i++)
1272     {
1273         if (!EqualMon(generic_column_name[i],column_name[i]))
1274         {
1275#ifdef writemsg
1276            PrintS("wrong seq of cols occured");
1277#else
1278            if (protocol) PrintS("sc");
1279#endif
1280            Discard ();
1281            return;
1282         }
1283     }
1284     good_primes++;
1285}
1286
1287void WriteGenerator () // writes generator (only for debugging)
1288{
1289     char *str;
1290     str=(char*)mdmALLOC(sizeof(char)*1000);
1291     int i;
1292     for (i=0;i<=final_base_dim;i++)
1293     {
1294         str=mpz_get_str(str,10,polycoef[i]);
1295         PrintS(str);
1296         PrintS("*");
1297         WriteMono(polyexp[i]);
1298         PrintS(" ");
1299     }
1300     mdmFREE(str);
1301     PrintLn();
1302}
1303
1304bool CheckGenerator () // evaluates generator to check whether it is good
1305{
1306     mpz_t val,sum,temp;
1307     int con,i;
1308     mpz_init(val);
1309     mpz_init(sum);
1310     for (con=0;con<final_base_dim;con++)
1311     {
1312       mpz_set_si(sum,0);
1313       for (i=0;i<=final_base_dim;i++)
1314       {
1315         int_Evaluate(val, polyexp[i], condition_list[con]);
1316         mpz_mul(val,val,polycoef[i]);
1317         mpz_add(sum,sum,val);
1318       }
1319       if (mpz_sgn(sum)!=0)
1320       {
1321          mpz_clear(val);
1322          mpz_clear(sum);
1323          return false;
1324       }
1325    }
1326    mpz_clear(val);
1327    mpz_clear(sum);
1328    return true;
1329}
1330
1331void ClearGenList ()
1332{
1333     gen_list_entry *temp;
1334     int i;
1335     while (gen_list!=NULL)
1336     {
1337         temp=gen_list->next;
1338         for (i=0;i<=final_base_dim;i++)
1339         {
1340             mpz_clear(gen_list->polycoef[i]);
1341             mdmFREE(gen_list->polyexp[i]);
1342         }
1343         mdmFREE(gen_list->polycoef);
1344         mdmFREE(gen_list->polyexp);
1345         mdmFREE(gen_list);
1346         gen_list=temp;
1347      }
1348}
1349
1350void UpdateGenList ()
1351{
1352     gen_list_entry *temp,*prev;
1353     int i,j;
1354     prev=NULL;
1355     temp=gen_list;
1356     exponent deg;
1357     for (i=0;i<=final_base_dim;i++)
1358     {
1359         deg=MonDegree(polyexp[i]);
1360         for (j=0;j<deg;j++)
1361         {
1362             mpz_mul(polycoef[i],polycoef[i],common_denom);
1363         }
1364     }
1365     ClearGCD ();
1366     while (temp!=NULL)
1367     {
1368         prev=temp;
1369         temp=temp->next;
1370     }
1371     temp=(gen_list_entry*)mdmALLOC(sizeof(gen_list_entry));
1372     if (prev==NULL) gen_list=temp; else prev->next=temp;
1373     temp->next=NULL;
1374     temp->polycoef=(mpz_t*)mdmALLOC(sizeof(mpz_t)*(final_base_dim+1));
1375     temp->polyexp=(mono_type*)mdmALLOC(sizeof(mono_type)*(final_base_dim+1));
1376     for (i=0;i<=final_base_dim;i++)
1377     {
1378         mpz_init(temp->polycoef[i]);
1379         mpz_set(temp->polycoef[i],polycoef[i]);
1380         temp->polyexp[i]=ZeroMonomial ();
1381         memcpy(temp->polyexp[i],polyexp[i],sizeof(exponent)*variables);
1382     }
1383}
1384
1385void ShowGenList ()
1386{
1387     gen_list_entry *temp;
1388     int i;
1389     char *str;
1390     str=(char*)mdmALLOC(sizeof(char)*1000);
1391     temp=gen_list;
1392     while (temp!=NULL)
1393     {
1394         PrintS("generator: ");
1395         for (i=0;i<=final_base_dim;i++)
1396         {
1397             str=mpz_get_str(str,10,temp->polycoef[i]);
1398             PrintS(str);
1399             PrintS("*");
1400             WriteMono(temp->polyexp[i]);
1401         }
1402         PrintLn();
1403         temp=temp->next;
1404     }
1405     mdmFREE(str);
1406}
1407
1408
1409void modp_Main ()
1410{
1411     mono_type cur_mon;
1412     cur_mon= ZeroMonomial ();
1413     modp_denom=1;
1414     bool row_is_zero;
1415
1416#ifdef debb
1417     Info ();
1418#endif
1419
1420     while (check_list!=NULL)
1421     {
1422           TakeNextMonomial (cur_mon);
1423           ProduceRow (cur_mon);
1424#ifdef debb
1425           cout << "row produced for monomial ";
1426           WriteMono (cur_mon);
1427           cout << endl;
1428           Info ();
1429#endif
1430           ReduceRow ();
1431           row_is_zero = RowIsZero ();
1432           if (row_is_zero)
1433           {
1434              lt_list=MonListAdd (lt_list,cur_mon);
1435              ReduceCheckListByMon (cur_mon);
1436              NewGenerator (cur_mon);
1437#ifdef debb
1438              cout << "row is zero - linear dependence found (should be seen in my_solve_row)" << endl;
1439              cout << "monomial added to leading terms list" << endl;
1440              cout << "check list updated" << endl;
1441              Info ();
1442#endif
1443           }
1444           else
1445           {
1446              base_list= MonListAdd (base_list,cur_mon);
1447              UpdateCheckList (cur_mon);
1448              ReduceCheckListByLTs ();
1449#ifdef debb
1450              cout << "row is non-zero" << endl;
1451              cout << "monomial added to quotient basis list" << endl;
1452              cout << "new monomials added to check list" << endl;
1453              cout << "check list reduced by monomials from leading term list" << endl;
1454              Info ();
1455#endif
1456              PrepareRow (cur_mon);
1457#ifdef debb
1458              cout << "row prepared and put into matrix" << endl;
1459              Info ();
1460#endif
1461           }
1462        }
1463        mdmFREE(cur_mon);
1464}
1465
1466void ResolveCoeff (mpq_t c, number m)
1467{
1468     if ((long)m & SR_INT)
1469     {
1470        long m_val=SR_TO_INT(m);
1471        mpq_set_si(c,m_val,1);
1472     }
1473     else
1474     {
1475        if (m->s<2)
1476        {
1477           mpz_set(mpq_numref(c),m->z);
1478           mpz_set(mpq_denref(c),m->n);
1479           mpq_canonicalize(c);
1480        }
1481        else
1482        {
1483           mpq_set_z(c,m->z);
1484        }
1485     }
1486}
1487
1488ideal interpolation(lists L, intvec *v)
1489{
1490  protocol=TEST_OPT_PROT;  // should be set if option(prot) is enabled
1491
1492  bool data_ok=true;
1493
1494  // reading the ring data ***************************************************
1495  if ((currRing==NULL) || ((!rField_is_Zp ())&&(!rField_is_Q ())))
1496  {
1497     WerrorS("coefficient field should be Zp or Q!");
1498     return NULL;
1499  }
1500  if ((currRing->qideal)!=NULL)
1501  {
1502     WerrorS("quotient ring not supported!");
1503     return NULL;
1504  }
1505  if ((currRing->OrdSgn)!=1)
1506  {
1507     WerrorS("ordering must be global!");
1508     return NULL;
1509  }
1510  n_points=v->length ();
1511  if (n_points!=(L->nr+1))
1512  {
1513     WerrorS("list and intvec must have the same length!");
1514     return NULL;
1515  }
1516  variables=currRing->N;
1517  only_modp=rField_is_Zp();
1518  if (only_modp) myp=rChar();
1519  // ring data read **********************************************************
1520
1521
1522  multiplicity=(int*)malloc(sizeof(int)*n_points);
1523  int i;
1524  for (i=0;i<n_points;i++) multiplicity[i]=(*v)[i];
1525
1526  final_base_dim = CalcBaseDim ();
1527
1528#ifdef writemsg
1529  Print("number of variables: %d\n", variables);
1530  Print("number of points: %d\n", n_points);
1531  PrintS("multiplicities: ");
1532  for (i=0;i<n_points;i++) Print("%d ", multiplicity[i]);
1533  PrintLn();
1534  Print("general initialization for dimension %d ...\n", final_base_dim);
1535#endif
1536
1537  GeneralInit ();
1538
1539// reading coordinates of points from ideals **********************************
1540  mpq_t divisor;
1541  if (!only_modp) mpq_init(divisor);
1542  int j;
1543  for(i=0; i<=L->nr;i++)
1544  {
1545    ideal I=(ideal)L->m[i].Data();
1546    for(j=0;j<IDELEMS(I);j++)
1547    {
1548      poly p=I->m[j];
1549      if (p!=NULL)
1550      {
1551        poly ph=pHead(p);
1552        int pcvar=pVar(ph);
1553        if (pcvar!=0)
1554        {
1555          pcvar--;
1556          if (coord_exist[i][pcvar])
1557          {
1558             Print("coordinate %d for point %d initialized twice!\n",pcvar+1,i+1);
1559             data_ok=false;
1560          }
1561          number m;
1562          m=pGetCoeff(p); // possible coefficient standing by a leading monomial
1563          if (!only_modp) ResolveCoeff (divisor,m);
1564          number n;
1565          if (pNext(p)!=NULL) n=pGetCoeff(pNext(p));
1566          else n=nInit(0);
1567          if (only_modp)
1568          {
1569            n=nNeg(n);
1570            n=nDiv(n,m);
1571            modp_points[i][pcvar]=(int)((long)n);
1572          }
1573          else
1574          {
1575            ResolveCoeff (q_points[i][pcvar],n);
1576            mpq_neg(q_points[i][pcvar],q_points[i][pcvar]);
1577            mpq_div(q_points[i][pcvar],q_points[i][pcvar],divisor);
1578          }
1579          coord_exist[i][pcvar]=true;
1580        }
1581        else
1582        {
1583          PrintS("not a variable? ");
1584          wrp(p);
1585          PrintLn();
1586          data_ok=false;
1587        }
1588        pDelete(&ph);
1589      }
1590    }
1591  }
1592  if (!only_modp) mpq_clear(divisor);
1593  // data from ideal read *******************************************************
1594
1595  // ckecking if all coordinates are initialized
1596  for (i=0;i<n_points;i++)
1597  {
1598      for (j=0;j<variables;j++)
1599      {
1600          if (!coord_exist[i][j])
1601          {
1602             Print("coordinate %d for point %d not known!\n",j+1,i+1);
1603             data_ok=false;
1604          }
1605      }
1606  }
1607
1608  if (!data_ok)
1609  {
1610     GeneralDone();
1611     WerrorS("data structure is invalid");
1612     return NULL;
1613  }
1614
1615  if (!only_modp) IntegerPoints ();
1616  MakeConditions ();
1617#ifdef writemsg
1618  PrintS("done.\n");
1619#else
1620  if (protocol) Print("[vdim %d]",final_base_dim);
1621#endif
1622
1623
1624// main procedure *********************************************************************
1625  int modp_cycles=10;
1626  bool correct_gen=false;
1627  if (only_modp) modp_cycles=1;
1628  #ifdef HAVE_FACTORY
1629  myp_index=cf_getNumSmallPrimes ();
1630  #endif
1631
1632  while ((!correct_gen)&&(myp_index>1))
1633  {
1634#ifdef writemsg
1635        Print("trying %d cycles mod p...\n",modp_cycles);
1636#else
1637        if (protocol) Print("(%d)",modp_cycles);
1638#endif
1639        while ((n_results<modp_cycles)&&(myp_index>1))  // some computations mod p
1640        {
1641            if (!only_modp) myp=TakePrime (myp);
1642            NewResultEntry ();
1643            InitProcData ();
1644            if (only_modp) modp_PrepareProducts (); else int_PrepareProducts ();
1645
1646            modp_Main ();
1647
1648            if (!only_modp)
1649            {
1650               MultGenerators ();
1651               CheckColumnSequence ();
1652            }
1653            else
1654            {
1655               modp_SetColumnNames ();
1656            }
1657            FreeProcData ();
1658        }
1659
1660        if (!only_modp)
1661        {
1662           PrepareChinese (modp_cycles);
1663           correct_gen=true;
1664           for (i=0;i<generic_n_generators;i++)
1665           {
1666               ReconstructGenerator (i,modp_cycles,false);
1667               correct_gen=CheckGenerator ();
1668               if (!correct_gen)
1669               {
1670#ifdef writemsg
1671                  PrintS("wrong generator!\n");
1672#else
1673//                  if (protocol) PrintS("!g");
1674#endif
1675                  ClearGenList ();
1676                  break;
1677               }
1678               else
1679               {
1680                  UpdateGenList ();
1681               }
1682           }
1683#ifdef checksize
1684           Print("maximal size of output: %d, precision bound: %d.\n",maximalsize,mpz_sizeinbase(bigcongr,10));
1685#endif
1686           CloseChinese (modp_cycles);
1687           modp_cycles=modp_cycles+10;
1688        }
1689        else
1690        {
1691           correct_gen=true;
1692        }
1693  }
1694// end of main procedure ************************************************************************************
1695
1696#ifdef writemsg
1697  PrintS("computations finished.\n");
1698#else
1699  if (protocol) PrintLn();
1700#endif
1701
1702  if (!correct_gen)
1703  {
1704     GeneralDone ();
1705     ClearGenList ();
1706     WerrorS("internal error - coefficient too big!");
1707     return NULL;
1708  }
1709
1710// passing data to ideal *************************************************************************************
1711  ideal ret;
1712
1713  if (only_modp)
1714  {
1715    mono_type mon;
1716    ret=idInit(modp_result->n_generators,1);
1717    generator_entry *cur_gen=modp_result->generator;
1718    for(i=0;i<IDELEMS(ret);i++)
1719    {
1720      poly p,sum;
1721      sum=NULL;
1722      int a;
1723      int cf;
1724      for (a=final_base_dim;a>=0;a--)
1725      {
1726        if (a==final_base_dim) cf=cur_gen->ltcoef; else cf=cur_gen->coef[a];
1727        if (cf!=0)
1728        {
1729            p=pISet(cf);
1730            if (a==final_base_dim) mon=cur_gen->lt; else mon=generic_column_name[a];
1731            for (j=0;j<variables;j++) pSetExp(p,j+1,mon[j]);
1732            pSetm(p);
1733            sum=pAdd(sum,p);
1734        }
1735      }
1736      ret->m[i]=sum;
1737      cur_gen=cur_gen->next;
1738    }
1739  }
1740  else
1741  {
1742    ret=idInit(generic_n_generators,1);
1743    gen_list_entry *temp=gen_list;
1744    for(i=0;i<IDELEMS(ret);i++)
1745    {
1746      poly p,sum;
1747      sum=NULL;
1748      int a;
1749      for (a=final_base_dim;a>=0;a--) // build one polynomial
1750      {
1751          if (mpz_sgn(temp->polycoef[a])!=0)
1752          {
1753             number n=(number)omAllocBin(rnumber_bin);
1754#ifdef LDEBUG
1755             n->debug=123456;
1756#endif
1757             mpz_init_set(n->z,temp->polycoef[a]);
1758             n->s=3;
1759             nlNormalize(n);
1760             p=pNSet(n); //a monomial
1761             for (j=0;j<variables;j++) pSetExp(p,j+1,temp->polyexp[a][j]);
1762             pSetm(p); // after all pSetExp
1763             sum=pAdd(sum,p);
1764          }
1765      }
1766      ret->m[i]=sum;
1767      temp=temp->next;
1768    }
1769  }
1770// data transferred ****************************************************************************
1771
1772
1773  GeneralDone ();
1774  ClearGenList ();
1775  return ret;
1776}
1777
1778
1779BOOLEAN jjINTERPOLATION (leftv res, leftv l, leftv v)
1780{
1781  res->data=interpolation((lists)l->Data(),(intvec*)v->Data());
1782  setFlag(res,FLAG_STD);
1783  return errorreported;
1784}
Note: See TracBrowser for help on using the repository browser.