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

spielwiese
Last change on this file since ba5e9e was ba5e9e, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Changed configure-scripts to generate individual public config files for each package: resources, libpolys, singular (main) fix: sources should include correct corresponding config headers.
  • Property mode set to 100644
File size: 10.3 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
404BOOLEAN ngfInitChar(coeffs n, void *parameter)
405{
406  assume( getCoeffType(n) == ID );
407
408  n->cfKillChar = ndKillChar; /* dummy */
409
410  n->cfSetChar = ngfSetChar;
411  n->ch = 0;
412 
413  n->cfDelete  = ngfDelete;
414  n->cfNormalize=ndNormalize;
415  n->cfInit   = ngfInit;
416  n->cfInt    = ngfInt;
417  n->cfAdd     = ngfAdd;
418  n->cfSub     = ngfSub;
419  n->cfMult    = ngfMult;
420  n->cfDiv     = ngfDiv;
421  n->cfExactDiv= ngfDiv;
422  n->cfNeg     = ngfNeg;
423  n->cfInvers  = ngfInvers;
424  n->cfCopy   = ngfCopy;
425  n->cfGreater = ngfGreater;
426  n->cfEqual   = ngfEqual;
427  n->cfIsZero  = ngfIsZero;
428  n->cfIsOne   = ngfIsOne;
429  n->cfIsMOne  = ngfIsMOne;
430  n->cfGreaterZero = ngfGreaterZero;
431  n->cfWriteLong  = ngfWrite;
432  n->cfRead    = ngfRead;
433  n->cfPower   = ngfPower;
434  n->cfSetMap = ngfSetMap;
435  n->cfCoeffWrite = ngfCoeffWrite;
436  n->cfInit_bigint = ngfMapQ;
437#ifdef LDEBUG
438  n->cfDBTest  = ndDBTest; // not yet implemented: ngfDBTest
439#endif
440
441  n->nCoeffIsEqual = ngfCoeffIsEqual;
442
443  if( parameter != NULL)
444  {
445    LongComplexInfo* p = (LongComplexInfo*)parameter;
446     
447    n->float_len = p->float_len;
448    n->float_len2 = p->float_len2;
449  } else // default values, just for testing!
450  {
451    n->float_len = SHORT_REAL_LENGTH;
452    n->float_len2 = SHORT_REAL_LENGTH;
453  }
454   
455  assume( n->float_len <= n->float_len2 );
456  assume( n->float_len2 >= SHORT_REAL_LENGTH );
457 
458  assume( n_NumberOfParameters(n) == 0 );
459  assume( n_ParameterNames(n) == NULL );
460
461  return FALSE;
462}
463
464number ngfMapQ(number from, const coeffs src, const coeffs dst)
465{
466  assume( getCoeffType(dst) == ID );
467  assume( getCoeffType(src) == n_Q );
468 
469  gmp_float *res=new gmp_float(numberFieldToFloat(from,QTOF,dst));
470  return (number)res;
471}
472
473static number ngfMapR(number from, const coeffs src, const coeffs dst)
474{
475  assume( getCoeffType(dst) == ID );
476  assume( getCoeffType(src) == n_R );
477 
478  gmp_float *res=new gmp_float((double)nf(from).F());
479  return (number)res;
480}
481
482static number ngfMapP(number from, const coeffs src, const coeffs dst)
483{
484  assume( getCoeffType(dst) == ID );
485  assume( getCoeffType(src) ==  n_Zp );
486 
487  return ngfInit(npInt(from,src), dst);
488}
489
490static number ngfMapC(number from, const coeffs src, const coeffs dst)
491{
492  assume( getCoeffType(dst) == ID );
493  assume( getCoeffType(src) ==  n_long_C );
494 
495  gmp_float *res=new gmp_float(((gmp_complex*)from)->real());
496  return (number)res;
497}
498
499nMapFunc ngfSetMap(const coeffs src, const coeffs dst)
500{
501  assume( getCoeffType(dst) == ID );
502 
503  if (nCoeff_is_Q(src))
504  {
505    return ngfMapQ;
506  }
507  if (nCoeff_is_long_R(src))
508  {
509    return ndCopyMap; //ngfCopyMap;
510  }
511  if (nCoeff_is_R(src))
512  {
513    return ngfMapR;
514  }
515  if (nCoeff_is_long_C(src))
516  {
517    return ngfMapC;
518  }
519  if (nCoeff_is_Zp(src))
520  {
521    return ngfMapP;
522  }
523  return NULL;
524}
525
526
527void    ngfCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
528{
529  Print("//   characteristic : 0 (real:%d digits, additional %d digits)\n",
530               r->float_len,r->float_len2);  /* long R */
531}
Note: See TracBrowser for help on using the repository browser.