source: git/libpolys/coeffs/shortfl.cc @ 6ce030f

spielwiese
Last change on this file since 6ce030f was cffd3e, checked in by Hans Schoenemann <hannes@…>, 12 years ago
fix: ringlist with real/complex
  • Property mode set to 100644
File size: 10.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/*
6* ABSTRACT:
7*/
8
9#include <coeffs/shortfl.h>
10
11#include <string.h>
12#include <coeffs/coeffs.h>
13#include <coeffs/numbers.h>
14#include <reporter/reporter.h>
15#include <coeffs/numbers.h>
16#include <coeffs/longrat.h>
17#include <coeffs/mpr_complex.h>
18
19#include <misc/mylimits.h>
20
21/// Our Type!
22static const n_coeffType ID = n_R;
23
24static const float nrEps = 1.0e-3;
25
26union nf
27{
28  float _f;
29  number _n;
30
31  nf(float f): _f(f){};
32
33  nf(number n): _n(n){};
34
35  inline float F() const {return _f;}
36  inline number N() const {return _n;}
37};
38
39
40
41
42float nrFloat(number n)
43{
44  return nf(n).F();
45}
46
47
48void    nrCoeffWrite  (const coeffs r, BOOLEAN /*details*/)
49{
50  assume( getCoeffType(r) == ID );
51  PrintS("//   characteristic : 0 (real)\n");  /* R */
52}
53
54
55BOOLEAN nrGreaterZero (number k, const coeffs r)
56{
57  assume( getCoeffType(r) == ID );
58
59  return nf(k).F() >= 0.0;
60}
61
62number nrMult (number a,number b, const coeffs r)
63{
64  assume( getCoeffType(r) == ID );
65
66  return nf(nf(a).F() * nf(b).F()).N();
67}
68
69/*2
70* create a number from int
71*/
72number nrInit (long i, const coeffs r)
73{
74  assume( getCoeffType(r) == ID );
75
76  float f = (float)i;
77  return nf(nf(f).F()).N();
78}
79
80/*2
81* convert a number to int
82*/
83int nrInt(number &n, const coeffs r)
84{
85  assume( getCoeffType(r) == ID );
86
87  int i;
88  float f = nf(n).F();
89  if (((float)(-MAX_INT_VAL-1) <= f) || ((float)MAX_INT_VAL >= f))
90    i = (int)f;
91  else
92    i = 0;
93  return i;
94}
95
96int nrSize(number n, const coeffs)
97{
98  float f = nf(n).F();
99  int i = (int)f;
100  /* basically return the largest integer in n;
101     only if this happens to be zero although n != 0,
102     return 1;
103     (this code ensures that zero has the size zero) */
104  if ((f != 0.0) & (i == 0)) i = 1;
105  return i;
106}
107
108number nrAdd (number a, number b, const coeffs r)
109{
110  assume( getCoeffType(r) == ID );
111
112  float x = nf(a).F();
113  float y = nf(b).F();
114  float f = x + y;
115  if (x > 0.0)
116  {
117    if (y < 0.0)
118    {
119      x = f / (x - y);
120      if (x < 0.0)
121        x = -x;
122      if (x < nrEps)
123        f = 0.0;
124    }
125  }
126  else
127  {
128    if (y > 0.0)
129    {
130      x = f / (y - x);
131      if (x < 0.0)
132        x = -x;
133      if (x < nrEps)
134        f = 0.0;
135    }
136  }
137  return nf(f).N();
138}
139
140number nrSub (number a, number b, const coeffs r)
141{
142  assume( getCoeffType(r) == ID );
143
144  float x = nf(a).F();
145  float y = nf(b).F();
146  float f = x - y;
147  if (x > 0.0)
148  {
149    if (y > 0.0)
150    {
151      x = f / (x + y);
152      if (x < 0.0)
153        x = -x;
154      if (x < nrEps)
155        f = 0.0;
156    }
157  }
158  else
159  {
160    if (y < 0.0)
161    {
162      x = f / (x + y);
163      if (x < 0.0)
164        x = -x;
165      if (x < nrEps)
166        f = 0.0;
167    }
168  }
169  return nf(f).N();
170}
171
172BOOLEAN nrIsZero (number  a, const coeffs r)
173{
174  assume( getCoeffType(r) == ID );
175
176  return (0.0 == nf(a).F());
177}
178
179BOOLEAN nrIsOne (number a, const coeffs r)
180{
181  assume( getCoeffType(r) == ID );
182
183  float aa=nf(a).F()-1.0;
184  if (aa<0.0) aa=-aa;
185  return (aa<nrEps);
186}
187
188BOOLEAN nrIsMOne (number a, const coeffs r)
189{
190  assume( getCoeffType(r) == ID );
191
192  float aa=nf(a).F()+1.0;
193  if (aa<0.0) aa=-aa;
194  return (aa<nrEps);
195}
196
197number nrDiv (number a,number b, const coeffs r)
198{
199  assume( getCoeffType(r) == ID );
200
201  float n = nf(b).F();
202  if (n == 0.0)
203  {
204    WerrorS(nDivBy0);
205    return nf((float)0.0).N();
206  }
207  else
208    return nf(nf(a).F() / n).N();
209}
210
211number  nrInvers (number c, const coeffs r)
212{
213  assume( getCoeffType(r) == ID );
214
215  float n = nf(c).F();
216  if (n == 0.0)
217  {
218    WerrorS(nDivBy0);
219    return nf((float)0.0).N();
220  }
221  return nf(1.0 / n).N();
222}
223
224number nrNeg (number c, const coeffs r)
225{
226  assume( getCoeffType(r) == ID );
227
228  return nf(-nf(c).F()).N();
229}
230
231BOOLEAN nrGreater (number a,number b, const coeffs r)
232{
233  assume( getCoeffType(r) == ID );
234
235  return nf(a).F() > nf(b).F();
236}
237
238BOOLEAN nrEqual (number a,number b, const coeffs r)
239{
240  assume( getCoeffType(r) == ID );
241
242  number x = nrSub(a,b,r);
243  return nf(x).F() == nf((float)0.0).F();
244}
245
246void nrWrite (number &a, const coeffs r)
247{
248  assume( getCoeffType(r) == ID );
249
250  StringAppend("%9.3e", nf(a).F());
251}
252
253void nrPower (number a, int i, number * result, const coeffs r)
254{
255  assume( getCoeffType(r) == ID );
256
257  if (i==0)
258  {
259    *result = nf(nf(1.0).F()).N();
260    return;
261  }
262  if (i==1)
263  {
264    *result = nf(nf(a).F()).N();
265    return;
266  }
267  nrPower(a,i-1,result,r);
268  *result = nf(nf(a).F() * nf(*result).F()).N();
269}
270
271namespace {
272  static const char* nrEatr(const char *s, float *r)
273  {
274    int i;
275
276    if    (*s >= '0' && *s <= '9')
277    {
278      *r = 0.0;
279      do
280      {
281        *r *= 10.0;
282        i = *s++ - '0';
283        *r += (float)i;
284      }
285      while (*s >= '0' && *s <= '9');
286    }
287    else *r = 1.0;
288    return s;
289  }
290}
291
292const char * nrRead (const char *s, number *a, const coeffs r)
293{
294
295  assume( getCoeffType(r) == ID );
296
297  static const char *nIllegalChar="illegal character in number";
298
299  const char *t;
300  const char *start=s;
301  float z1,z2;
302  float n=1.0;
303
304  s = nrEatr(s, &z1);
305  if (*s == '/')
306  {
307    if (s==start) { WerrorS(nIllegalChar);return s; }
308    s++;
309    s = nrEatr(s, &z2);
310    if (z2==0.0)
311      WerrorS(nDivBy0);
312    else
313      z1 /= z2;
314  }
315  else if (*s =='.')
316  {
317    if (s==start) { WerrorS(nIllegalChar);return s; }
318    s++;
319    t = s;
320    while (*t >= '0' && *t <= '9')
321    {
322      t++;
323      n *= 10.0;
324    }
325    s = nrEatr(s, &z2);
326    z1 = (z1*n + z2) / n;
327    if (*s=='e')
328    {
329      int e=0; /* exponent */
330      int si=1;/* sign of exponent */
331      s++;
332      if (*s=='+') s++;
333      else if (*s=='-') {s++; si=-1; }
334      while (*s >= '0' && *s <= '9')
335      {
336        e=e*10+(*s)-'0';
337        s++;
338      }
339      if (si==1)
340      {
341        while (e>0) {z1*=10.0; e--; }
342      }
343      else
344      {
345        while (e>0) {z1/=10.0; e--; }
346      }
347    }
348  }
349  *a = nf(z1).N();
350  return s;
351}
352
353
354// the last used charcteristic
355// int nrGetChar(){ return 0; }
356
357
358#ifdef LDEBUG
359/*2
360* test valid numbers: not implemented yet
361*/
362#pragma GCC diagnostic ignored "-Wunused-parameter"
363BOOLEAN  nrDBTest(number a, const char *f, const int l, const coeffs r)
364{
365  assume( getCoeffType(r) == ID );
366
367  return TRUE;
368}
369#endif
370
371static number nrMapP(number from, const coeffs aRing, const coeffs r)
372{
373  assume( getCoeffType(r) == ID );
374  assume( getCoeffType(aRing) ==  n_Zp );
375 
376  int i = (int)((long)from);
377  float f = (float)i;
378  return nf(f).N();
379}
380
381static number nrMapLongR(number from, const coeffs aRing, const coeffs r)
382{
383  assume( getCoeffType(r) == ID );
384  assume( getCoeffType(aRing) == n_long_R );
385
386  float t =(float)mpf_get_d((mpf_srcptr)from);
387  return nf(t).N();
388}
389
390static number nrMapC(number from, const coeffs aRing, const coeffs r)
391{ 
392  assume( getCoeffType(r) == ID );
393  assume( getCoeffType(aRing) == n_long_C );
394 
395  gmp_float h = ((gmp_complex*)from)->real();
396  float t =(float)mpf_get_d((mpf_srcptr)&h);
397  return nf(t).N();
398}
399
400
401number nrMapQ(number from, const coeffs aRing, const coeffs r)
402{
403/* in longrat.h
404#define SR_INT    1
405#define mpz_size1(A) (ABS((A)->_mp_size))
406*/
407#define SR_HDL(A) ((long)(A))
408#define mpz_isNeg(A) ((A)->_mp_size<0)
409#define mpz_limb_size(A) ((A)->_mp_size)
410#define mpz_limb_d(A) ((A)->_mp_d)
411#define MPZ_DIV(A,B,C) mpz_tdiv_q((A),(B),(C))
412#define IS_INT(A) ((A)->s==3)
413#define IS_IMM(A) (SR_HDL(A)&SR_INT)
414#define GET_NOM(A) ((A)->z)
415#define GET_DENOM(A) ((A)->n)
416#define MPZ_INIT mpz_init
417#define MPZ_CLEAR mpz_clear
418
419  assume( getCoeffType(r) == ID );
420  assume( getCoeffType(aRing) == n_Q );
421
422  mpz_t h;
423  mpz_ptr g,z,n;
424  int i,j,t,s;
425  float ba,rr,rn,y;
426
427  if (IS_IMM(from))
428    return nf((float)nlInt(from,NULL /* dummy for nlInt*/)).N();
429  z=GET_NOM(from);
430  s=0X10000;
431  ba=(float)s;
432  ba*=ba;
433  rr=0.0;
434  i=mpz_size1(z);
435  if(IS_INT(from))
436  {
437    if(i>4)
438    {
439      WerrorS("float overflow");
440      return nf(rr).N();
441    }
442    i--;
443    rr=(float)mpz_limb_d(z)[i];
444    while(i>0)
445    {
446      i--;
447      y=(float)mpz_limb_d(z)[i];
448      rr=rr*ba+y;
449    }
450    if(mpz_isNeg(z))
451      rr=-rr;
452    return nf(rr).N();
453  }
454  n=GET_DENOM(from);
455  j=s=mpz_limb_size(n);
456  if(j>i)
457  {
458    g=n; n=z; z=g;
459    t=j; j=i; i=t;
460  }
461  t=i-j;
462  if(t>4)
463  {
464    if(j==s)
465      WerrorS("float overflow");
466    return nf(rr).N();
467  }
468  if(t>1)
469  {
470    g=h;
471    MPZ_INIT(g);
472    MPZ_DIV(g,z,n);
473    t=mpz_size1(g);
474    if(t>4)
475    {
476      MPZ_CLEAR(g);
477      if(j==s)
478        WerrorS("float overflow");
479      return nf(rr).N();
480    }
481    t--;
482    rr=(float)mpz_limb_d(g)[t];
483    while(t)
484    {
485      t--;
486      y=(float)mpz_limb_d(g)[t];
487      rr=rr*ba+y;
488    }
489    MPZ_CLEAR(g);
490    if(j!=s)
491      rr=1.0/rr;
492    if(mpz_isNeg(z))
493      rr=-rr;
494    return nf(rr).N();
495  }
496  rn=(float)mpz_limb_d(n)[j-1];
497  rr=(float)mpz_limb_d(z)[i-1];
498  if(j>1)
499  {
500    rn=rn*ba+(float)mpz_limb_d(n)[j-2];
501    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
502    i--;
503  }
504  if(t!=0)
505    rr=rr*ba+(float)mpz_limb_d(z)[i-2];
506  if(j==s)
507    rr=rr/rn;
508  else
509    rr=rn/rr;
510  if(mpz_isNeg(z))
511    rr=-rr;
512  return nf(rr).N();
513}
514
515
516nMapFunc nrSetMap(const coeffs src, const coeffs dst)
517{
518  assume( getCoeffType(dst) == ID );
519
520  if (nCoeff_is_Q(src))
521  {
522    return nrMapQ;
523  }
524  if (nCoeff_is_long_R(src))
525  {
526    return nrMapLongR;
527  }
528  if (nCoeff_is_R(src))
529  {
530    return ndCopyMap;
531  }
532  if(nCoeff_is_Zp(src))
533  {
534    return nrMapP;
535  }
536  if (nCoeff_is_long_C(src))
537  {
538    return nrMapC;
539  }
540  return NULL;
541}
542
543BOOLEAN nrInitChar(coeffs n, void* p)
544{
545  assume( getCoeffType(n) == ID );
546   
547  assume( p == NULL );
548   
549  n->cfKillChar = ndKillChar; /* dummy */
550  n->ch = 0;
551
552  n->cfInit = nrInit;
553  n->cfInt  = nrInt;
554  n->cfAdd   = nrAdd;
555  n->cfSub   = nrSub;
556  n->cfMult  = nrMult;
557  n->cfDiv   = nrDiv;
558  n->cfExactDiv= nrDiv;
559  n->cfNeg   = nrNeg;
560  n->cfInvers= nrInvers;
561  n->cfCopy  = ndCopy;
562  n->cfGreater = nrGreater;
563  n->cfEqual = nrEqual;
564  n->cfIsZero = nrIsZero;
565  n->cfIsOne = nrIsOne;
566  n->cfIsMOne = nrIsMOne;
567  n->cfGreaterZero = nrGreaterZero;
568  n->cfWriteLong = nrWrite;
569  n->cfRead = nrRead;
570  n->cfPower = nrPower;
571  n->cfSetMap = nrSetMap;
572  n->cfCoeffWrite  = nrCoeffWrite;
573  n->cfInit_bigint = nrMapQ;
574
575    /* nName= ndName; */
576    /*nSize  = ndSize;*/
577#ifdef LDEBUG
578  n->cfDBTest=ndDBTest; // not yet implemented: nrDBTest;
579#endif
580 
581  n->nCoeffIsEqual = ndCoeffIsEqual;
582
583  n->float_len = SHORT_REAL_LENGTH;
584  n->float_len2 = SHORT_REAL_LENGTH;
585   
586  // TODO: Any variables?
587  return FALSE;
588}
Note: See TracBrowser for help on using the repository browser.