/**************************************** * Computer Algebra System SINGULAR * ****************************************/ #include "config.h" #include #include #ifdef HAVE_FACTORY #define SI_DONT_HAVE_GLOBAL_VARS # include #endif /* HAVE_FACTORY */ #include #include #include #include #include #include #include #include "lists.h" #include "ipid.h" // parameters to debug //#define shmat //#define checksize //#define writemsg // possible strategies #define unsortedmatrix //#define integerstrategy #define modp_number int #define exponent int modp_number myp; // all modp computation done mod myp int myp_index; // index of small prime in Singular table of primes static inline modp_number modp_mul (modp_number x,modp_number y) { // return (x*y)%myp; return (modp_number)(((unsigned long)x)*((unsigned long)y)%((unsigned long)myp)); } static inline modp_number modp_sub (modp_number x,modp_number y) { // if (x>=y) return x-y; else return x+myp-y; return (x+myp-y)%myp; } typedef exponent *mono_type; typedef struct {mono_type mon; unsigned int point_ref;} condition_type; typedef modp_number *coordinate_products; typedef coordinate_products *coordinates; struct mon_list_entry_struct {mono_type mon; struct mon_list_entry_struct *next;}; typedef struct mon_list_entry_struct mon_list_entry; struct row_list_entry_struct {modp_number *row_matrix; modp_number *row_solve; int first_col; struct row_list_entry_struct *next;}; typedef struct row_list_entry_struct row_list_entry; struct generator_struct {modp_number *coef; mono_type lt; modp_number ltcoef; struct generator_struct *next;}; typedef struct generator_struct generator_entry; struct modp_result_struct {modp_number p; generator_entry *generator; int n_generators; struct modp_result_struct *next; struct modp_result_struct *prev;}; typedef struct modp_result_struct modp_result_entry; typedef modp_number *modp_coordinates; typedef mpq_t *q_coordinates; typedef mpz_t *int_coordinates; typedef bool *coord_exist_table; int final_base_dim; // dimension of the quotient space, known from the beginning int last_solve_column; // last non-zero column in "solve" part of matrix, used for speed up int n_points; // modp_number of ideals (points) int *multiplicity; // multiplicities of points int variables; // modp_number of variables int max_coord; // maximal possible coordinate product used during Evaluation bool only_modp; // perform only one modp computations modp_coordinates *modp_points; // coordinates of points for modp problem - used by Evaluate (this is also initial data for only modp) q_coordinates *q_points; // coordinates of points for rational data (not used for modp) int_coordinates *int_points; // coordinates of points for integer data - used to check generators (not used for modp) coord_exist_table *coord_exist; // checks whether all coordinates has been initialized mon_list_entry *check_list; // monomials to be checked in next stages coordinates *points; // power products of coordinates of points used in modp cycles condition_type *condition_list; // conditions stored in an array mon_list_entry *lt_list; // leading terms found so far mon_list_entry *base_list; // standard monomials found so far row_list_entry *row_list; // rows of the matrix (both parts) modp_number *my_row; // one special row to perform operations modp_number *my_solve_row; // one special row to find the linear dependence ("solve" part) mono_type *column_name; // monomials assigned to columns in solve_row int n_results; // modp_number of performed modp computations (not discarded) modp_number modp_denom; // denominator of mod p computations modp_result_entry *modp_result; // list of results for various mod p calculations (used for modp - first result is the desired one) modp_result_entry *cur_result; // pointer to current result (as before) modp_number *congr; // primes used in computations (chinese remainder theorem) (not used for modp) modp_number *in_gamma; // inverts used in chinese remainder theorem (not used for modp) mpz_t bigcongr; // result, in fact, is given in mod bigcongr (not used for modp) mpz_t *polycoef; // polynomial integercoefficients (not used for modp) mono_type *polyexp; // polynomial exponents struct gen_list_struct {mpz_t *polycoef; mono_type *polyexp; struct gen_list_struct *next;}; typedef struct gen_list_struct gen_list_entry; gen_list_entry *gen_list=NULL; // list of resulting generators - output data (integer version) int generic_n_generators; // modp_number of generators - should be the same for all modp comp (not used for modp) mono_type *generic_column_name; // monomials assigned to columns in solve_row - should be the same for all modp comp (!!! used for modp) mon_list_entry *generic_lt=NULL; // leading terms for ordered generators - should be the same for all modp comp (not used for modp) int good_primes; // modp_number of good primes so far; int bad_primes; // modp_number of bad primes so far; mpz_t common_denom; // common denominator used to force points coordinates to Z (not used for modp) bool denom_divisible; // common denominator is divisible by p (not used for modp) poly comparizon_p1; //polynomials used to do comparizons by Singular poly comparizon_p2; modp_number *modp_Reverse; // reverses in mod p bool protocol; // true to show the protocol #ifdef checksize int maximal_size=0; #endif #if 0 /* only for debuggig*/ void WriteMono (mono_type m) // Writes a monomial on the screen - only for debug { int i; for (i=0;imon); ptr=ptr->next; } } void Info () { int i; row_list_entry *curptr; modp_number *row; modp_number *solve; char ch; cout << endl << "quotient basis: "; WriteMonoList (base_list); cout << endl << "leading terms: "; WriteMonoList (lt_list); cout << endl << "to be checked: "; WriteMonoList (check_list); #ifdef shmat cout << endl << "Matrix:" << endl; cout << " "; for (i=0;irow_matrix; solve=curptr->row_solve; for (i=0;inext; cout << endl;} cout << "Special row: Solve row:" << endl; row=my_row; for (i=0;i> ch; cout << endl << endl; } #endif modp_number OneInverse(modp_number a,modp_number p) // computes inverse of d mod p without using tables { long u, v, u0, u1, u2, q, r; u1=1; u2=0; u = a; v = p; while (v != 0) { q = u / v; r = u % v; u = v; v = r; u0 = u2; u2 = u1 - q*u2; u1 = u0; } if (u1 < 0) u1=u1+p; // now it should be ok, but for any case... if ((u1<0)||((u1*a)%p!=1)) { PrintS("?"); modp_number i; for (i=1;i m2, false otherwise. uses Singular comparing function { for (int j = variables; j; j--) { pSetExp(comparizon_p1, j, m1[j-1]); pSetExp(comparizon_p2, j, m2[j-1]); } pSetm(comparizon_p1); pSetm(comparizon_p2); bool res=(pLmCmp(comparizon_p1,comparizon_p2)>0); return res; } mon_list_entry* MonListAdd (mon_list_entry *list, mono_type mon) // adds one entry to the list of monomials structure { mon_list_entry *curptr=list; mon_list_entry *prevptr=NULL; mon_list_entry *temp; while (curptr!=NULL) { if (EqualMon (mon,(*curptr).mon)) return list; if (Greater ((*curptr).mon,mon)) break; prevptr=curptr; curptr=curptr->next; } temp=(mon_list_entry*)omAlloc0(sizeof(mon_list_entry)); (*temp).next=curptr; (*temp).mon=(exponent*)omAlloc(sizeof(exponent)*variables); memcpy(temp->mon,mon,sizeof(exponent)*variables); if (prevptr==NULL) return temp; else { prevptr->next=temp; return list; } } mono_type MonListElement (mon_list_entry *list, int n) // returns ith element from list of monomials - no error checking! { mon_list_entry *cur=list; int i; for (i=0;inext; return cur->mon; } mono_type ZeroMonomial () // allocates memory for new monomial with all enries equal 0 { mono_type m; m=(exponent*)omAlloc0(sizeof(exponent)*variables); return m; } void GeneralInit () // general initialization { int i,j,k; points=(coordinates*)omAlloc(sizeof(coordinates)*n_points); for (i=0;inext; omFree(ptr->mon); omFree(ptr); ptr=pptr;} return NULL; } void GeneralDone () // to be called before exit to free memory { int i,j,k; for (i=0;inext; omFree(ptr->row_matrix); omFree(ptr->row_solve); omFree(ptr); ptr=pptr; } row_list=NULL; for (i=0;i mon[i]) return ;; *ev=1; int j,k; mono_type mn; mn=(exponent*)omAlloc(sizeof(exponent)*variables); memcpy(mn,mon,sizeof(exponent)*variables); for (k=0;k mon[i]) return ;; mpz_set_si(ev,1); mpz_t mon_conv; mpz_init(mon_conv); int j,k; mono_type mn; mn=(exponent*)omAlloc(sizeof(exponent)*variables); memcpy(mn,mon,sizeof(exponent)*variables); for (k=0;kmon,mon,sizeof(exponent)*variables); con->point_ref=n; con++; } k=variables-1; mon[k]++; while ((k>0)&&(mon[k]>=multiplicity[n])) { mon[k]=0; k--; mon[k]++; } } } omFree(mon); } void ReduceRow () // reduces my_row by previous rows, does the same for solve row { if (row_list==NULL) return ; row_list_entry *row_ptr; modp_number *cur_row_ptr; modp_number *solve_row_ptr; modp_number *my_row_ptr; modp_number *my_solve_row_ptr; int first_col; int i; modp_number red_val; modp_number mul_val; #ifdef integerstrategy modp_number *m_row_ptr; modp_number prep_val; #endif row_ptr=row_list; while (row_ptr!=NULL) { cur_row_ptr=row_ptr->row_matrix; solve_row_ptr=row_ptr->row_solve; my_row_ptr=my_row; my_solve_row_ptr=my_solve_row; first_col=row_ptr->first_col; cur_row_ptr=cur_row_ptr+first_col; // reduction begins at first_col position my_row_ptr=my_row_ptr+first_col; red_val=*my_row_ptr; if (red_val!=0) { #ifdef integerstrategy prep_val=*cur_row_ptr; if (prep_val!=1) { m_row_ptr=my_row; for (i=0;inext; #if 0 /* only debugging */ PrintS("reduction by row "); Info (); #endif } } bool RowIsZero () // check whether a row is zero { bool zero=1; int i; modp_number *row; row=my_row; for (i=0;im2[i]) return false;; return true; } void ReduceCheckListByMon (mono_type m) // from check_list monomials divisible by m are thrown out { mon_list_entry *c_ptr; mon_list_entry *p_ptr; mon_list_entry *n_ptr; c_ptr=check_list; p_ptr=NULL; while (c_ptr!=NULL) { if (DivisibleMon (m,c_ptr->mon)) { if (p_ptr==NULL) check_list=c_ptr->next; else p_ptr->next=c_ptr->next; n_ptr=c_ptr->next; omFree(c_ptr->mon); omFree(c_ptr); c_ptr=n_ptr; } else { p_ptr=c_ptr; c_ptr=c_ptr->next; } } } void TakeNextMonomial (mono_type mon) // reads first monomial from check_list, then it is deleted { mon_list_entry *n_check_list; if (check_list!=NULL) { memcpy(mon,check_list->mon,sizeof(exponent)*variables); n_check_list=check_list->next; omFree(check_list->mon); omFree(check_list); check_list=n_check_list; } } void UpdateCheckList (mono_type m) // adds all monomials which are "next" to m (divisible by m and degree +1) { int i; for (i=0;imon); ptr=ptr->next; } } void RowListAdd (int first_col, mono_type mon) // puts a row into matrix { row_list_entry *ptr; row_list_entry *pptr; row_list_entry *temp; ptr=row_list; pptr=NULL; while (ptr!=NULL) { #ifndef unsortedmatrix if ( first_col <= ptr->first_col ) break; #endif pptr=ptr; ptr=ptr->next; } temp=(row_list_entry*)omAlloc0(sizeof(row_list_entry)); (*temp).row_matrix=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim); memcpy((*temp).row_matrix,my_row,sizeof(modp_number)*(final_base_dim)); (*temp).row_solve=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim); memcpy((*temp).row_solve,my_solve_row,sizeof(modp_number)*(final_base_dim)); (*temp).first_col=first_col; temp->next=ptr; if (pptr==NULL) row_list=temp; else pptr->next=temp; memcpy(column_name[first_col],mon,sizeof(exponent)*variables); } void PrepareRow (mono_type mon) // prepares a row and puts it into matrix { modp_number *row; int first_col=-1; int col; modp_number red_val=1; row=my_row; #ifdef integerstrategy for (col=0;col last_solve_column) last_solve_column=first_col; #else for (col=0;col last_solve_column) last_solve_column=first_col; if (red_val!=1) { row++; for (col=first_col+1;colprev=NULL; } else { temp->prev=cur_result; cur_result->next=temp; } cur_result=temp; cur_result->next=NULL; cur_result->p=myp; cur_result->generator=NULL; cur_result->n_generators=0; n_results++; } void FreeResultEntry (modp_result_entry *e) // destroys the result entry, without worrying about where it is { generator_entry *cur_gen; generator_entry *next_gen; cur_gen=e->generator; while (cur_gen!=NULL) { next_gen=cur_gen->next; omFree(cur_gen->coef); omFree(cur_gen->lt); omFree(cur_gen); cur_gen=next_gen; } omFree(e); } void NewGenerator (mono_type mon) // new generator in modp comp found, shoul be stored on the list { int i; generator_entry *cur_ptr; generator_entry *prev_ptr; generator_entry *temp; cur_ptr=cur_result->generator; prev_ptr=NULL; while (cur_ptr!=NULL) { prev_ptr=cur_ptr; cur_ptr=cur_ptr->next; } temp=(generator_entry*)omAlloc0(sizeof(generator_entry)); if (prev_ptr==NULL) cur_result->generator=temp; else prev_ptr->next=temp; temp->next=NULL; temp->coef=(modp_number*)omAlloc0(sizeof(modp_number)*final_base_dim); memcpy(temp->coef,my_solve_row,sizeof(modp_number)*final_base_dim); temp->lt=ZeroMonomial (); memcpy(temp->lt,mon,sizeof(exponent)*variables); temp->ltcoef=1; cur_result->n_generators++; } void MultGenerators () // before reconstructing, all denominators must be cancelled { #ifndef integerstrategy int i; generator_entry *cur_ptr; cur_ptr=cur_result->generator; while (cur_ptr!=NULL) { for (i=0;icoef[i]=modp_mul(cur_ptr->coef[i],modp_denom); cur_ptr->ltcoef=modp_denom; cur_ptr=cur_ptr->next; } #endif } #if 0 /* only debbuging */ void PresentGenerator (int i) // only for debuging, writes a generator in its form in program { int j; modp_result_entry *cur_ptr; generator_entry *cur_gen; cur_ptr=modp_result; while (cur_ptr!=NULL) { cur_gen=cur_ptr->generator; for (j=0;jnext; for (j=0;jcoef[j]); } PrintS(" and LT = "); WriteMono (cur_gen->lt); Print(" ( %d ) prime = %d\n", cur_gen->ltcoef, cur_ptr->p); cur_ptr=cur_ptr->next; } } #endif modp_number TakePrime (modp_number p) // takes "previous" (smaller) prime { #ifdef HAVE_FACTORY myp_index--; return cf_getSmallPrime(myp_index); #else return IsPrime(p-1); #endif } void PrepareChinese (int n) // initialization for CRA { int i,k; modp_result_entry *cur_ptr; cur_ptr=modp_result; modp_number *congr_ptr; modp_number prod; in_gamma=(modp_number*)omAlloc0(sizeof(modp_number)*n); congr=(modp_number*)omAlloc0(sizeof(modp_number)*n); congr_ptr=congr; while (cur_ptr!=NULL) { *congr_ptr=cur_ptr->p; cur_ptr=cur_ptr->next; congr_ptr++; } for (k=1;kgenerator; for (j=0;jnext; // we have to take jth generator if (coefcoef[coef]; else u[i]=cur_gen->ltcoef; cur_ptr=cur_ptr->next; i++; } v[0]=u[0]; // now CRA begins for (k=1;k=0;j--) temp=(temp*congr[j]+v[j])%congr[k]; temp=u[k]-temp; if (temp<0) temp=temp+congr[k]; v[k]=(temp*in_gamma[k])%congr[k]; } mpz_set_si(sol,v[n-1]); for (k=n-2;k>=0;k--) { mpz_mul_ui(sol,sol,congr[k]); mpz_add_ui(sol,sol,v[k]); } // now CRA ends mpz_sub(nsol,sol,bigcongr); int s=mpz_cmpabs(sol,nsol); if (s>0) mpz_set(sol,nsol); // chooses representation closer to 0 mpz_set(polycoef[coef],sol); if (coefmaximal_size) maximal_size=size; #endif } omFree(u); omFree(v); omFree(str); ClearGCD (); mpz_clear(sol); mpz_clear(nsol); } void Discard () // some unlucky prime occures { modp_result_entry *temp; #ifdef writemsg Print(", prime=%d", cur_result->p); #endif bad_primes++; if (good_primes>bad_primes) { #ifdef writemsg Print("-discarding this comp (%dth)\n", n_results); #endif temp=cur_result; cur_result=cur_result->prev; cur_result->next=NULL; n_results--; FreeResultEntry (temp); } else { #ifdef writemsg PrintS("-discarding ALL.\n"); #endif int i; modp_result_entry *ntfree; generator_entry *cur_gen; temp=cur_result->prev; while (temp!=NULL) { ntfree=temp->prev; FreeResultEntry (temp); temp=ntfree; } modp_result=cur_result; cur_result->prev=NULL; n_results=1; good_primes=1; bad_primes=0; generic_n_generators=cur_result->n_generators; cur_gen=cur_result->generator; generic_lt=FreeMonList (generic_lt); for (i=0;ilt); cur_gen=cur_gen->next; } for (i=0;in_generators!=generic_n_generators) { #ifdef writemsg PrintS("wrong number of generators occured"); #else if (protocol) PrintS("ng"); #endif Discard (); return; } if (denom_divisible) { #ifdef writemsg PrintS("denom of coef divisible by p"); #else if (protocol) PrintS("dp"); #endif Discard (); return; } generator_entry *cur_gen; mon_list_entry *cur_mon; cur_gen=cur_result->generator; cur_mon=generic_lt; for (i=0;imon,cur_gen->lt)) { #ifdef writemsg PrintS("wrong leading term occured"); #else if (protocol) PrintS("lt"); #endif Discard (); return; } cur_gen=cur_gen->next; cur_mon=cur_mon->next; } for (i=0;inext; for (i=0;i<=final_base_dim;i++) { mpz_clear(gen_list->polycoef[i]); omFree(gen_list->polyexp[i]); } omFree(gen_list->polycoef); omFree(gen_list->polyexp); omFree(gen_list); gen_list=temp; } } void UpdateGenList () { gen_list_entry *temp,*prev; int i,j; prev=NULL; temp=gen_list; exponent deg; for (i=0;i<=final_base_dim;i++) { deg=MonDegree(polyexp[i]); for (j=0;jnext; } temp=(gen_list_entry*)omAlloc0(sizeof(gen_list_entry)); if (prev==NULL) gen_list=temp; else prev->next=temp; temp->next=NULL; temp->polycoef=(mpz_t*)omAlloc(sizeof(mpz_t)*(final_base_dim+1)); temp->polyexp=(mono_type*)omAlloc(sizeof(mono_type)*(final_base_dim+1)); for (i=0;i<=final_base_dim;i++) { mpz_init(temp->polycoef[i]); mpz_set(temp->polycoef[i],polycoef[i]); temp->polyexp[i]=ZeroMonomial (); memcpy(temp->polyexp[i],polyexp[i],sizeof(exponent)*variables); } } #if 0 /* only debugging */ void ShowGenList () { gen_list_entry *temp; int i; char *str; str=(char*)omAlloc0(sizeof(char)*1000); temp=gen_list; while (temp!=NULL) { PrintS("generator: "); for (i=0;i<=final_base_dim;i++) { str=mpz_get_str(str,10,temp->polycoef[i]); PrintS(str); PrintS("*"); WriteMono(temp->polyexp[i]); } PrintLn(); temp=temp->next; } omFree(str); } #endif void modp_Main () { mono_type cur_mon; cur_mon= ZeroMonomial (); modp_denom=1; bool row_is_zero; #if 0 /* only debugging */ Info (); #endif while (check_list!=NULL) { TakeNextMonomial (cur_mon); ProduceRow (cur_mon); #if 0 /* only debugging */ cout << "row produced for monomial "; WriteMono (cur_mon); cout << endl; Info (); #endif ReduceRow (); row_is_zero = RowIsZero (); if (row_is_zero) { lt_list=MonListAdd (lt_list,cur_mon); ReduceCheckListByMon (cur_mon); NewGenerator (cur_mon); #if 0 /* only debugging */ cout << "row is zero - linear dependence found (should be seen in my_solve_row)" << endl; cout << "monomial added to leading terms list" << endl; cout << "check list updated" << endl; Info (); #endif } else { base_list= MonListAdd (base_list,cur_mon); UpdateCheckList (cur_mon); ReduceCheckListByLTs (); #if 0 /* only debugging */ cout << "row is non-zero" << endl; cout << "monomial added to quotient basis list" << endl; cout << "new monomials added to check list" << endl; cout << "check list reduced by monomials from leading term list" << endl; Info (); #endif PrepareRow (cur_mon); #if 0 /* only debugging */ cout << "row prepared and put into matrix" << endl; Info (); #endif } } omFree(cur_mon); } void ResolveCoeff (mpq_t c, number m) { if ((long)m & SR_INT) { long m_val=SR_TO_INT(m); mpq_set_si(c,m_val,1); } else { if (m->s<2) { mpz_set(mpq_numref(c),m->z); mpz_set(mpq_denref(c),m->n); mpq_canonicalize(c); } else { mpq_set_z(c,m->z); } } } ideal interpolation(lists L, intvec *v) { protocol=TEST_OPT_PROT; // should be set if option(prot) is enabled bool data_ok=true; // reading the ring data *************************************************** if ((currRing==NULL) || ((!rField_is_Zp (currRing))&&(!rField_is_Q (currRing)))) { WerrorS("coefficient field should be Zp or Q!"); return NULL; } if ((currRing->qideal)!=NULL) { WerrorS("quotient ring not supported!"); return NULL; } if ((currRing->OrdSgn)!=1) { WerrorS("ordering must be global!"); return NULL; } n_points=v->length (); if (n_points!=(L->nr+1)) { WerrorS("list and intvec must have the same length!"); return NULL; } variables=currRing->N; only_modp=rField_is_Zp(currRing); if (only_modp) myp=rChar(currRing); // ring data read ********************************************************** multiplicity=(int*)malloc(sizeof(int)*n_points); int i; for (i=0;inr;i++) { ideal I=(ideal)L->m[i].Data(); for(j=0;jm[j]; if (p!=NULL) { poly ph=pHead(p); int pcvar=pVar(ph); if (pcvar!=0) { pcvar--; if (coord_exist[i][pcvar]) { Print("coordinate %d for point %d initialized twice!\n",pcvar+1,i+1); data_ok=false; } number m; m=pGetCoeff(p); // possible coefficient standing by a leading monomial if (!only_modp) ResolveCoeff (divisor,m); number n; if (pNext(p)!=NULL) n=pGetCoeff(pNext(p)); else n=nInit(0); if (only_modp) { n=nNeg(n); n=nDiv(n,m); modp_points[i][pcvar]=(int)((long)n); } else { ResolveCoeff (q_points[i][pcvar],n); mpq_neg(q_points[i][pcvar],q_points[i][pcvar]); mpq_div(q_points[i][pcvar],q_points[i][pcvar],divisor); } coord_exist[i][pcvar]=true; } else { PrintS("not a variable? "); wrp(p); PrintLn(); data_ok=false; } pDelete(&ph); } } } if (!only_modp) mpq_clear(divisor); // data from ideal read ******************************************************* // ckecking if all coordinates are initialized for (i=0;i1)) { #ifdef writemsg Print("trying %d cycles mod p...\n",modp_cycles); #else if (protocol) Print("(%d)",modp_cycles); #endif while ((n_results1)) // some computations mod p { if (!only_modp) myp=TakePrime (myp); NewResultEntry (); InitProcData (); if (only_modp) modp_PrepareProducts (); else int_PrepareProducts (); modp_Main (); if (!only_modp) { MultGenerators (); CheckColumnSequence (); } else { modp_SetColumnNames (); } FreeProcData (); } if (!only_modp) { PrepareChinese (modp_cycles); correct_gen=true; for (i=0;in_generators,1); generator_entry *cur_gen=modp_result->generator; for(i=0;i=0;a--) { if (a==final_base_dim) cf=cur_gen->ltcoef; else cf=cur_gen->coef[a]; if (cf!=0) { p=pISet(cf); if (a==final_base_dim) mon=cur_gen->lt; else mon=generic_column_name[a]; for (j=0;jm[i]=sum; cur_gen=cur_gen->next; } } else { ret=idInit(generic_n_generators,1); gen_list_entry *temp=gen_list; for(i=0;i=0;a--) // build one polynomial { if (mpz_sgn(temp->polycoef[a])!=0) { number n=ALLOC_RNUMBER(); #ifdef LDEBUG n->debug=123456; #endif mpz_init_set(n->z,temp->polycoef[a]); n->s=3; nlNormalize(n, currRing->cf); p=pNSet(n); //a monomial for (j=0;jpolyexp[a][j]); pSetm(p); // after all pSetExp sum=pAdd(sum,p); } } ret->m[i]=sum; temp=temp->next; } } // data transferred **************************************************************************** GeneralDone (); ClearGenList (); return ret; } BOOLEAN jjINTERPOLATION (leftv res, leftv l, leftv v) { res->data=interpolation((lists)l->Data(),(intvec*)v->Data()); setFlag(res,FLAG_STD); return errorreported; }