source: git/Singular/interpolation.cc @ b5e57e2

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