source: git/libpolys/coeffs/gnumpfl.cc @ a3f0fea

spielwiese
Last change on this file since a3f0fea was a3f0fea, checked in by Reimer Behrends <behrends@…>, 5 years ago
Modify variable declarions for pSingular.
  • Property mode set to 100644
File size: 11.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: computations with GMP floating-point numbers
6*
7* ngf == number gnu floats
8*/
9
10#include "misc/auxiliary.h"
11
12#include "reporter/reporter.h"
13
14#include "coeffs/coeffs.h"
15#include "coeffs/numbers.h"
16#include "coeffs/mpr_complex.h"
17
18#include "coeffs/longrat.h"
19#include "coeffs/shortfl.h"
20#include "coeffs/gnumpfl.h"
21#include "coeffs/gnumpc.h"
22#include "coeffs/modulop.h"
23
24const char *   ngfRead (const char *s, number *a, const coeffs r);
25
26union nf
27{
28  SI_FLOAT _f;
29  number _n;
30  nf(SI_FLOAT f) {_f = f;}
31  nf(number n) {_n = n;}
32  SI_FLOAT F() const {return _f;}
33  number N() const {return _n;}
34};
35
36/*2
37* n := i
38*/
39static number ngfInit (long i, const coeffs r)
40{
41  assume( getCoeffType(r) == n_long_R );
42
43  gmp_float* n= new gmp_float( (double)i );
44  return (number)n;
45}
46
47/*2
48* convert number to int
49*/
50static long ngfInt(number &i, const coeffs r)
51{
52  assume( getCoeffType(r) == n_long_R );
53
54  double d=(double)*(gmp_float*)i;
55  if (d<0.0)
56    return (long)(d-0.5);
57  else
58    return (long)(d+0.5);
59}
60
61static BOOLEAN ngfIsZero (number a, const coeffs r)
62{
63  assume( getCoeffType(r) == n_long_R );
64
65  return ( ((gmp_float*)a)->isZero() );
66}
67
68static int ngfSize(number n, const coeffs r)
69{
70  long i = ngfInt(n, r);
71  /* basically return the largest integer in n;
72     only if this happens to be zero although n != 0,
73     return 1;
74     (this code ensures that zero has the size zero) */
75  if ((i == 0) && (ngfIsZero(n,r) == FALSE)) i = 1;
76  return ABS(i);
77}
78
79/*2
80* delete a
81*/
82static void ngfDelete (number * a, const coeffs r)
83{
84  assume( getCoeffType(r) == n_long_R );
85
86  if ( *a != NULL )
87  {
88    delete *(gmp_float**)a;
89    *a=NULL;
90  }
91}
92
93/*2
94* copy a to b
95*/
96static number ngfCopy(number a, const coeffs r)
97{
98  assume( getCoeffType(r) == n_long_R );
99
100  gmp_float* b= new gmp_float( *(gmp_float*)a );
101  return (number)b;
102}
103
104#if 0
105static number ngfCopyMap(number a, const coeffs r1, const coeffs r2)
106{
107  assume( getCoeffType(r1) == n_long_R );
108  assume( getCoeffType(r2) == n_long_R );
109
110  gmp_float* b= NULL;
111  if ( a !=  NULL )
112  {
113    b= new gmp_float( *(gmp_float*)a );
114  }
115  return (number)b;
116}
117#endif
118
119/*2
120* za:= - za
121*/
122static number ngfNeg (number a, const coeffs r)
123{
124  assume( getCoeffType(r) == n_long_R );
125
126  *(gmp_float*)a= -(*(gmp_float*)a);
127  return (number)a;
128}
129
130/*
131* 1/a
132*/
133static number ngfInvers(number a, const coeffs r)
134{
135  assume( getCoeffType(r) == n_long_R );
136
137  gmp_float* f= NULL;
138  if (((gmp_float*)a)->isZero() )
139  {
140    WerrorS(nDivBy0);
141  }
142  else
143  {
144    f= new gmp_float( gmp_float(1) / (*(gmp_float*)a) );
145  }
146  return (number)f;
147}
148
149/*2
150* u:= a + b
151*/
152static number ngfAdd (number a, number b, const coeffs R)
153{
154  assume( getCoeffType(R) == n_long_R );
155
156  gmp_float* r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
157  return (number)r;
158}
159
160/*2
161* u:= a - b
162*/
163static number ngfSub (number a, number b, const coeffs R)
164{
165  assume( getCoeffType(R) == n_long_R );
166
167  gmp_float* r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
168  return (number)r;
169}
170
171/*2
172* u := a * b
173*/
174static number ngfMult (number a, number b, const coeffs R)
175{
176  assume( getCoeffType(R) == n_long_R );
177
178  gmp_float* r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
179  return (number)r;
180}
181
182/*2
183* u := a / b
184*/
185static number ngfDiv (number a, number b, const coeffs r)
186{
187  assume( getCoeffType(r) == n_long_R );
188
189  if ( ((gmp_float*)b)->isZero() )
190  {
191    // a/0 = error
192    WerrorS(nDivBy0);
193    return NULL;
194  }
195  gmp_float* f= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
196  return (number)f;
197}
198
199/*2
200* u:= x ^ exp
201*/
202static number ngfPower (number x, int exp, const coeffs r)
203{
204  assume( getCoeffType(r) == n_long_R );
205
206  if ( exp == 0 )
207  {
208    gmp_float* n = new gmp_float(1);
209    return (number)n;
210  }
211  else if ( ngfIsZero(x, r) ) // 0^e, e>0
212  {
213    return ngfInit(0, r);
214  }
215  else if ( exp == 1 )
216  {
217    return ngfCopy(x,r);
218  }
219  return (number) ( new gmp_float( (*(gmp_float*)x)^exp ) );
220}
221
222/* kept for compatibility reasons, to be deleted */
223static void ngfPower ( number x, int exp, number * u, const coeffs r )
224{
225  *u = ngfPower(x, exp, r);
226}
227
228/*2
229* za > 0 ?
230*/
231static BOOLEAN ngfGreaterZero (number a, const coeffs r)
232{
233  assume( getCoeffType(r) == n_long_R );
234
235  return (((gmp_float*)a)->sign() > 0);
236}
237
238/*2
239* a > b ?
240*/
241static BOOLEAN ngfGreater (number a, number b, const coeffs r)
242{
243  assume( getCoeffType(r) == n_long_R );
244
245  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
246}
247
248/*2
249* a = b ?
250*/
251static BOOLEAN ngfEqual (number a, number b, const coeffs r)
252{
253  assume( getCoeffType(r) == n_long_R );
254
255  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
256}
257
258/*2
259* a == 1 ?
260*/
261static BOOLEAN ngfIsOne (number a, const coeffs r)
262{
263  assume( getCoeffType(r) == n_long_R );
264
265  return ((gmp_float*)a)->isOne();
266}
267
268/*2
269* a == -1 ?
270*/
271static BOOLEAN ngfIsMOne (number a, const coeffs r)
272{
273  assume( getCoeffType(r) == n_long_R );
274
275  return ((gmp_float*)a)->isMOne();
276}
277
278static char * ngfEatFloatNExp(char * s )
279{
280  char *start= s;
281
282  // eat floats (mantissa) like:
283  //   0.394394993, 102.203003008,  .300303032, pssibly starting with -
284  if (*s == '-') s++;
285  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
286
287  // eat the exponent, starts with 'e' followed by '+', '-'
288  // and digits, like:
289  //   e-202, e+393, accept also E7
290  if ( (s != start) && ((*s == 'e')||(*s=='E')))
291  {
292    if (*s=='E') *s='e';
293    s++; // skip 'e'/'E'
294    if ((*s == '+') || (*s == '-')) s++;
295    while ((*s >= '0' && *s <= '9')) s++;
296  }
297
298  return s;
299}
300
301/*2
302* extracts the number a from s, returns the rest
303*
304* This is also called to print components of complex coefficients.
305* Handle with care!
306*/
307const char * ngfRead (const char * start, number * a, const coeffs r)
308{
309  assume( getCoeffType(r) == n_long_R or getCoeffType(r) == n_long_C);
310
311  char *s= (char *)start;
312
313  //Print("%s\n",s);
314
315  s= ngfEatFloatNExp( s );
316
317  if (*s=='\0')  // 0
318  {
319    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
320    (*(gmp_float**)a)->setFromStr(start);
321  }
322  else if (s==start)  // 1
323  {
324    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
325    (*(gmp_float**)a)= new gmp_float(1);
326  }
327  else
328  {
329    gmp_float divisor(1.0);
330    char *start2=s;
331    if ( *s == '/' )
332    {
333      s++;
334      s= ngfEatFloatNExp( (char *)s );
335      if (s!= start2+1)
336      {
337        char tmp_c=*s;
338        *s='\0';
339        divisor.setFromStr(start2+1);
340        *s=tmp_c;
341      }
342      else
343      {
344        Werror("wrong long real format: %s",start2);
345      }
346    }
347    char c=*start2;
348    *start2='\0';
349    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
350    (*(gmp_float**)a)->setFromStr(start);
351    *start2=c;
352    if (divisor.isZero())
353    {
354      WerrorS(nDivBy0);
355    }
356    else
357      (**(gmp_float**)a) /= divisor;
358  }
359
360  return s;
361}
362
363/*2
364* write a floating point number
365*/
366static void ngfWrite (number a, const coeffs r)
367{
368  assume( getCoeffType(r) == n_long_R );
369
370  char *out;
371  if ( a != NULL )
372  {
373    out= floatToStr(*(gmp_float*)a, r->float_len);
374    StringAppendS(out);
375    //omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
376    omFree( (void *)out );
377  }
378  else
379  {
380    StringAppendS("0");
381  }
382}
383
384static BOOLEAN ngfCoeffIsEqual (const coeffs r, n_coeffType n, void * parameter)
385{
386  if (n==n_long_R)
387  {
388    LongComplexInfo* p = (LongComplexInfo *)(parameter);
389    if ((p!=NULL)
390    && (p->float_len == r->float_len)
391    && (p->float_len2 == r->float_len2))
392      return TRUE;
393  }
394  return FALSE;
395}
396
397static void ngfSetChar(const coeffs r)
398{
399  setGMPFloatDigits(r->float_len, r->float_len2);
400}
401
402static char* ngfCoeffString(const coeffs r)
403{
404  char *s=(char*)omAlloc(30);
405  snprintf(s,30,"Float(%d,%d)",r->float_len,r->float_len2);
406  return s;
407}
408
409static char* ngfCoeffName(const coeffs r)
410{
411  STATIC_VAR char ngfCoeffName_buf[30];
412  snprintf(ngfCoeffName_buf,30,"Float(%d,%d)",r->float_len,r->float_len2);
413  return ngfCoeffName_buf;
414}
415
416static number ngfMapQ(number from, const coeffs src, const coeffs dst)
417{
418  assume( getCoeffType(dst) == n_long_R );
419  assume( src->rep == n_rep_gap_rat );
420
421  gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF));
422  return (number)res;
423}
424static number ngfMapZ(number from, const coeffs aRing, const coeffs r)
425{
426  assume( getCoeffType(r) == n_long_R );
427  assume( aRing->rep == n_rep_gap_gmp);
428
429  if ( from != NULL )
430  {
431    if (SR_HDL(from) & SR_INT)
432    {
433      gmp_float f_i= gmp_float(SR_TO_INT(from));
434      gmp_float *res=new gmp_float(f_i);
435      return (number)res;
436    }
437    gmp_float f_i=(mpz_ptr)from;
438    gmp_float *res=new gmp_float(f_i);
439    return (number)res;
440  }
441  else
442    return NULL;
443}
444
445static number ngfMapR(number from, const coeffs src, const coeffs dst)
446{
447  assume( getCoeffType(dst) == n_long_R );
448  assume( getCoeffType(src) == n_R );
449
450  gmp_float *res=new gmp_float((double)nf(from).F());
451  return (number)res;
452}
453
454static number ngfMapP(number from, const coeffs src, const coeffs dst)
455{
456  assume( getCoeffType(dst) == n_long_R );
457  assume( getCoeffType(src) ==  n_Zp );
458
459  return ngfInit(npInt(from,src), dst); // FIXME? TODO? // extern int     npInt         (number &n, const coeffs r);
460}
461
462static number ngfMapC(number from, const coeffs src, const coeffs dst)
463{
464  assume( getCoeffType(dst) == n_long_R );
465  assume( getCoeffType(src) ==  n_long_C );
466
467  gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
468  return (number)res;
469}
470
471static nMapFunc ngfSetMap(const coeffs src, const coeffs dst)
472{
473  assume( getCoeffType(dst) == n_long_R );
474
475  if (src->rep==n_rep_gap_rat) /*Q, Z*/
476  {
477    return ngfMapQ;
478  }
479  if (src->rep==n_rep_gap_gmp) /*Q, Z*/
480  {
481    return ngfMapZ;
482  }
483  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
484  {
485    return ndCopyMap; //ngfCopyMap;
486  }
487  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
488  {
489    return ngfMapR;
490  }
491  if ((src->rep==n_rep_gmp_complex) && nCoeff_is_long_C(src))
492  {
493    return ngfMapC;
494  }
495  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
496  {
497    return ngfMapP;
498  }
499  return NULL;
500}
501
502static void ngfCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
503{
504  Print("Float(%d,%d)", r->float_len,r->float_len2);  /* long R */
505}
506
507BOOLEAN ngfInitChar(coeffs n, void *parameter)
508{
509  assume( getCoeffType(n) == n_long_R );
510
511  n->is_field=TRUE;
512  n->is_domain=TRUE;
513  n->rep=n_rep_gmp_float;
514
515  //n->cfKillChar = ndKillChar; /* dummy */
516
517  n->cfSetChar = ngfSetChar;
518  n->ch = 0;
519  n->cfCoeffString=ngfCoeffString;
520  n->cfCoeffName=ngfCoeffName;
521
522  n->cfDelete  = ngfDelete;
523  //n->cfNormalize=ndNormalize;
524  n->cfInit   = ngfInit;
525  n->cfInt    = ngfInt;
526  n->cfAdd     = ngfAdd;
527  n->cfSub     = ngfSub;
528  n->cfMult    = ngfMult;
529  n->cfDiv     = ngfDiv;
530  n->cfExactDiv= ngfDiv;
531  n->cfInpNeg     = ngfNeg;
532  n->cfInvers  = ngfInvers;
533  n->cfCopy   = ngfCopy;
534  n->cfGreater = ngfGreater;
535  n->cfEqual   = ngfEqual;
536  n->cfIsZero  = ngfIsZero;
537  n->cfIsOne   = ngfIsOne;
538  n->cfIsMOne  = ngfIsMOne;
539  n->cfGreaterZero = ngfGreaterZero;
540  n->cfWriteLong  = ngfWrite;
541  n->cfRead    = ngfRead;
542  n->cfPower   = ngfPower;
543  n->cfSetMap = ngfSetMap;
544  n->cfCoeffWrite = ngfCoeffWrite;
545#ifdef LDEBUG
546  //n->cfDBTest  = ndDBTest; // not yet implemented: ngfDBTest
547#endif
548
549  n->nCoeffIsEqual = ngfCoeffIsEqual;
550
551  if( parameter != NULL)
552  {
553    LongComplexInfo* p = (LongComplexInfo*)parameter;
554
555    n->float_len = p->float_len;
556    n->float_len2 = p->float_len2;
557  } else // default values, just for testing!
558  {
559    n->float_len = SHORT_REAL_LENGTH;
560    n->float_len2 = SHORT_REAL_LENGTH;
561  }
562
563  assume( n->float_len2 >= SHORT_REAL_LENGTH );
564
565  assume( n_NumberOfParameters(n) == 0 );
566  assume( n_ParameterNames(n) == NULL );
567
568  return FALSE;
569}
Note: See TracBrowser for help on using the repository browser.