source: git/libpolys/coeffs/shortfl.cc @ 777f8b

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