source: git/libpolys/coeffs/flintcf_Q.cc @ 541b207

fieker-DuValspielwiese
Last change on this file since 541b207 was 541b207, checked in by Hans Schoenemann <hannes@…>, 7 years ago
fix: include path
  • Property mode set to 100644
File size: 15.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: flint: fmpq_poly
6*/
7#include <ctype.h> /* isdigit*/
8
9#include "libpolys/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 "omalloc/omalloc.h"
18#include "libpolys/coeffs/coeffs.h"
19
20#include "libpolys/coeffs/numbers.h"
21#include "libpolys/coeffs/longrat.h"
22
23typedef fmpq_poly_struct *fmpq_poly_ptr;
24typedef fmpz *fmpz_ptr;
25/*2
26* extracts a long integer from s, returns the rest
27*/
28static char * nlEatLong(char *s, mpz_ptr i)
29{
30  const char * start=s;
31
32  while (*s >= '0' && *s <= '9') s++;
33  if (*s=='\0')
34  {
35    mpz_set_str(i,start,10);
36  }
37  else
38  {
39    char c=*s;
40    *s='\0';
41    mpz_set_str(i,start,10);
42    *s=c;
43  }
44  return s;
45}
46
47static const char* Eati(const char *s, int *i)
48{
49
50  if (((*s) >= '0') && ((*s) <= '9'))
51  {
52    unsigned long ii=0L;
53    do
54    {
55      ii *= 10;
56      ii += *s++ - '0';
57    }
58    while (((*s) >= '0') && ((*s) <= '9'));
59    *i=(int)ii;
60  }
61  else (*i) = 1;
62  return s;
63}
64
65
66
67static void CoeffWrite(const coeffs r, BOOLEAN details)
68{
69  PrintS("flint fmpq_poly");
70}
71static BOOLEAN CoeffIsEqual(const coeffs r, n_coeffType n, void * parameter)
72{
73  return (r->type==n);
74}
75static void KillChar(coeffs r)
76{
77  // not yet
78}
79static void SetChar(const coeffs r)
80{
81  // dummy
82}
83static number Mult(number a, number b, const coeffs c)
84{
85  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
86  fmpq_poly_init(res);
87  fmpq_poly_mul(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
88  return (number)res;
89}
90static number Sub(number a, number b, const coeffs c)
91{
92  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
93  fmpq_poly_init(res);
94  fmpq_poly_sub(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
95  return (number)res;
96}
97static number Add(number a, number b, const coeffs c)
98{
99  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
100  fmpq_poly_init(res);
101  fmpq_poly_add(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
102  return (number)res;
103}
104static number Div(number a, number b, const coeffs c)
105{
106  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
107  fmpq_poly_init(res);
108  if(fmpq_poly_is_zero((fmpq_poly_ptr)b))
109  {
110     WerrorS(nDivBy0);
111  }
112  else
113  {
114    fmpq_poly_div(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
115    fmpq_poly_t mod;
116    fmpq_poly_init(mod);
117    fmpq_poly_rem(mod,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
118    if (!fmpq_poly_is_zero((fmpq_poly_ptr)mod))
119    {
120      WerrorS("cannot divide");
121    }
122    fmpq_poly_clear(mod);
123  }
124  return (number)res;
125}
126static number ExactDiv(number a, number b, const coeffs c)
127{
128  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
129  fmpq_poly_init(res);
130  if(fmpq_poly_is_zero((fmpq_poly_ptr)b))
131  {
132     WerrorS(nDivBy0);
133  }
134  else
135    fmpq_poly_div(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
136  return (number)res;
137}
138static number IntMod(number a, number b, const coeffs c)
139{
140  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
141  fmpq_poly_init(res);
142  fmpq_poly_rem(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
143  return (number)res;
144}
145static number Init (long i, const coeffs r)
146{
147  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
148  fmpq_poly_init(res);
149  fmpq_poly_set_si(res,i);
150  return (number)res;
151}
152static number InitMPZ (mpz_t i, const coeffs r)
153{
154  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
155  fmpq_poly_init(res);
156  fmpq_poly_set_mpz(res,i);
157  return (number)res;
158}
159static int Size (number n, const coeffs r)
160{
161  return fmpq_poly_degree((fmpq_poly_ptr)n);
162}
163static long Int (number &n, const coeffs r)
164{
165  if (fmpq_poly_degree((fmpq_poly_ptr)n)==0)
166  {
167    mpq_t m;
168    mpq_init(m);
169    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)n,0);
170    mpz_t num,den;
171    mpz_init(num);
172    mpz_init(den);
173    mpq_get_num(num,m);
174    mpq_get_den(den,m);
175    long nl=mpz_get_si(num);
176    if (mpz_cmp_si(num,nl)!=0) nl=0;
177    long dl=mpz_get_si(den);
178    if ((dl!=1)||(mpz_cmp_si(den,dl)!=0)) nl=0;
179    mpz_clear(num);
180    mpz_clear(den);
181    mpq_clear(m);
182    return nl;
183  }
184  return 0;
185}
186static void MPZ(mpz_t result, number &n, const coeffs r)
187{
188  mpz_init(result);
189  if (fmpq_poly_degree((fmpq_poly_ptr)n)==0)
190  {
191    mpq_t m;
192    mpq_init(m);
193    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)n,0);
194    mpz_t den;
195    mpz_init(den);
196    mpq_get_num(result,m);
197    mpq_get_den(den,m);
198    int dl=(int)mpz_get_si(den);
199    if ((dl!=1)||(mpz_cmp_si(den,(long)dl)!=0)) mpz_set_ui(result,0);
200    mpz_clear(den);
201    mpq_clear(m);
202  }
203}
204static number Neg(number a, const coeffs r)
205{
206  fmpq_poly_neg((fmpq_poly_ptr)a,(fmpq_poly_ptr)a);
207  return a;
208}
209static number Invers(number a, const coeffs r)
210{
211  if(fmpq_poly_is_zero((fmpq_poly_ptr)a))
212  {
213    WerrorS(nDivBy0);
214    return NULL;
215  }
216  if (fmpq_poly_degree((fmpq_poly_ptr)a)==0)
217  {
218    fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
219    fmpq_poly_init(res);
220    fmpq_poly_inv(res,(fmpq_poly_ptr)a);
221    return (number)res;
222  }
223  else
224  {
225    WerrorS("not invertable");
226    return NULL;
227  }
228}
229static number Copy(number a, const coeffs r)
230{
231 fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
232 fmpq_poly_init(res);
233 fmpq_poly_set(res,(fmpq_poly_ptr)a);
234 return (number)res;
235}
236//static number RePart(number a, const coeffs r)
237//{
238//}
239//static number ImPart(number a, const coeffs r)
240//{
241//}
242static BOOLEAN IsOne (number a, const coeffs r);
243static BOOLEAN IsZero (number a, const coeffs r);
244//static void WriteLong(number &a, const coeffs r)
245//{
246//}
247static void WriteShort(number a, const coeffs r)
248{
249  //fmpq_poly_print_pretty((fmpq_poly_ptr)a,r->pParameterNames[0]);
250  if (IsOne(a,r)) StringAppendS("1");
251  else if (IsZero(a,r)) StringAppendS("0");
252  else
253  {
254  StringAppendS("(");
255  mpq_t m;
256  mpq_init(m);
257  mpz_t num,den;
258  mpz_init(num);
259  mpz_init(den);
260  BOOLEAN need_plus=FALSE;
261  for(int i=fmpq_poly_length((fmpq_poly_ptr)a);i>=0;i--)
262  {
263    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)a,i);
264    mpq_get_num(num,m);
265    mpq_get_den(den,m);
266    if (mpz_cmp_ui(num,0)!=0)
267    {
268      if (need_plus && (mpz_cmp_si(num,0)>0))
269        StringAppendS("+");
270      need_plus=TRUE;
271      int l=mpz_sizeinbase(num,10);
272      l=si_max(l,(int)mpz_sizeinbase(den,10));
273      l+=2;
274      char *s=(char*)omAlloc(l);
275      char *z=mpz_get_str(s,10,num);
276      if ((i==0)
277      ||(mpz_cmp_si(num,1)!=0)
278      ||(mpz_cmp_si(den,1)!=0))
279      {
280        StringAppendS(z);
281        if (mpz_cmp_si(den,1)!=0)
282        {
283          StringAppendS("/");
284          z=mpz_get_str(s,10,den);
285          StringAppendS(z);
286        }
287        if (i!=0) StringAppendS("*");
288      }
289      if (i>1)
290        StringAppend("%s^%d",r->pParameterNames[0],i);
291      else if (i==1)
292        StringAppend("%s",r->pParameterNames[0]);
293    }
294  }
295  mpz_clear(den);
296  mpz_clear(num);
297  mpq_clear(m);
298  StringAppendS(")");
299  }
300}
301static const char* Read(const char * st, number * a, const coeffs r)
302{
303// we only read "monomials" (i.e. [-][digits][parameter]),
304// everythings else (+,*,^,()) is left to the singular interpreter
305  const char *s=st;
306  *a=(number)omAlloc(sizeof(fmpq_poly_t));
307  fmpq_poly_init((fmpq_poly_ptr)(*a));
308  BOOLEAN neg=FALSE;
309  if (*s=='-') { neg=TRUE; s++;}
310  if (isdigit(*s))
311  {
312    mpz_t z;
313    mpz_init(z);
314    s=nlEatLong((char *)s, z);
315    fmpq_poly_set_mpz((fmpq_poly_ptr)(*a),z);
316    if (*s == '/')
317    {
318      s++;
319      s=nlEatLong((char *)s, z);
320      fmpq_poly_scalar_div_mpz((fmpq_poly_ptr)(*a),(fmpq_poly_ptr)(*a),z);
321    }
322    mpz_clear(z);
323  }
324  else if(strncmp(s,r->pParameterNames[0],strlen(r->pParameterNames[0]))==0)
325  {
326    fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),1,1);
327    s+=strlen(r->pParameterNames[0]);
328    if(isdigit(*s))
329    {
330      int i=1;
331      s=Eati(s,&i);
332      if (i!=1)
333      {
334        fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),1,0);
335        fmpq_poly_set_coeff_si((fmpq_poly_ptr)(*a),i,1);
336      }
337    }
338  }
339  if (neg)
340    fmpq_poly_neg((fmpq_poly_ptr)(*a),(fmpq_poly_ptr)(*a));
341  return s;
342}
343static void Normalize(number &a, const coeffs r)
344{
345  fmpq_poly_canonicalise((fmpq_poly_ptr)a);
346}
347static BOOLEAN Greater (number a, number b, const coeffs r)
348{
349  return (fmpq_poly_cmp((fmpq_poly_ptr)a,(fmpq_poly_ptr)b)>0);
350}
351static BOOLEAN Equal (number a, number b, const coeffs r)
352{
353  return (fmpq_poly_equal((fmpq_poly_ptr)a,(fmpq_poly_ptr)b));
354}
355static BOOLEAN IsZero (number a, const coeffs r)
356{
357  return fmpq_poly_is_zero((fmpq_poly_ptr)a);
358}
359static BOOLEAN IsOne (number a, const coeffs r)
360{
361  return fmpq_poly_is_one((fmpq_poly_ptr)a);
362}
363static BOOLEAN IsMOne (number k, const coeffs r)
364{
365  if (fmpq_poly_length((fmpq_poly_ptr)k)>0) return FALSE;
366  fmpq_poly_canonicalise((fmpq_poly_ptr)k);
367  mpq_t m;
368  mpq_init(m);
369  fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)k,0);
370  mpz_t num,den;
371  mpz_init(num);
372  mpq_get_num(num,m);
373  BOOLEAN result=TRUE;
374  if (mpz_cmp_si(num,(long)-1)!=0) result=FALSE;
375  else
376  {
377    mpz_init(den);
378    mpq_get_den(den,m);
379    int dl=(int)mpz_get_si(den);
380    if ((dl!=1)||(mpz_cmp_si(den,(long)dl)!=0)) result=FALSE;
381    mpz_clear(den);
382  }
383  mpz_clear(num);
384  mpq_clear(m);
385  return (result);
386}
387static BOOLEAN GreaterZero (number k, const coeffs r)
388{
389  // does it have a leading sign?
390  // no: 0 and 1 do not have, everything else is in (...)
391  return TRUE;
392}
393static void Power(number a, int i, number * result, const coeffs r)
394{
395  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
396  fmpq_poly_init(res);
397  *result=(number)res;
398  fmpq_poly_pow((fmpq_poly_ptr)(*result),(fmpq_poly_ptr)a,i);
399}
400static number GetDenom(number &n, const coeffs r)
401{
402 fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
403 fmpq_poly_init(res);
404 fmpz_ptr den=fmpq_poly_denref(res);
405 fmpq_poly_set_fmpz(res,den);
406 return (number)res;
407}
408static number GetNumerator(number &n, const coeffs r)
409{
410 fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
411 fmpq_poly_init(res);
412 fmpq_poly_set(res,(fmpq_poly_ptr)n);
413 fmpz_ptr den=fmpq_poly_denref(res);
414 fmpq_poly_scalar_mul_fmpz(res,res,den);
415 return (number)res;
416}
417static number Gcd(number a, number b, const coeffs r)
418{
419  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
420  fmpq_poly_init(res);
421  fmpq_poly_gcd(res,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
422  return (number)res;
423}
424static number ExtGcd(number a, number b, number *s, number *t,const coeffs r)
425{
426  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
427  fmpq_poly_init(res);
428  fmpq_poly_init((fmpq_poly_ptr)*s);
429  fmpq_poly_init((fmpq_poly_ptr)*t);
430  fmpq_poly_xgcd(res,(fmpq_poly_ptr)*s,(fmpq_poly_ptr)*t,(fmpq_poly_ptr)a,(fmpq_poly_ptr)b);
431  return (number)res;
432}
433static number Lcm(number a, number b, const coeffs r)
434{
435  WerrorS("not yet: Lcm");
436}
437static void Delete(number * a, const coeffs r)
438{
439  if ((*a)!=NULL)
440  {
441    fmpq_poly_clear((fmpq_poly_ptr)*a);
442    omFree(*a);
443    *a=NULL;
444  }
445}
446static nMapFunc SetMap(const coeffs src, const coeffs dst)
447{
448  WerrorS("not yet: SetMap");
449  return NULL;
450}
451//static void InpMult(number &a, number b, const coeffs r)
452//{
453//}
454//static void InpAdd(number &a, number b, const coeffs r)
455//{
456//}
457static number Init_bigint(number i, const coeffs dummy, const coeffs dst)
458{
459  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
460  fmpq_poly_init(res);
461  if (SR_HDL(i) & SR_INT)
462  {
463    fmpq_poly_set_si(res,SR_TO_INT(i));
464  }
465  else
466    fmpq_poly_set_mpz(res,i->z);
467  return (number)res;
468}
469static number Farey(number p, number n, const coeffs)
470{
471  WerrorS("not yet: Farey");
472}
473static number ChineseRemainder(number *x, number *q,int rl, BOOLEAN sym,CFArray &inv_cache,const coeffs)
474{
475  WerrorS("not yet: ChineseRemainder");
476}
477static int ParDeg(number x,const coeffs r)
478{
479  return fmpq_poly_degree((fmpq_poly_ptr)x);
480}
481static number Parameter(const int i, const coeffs r)
482{
483  fmpq_poly_ptr res=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
484  fmpq_poly_init(res);
485  fmpq_poly_set_coeff_si(res,1,1);
486  return (number)res;
487}
488static void WriteFd(number a, FILE *f, const coeffs)
489{
490  // format: len a_len(num den) .. a_0
491  fmpq_poly_ptr aa=(fmpq_poly_ptr)a;
492  int l=fmpq_poly_length(aa);
493  fprintf(f,"%d ",l);
494  mpq_t m;
495  mpq_init(m);
496  mpz_t num,den;
497  mpz_init(num);
498  mpz_init(den);
499  for(int i=l; i>=0; i--)
500  {
501    fmpq_poly_get_coeff_mpq(m,(fmpq_poly_ptr)a,i);
502    mpq_get_num(num,m);
503    mpq_get_den(den,m);
504    mpz_out_str (f,SSI_BASE, num);
505    fputc(' ',f);
506    mpz_out_str (f,SSI_BASE, den);
507    fputc(' ',f);
508  }
509  mpz_clear(den);
510  mpz_clear(num);
511  mpq_clear(m);
512}
513static number ReadFd(s_buff f, const coeffs)
514{
515  // format: len a_len .. a_0
516  fmpq_poly_ptr aa=(fmpq_poly_ptr)omAlloc(sizeof(fmpq_poly_t));
517  fmpq_poly_init(aa);
518  int l=s_readint(f);
519  mpz_t nm;
520  mpz_init(nm);
521  mpq_t m;
522  mpq_init(m);
523  for (int i=l;i>=0;i--)
524  {
525
526    s_readmpz_base (f,nm, SSI_BASE);
527    mpq_set_num(m,nm);
528    s_readmpz_base (f,nm, SSI_BASE);
529    mpq_set_den(m,nm);
530    fmpq_poly_set_coeff_mpq(aa,i,m);
531  }
532  mpz_clear(nm);
533  mpq_clear(m);
534  return (number)aa;
535}
536// cfClearContent
537// cfClearDenominators
538static number ConvFactoryNSingN( const CanonicalForm n, const coeffs r)
539{
540  WerrorS("not yet: ConvFactoryNSingN");
541}
542static CanonicalForm ConvSingNFactoryN( number n, BOOLEAN setChar, const coeffs r )
543{
544  WerrorS("not yet: ConvSingNFactoryN");
545}
546char * CoeffName(const coeffs r)
547{
548  return (char*)"flint:Q[a]";
549}
550static char* CoeffString(const coeffs r)
551{
552  return omStrDup(CoeffName(r));
553}
554#ifdef LDEBUG
555static BOOLEAN DBTest(number a, const char *f, const int l, const coeffs r)
556{
557  return TRUE;
558}
559#endif
560BOOLEAN flintQ_InitChar(coeffs cf, void * infoStruct)
561{
562  cf->cfCoeffString  = CoeffString;
563  cf->cfCoeffName    = CoeffName;
564  cf->cfCoeffWrite   = CoeffWrite;
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]=(char*)omStrDup("a");
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
Note: See TracBrowser for help on using the repository browser.