source: git/coeffs/shortfl.cc @ 210852

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