source: git/coeffs/gnumpfl.cc @ 210852

spielwiese
Last change on this file since 210852 was 210852, checked in by Mohamed Barakat <mohamed.barakat@…>, 14 years ago
started adapting gnumpfl.{h,cc}
  • Property mode set to 100644
File size: 9.5 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[341696]4/* $Id$ */
[35aab3]5/*
6* ABSTRACT: computations with GMP floating-point numbers
7*
8* ngf == number gnu floats
9*/
10
[58aa457]11#include "config.h"
12#include "coeffs.h"
13#include <output.h>
14#include <omalloc.h>
15#include "numbers.h"
16#include "modulop.h"
17#include "longrat.h"
[35aab3]18
[58aa457]19#include <gnumpfl.h>
20#include <mpr_complex.h>
[35aab3]21
22extern size_t gmp_output_digits;
[58aa457]23//ring ngfMapRing; // to be used also in gnumpc.cc
[35aab3]24
[210852]25/// Our Type!
26static const n_coeffType ID = n_gnump_R;
27
[58aa457]28static number ngfMapP(number from, const coeffs src, const coeffs dst)
[35aab3]29{
[58aa457]30  return ngfInit(npInt(from,src), dst);
[35aab3]31}
[58aa457]32number ngfMapQ(number from, const coeffs src, const coeffs dst)
[35aab3]33{
[c12222]34  gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF));
35  return (number)res;
[35aab3]36}
37union nf
38{
39  float _f;
40  number _n;
41  nf(float f) {_f = f;}
42  nf(number n) {_n = n;}
43  float F() const {return _f;}
44  number N() const {return _n;}
45};
[58aa457]46static number ngfMapR(number from, const coeffs src, const coeffs dst)
[35aab3]47{
[c12222]48  gmp_float *res=new gmp_float((double)nf(from).F());
49  return (number)res;
[35aab3]50}
[58aa457]51static number ngfMapC(number from, const coeffs src, const coeffs dst)
[35aab3]52{
[c12222]53  gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
54  return (number)res;
[35aab3]55}
56
57/*2
58* n := i
59*/
[58aa457]60number ngfInit (int i, const coeffs r)
[35aab3]61{
[210852]62  assume( getCoeffType(r) == ID );
63 
[c12222]64  gmp_float* n= new gmp_float( (double)i );
[35aab3]65  return (number)n;
66}
67
68/*2
69* convert number to int
70*/
[58aa457]71int ngfInt(number &i, const coeffs r)
[35aab3]72{
[210852]73  assume( getCoeffType(r) == ID );
74 
[3c6379]75  double d=(double)*(gmp_float*)i;
76  if (d<0.0)
77    return (int)(d-0.5);
78  else
79    return (int)(d+0.5);
[35aab3]80}
81
[58aa457]82int ngfSize(number n, const coeffs r)
[12cca3]83{
[58aa457]84  int i = ngfInt(n, r);
[12cca3]85  /* basically return the largest integer in n;
86     only if this happens to be zero although n != 0,
87     return 1;
88     (this code ensures that zero has the size zero) */
89  if ((i == 0) && (ngfIsZero(n) == FALSE)) i = 1;
90  return i;
91}
92
[35aab3]93/*2
94* delete a
95*/
[58aa457]96void ngfDelete (number * a, const coeffs r)
[35aab3]97{
[210852]98  assume( getCoeffType(r) == ID );
99 
[35aab3]100  if ( *a != NULL )
101  {
102    delete *(gmp_float**)a;
103    *a=NULL;
104  }
105}
106
107/*2
108* copy a to b
109*/
[58aa457]110number ngfCopy(number a, const coeffs r)
[35aab3]111{
[210852]112  assume( getCoeffType(r) == ID );
113 
[c12222]114  gmp_float* b= new gmp_float( *(gmp_float*)a );
[35aab3]115  return (number)b;
116}
117
118/*2
119* za:= - za
120*/
[58aa457]121number ngfNeg (number a, const coeffs r)
[35aab3]122{
[210852]123  assume( getCoeffType(r) == ID );
124 
[35aab3]125  *(gmp_float*)a= -(*(gmp_float*)a);
126  return (number)a;
127}
128
129/*
130* 1/a
131*/
[210852]132number ngfInvers(number a, const coeffs r)
[35aab3]133{
[210852]134  assume( getCoeffType(r) == ID );
135 
136  gmp_float* f= NULL;
[c12222]137  if (((gmp_float*)a)->isZero() )
[35aab3]138  {
[b7e838]139    WerrorS(nDivBy0);
[35aab3]140  }
141  else
142  {
[58aa457]143    f= new gmp_float( gmp_float(1) / (*(gmp_float*)a) );
[35aab3]144  }
[58aa457]145  return (number)f;
[35aab3]146}
147
148/*2
149* u:= a + b
150*/
[58aa457]151number ngfAdd (number a, number b, const coeffs R)
[35aab3]152{
[210852]153  assume( getCoeffType(R) == ID );
154 
[c12222]155  gmp_float* r= new gmp_float( (*(gmp_float*)a) + (*(gmp_float*)b) );
[35aab3]156  return (number)r;
157}
158
159/*2
160* u:= a - b
161*/
[58aa457]162number ngfSub (number a, number b, const coeffs R)
[35aab3]163{
[210852]164  assume( getCoeffType(R) == ID );
165 
[c12222]166  gmp_float* r= new gmp_float( (*(gmp_float*)a) - (*(gmp_float*)b) );
[35aab3]167  return (number)r;
168}
169
170/*2
171* u := a * b
172*/
[58aa457]173number ngfMult (number a, number b, const coeffs R)
[35aab3]174{
[210852]175  assume( getCoeffType(R) == ID );
176 
[c12222]177  gmp_float* r= new gmp_float( (*(gmp_float*)a) * (*(gmp_float*)b) );
[35aab3]178  return (number)r;
179}
180
181/*2
182* u := a / b
183*/
[58aa457]184number ngfDiv (number a, number b, const coeffs r)
[35aab3]185{
[210852]186  assume( getCoeffType(r) == ID );
187 
[c12222]188  if ( ((gmp_float*)b)->isZero() )
[35aab3]189  {
[b7e838]190    // a/0 = error
191    WerrorS(nDivBy0);
[35aab3]192    return NULL;
193  }
[58aa457]194  gmp_float* f= new gmp_float( (*(gmp_float*)a) / (*(gmp_float*)b) );
195  return (number)f;
[35aab3]196}
197
198/*2
199* u:= x ^ exp
200*/
[58aa457]201number ngfPower (number x, int exp, const coeffs r)
[35aab3]202{
[210852]203  assume( getCoeffType(r) == ID );
204 
[35aab3]205  if ( exp == 0 )
206  {
207    gmp_float* n = new gmp_float(1);
208    *u=(number)n;
209    return;
210  }
[f945d2b]211  else if ( ngfIsZero(x, r) ) // 0^e, e>0
[2fa632]212  {
[58aa457]213    *u=ngfInit(0, r);
[2fa632]214    return;
215  }
216  else if ( exp == 1 )
[35aab3]217  {
[58aa457]218    n_New(u, r);
[c12222]219    gmp_float* n = new gmp_float();
220    *n= *(gmp_float*)x;
221    *u=(number)n;
[35aab3]222    return;
223  }
[f945d2b]224  return (number) ( new gmp_float( (*(gmp_float*)x)^exp ) );
[35aab3]225}
226
[58aa457]227/* kept for compatibility reasons, to be deleted */
228void ngfPower ( number x, int exp, number * u, const coeffs r )
229{
230  *u = ngfPower(x, exp, r);
231} 
232
233BOOLEAN ngfIsZero (number a, const coeffs r)
[35aab3]234{
[210852]235  assume( getCoeffType(r) == ID );
236 
[35aab3]237  return ( ((gmp_float*)a)->isZero() );
238}
239
240/*2
[58aa457]241* za > 0 ?
[35aab3]242*/
[58aa457]243BOOLEAN ngfGreaterZero (number a, const coeffs r)
[35aab3]244{
[210852]245  assume( getCoeffType(r) == ID );
246 
[58aa457]247  return (((gmp_float*)a)->sign() > 0);
[35aab3]248}
249
250/*2
251* a > b ?
252*/
[58aa457]253BOOLEAN ngfGreater (number a, number b, const coeffs r)
[35aab3]254{
[210852]255  assume( getCoeffType(r) == ID );
256 
[35aab3]257  return ( (*(gmp_float*)a) > (*(gmp_float*)b) );
258}
259
260/*2
261* a = b ?
262*/
[58aa457]263BOOLEAN ngfEqual (number a, number b, const coeffs r)
[35aab3]264{
[210852]265  assume( getCoeffType(r) == ID );
266 
[35aab3]267  return ( (*(gmp_float*)a) == (*(gmp_float*)b) );
268}
269
270/*2
271* a == 1 ?
272*/
[58aa457]273BOOLEAN ngfIsOne (number a, const coeffs r)
[35aab3]274{
[210852]275  assume( getCoeffType(r) == ID );
276 
[35aab3]277  return ((gmp_float*)a)->isOne();
278}
279
280/*2
281* a == -1 ?
282*/
[58aa457]283BOOLEAN ngfIsMOne (number a, const coeffs r)
[35aab3]284{
[210852]285  assume( getCoeffType(r) == ID );
286 
[35aab3]287  return ((gmp_float*)a)->isMOne();
288}
289
[85e68dd]290static char * ngfEatFloatNExp(char * s )
[35aab3]291{
292  char *start= s;
293
294  // eat floats (mantissa) like:
[df1a7e]295  //   0.394394993, 102.203003008,  .300303032, pssibly starting with -
296  if (*s == '-') s++;
[35aab3]297  while ((*s >= '0' && *s <= '9')||(*s == '.')) s++;
298
299  // eat the exponent, starts with 'e' followed by '+', '-'
300  // and digits, like:
[cb8700]301  //   e-202, e+393, accept also E7
302  if ( (s != start) && ((*s == 'e')||(*s=='E')))
[35aab3]303  {
[df1a7e]304    if (*s=='E') *s='e';
[cb8700]305    s++; // skip 'e'/'E'
306    if ((*s == '+') || (*s == '-')) s++;
[35aab3]307    while ((*s >= '0' && *s <= '9')) s++;
308  }
309
310  return s;
311}
312
313/*2
314* extracts the number a from s, returns the rest
315*/
[58aa457]316const char * ngfRead (const char * start, number * a, const coeffs r)
[35aab3]317{
[210852]318  assume( getCoeffType(r) == ID );
319 
[85e68dd]320  char *s= (char *)start;
[35aab3]321
322  //Print("%s\n",s);
323
324  s= ngfEatFloatNExp( s );
325
326  if (*s=='\0')  // 0
327  {
328    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
329    (*(gmp_float**)a)->setFromStr(start);
330  }
331  else if (s==start)  // 1
332  {
333    if ( *(gmp_float**)a != NULL )  delete (*(gmp_float**)a);
334    (*(gmp_float**)a)= new gmp_float(1);
335  }
336  else
337  {
338    gmp_float divisor(1.0);
339    char *start2=s;
340    if ( *s == '/' )
341    {
342      s++;
[85e68dd]343      s= ngfEatFloatNExp( (char *)s );
[35aab3]344      if (s!= start2+1)
345      {
346        char tmp_c=*s;
347        *s='\0';
348        divisor.setFromStr(start2+1);
349        *s=tmp_c;
350      }
351      else
352      {
353        Werror("wrong long real format: %s",start2);
354      }
355    }
356    char c=*start2;
357    *start2='\0';
358    if ( *(gmp_float**)a == NULL ) (*(gmp_float**)a)= new gmp_float();
359    (*(gmp_float**)a)->setFromStr(start);
360    *start2=c;
[7c961ba]361    if (divisor.isZero())
362    {
363      WerrorS(nDivBy0);
364    }
365    else
366      (**(gmp_float**)a) /= divisor;
[35aab3]367  }
368
369  return s;
370}
371
372/*2
373* write a floating point number
374*/
[58aa457]375void ngfWrite (number &a, const coeffs r)
[35aab3]376{
[210852]377  assume( getCoeffType(r) == ID );
378 
379  extern size_t gmp_output_digits;
[35aab3]380  char *out;
381  if ( a != NULL )
382  {
[210852]383    out= floatToStr(*(gmp_float*)a, gmp_output_digits, r);
[e53182]384    StringAppendS(out);
[7d90aa]385    //omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
386    omFree( (void *)out );
[35aab3]387  }
388  else
389  {
[e53182]390    StringAppendS("0");
[35aab3]391  }
392}
393
[210852]394static BOOLEAN ngfCoeffsEqual(const coeffs r, n_coeffType n, int)
395{
396  assume( getCoeffType(r) == ID );
397 
398  return (n == ID);
399};
400
401void ngfInitChar(coeffs n, int)
402{
403  assume( getCoeffType(n) == ID );
404
405  n->cfDelete  = ngfDelete;
406  n->nNormalize=ndNormalize;
407  n->cfInit   = ngfInit;
408  n->n_Int    = ngfInt;
409  n->nAdd     = ngfAdd;
410  n->nSub     = ngfSub;
411  n->nMult    = ngfMult;
412  n->nDiv     = ngfDiv;
413  n->nExactDiv= ngfDiv;
414  n->nNeg     = ngfNeg;
415  n->nInvers  = ngfInvers;
416  n->cfCopy   = ngfCopy;
417  n->nGreater = ngfGreater;
418  n->nEqual   = ngfEqual;
419  n->nIsZero  = ngfIsZero;
420  n->nIsOne   = ngfIsOne;
421  n->nIsMOne  = ngfIsMOne;
422  n->nGreaterZero = ngfGreaterZero;
423  n->cfWrite  = ngfWrite;
424  n->nRead    = ngfRead;
425  n->nPower   = ngfPower;
426  n->cfSetMap = ngfSetMap;
427#ifdef LDEBUG
428  n->nDBTest  = ndDBTest; // not yet implemented: ngfDBTest
429#endif
430
431number ngfMapQ(number from, const coeffs aRing, const coeffs r)
432{
433  assume( getCoeffType(r) == ID );
434  assume( getCoeffType(aRing) == n_Q );
435 
436  if ( from != NULL )
437  {
438    gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF));
439    return (number)res;
440  }
441  else
442    return NULL;
443}
444
445static number ngfMapR(number from, const coeffs aRing, const coeffs r)
446{
447  assume( getCoeffType(r) == ID );
448  assume( getCoeffType(aRing) == n_R );
449 
450  if ( from != NULL )
451  {
452    gmp_float *res=new gmp_float((double)nrFloat(from));
453    return (number)res;
454  }
455  else
456    return NULL;
457}
458
459static number ngfMapP(number from, const coeffs aRing, const coeffs r)
460{
461  assume( getCoeffType(r) == ID );
462  assume( getCoeffType(aRing) ==  n_Zp );
463 
464  if ( from != NULL )
465    return ngfInit(npInt(from,src), dst);
466  else
467    return NULL;
468}
469
470static number ngfMapC(number from, const coeffs aRing, const coeffs r)
471{
472  assume( getCoeffType(r) == ID );
473  assume( getCoeffType(aRing) ==  n_long_C );
474 
475  if ( (from != NULL) || ((gmp_complex*)from)->real().isZero() )
476  {
477    gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
478    return (number)res;
479  }
480  else
481    return NULL;
482}
483
484nMapFunc ngfSetMap(const coeffs src, const coeffs dst)
485{
486  assume( getCoeffType(dst) == ID );
487 
488  if (nField_is_Q(src))
489  {
490    return ngfMapQ;
491  }
492  if (nField_is_long_R(src))
493  {
494    return ngfCopy;
495  }
496  if (nField_is_R(src))
497  {
498    return ngfMapR;
499  }
500  if (nField_is_long_C(src))
501  {
502    return ngfMapC;
503  }
504  if (nField_is_Zp(src))
505  {
506    return ngfMapP;
507  }
508  return NULL;
509}
510
511
Note: See TracBrowser for help on using the repository browser.