source: git/coeffs/gnumpfl.cc @ 37d318

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