1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /*
5 * ABSTRACT: flint: fmpq_poly
6 */
7 #include <ctype.h> /* isdigit*/
8 
9 #include "misc/auxiliary.h"
10 
11 #ifdef HAVE_FLINT
12 
13 #include <flint/flint.h>
14 #include <flint/fmpq_poly.h>
15 #include "factory/factory.h"
16 
17 #include "coeffs/coeffs.h"
18 
19 #include "coeffs/numbers.h"
20 #include "coeffs/longrat.h"
21 
22 typedef fmpq_poly_struct *fmpq_poly_ptr;
23 typedef fmpz *fmpz_ptr;
24 /*2
25 * extracts a long integer from s, returns the rest
26 */
nlEatLong(char * s,mpz_ptr i)27 static char * nlEatLong(char *s, mpz_ptr i)
28 {
29   const char * start=s;
30 
31   while (*s >= '0' && *s <= '9') s++;
32   if (*s=='\0')
33   {
34     mpz_set_str(i,start,10);
35   }
36   else
37   {
38     char c=*s;
39     *s='\0';
40     mpz_set_str(i,start,10);
41     *s=c;
42   }
43   return s;
44 }
45 
CoeffIsEqual(const coeffs r,n_coeffType n,void *)46 static BOOLEAN CoeffIsEqual(const coeffs r, n_coeffType n, void *)
47 {
48   return (r->type==n);
49 }
SetChar(const coeffs)50 static void SetChar(const coeffs)
51 {
52   // dummy
53 }
Mult(number a,number b,const coeffs)54 static number Mult(number a, number b, const coeffs)
55 {
56   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
57   fmpq_poly_init(res);
58   fmpq_poly_mul(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
59   return (number)res;
60 }
Sub(number a,number b,const coeffs)61 static number Sub(number a, number b, const coeffs)
62 {
63   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
64   fmpq_poly_init(res);
65   fmpq_poly_sub(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
66   return (number)res;
67 }
Add(number a,number b,const coeffs)68 static number Add(number a, number b, const coeffs)
69 {
70   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
71   fmpq_poly_init(res);
72   fmpq_poly_add(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
73   return (number)res;
74 }
Div(number a,number b,const coeffs)75 static number Div(number a, number b, const coeffs)
76 {
77   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
78   fmpq_poly_init(res);
79   if(fmpq_poly_is_zero((fmpq_poly_ptr)b))
80   {
81      WerrorS(nDivBy0);
82   }
83   else
84   {
85     fmpq_poly_div(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
86     fmpq_poly_t mod;
87     fmpq_poly_init(mod);
88     fmpq_poly_rem(mod,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
89     if (!fmpq_poly_is_zero((fmpq_poly_ptr)mod))
90     {
91       WerrorS("cannot divide");
92     }
93     fmpq_poly_clear(mod);
94   }
95   return (number)res;
96 }
ExactDiv(number a,number b,const coeffs)97 static number ExactDiv(number a, number b, const coeffs)
98 {
99   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
100   fmpq_poly_init(res);
101   if(fmpq_poly_is_zero((fmpq_poly_ptr)b))
102   {
103      WerrorS(nDivBy0);
104   }
105   else
106     fmpq_poly_div(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
107   return (number)res;
108 }
109 #if 0
110 static number IntMod(number a, number b, const coeffs)
111 {
112   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
113   fmpq_poly_init(res);
114   fmpq_poly_rem(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
115   return (number)res;
116 }
117 #endif
Init(long i,const coeffs)118 static number Init (long i, const coeffs)
119 {
120   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
121   fmpq_poly_init(res);
122   fmpq_poly_set_si(res,i);
123   return (number)res;
124 }
InitMPZ(mpz_t i,const coeffs)125 static number InitMPZ (mpz_t i, const coeffs)
126 {
127   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
128   fmpq_poly_init(res);
129   fmpq_poly_set_mpz(res,i);
130   return (number)res;
131 }
Size(number n,const coeffs)132 static int Size (number n, const coeffs)
133 {
134   return fmpq_poly_degree((fmpq_poly_ptr)n);
135 }
Int(number & n,const coeffs)136 static long Int (number &n, const coeffs)
137 {
138   if (fmpq_poly_degree((fmpq_poly_ptr)n)==0)
139   {
140     mpq_t m;
141     mpq_init(m);
142     fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)n,0);
143     mpz_t num,den;
144     mpz_init(num);
145     mpz_init(den);
146     mpq_get_num(num,m);
147     mpq_get_den(den,m);
148     long nl=mpz_get_si(num);
149     if (mpz_cmp_si(num,nl)!=0) nl=0;
150     long dl=mpz_get_si(den);
151     if ((dl!=1)||(mpz_cmp_si(den,dl)!=0)) nl=0;
152     mpz_clear(num);
153     mpz_clear(den);
154     mpq_clear(m);
155     return nl;
156   }
157   return 0;
158 }
MPZ(mpz_t result,number & n,const coeffs)159 static void MPZ(mpz_t result, number &n, const coeffs)
160 {
161   mpz_init(result);
162   if (fmpq_poly_degree((fmpq_poly_ptr)n)==0)
163   {
164     mpq_t m;
165     mpq_init(m);
166     fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)n,0);
167     mpz_t den;
168     mpz_init(den);
169     mpq_get_num(result,m);
170     mpq_get_den(den,m);
171     int dl=(int)mpz_get_si(den);
172     if ((dl!=1)||(mpz_cmp_si(den,(long)dl)!=0)) mpz_set_ui(result,0);
173     mpz_clear(den);
174     mpq_clear(m);
175   }
176 }
Neg(number a,const coeffs)177 static number Neg(number a, const coeffs)
178 {
179   fmpq_poly_neg((fmpq_poly_ptr)a,(fmpq_poly_ptr)a);
180   return a;
181 }
Invers(number a,const coeffs)182 static number Invers(number a, const coeffs)
183 {
184   if(fmpq_poly_is_zero((fmpq_poly_ptr)a))
185   {
186     WerrorS(nDivBy0);
187     return NULL;
188   }
189   if (fmpq_poly_degree((fmpq_poly_ptr)a)==0)
190   {
191     fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
192     fmpq_poly_init(res);
193     fmpq_poly_inv(res,(fmpq_poly_ptr)a);
194     return (number)res;
195   }
196   else
197   {
198     WerrorS("not invertable");
199     return NULL;
200   }
201 }
Copy(number a,const coeffs)202 static number Copy(number a, const coeffs)
203 {
204  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
205  fmpq_poly_init(res);
206  fmpq_poly_set(res,(fmpq_poly_ptr)a);
207  return (number)res;
208 }
209 //static number RePart(number a, const coeffs)
210 //{
211 //}
212 //static number ImPart(number a, const coeffs)
213 //{
214 //}
215 static BOOLEAN IsOne (number a, const coeffs);
216 static BOOLEAN IsZero (number a, const coeffs);
217 //static void WriteLong(number &a, const coeffs)
218 //{
219 //}
WriteShort(number a,const coeffs r)220 static void WriteShort(number a, const coeffs r)
221 {
222   //fmpq_poly_print_pretty((fmpq_poly_ptr)a,r->pParameterNames[0]);
223   if (IsOne(a,r)) StringAppendS("1");
224   else if (IsZero(a,r)) StringAppendS("0");
225   else
226   {
227   StringAppendS("(");
228   mpq_t m;
229   mpq_init(m);
230   mpz_t num,den;
231   mpz_init(num);
232   mpz_init(den);
233   BOOLEAN need_plus=FALSE;
234   for(int i=fmpq_poly_length((fmpq_poly_ptr)a);i>=0;i--)
235   {
236     fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)a,i);
237     mpq_get_num(num,m);
238     mpq_get_den(den,m);
239     if (mpz_sgn1(num)!=0)
240     {
241       if (need_plus && (mpz_sgn1(num)>0))
242         StringAppendS("+");
243       need_plus=TRUE;
244       int l=mpz_sizeinbase(num,10);
245       l=si_max(l,(int)mpz_sizeinbase(den,10));
246       l+=2;
247       char *s=(char*)omAlloc(l);
248       char *z=mpz_get_str(s,10,num);
249       if ((i==0)
250       ||(mpz_cmp_si(num,1)!=0)
251       ||(mpz_cmp_si(den,1)!=0))
252       {
253         StringAppendS(z);
254         if (mpz_cmp_si(den,1)!=0)
255         {
256           StringAppendS("/");
257           z=mpz_get_str(s,10,den);
258           StringAppendS(z);
259         }
260         if (i!=0) StringAppendS("*");
261       }
262       if (i>1)
263         StringAppend("%s^%d",r->pParameterNames[0],i);
264       else if (i==1)
265         StringAppend("%s",r->pParameterNames[0]);
266     }
267   }
268   mpz_clear(den);
269   mpz_clear(num);
270   mpq_clear(m);
271   StringAppendS(")");
272   }
273 }
Read(const char * st,number * a,const coeffs r)274 static const char* Read(const char * st, number * a, const coeffs r)
275 {
276 // we only read "monomials" (i.e. [-][digits][parameter]),
277 // everythings else (+,*,^,()) is left to the singular interpreter
278   char *s=(char *)st;
279   *a=(number)omAlloc(sizeof(fmpq_poly_t));
280   fmpq_poly_init((fmpq_poly_ptr)(*a));
281   BOOLEAN neg=FALSE;
282   if (*s=='-') { neg=TRUE; s++;}
283   if (isdigit(*s))
284   {
285     mpz_t z;
286     mpz_init(z);
287     s=nlEatLong((char *)s, z);
288     fmpq_poly_set_mpz((fmpq_poly_ptr)(*a),z);
289     if (*s == '/')
290     {
291       s++;
292       s=nlEatLong((char *)s, z);
293       fmpq_poly_scalar_div_mpz((fmpq_poly_ptr)(*a),(fmpq_poly_ptr)(*a),z);
294     }
295     mpz_clear(z);
296   }
297   else if(strncmp(s,r->pParameterNames[0],strlen(r->pParameterNames[0]))==0)
298   {
299     fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),1,1);
300     s+=strlen(r->pParameterNames[0]);
301     if(isdigit(*s))
302     {
303       int i=1;
304       s=nEati(s,&i,0);
305       if (i!=1)
306       {
307         fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),1,0);
308         fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),i,1);
309       }
310     }
311   }
312   if (neg)
313     fmpq_poly_neg((fmpq_poly_ptr)(*a),(fmpq_poly_ptr)(*a));
314   return s;
315 }
Normalize(number & a,const coeffs)316 static void Normalize(number &a, const coeffs)
317 {
318   fmpq_poly_canonicalise((fmpq_poly_ptr)a);
319 }
Greater(number a,number b,const coeffs)320 static BOOLEAN Greater (number a, number b, const coeffs)
321 {
322   return (fmpq_poly_cmp((fmpq_poly_ptr)a,(fmpq_poly_ptr)b)>0);
323 }
Equal(number a,number b,const coeffs)324 static BOOLEAN Equal (number a, number b, const coeffs)
325 {
326   return (fmpq_poly_equal((fmpq_poly_ptr)a,(fmpq_poly_ptr)b));
327 }
IsZero(number a,const coeffs)328 static BOOLEAN IsZero (number a, const coeffs)
329 {
330   return fmpq_poly_is_zero((fmpq_poly_ptr)a);
331 }
IsOne(number a,const coeffs)332 static BOOLEAN IsOne (number a, const coeffs)
333 {
334   return fmpq_poly_is_one((fmpq_poly_ptr)a);
335 }
IsMOne(number k,const coeffs)336 static BOOLEAN IsMOne (number k, const coeffs)
337 {
338   if (fmpq_poly_length((fmpq_poly_ptr)k)>0) return FALSE;
339   fmpq_poly_canonicalise((fmpq_poly_ptr)k);
340   mpq_t m;
341   mpq_init(m);
342   fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)k,0);
343   mpz_t num,den;
344   mpz_init(num);
345   mpq_get_num(num,m);
346   BOOLEAN result=TRUE;
347   if (mpz_cmp_si(num,(long)-1)!=0) result=FALSE;
348   else
349   {
350     mpz_init(den);
351     mpq_get_den(den,m);
352     int dl=(int)mpz_get_si(den);
353     if ((dl!=1)||(mpz_cmp_si(den,(long)dl)!=0)) result=FALSE;
354     mpz_clear(den);
355   }
356   mpz_clear(num);
357   mpq_clear(m);
358   return (result);
359 }
GreaterZero(number,const coeffs)360 static BOOLEAN GreaterZero (number, const coeffs)
361 {
362   // does it have a leading sign?
363   // no: 0 and 1 do not have, everything else is in (...)
364   return TRUE;
365 }
Power(number a,int i,number * result,const coeffs)366 static void Power(number a, int i, number * result, const coeffs)
367 {
368   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
369   fmpq_poly_init(res);
370   *result=(number)res;
371   fmpq_poly_pow((fmpq_poly_ptr)(*result),(fmpq_poly_ptr)a,i);
372 }
GetDenom(number & n,const coeffs)373 static number GetDenom(number &n, const coeffs)
374 {
375  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
376  fmpq_poly_init(res);
377  fmpz_ptr den=fmpq_poly_denref((fmpq_poly_ptr)n);
378  fmpq_poly_set_fmpz(res,den);
379  return (number)res;
380 }
GetNumerator(number & n,const coeffs)381 static number GetNumerator(number &n, const coeffs)
382 {
383  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
384  fmpq_poly_init(res);
385  fmpq_poly_set(res,(fmpq_poly_ptr)n);
386  fmpz_ptr den=fmpq_poly_denref(res);
387  fmpq_poly_scalar_mul_fmpz(res,res,den);
388  return (number)res;
389 }
Gcd(number a,number b,const coeffs)390 static number Gcd(number a, number b, const coeffs)
391 {
392   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
393   fmpq_poly_init(res);
394   fmpq_poly_gcd(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
395   return (number)res;
396 }
ExtGcd(number a,number b,number * s,number * t,const coeffs)397 static number ExtGcd(number a, number b, number *s, number *t,const coeffs)
398 {
399   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
400   fmpq_poly_init(res);
401   fmpq_poly_init((fmpq_poly_ptr)*s);
402   fmpq_poly_init((fmpq_poly_ptr)*t);
403   fmpq_poly_xgcd(res,(fmpq_poly_ptr)*s,(fmpq_poly_ptr)*t,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
404   return (number)res;
405 }
Lcm(number,number,const coeffs)406 static number Lcm(number, number, const coeffs)
407 {
408   WerrorS("not yet: Lcm");
409   return NULL;
410 }
Delete(number * a,const coeffs)411 static void Delete(number * a, const coeffs)
412 {
413   if ((*a)!=NULL)
414   {
415     fmpq_poly_clear((fmpq_poly_ptr)*a);
416     omFree(*a);
417     *a=NULL;
418   }
419 }
SetMap(const coeffs,const coeffs)420 static nMapFunc SetMap(const coeffs, const coeffs)
421 {
422   WerrorS("not yet: SetMap");
423   return NULL;
424 }
425 //static void InpMult(number &a, number b, const coeffs)
426 //{
427 //}
428 //static void InpAdd(number &a, number b, const coeffs)
429 //{
430 //}
431 #if 0
432 static number Init_bigint(number i, const coeffs, const coeffs)
433 {
434   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
435   fmpq_poly_init(res);
436   if (SR_HDL(i) & SR_INT)
437   {
438     fmpq_poly_set_si(res,SR_TO_INT(i));
439   }
440   else
441     fmpq_poly_set_mpz(res,i->z);
442   return (number)res;
443 }
444 #endif
Farey(number,number,const coeffs)445 static number Farey(number, number, const coeffs)
446 {
447   WerrorS("not yet: Farey");
448   return NULL;
449 }
ChineseRemainder(number *,number *,int,BOOLEAN,CFArray &,const coeffs)450 static number ChineseRemainder(number *, number *,int , BOOLEAN ,CFArray &,const coeffs)
451 {
452   WerrorS("not yet: ChineseRemainder");
453   return NULL;
454 }
ParDeg(number x,const coeffs)455 static int ParDeg(number x,const coeffs)
456 {
457   return fmpq_poly_degree((fmpq_poly_ptr)x);
458 }
Parameter(const int,const coeffs)459 static number Parameter(const int, const coeffs)
460 {
461   fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
462   fmpq_poly_init(res);
463   fmpq_poly_set_coeff_si(res,1,1);
464   return (number)res;
465 }
WriteFd(number a,const ssiInfo * d,const coeffs)466 static void WriteFd(number a, const ssiInfo *d, const coeffs)
467 {
468   // format: len a_len(num den) .. a_0
469   fmpq_poly_ptr aa=(fmpq_poly_ptr)a;
470   int l=fmpq_poly_length(aa);
471   fprintf(d->f_write,"%d ",l);
472   mpq_t m;
473   mpq_init(m);
474   mpz_t num,den;
475   mpz_init(num);
476   mpz_init(den);
477   for(int i=l; i>=0; i--)
478   {
479     fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)a,i);
480     mpq_get_num(num,m);
481     mpq_get_den(den,m);
482     mpz_out_str (d->f_write,SSI_BASE, num);
483     fputc(' ',d->f_write);
484     mpz_out_str (d->f_write,SSI_BASE, den);
485     fputc(' ',d->f_write);
486   }
487   mpz_clear(den);
488   mpz_clear(num);
489   mpq_clear(m);
490 }
ReadFd(const ssiInfo * d,const coeffs)491 static number ReadFd(const ssiInfo *d, const coeffs)
492 {
493   // format: len a_len .. a_0
494   fmpq_poly_ptr aa=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
495   fmpq_poly_init(aa);
496   int l=s_readint(d->f_read);
497   mpz_t nm;
498   mpz_init(nm);
499   mpq_t m;
500   mpq_init(m);
501   for (int i=l;i>=0;i--)
502   {
503 
504     s_readmpz_base (d->f_read,nm, SSI_BASE);
505     mpq_set_num(m,nm);
506     s_readmpz_base (d->f_read,nm, SSI_BASE);
507     mpq_set_den(m,nm);
508     fmpq_poly_set_coeff_mpq(aa,i,m);
509   }
510   mpz_clear(nm);
511   mpq_clear(m);
512   return (number)aa;
513 }
514 // cfClearContent
515 // cfClearDenominators
ConvFactoryNSingN(const CanonicalForm,const coeffs)516 static number ConvFactoryNSingN( const CanonicalForm, const coeffs)
517 {
518   WerrorS("not yet: ConvFactoryNSingN");
519   return NULL;
520 }
ConvSingNFactoryN(number,BOOLEAN,const coeffs)521 static CanonicalForm ConvSingNFactoryN( number, BOOLEAN, const coeffs )
522 {
523   WerrorS("not yet: ConvSingNFactoryN");
524   return CanonicalForm(0);
525 }
CoeffName(const coeffs r)526 char * CoeffName(const coeffs r)
527 {
528   STATIC_VAR char CoeffName_flint_Q[20];
529   sprintf(CoeffName_flint_Q,"flintQp[%s]",r->pParameterNames[0]);
530   return (char*)CoeffName_flint_Q;
531 
532 }
flintQInitCfByName(char * s,n_coeffType n)533 coeffs flintQInitCfByName(char *s,n_coeffType n)
534 {
535   const char start[]="flintQp[";
536   const int start_len=strlen(start);
537   if (strncmp(s,start,start_len)==0)
538   {
539     s+=start_len;
540     char st[10];
541     int l=sscanf(s,"%s",st);
542     if (l==1)
543     {
544       while (st[strlen(st)-1]==']') st[strlen(st)-1]='\0';
545       return nInitChar(n,(void*)st);
546     }
547   }
548   return NULL;
549 }
550 #ifdef LDEBUG
DBTest(number,const char *,const int,const coeffs)551 static BOOLEAN DBTest(number, const char *, const int, const coeffs)
552 {
553   return TRUE;
554 }
555 #endif
KillChar(coeffs cf)556 static void KillChar(coeffs cf)
557 {
558   omFree((ADDRESS)(cf->pParameterNames[0]));
559   omFreeSize(cf->pParameterNames,sizeof(char*));
560 }
flintQ_InitChar(coeffs cf,void * infoStruct)561 BOOLEAN flintQ_InitChar(coeffs cf, void * infoStruct)
562 {
563   char *pp=(char*)infoStruct;
564   cf->cfCoeffName    = CoeffName;
565   cf->nCoeffIsEqual  = CoeffIsEqual;
566   cf->cfKillChar     = KillChar;
567   cf->cfSetChar      = SetChar;
568   cf->ch=0; //char 0
569   cf->cfMult         = Mult;
570   cf->cfSub          = Sub;
571   cf->cfAdd          = Add;
572   cf->cfDiv          = Div;
573   cf->cfExactDiv     = ExactDiv; // ???
574   cf->cfInit         =Init;
575   cf->cfInitMPZ      =InitMPZ;
576   cf->cfSize         = Size;
577   cf->cfInt          = Int;
578   cf->cfMPZ          = MPZ;
579   cf->cfInpNeg       = Neg;
580   cf->cfInvers       = Invers;
581   cf->cfCopy         = Copy;
582   cf->cfRePart       = Copy;
583   // default: cf->cfImPart       = ndReturn0;
584   cf->cfWriteLong    = WriteShort; //WriteLong;
585   cf->cfWriteShort = WriteShort;
586   cf->cfRead         = Read;
587   cf->cfNormalize    = Normalize;
588 
589   //cf->cfDivComp=
590   //cf->cfIsUnit=
591   //cf->cfGetUnit=
592   //cf->cfDivBy=
593 
594   cf->cfGreater=Greater;
595   cf->cfEqual  =Equal;
596   cf->cfIsZero =IsZero;
597   cf->cfIsOne  =IsOne;
598   cf->cfIsMOne =IsMOne;
599   cf->cfGreaterZero=GreaterZero;
600 
601   cf->cfPower        = Power;
602   cf->cfGetDenom     = GetDenom;
603   cf->cfGetNumerator = GetNumerator;
604   cf->cfGcd          = Gcd;
605   cf->cfExtGcd         = ExtGcd;
606   cf->cfLcm          = Lcm;
607   cf->cfDelete       = Delete;
608   cf->cfSetMap       = SetMap;
609   // default: cf->cfInpMult
610   // default: cf->cfInpAdd
611   cf->cfFarey        =Farey;
612   cf->cfChineseRemainder=ChineseRemainder;
613   cf->cfParDeg = ParDeg;
614   cf->cfParameter = Parameter;
615   //  cf->cfClearContent = ClearContent;
616   //  cf->cfClearDenominators = ClearDenominators;
617   cf->convFactoryNSingN=ConvFactoryNSingN;
618   cf->convSingNFactoryN=ConvSingNFactoryN;
619   cf->cfWriteFd  = WriteFd;
620   cf->cfReadFd = ReadFd;
621 #ifdef LDEBUG
622   cf->cfDBTest       = DBTest;
623 #endif
624 
625   cf->iNumberOfParameters = 1;
626   char **pn=(char**)omAlloc0(sizeof(char*));
627   pn[0]=omStrDup(pp);
628   cf->pParameterNames = (const char **)pn;
629   cf->has_simple_Inverse= FALSE;
630   cf->has_simple_Alloc= FALSE;
631   cf->is_field=FALSE;
632 
633   return FALSE;
634 }
635 #endif
636