source: git/libpolys/coeffs/gnumpfl.cc @ 61e855

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