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

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