source: git/libpolys/coeffs/gnumpfl.cc @ 2e4ec14

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