source: git/libpolys/coeffs/shortfl.cc @ 295424

fieker-DuValspielwiese
Last change on this file since 295424 was d276bb, checked in by Hans Schoenemann <hannes@…>, 3 years ago
compiler warnings
  • Property mode set to 100644
File size: 13.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/*
6* ABSTRACT: float as coeffs
7*/
8
9#include "misc/auxiliary.h"
10#include "misc/mylimits.h"
11
12#include "reporter/reporter.h"
13
14#include "coeffs/numbers.h"
15#include "coeffs/coeffs.h"
16#include "coeffs/mpr_complex.h"
17
18#include "coeffs/shortfl.h"
19#include "coeffs/longrat.h"
20
21//#include <string.h>
22#include <cmath>
23
24/// Get a mapping function from src into the domain of this type: n_R
25static nMapFunc nrSetMap(const coeffs src, const coeffs dst);
26
27// Where are the following used?
28static number nrMapQ(number from, const coeffs r, const coeffs aRing);
29
30static const SI_FLOAT nrEps = 1.0e-3;
31
32union nf
33{
34  SI_FLOAT _f;
35  number _n;
36
37  nf(SI_FLOAT f): _f(f){};
38
39  nf(number n): _n(n){};
40
41  inline SI_FLOAT F() const {return _f;}
42  inline number N() const {return _n;}
43};
44
45
46
47
48SI_FLOAT nrFloat(number n)
49{
50  return nf(n).F();
51}
52
53static BOOLEAN nrGreaterZero (number k, const coeffs r)
54{
55  assume( getCoeffType(r) == n_R );
56
57  return nf(k).F() >= 0.0;
58}
59
60static number nrMult (number a,number b, const coeffs r)
61{
62  assume( getCoeffType(r) == n_R );
63
64  return nf(nf(a).F() * nf(b).F()).N();
65}
66
67/*2
68* create a number from int
69*/
70static number nrInit (long i, const coeffs r)
71{
72  assume( getCoeffType(r) == n_R );
73
74  SI_FLOAT f = (SI_FLOAT)i;
75  return nf(nf(f).F()).N();
76}
77
78/*2
79* convert a number to int
80*/
81static long nrInt(number &n, const coeffs r)
82{
83  assume( getCoeffType(r) == n_R );
84
85  long i;
86  SI_FLOAT f = nf(n).F();
87  if (((SI_FLOAT)(-MAX_INT_VAL-1) <= f) || ((SI_FLOAT)MAX_INT_VAL >= f))
88    i = (long)f;
89  else
90    i = 0;
91  return i;
92}
93
94static number nrAdd (number a, number b, const coeffs r)
95{
96  assume( getCoeffType(r) == n_R );
97
98  SI_FLOAT x = nf(a).F();
99  SI_FLOAT y = nf(b).F();
100  SI_FLOAT f = x + y;
101  if (x > 0.0)
102  {
103    if (y < 0.0)
104    {
105      x = f / (x - y);
106      if (x < 0.0)
107        x = -x;
108      if (x < nrEps)
109        f = 0.0;
110    }
111  }
112  else
113  {
114    if (y > 0.0)
115    {
116      x = f / (y - x);
117      if (x < 0.0)
118        x = -x;
119      if (x < nrEps)
120        f = 0.0;
121    }
122  }
123  return nf(f).N();
124}
125
126static number nrSub (number a, number b, const coeffs r)
127{
128  assume( getCoeffType(r) == n_R );
129
130  SI_FLOAT x = nf(a).F();
131  SI_FLOAT y = nf(b).F();
132  SI_FLOAT f = x - y;
133  if (x > 0.0)
134  {
135    if (y > 0.0)
136    {
137      x = f / (x + y);
138      if (x < 0.0)
139        x = -x;
140      if (x < nrEps)
141        f = 0.0;
142    }
143  }
144  else
145  {
146    if (y < 0.0)
147    {
148      x = f / (x + y);
149      if (x < 0.0)
150        x = -x;
151      if (x < nrEps)
152        f = 0.0;
153    }
154  }
155  return nf(f).N();
156}
157
158static BOOLEAN nrIsZero (number  a, const coeffs r)
159{
160  assume( getCoeffType(r) == n_R );
161
162  return (0.0 == nf(a).F());
163}
164
165static BOOLEAN nrIsOne (number a, const coeffs r)
166{
167  assume( getCoeffType(r) == n_R );
168
169  SI_FLOAT aa=nf(a).F()-1.0;
170  if (aa<0.0) aa=-aa;
171  return (aa<nrEps);
172}
173
174static BOOLEAN nrIsMOne (number a, const coeffs r)
175{
176  assume( getCoeffType(r) == n_R );
177
178  SI_FLOAT aa=nf(a).F()+1.0;
179  if (aa<0.0) aa=-aa;
180  return (aa<nrEps);
181}
182
183static number nrDiv (number a,number b, const coeffs r)
184{
185  assume( getCoeffType(r) == n_R );
186
187  SI_FLOAT n = nf(b).F();
188  if (n == 0.0)
189  {
190    WerrorS(nDivBy0);
191    return nf((SI_FLOAT)0.0).N();
192  }
193  else
194    return nf(nf(a).F() / n).N();
195}
196
197static number nrInvers (number c, const coeffs r)
198{
199  assume( getCoeffType(r) == n_R );
200
201  SI_FLOAT n = nf(c).F();
202  if (n == 0.0)
203  {
204    WerrorS(nDivBy0);
205    return nf((SI_FLOAT)0.0).N();
206  }
207  return nf(1.0 / n).N();
208}
209
210static number nrNeg (number c, const coeffs r)
211{
212  assume( getCoeffType(r) == n_R );
213
214  return nf(-nf(c).F()).N();
215}
216
217static BOOLEAN nrGreater (number a,number b, const coeffs r)
218{
219  assume( getCoeffType(r) == n_R );
220
221  return nf(a).F() > nf(b).F();
222}
223
224static BOOLEAN nrEqual (number a,number b, const coeffs r)
225{
226  assume( getCoeffType(r) == n_R );
227
228  number x = nrSub(a,b,r);
229  return nf(x).F() == nf((SI_FLOAT)0.0).F();
230}
231
232static void nrWrite (number a, const coeffs r)
233{
234  assume( getCoeffType(r) == n_R );
235
236  //#if SIZEOF_DOUBLE == SIZEOF_LONG
237  //char ch[16];
238  //int n = sprintf(ch,"%12.6e", nf(a).F());
239  //#else
240  char ch[11];
241  int n = sprintf(ch,"%9.3e", nf(a).F());
242  //#endif
243  if (ch[0] == '-')
244  {
245    char* chbr = new char[n+3];
246    memcpy(&chbr[2],&ch[1],n-1);
247    chbr[0] = '-';
248    chbr[1] = '(';
249    chbr[n+1] = ')';
250    chbr[n+2] = '\0';
251    StringAppendS(chbr);
252    delete[] chbr;
253  }
254  else
255    StringAppend("(%s)",ch);
256}
257
258#if 0
259static void nrPower (number a, int i, number * result, const coeffs r)
260{
261  assume( getCoeffType(r) == n_R );
262
263  if (i==0)
264  {
265    *result = nf(nf(1.0).F()).N();
266    return;
267  }
268  if (i==1)
269  {
270    *result = nf(nf(a).F()).N();
271    return;
272  }
273  nrPower(a,i-1,result,r);
274  *result = nf(nf(a).F() * nf(*result).F()).N();
275}
276#endif
277
278namespace {
279  static const char* nrEatr(const char *s, SI_FLOAT *r)
280  {
281    int i;
282
283    if    (*s >= '0' && *s <= '9')
284    {
285      *r = 0.0;
286      do
287      {
288        *r *= 10.0;
289        i = *s++ - '0';
290        *r += (SI_FLOAT)i;
291      }
292      while (*s >= '0' && *s <= '9');
293    }
294    else *r = 1.0;
295    return s;
296  }
297}
298
299static const char * nrRead (const char *s, number *a, const coeffs r)
300{
301
302  assume( getCoeffType(r) == n_R );
303
304  static const char *nIllegalChar="illegal character in number";
305
306  const char *t;
307  const char *start=s;
308  SI_FLOAT z1,z2;
309  SI_FLOAT n=1.0;
310
311  s = nrEatr(s, &z1);
312  if (*s == '/')
313  {
314    if (s==start) { WerrorS(nIllegalChar);return s; }
315    s++;
316    s = nrEatr(s, &z2);
317    if (z2==0.0)
318      WerrorS(nDivBy0);
319    else
320      z1 /= z2;
321  }
322  else if (*s =='.')
323  {
324    if (s==start) { WerrorS(nIllegalChar);return s; }
325    s++;
326    t = s;
327    while (*t >= '0' && *t <= '9')
328    {
329      t++;
330      n *= 10.0;
331    }
332    s = nrEatr(s, &z2);
333    z1 = (z1*n + z2) / n;
334    if (*s=='e')
335    {
336      int e=0; /* exponent */
337      int si=1;/* sign of exponent */
338      s++;
339      if (*s=='+') s++;
340      else if (*s=='-') {s++; si=-1; }
341      while (*s >= '0' && *s <= '9')
342      {
343        e=e*10+(*s)-'0';
344        s++;
345      }
346      if (si==1)
347      {
348        while (e>0) {z1*=10.0; e--; }
349      }
350      else
351      {
352        while (e>0) {z1/=10.0; e--; }
353      }
354    }
355  }
356  *a = nf(z1).N();
357  return s;
358}
359
360
361// the last used charcteristic
362// int nrGetChar(){ return 0; }
363
364
365#ifdef LDEBUG
366/*2
367* test valid numbers: not implemented yet
368*/
369#pragma GCC diagnostic ignored "-Wunused-parameter"
370static BOOLEAN  nrDBTest(number a, const char *f, const int l, const coeffs r)
371{
372  assume( getCoeffType(r) == n_R );
373
374  return TRUE;
375}
376#endif
377
378static number nrMapP(number from, const coeffs aRing, const coeffs r)
379{
380  assume( getCoeffType(r) == n_R );
381  assume( getCoeffType(aRing) ==  n_Zp );
382
383  int i = (int)((long)from);
384  SI_FLOAT f = (SI_FLOAT)i;
385  return nf(f).N();
386}
387
388static number nrMapLongR(number from, const coeffs aRing, const coeffs r)
389{
390  assume( getCoeffType(r) == n_R );
391  assume( getCoeffType(aRing) == n_long_R );
392
393  SI_FLOAT t =(SI_FLOAT)mpf_get_d((mpf_srcptr)from);
394  return nf(t).N();
395}
396
397static number nrMapC(number from, const coeffs aRing, const coeffs r)
398{
399  assume( getCoeffType(r) == n_R );
400  assume( getCoeffType(aRing) == n_long_C );
401
402  gmp_float h = ((gmp_complex*)from)->real();
403  SI_FLOAT t =(SI_FLOAT)mpf_get_d((mpf_srcptr)&h);
404  return nf(t).N();
405}
406
407
408static number nrMapQ(number from, const coeffs aRing, const coeffs r)
409{
410/* in longrat.h
411#define SR_INT    1
412#define mpz_size1(A) (ABS((A)->_mp_size))
413*/
414#define SR_HDL(A) ((long)(A))
415#define IS_INT(A) ((A)->s==3)
416#define IS_IMM(A) (SR_HDL(A) & SR_INT)
417#define GET_NOM(A) ((A)->z)
418#define GET_DENOM(A) ((A)->n)
419
420  assume( getCoeffType(r) == n_R );
421  assume( aRing->rep == n_rep_gap_rat );
422
423  if (IS_IMM(from))
424  {
425    SI_FLOAT f = (SI_FLOAT)SR_TO_INT(from);
426    return nf(nf(f).F()).N();
427  }
428  else
429  {
430    /* read out the enumerator */
431    if (IS_INT(from))
432    {
433      mpf_t e;
434      mpf_init(e);
435      mpf_set_z(e,GET_NOM(from));
436      SI_FLOAT f = mpf_get_d(e);
437      mpf_clear(e);
438      return nf(nf(f).F()).N();
439    }
440    else /*quotient*/
441    {
442      mpf_t z,n,q;
443      mpf_init(z);
444      mpf_init(n);
445      mpf_init(q);
446      mpf_set_z(z,GET_NOM(from));
447      mpf_set_z(n,GET_DENOM(from));
448      mpf_div(q,z,n);
449      mpf_clear(z);
450      mpf_clear(n);
451      SI_FLOAT f = mpf_get_d(q);
452      mpf_clear(q);
453      return nf(nf(f).F()).N();
454    }
455  }
456}
457
458static number nrMapZ(number from, const coeffs aRing, const coeffs r)
459{
460  assume( getCoeffType(r) == n_R );
461  assume( aRing->rep == n_rep_gap_gmp );
462
463  mpz_ptr z;
464  mpz_ptr zz=NULL;
465  if (IS_IMM(from))
466  {
467     zz=(mpz_ptr)omAlloc(sizeof(mpz_t));
468     mpz_init_set_si(zz,SR_TO_INT(from));
469     z=zz;
470  }
471  else
472  {
473    /* read out the enumerator */
474    z=(mpz_ptr)from;
475  }
476
477  int i = mpz_size1(z);
478  mpf_t e;
479  mpf_init(e);
480  mpf_set_z(e,z);
481  int sign= mpf_sgn(e);
482  mpf_abs (e, e);
483
484  if (zz!=NULL)
485  {
486    mpz_clear(zz);
487    omFreeSize(zz,sizeof(mpz_t));
488  }
489  if(i>4)
490  {
491    WerrorS("float overflow");
492    return nf(0.0).N();
493  }
494  double basis;
495  signed long int exp;
496  basis = mpf_get_d_2exp(&exp, e);
497  SI_FLOAT f= sign*ldexp(basis,exp);
498  mpf_clear(e);
499  return nf(f).N();
500}
501
502// old version:
503// number nrMapQ(number from, const coeffs aRing, const coeffs r)
504// {
505// /* in longrat.h
506// #define SR_INT    1
507// #define mpz_size1(A) (ABS((A)->_mp_size))
508// */
509// #define SR_HDL(A) ((long)(A))
510// #define mpz_isNeg(A) ((A)->_mp_size<0)
511// #define mpz_limb_size(A) ((A)->_mp_size)
512// #define mpz_limb_d(A) ((A)->_mp_d)
513// #define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
514// #define IS_INT(A) ((A)->s==3)
515// #define IS_IMM(A) (SR_HDL(A)&SR_INT)
516// #define GET_NOM(A) ((A)->z)
517// #define GET_DENOM(A) ((A)->n)
518// #define MPZ_INIT mpz_init
519// #define MPZ_CLEAR mpz_clear
520
521//   assume( getCoeffType(r) == n_R );
522//   assume( getCoeffType(aRing) == n_Q );
523
524//   mpz_t h;
525//   mpz_ptr g,z,n;
526//   int i,j,t,s;
527//   SI_FLOAT ba,rr,rn,y;
528
529//   if (IS_IMM(from))
530//     return nf((SI_FLOAT)nlInt(from,NULL /* dummy for nlInt*/)).N();
531//   z=GET_NOM(from);
532//   s=0X10000;
533//   ba=(SI_FLOAT)s;
534//   ba*=ba;
535//   rr=0.0;
536//   i=mpz_size1(z);
537//   if(IS_INT(from))
538//   {
539//     if(i>4)
540//     {
541//       WerrorS("SI_FLOAT overflow");
542//       return nf(rr).N();
543//     }
544//     i--;
545//     rr=(SI_FLOAT)mpz_limb_d(z)[i];
546//     while(i>0)
547//     {
548//       i--;
549//       y=(SI_FLOAT)mpz_limb_d(z)[i];
550//       rr=rr*ba+y;
551//     }
552//     if(mpz_isNeg(z))
553//       rr=-rr;
554//     return nf(rr).N();
555//   }
556//   n=GET_DENOM(from);
557//   j=s=mpz_limb_size(n);
558//   if(j>i)
559//   {
560//     g=n; n=z; z=g;
561//     t=j; j=i; i=t;
562//   }
563//   t=i-j;
564//   if(t>4)
565//   {
566//     if(j==s)
567//       WerrorS("SI_FLOAT overflow");
568//     return nf(rr).N();
569//   }
570//   if(t>1)
571//   {
572//     g=h;
573//     MPZ_INIT(g);
574//     MPZ_DIV(g,z,n);
575//     t=mpz_size1(g);
576//     if(t>4)
577//     {
578//       MPZ_CLEAR(g);
579//       if(j==s)
580//         WerrorS("SI_FLOAT overflow");
581//       return nf(rr).N();
582//     }
583//     t--;
584//     rr=(SI_FLOAT)mpz_limb_d(g)[t];
585//     while(t)
586//     {
587//       t--;
588//       y=(SI_FLOAT)mpz_limb_d(g)[t];
589//       rr=rr*ba+y;
590//     }
591//     MPZ_CLEAR(g);
592//     if(j!=s)
593//       rr=1.0/rr;
594//     if(mpz_isNeg(z))
595//       rr=-rr;
596//     return nf(rr).N();
597//   }
598//   rn=(SI_FLOAT)mpz_limb_d(n)[j-1];
599//   rr=(SI_FLOAT)mpz_limb_d(z)[i-1];
600//   if(j>1)
601//   {
602//     rn=rn*ba+(SI_FLOAT)mpz_limb_d(n)[j-2];
603//     rr=rr*ba+(SI_FLOAT)mpz_limb_d(z)[i-2];
604//     i--;
605//   }
606//   if(t!=0)
607//     rr=rr*ba+(SI_FLOAT)mpz_limb_d(z)[i-2];
608//   if(j==s)
609//     rr=rr/rn;
610//   else
611//     rr=rn/rr;
612//   if(mpz_isNeg(z))
613//     rr=-rr;
614//   return nf(rr).N();
615// }
616
617static nMapFunc nrSetMap(const coeffs src, const coeffs dst)
618{
619  assume( getCoeffType(dst) == n_R );
620
621  if (src->rep==n_rep_gap_rat) /*Q, Z */
622  {
623    return nrMapQ;
624  }
625  if (src->rep==n_rep_gap_gmp) /*Q, Z */
626  {
627    return nrMapZ;
628  }
629  if ((src->rep==n_rep_gmp_float) && nCoeff_is_long_R(src))
630  {
631    return nrMapLongR;
632  }
633  if ((src->rep==n_rep_float) && nCoeff_is_R(src))
634  {
635    return ndCopyMap;
636  }
637  if ((src->rep==n_rep_int) && nCoeff_is_Zp(src))
638  {
639    return nrMapP;
640  }
641  if ((src->rep==n_rep_gmp_complex) && nCoeff_is_long_C(src))
642  {
643    return nrMapC;
644  }
645  return NULL;
646}
647
648static char* nrCoeffString(const coeffs r)
649{
650  return omStrDup("Float()");
651}
652
653static char* nrCoeffName(const coeffs r)
654{
655  return (char*)"Float()";
656}
657
658BOOLEAN nrInitChar(coeffs n, void* p)
659{
660  assume( getCoeffType(n) == n_R );
661
662  assume( p == NULL );
663
664  n->is_field=TRUE;
665  n->is_domain=TRUE;
666  n->rep=n_rep_float;
667
668  //n->cfKillChar = ndKillChar; /* dummy */
669  n->ch = 0;
670  n->cfCoeffName = nrCoeffName;
671
672  n->cfInit = nrInit;
673  n->cfInt  = nrInt;
674  n->cfAdd   = nrAdd;
675  n->cfSub   = nrSub;
676  n->cfMult  = nrMult;
677  n->cfDiv   = nrDiv;
678  n->cfExactDiv= nrDiv;
679  n->cfInpNeg   = nrNeg;
680  n->cfInvers= nrInvers;
681  //n->cfCopy  = ndCopy;
682  n->cfGreater = nrGreater;
683  n->cfEqual = nrEqual;
684  n->cfIsZero = nrIsZero;
685  n->cfIsOne = nrIsOne;
686  n->cfIsMOne = nrIsMOne;
687  n->cfGreaterZero = nrGreaterZero;
688  n->cfWriteLong = nrWrite;
689  n->cfRead = nrRead;
690  //n->cfPower = nrPower;
691  n->cfSetMap = nrSetMap;
692
693    /* nName= ndName; */
694    /*nSize  = ndSize;*/
695#ifdef LDEBUG
696  n->cfDBTest=nrDBTest; // not yet implemented: nrDBTest;
697#endif
698
699  //n->nCoeffIsEqual = ndCoeffIsEqual;
700
701  n->float_len = SHORT_REAL_LENGTH;
702  n->float_len2 = SHORT_REAL_LENGTH;
703
704  // TODO: Any variables?
705  return FALSE;
706}
Note: See TracBrowser for help on using the repository browser.