source: git/libpolys/coeffs/mpr_complex.cc @ d3c0a0

spielwiese
Last change on this file since d3c0a0 was d3c0a0, checked in by Adi Popescu <adi_popescum@…>, 10 years ago
bugfix: 64 bit Long/solve_l.tst
  • Property mode set to 100644
File size: 18.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4
5/*
6* ABSTRACT - multipolynomial resultants - real floating-point numbers using gmp
7*            and complex numbers based on pairs of real floating-point numbers
8*
9*/
10
11// WARNING! ALWAYS use omAlloc and FreeL when alloc. memory for some char* !!
12
13
14#include <misc/auxiliary.h>
15
16//#ifdef HAVE_MPR
17#include <coeffs/coeffs.h>
18#include <reporter/reporter.h>
19#include <omalloc/omalloc.h>
20#include <coeffs/numbers.h>
21#include <coeffs/longrat.h>
22#include <math.h>
23#include <coeffs/mpr_complex.h>
24
25//%s
26// this was copied form longrat0.cc
27// and will be used in numberToFloat.
28// Make sure that it is up to date!!
29#define SR_HDL(A) ((long)(A))
30#define SR_TO_INT(SR) (((long)SR) >> 2)
31
32#define SIGN_PLUS  1
33#define SIGN_SPACE 2
34#define SIGN_EMPTY 4
35
36#define EXTRABYTES 4
37
38#define DEFPREC        20         // minimum number of digits (output operations)
39size_t gmp_output_digits= DEFPREC;
40
41static gmp_float *gmpRel=NULL;
42static gmp_float *diff=NULL;
43
44
45/** Set size of mantissa
46 *  digits - the number of output digits (basis 10)
47 *  the size of mantissa consists of two parts:
48 *    the "output" part a and the "rest" part b.
49 *  According to the GMP-precision digits is
50 *  recomputed to bits (basis 2).
51 *  Two numbers a, b are equal if
52 *    | a - b | < | a | * 0.1^digits .
53 *  In this case we have a - b = 0 .
54 *  The epsilon e is e=0.1^(digits+rest) with
55 *  1+e != 1, but 1+0.1*e = 1.
56 */
57void setGMPFloatDigits( size_t digits, size_t rest )
58{
59  size_t bits = 1 + (size_t) ((float)digits * 3.5);
60  size_t rb = 1 + (size_t) ((float)rest * 3.5);
61  size_t db = bits+rb;
62  gmp_output_digits= digits;
63  mpf_set_default_prec( db );
64  if (diff!=NULL) delete diff;
65  diff=new gmp_float(0.0);
66  mpf_set_prec(*diff->_mpfp(),32);
67  if (gmpRel!=NULL) delete gmpRel;
68  gmpRel=new gmp_float(0.0);
69  mpf_set_prec(*gmpRel->_mpfp(),32);
70  mpf_set_d(*gmpRel->_mpfp(),0.1);
71  mpf_pow_ui(*gmpRel->_mpfp(),*gmpRel->_mpfp(),digits);
72}
73
74#if 1
75void gmp_float::setFromStr(const char * in )
76{
77  BOOLEAN neg=false;
78  if (*in == '-') { in++; neg=TRUE; }
79  char *s;
80  if ((s=strchr((char *)in,'E')) !=NULL)
81  {
82    *s='e';
83  }
84
85  // gmp doesn't understand number which begin with "." -- it needs 0.
86  // so, insert the zero
87  if (*in == '.')
88  {
89    int len = strlen(in)+2;
90    char* c_in = (char*) omAlloc(len);
91    *c_in = '0';
92    strcpy(&(c_in[1]), in);
93
94    if(mpf_set_str( t, c_in, 10 )!=0) WerrorS("syntax error in GMP float");
95    omFreeSize((void*)c_in, len);
96  }
97  else
98  {
99    if(mpf_set_str( t, in, 10 )!=0) WerrorS("syntax error in GMP float");
100  }
101  if (neg)  mpf_neg( t, t );
102}
103#else
104// problemns with solve_s.tst
105void gmp_float::setFromStr(const char * in )
106{
107  BOOLEAN neg=false;
108  BOOLEAN E_found=FALSE;
109  if (*in == '-') { in++; neg=TRUE; }
110  char *s;
111  if ((s=strchr(in,'E')) !=NULL)
112  {
113    *s='e';
114    E_found=TRUE;
115  }
116  // gmp doesn't understand number like 1e1, it need 1e+1
117  // so, insert the +
118  if (E_found ||((s=strchr(in,'e')) !=NULL))
119  {
120    if ((*(s+1)!='+') && (*(s+1)!='-'))
121    {
122      int len = strlen(in)+3;
123      char* c_in = (char*) omAlloc(len);
124      if (*in == '.')
125      {
126        *c_in = '0';
127        strcpy(&(c_in[1]), in);
128      }
129      else
130      {
131        strcpy(c_in, in);
132      }
133      char * ss=strchr(c_in,'e');
134      memmove(ss+2,s+1,strlen(s+1));
135      *(ss+1)+'+';
136
137      mpf_set_str( t, c_in, 10 );
138      omFreeSize((void*)c_in, len);
139    }
140  }
141
142  // gmp doesn't understand number which begin with "." -- it needs 0.
143  // so, insert the zero
144  else if (*in == '.')
145  {
146    int len = strlen(in)+2;
147    char* c_in = (char*) omAlloc(len);
148    *c_in = '0';
149    strcpy(&(c_in[1]), in);
150
151    mpf_set_str( t, c_in, 10 );
152    omFreeSize((void*)c_in, len);
153  }
154  else
155  {
156    mpf_set_str( t, in, 10 );
157  }
158  if (neg)  mpf_neg( t, t );
159}
160#endif
161
162
163// <gmp_float> = <gmp_float> operator <gmp_float>
164gmp_float operator + ( const gmp_float & a, const gmp_float & b )
165{
166  gmp_float tmp( a );
167  tmp += b;
168  return tmp;
169}
170gmp_float operator - ( const gmp_float & a, const gmp_float & b )
171{
172  gmp_float tmp( a );
173  tmp -= b;
174  return tmp;
175}
176gmp_float operator * ( const gmp_float & a, const gmp_float & b )
177{
178  gmp_float tmp( a );
179  tmp *= b;
180  return tmp;
181}
182gmp_float operator / ( const gmp_float & a, const gmp_float & b )
183{
184  gmp_float tmp( a );
185  tmp /= b;
186  return tmp;
187}
188
189// <gmp_float> operator <gmp_float>
190gmp_float & gmp_float::operator += ( const gmp_float & a )
191{
192  if (mpf_sgn(t) != -(mpf_sgn(a.t)))
193  {
194    mpf_add( t, t, a.t);
195    return *this;
196  }
197  if((mpf_sgn(a.t)==0) && (mpf_sgn(t)==0))
198  {
199    mpf_set_d( t, 0.0);
200    return *this;
201  }
202  mpf_add( t, t, a.t );
203  mpf_set(diff->t, t);
204  mpf_set_prec(diff->t, 32);
205  mpf_div(diff->t, diff->t, a.t);
206  mpf_abs(diff->t, diff->t);
207  if(mpf_cmp(diff->t, gmpRel->t) < 0)
208    mpf_set_d( t, 0.0);
209  return *this;
210}
211gmp_float & gmp_float::operator -= ( const gmp_float & a )
212{
213  if (mpf_sgn(t) != mpf_sgn(a.t))
214  {
215    mpf_sub( t, t, a.t);
216    return *this;
217  }
218  if((mpf_sgn(a.t)==0) && (mpf_sgn(t)==0))
219  {
220    mpf_set_d( t, 0.0);
221    return *this;
222  }
223  mpf_sub( t, t, a.t );
224  mpf_set(diff->t, t);
225  mpf_set_prec(diff->t, 32);
226  mpf_div(diff->t, diff->t, a.t);
227  mpf_abs(diff->t, diff->t);
228  if(mpf_cmp(diff->t, gmpRel->t) < 0)
229    mpf_set_d( t, 0.0);
230  return *this;
231}
232
233// <gmp_float> == <gmp_float> ??
234bool operator == ( const gmp_float & a, const gmp_float & b )
235{
236  if(mpf_sgn(a.t) != mpf_sgn(b.t))
237    return false;
238  if((mpf_sgn(a.t)==0) && (mpf_sgn(b.t)==0))
239    return true;
240  mpf_sub(diff->t, a.t, b.t);
241  mpf_div(diff->t, diff->t, a.t);
242  mpf_abs(diff->t, diff->t);
243  if(mpf_cmp(diff->t, gmpRel->t) < 0)
244    return true;
245  else
246    return false;
247}
248// t == 0 ?
249bool gmp_float::isZero() const
250{
251  return (mpf_sgn( t ) == 0);
252}
253// t == 1 ?
254bool gmp_float::isOne() const
255{
256#ifdef  VARIANTE_1
257  return (mpf_cmp_ui( t , 1 ) == 0);
258#else
259  if (mpf_sgn(t) <= 0)
260    return false;
261  mpf_sub_ui(diff->t, t, 1);
262  mpf_abs(diff->t, diff->t);
263  if(mpf_cmp(diff->t, gmpRel->t) < 0)
264    return true;
265  else
266    return false;
267#endif
268}
269// t == -1 ?
270bool gmp_float::isMOne() const
271{
272#ifdef VARIANTE_1
273  return (mpf_cmp_si( t , -1 ) == 0);
274#else
275  if (mpf_sgn(t) >= 0)
276    return false;
277  mpf_add_ui(diff->t, t, 1);
278  mpf_abs(diff->t, diff->t);
279  if(mpf_cmp(diff->t, gmpRel->t) < 0)
280    return true;
281  else
282    return false;
283#endif
284}
285bool operator > ( const gmp_float & a, const gmp_float & b )
286{
287  if (a.t == b.t)
288    return false;
289  return mpf_cmp( a.t, b.t ) > 0;
290}
291bool operator < ( const gmp_float & a, const gmp_float & b )
292{
293  if (a.t == b.t)
294    return false;
295  return mpf_cmp( a.t, b.t ) < 0;
296}
297bool operator >= ( const gmp_float & a, const gmp_float & b )
298{
299  if (a.t == b.t)
300    return true;
301  return mpf_cmp( a.t, b.t ) >= 0;
302}
303bool operator <= ( const gmp_float & a, const gmp_float & b )
304{
305  if (a.t == b.t)
306    return true;
307  return mpf_cmp( a.t, b.t ) <= 0;
308}
309
310// unary -
311gmp_float operator - ( const gmp_float & a )
312{
313  gmp_float tmp;
314  mpf_neg( *(tmp._mpfp()), *(a.mpfp()) );
315  return tmp;
316}
317
318gmp_float abs( const gmp_float & a )
319{
320  gmp_float tmp;
321  mpf_abs( *(tmp._mpfp()), *a.mpfp() );
322  return tmp;
323}
324gmp_float sqrt( const gmp_float & a )
325{
326  gmp_float tmp;
327  mpf_sqrt( *(tmp._mpfp()), *a.mpfp() );
328  return tmp;
329}
330gmp_float sin( const gmp_float & a )
331{
332  gmp_float tmp( sin((double)a) );
333  return tmp;
334}
335gmp_float cos( const gmp_float & a )
336{
337  gmp_float tmp( cos((double)a) );
338  return tmp;
339}
340gmp_float log( const gmp_float & a )
341{
342  gmp_float tmp( log((double)a) );
343  return tmp;
344}
345gmp_float hypot( const gmp_float & a, const gmp_float & b )
346{
347#if 1
348  return ( sqrt( (a*a) + (b*b) ) );
349#else
350  gmp_float tmp( hypot( (double)a, (double)b ) );
351  return tmp;
352#endif
353}
354gmp_float exp( const gmp_float & a )
355{
356  gmp_float tmp( exp((double)a) );
357  return tmp;
358}
359gmp_float max( const gmp_float & a, const gmp_float & b )
360{
361  gmp_float tmp;
362  a > b ? tmp= a : tmp= b;
363  return tmp;
364}
365//
366// number to float, number = Q, R, C
367// makes a COPY of num! (Ist das gut?)
368//
369gmp_float numberToFloat( number num, const coeffs src)
370{
371  gmp_float r;
372
373  if ( nCoeff_is_Q(src) )
374  {
375    if ( num != NULL )
376    {
377      if (SR_HDL(num) & SR_INT)
378      {
379        //n_Print(num, src);printf("\n");
380        int nn = SR_TO_INT(num);
381        if((long)nn == SR_TO_INT(num))
382            r = SR_TO_INT(num);
383        else
384            r = gmp_float(SR_TO_INT(num));
385        //int dd = 20;
386        //gmp_printf("\nr = %.*Ff\n",dd,*r.mpfp());
387        //getchar();
388      }
389      else
390      {
391        if ( num->s == 0 )
392        {
393          nlNormalize( num, src );
394        }
395        if (SR_HDL(num) & SR_INT)
396        {
397          r= SR_TO_INT(num);
398        }
399        else
400        {
401          if ( num->s != 3 )
402          {
403            r= num->z;
404            r/= (gmp_float)num->n;
405          }
406          else
407          {
408            r= num->z;
409          }
410        }
411      }
412    }
413    else
414    {
415      r= 0.0;
416    }
417  }
418  else if (nCoeff_is_long_R(src) || nCoeff_is_long_C(src))
419  {
420    r= *(gmp_float*)num;
421  }
422  else if ( nCoeff_is_R(src) )
423  {
424    // Add some code here :-)
425    WerrorS("Ground field not implemented!");
426  }
427  else
428  {
429    WerrorS("Ground field not implemented!");
430  }
431
432  return r;
433}
434
435gmp_float numberFieldToFloat( number num, int k, const coeffs src)
436{
437  gmp_float r;
438
439  switch (k)
440  {
441  case QTOF:
442    if ( num != NULL )
443    {
444      if (SR_HDL(num) & SR_INT)
445      {
446        int nn = SR_TO_INT(num);
447        if((long)nn == SR_TO_INT(num))
448            r = SR_TO_INT(num);
449        else
450            r = gmp_float(SR_TO_INT(num));
451      }
452      else
453      {
454        if ( num->s == 0 )
455        {
456          nlNormalize( num, src );
457        }
458        if (SR_HDL(num) & SR_INT)
459        {
460          r= SR_TO_INT(num);
461        }
462        else
463        {
464          if ( num->s != 3 )
465          {
466            r= num->z;
467            r/= (gmp_float)num->n;
468          }
469          else
470          {
471            r= num->z;
472          }
473        }
474      }
475    }
476    else
477    {
478      r= 0.0;
479    }
480    break;
481  case RTOF:
482    r= *(gmp_float*)num;
483    break;
484  case CTOF:
485    WerrorS("Can not map from field C to field R!");
486    break;
487  case ZTOF:
488  default:
489    WerrorS("Ground field not implemented!");
490  } // switch
491
492  return r;
493}
494
495// Do some strange things with the mantissa string and the exponent
496// to get some nice output string.
497char *nicifyFloatStr( char * in, mp_exp_t exponent, size_t oprec, int *size, int thesign )
498{
499  char *out;
500
501  int sign= (in[0] == '-') ? 1 : 0;
502  char csign[2];
503
504  switch (thesign)
505  {
506    case SIGN_PLUS:
507      sign ? strcpy(csign,"-") : strcpy(csign,"+");  //+123, -123
508      break;
509    case SIGN_SPACE:
510      sign ? strcpy(csign,"-") : strcpy(csign," ");  // 123, -123
511      break;
512    case SIGN_EMPTY:
513    default:
514      sign ? strcpy(csign,"-") : strcpy(csign,"");   //123, -123
515      break;
516  }
517
518  if ( strlen(in) == 0 )
519  {
520    *size= 2*sizeof(char);
521    return omStrDup("0");
522  }
523
524  if ( ((unsigned int)ABS(exponent) <= oprec)
525       /*|| (exponent+sign >= (int)strlen(in))*/ )
526  {
527    if ( exponent+sign < (int)strlen(in) )
528    {
529      int eexponent= (exponent >= 0) ? 0 : -exponent;
530      int eeexponent= (exponent >= 0) ? exponent : 0;
531      *size= (strlen(in)+15+eexponent) * sizeof(char);
532      out= (char*)omAlloc(*size);
533      memset(out,0,*size);
534
535      strcpy(out,csign);
536      strncat(out,in+sign,eeexponent);
537
538      if (exponent == 0)
539        strcat(out,"0.");
540      else if ( exponent > 0 )
541        strcat(out,".");
542      else
543      {
544        strcat(out,"0.");
545        memset(out+strlen(out),'0',eexponent);
546      }
547      strcat(out,in+sign+eeexponent);
548    }
549    else if ( exponent+sign > (int)strlen(in) )
550    {
551      *size= (strlen(in)+exponent+12)*sizeof(char);
552      out= (char*)omAlloc(*size);
553      memset(out,0,*size);
554      sprintf(out,"%s%s",csign,in+sign);
555      memset(out+strlen(out),'0',exponent-strlen(in)+sign);
556    }
557    else
558    {
559      *size= (strlen(in)+2) * sizeof(char) + 10;
560      out= (char*)omAlloc(*size);
561      memset(out,0,*size);
562      sprintf(out,"%s%s",csign,in+sign);
563    }
564  }
565  else
566  {
567//      if ( exponent > 0 )
568//      {
569      int c=1,d=10;
570      while ( exponent / d > 0 )
571      { // count digits
572        d*=10;
573        c++;
574      }
575      *size= (strlen(in)+12+c) * sizeof(char) + 10;
576      out= (char*)omAlloc(*size);
577      memset(out,0,*size);
578      sprintf(out,"%s0.%se%s%d",csign,in+sign,exponent>=0?"+":"",(int)exponent);
579//      }
580//      else
581//      {
582//        *size=2;
583//        out= (char*)omAlloc(*size);
584//        strcpy(out,"0");
585//      }
586  }
587  return out;
588}
589
590char *floatToStr( const gmp_float & r, const unsigned int oprec )
591{
592#if 1
593  mp_exp_t exponent;
594  int size,insize;
595  char *nout,*out,*in;
596
597  insize= (oprec+2) * sizeof(char) + 10;
598  in= (char*)omAlloc( insize );
599
600  mpf_get_str(in,&exponent,10,oprec,*(r.mpfp()));
601
602  if ( (exponent > 0)
603  && (exponent < (int)oprec)
604  && (strlen(in)-(in[0]=='-'?1:0) == oprec) )
605  {
606    omFree( (void *) in );
607    insize= (exponent+oprec+2) * sizeof(char) + 10;
608    in= (char*)omAlloc( insize );
609    int newprec= exponent+oprec;
610    mpf_get_str(in,&exponent,10,newprec,*(r.mpfp()));
611  }
612  nout= nicifyFloatStr( in, exponent, oprec, &size, SIGN_EMPTY );
613  omFree( (void *) in );
614  out= (char*)omAlloc( (strlen(nout)+1) * sizeof(char) );
615  strcpy( out, nout );
616  omFree( (void *) nout );
617
618  return out;
619#else
620  // for testing purpose...
621  char *out= (char*)omAlloc( (1024) * sizeof(char) );
622  sprintf(out,"% .10f",(double)r);
623  return out;
624#endif
625}
626//<-
627
628//-> gmp_complex::*
629// <gmp_complex> = <gmp_complex> operator <gmp_complex>
630//
631gmp_complex operator + ( const gmp_complex & a, const gmp_complex & b )
632{
633  return gmp_complex( a.r + b.r, a.i + b.i );
634}
635gmp_complex operator - ( const gmp_complex & a, const gmp_complex & b )
636{
637  return gmp_complex( a.r - b.r, a.i - b.i );
638}
639gmp_complex operator * ( const gmp_complex & a, const gmp_complex & b )
640{
641  return gmp_complex( a.r * b.r - a.i * b.i,
642                  a.r * b.i + a.i * b.r);
643}
644gmp_complex operator / ( const gmp_complex & a, const gmp_complex & b )
645{
646  gmp_float d = b.r*b.r + b.i*b.i;
647  return gmp_complex( (a.r * b.r + a.i * b.i) / d,
648                (a.i * b.r - a.r * b.i) / d);
649}
650
651// <gmp_complex> operator <gmp_complex>
652//
653gmp_complex & gmp_complex::operator += ( const gmp_complex & b )
654{
655  r+=b.r;
656  i+=b.i;
657  return *this;
658}
659gmp_complex & gmp_complex::operator -= ( const gmp_complex & b )
660{
661  r-=b.r;
662  i-=b.i;
663  return *this;
664}
665gmp_complex & gmp_complex::operator *= ( const gmp_complex & b )
666{
667  gmp_float f = r * b.r - i * b.i;
668  i = r * b.i + i * b.r;
669  r = f;
670  return *this;
671}
672gmp_complex & gmp_complex::neg ( )
673{
674  i.neg();
675  r.neg();
676  return *this;
677}
678gmp_complex & gmp_complex::operator /= ( const gmp_complex & b )
679{
680  gmp_float d = b.r*b.r + b.i*b.i;
681  r = (r * b.r + i * b.i) / d;
682  i = (i * b.r - r * b.i) / d;
683  return *this;
684}
685
686// Returns square root of gmp_complex number
687//
688gmp_complex sqrt( const gmp_complex & x )
689{
690  gmp_float r = abs(x);
691  gmp_float nr, ni;
692  if (r == (gmp_float) 0.0)
693  {
694    nr = ni = r;
695  }
696  else if ( x.real() > (gmp_float)0)
697  {
698    nr = sqrt((gmp_float)0.5 * (r + x.real()));
699    ni = x.imag() / nr / (gmp_float)2;
700  }
701  else
702  {
703    ni = sqrt((gmp_float)0.5 * (r - x.real()));
704    if (x.imag() < (gmp_float)0)
705    {
706      ni = - ni;
707    }
708    nr = x.imag() / ni / (gmp_float)2;
709  }
710  gmp_complex tmp(nr, ni);
711  return tmp;
712}
713
714// converts a gmp_complex to a string ( <real part> + I * <imaginary part> )
715//
716char *complexToStr( gmp_complex & c, const unsigned int oprec, const coeffs src )
717{
718  const char * complex_parameter = "I";
719  int N = 1; // strlen(complex_parameter);
720   
721  if (nCoeff_is_long_C(src))
722  {
723    complex_parameter = n_ParameterNames(src)[0];
724    N = strlen(complex_parameter);
725  }
726
727  assume( complex_parameter != NULL && N > 0);
728 
729  char *out,*in_imag,*in_real;
730
731  c.SmallToZero();
732  if ( !c.imag().isZero() )
733  {
734
735    in_real=floatToStr( c.real(), oprec );         // get real part
736    in_imag=floatToStr( abs(c.imag()), oprec );    // get imaginary part
737
738    if (nCoeff_is_long_C(src))
739    {
740      int len=(strlen(in_real)+strlen(in_imag)+7+N)*sizeof(char);
741      out=(char*)omAlloc(len);
742      memset(out,0,len);
743      if (  !c.real().isZero() )  // (-23-i*5.43) or (15.1+i*5.3)
744        sprintf(out,"(%s%s%s*%s)",in_real,c.imag().sign()>=0?"+":"-",complex_parameter,in_imag);
745      else // (-i*43) or (i*34)
746      {
747        if (c.imag().isOne())
748          sprintf(out,"%s", complex_parameter);
749        else if (c.imag().isMOne())
750          sprintf(out,"-%s", complex_parameter);
751        else
752          sprintf(out,"(%s%s*%s)",c.imag().sign()>=0?"":"-", complex_parameter,in_imag);
753      }
754    }
755    else
756    {
757      int len=(strlen(in_real)+strlen(in_imag)+9) * sizeof(char);
758      out=(char*)omAlloc( len );
759      memset(out,0,len);
760      if ( !c.real().isZero() )
761        sprintf(out,"(%s%s%s)",in_real,c.imag().sign()>=0?"+I*":"-I*",in_imag);
762      else
763        sprintf(out,"(%s%s)",c.imag().sign()>=0?"I*":"-I*",in_imag);
764    }
765    omFree( (void *) in_real );
766    omFree( (void *) in_imag );
767  }
768  else
769  {
770    out= floatToStr( c.real(), oprec );
771  }
772
773  return out;
774}
775//<-
776
777bool complexNearZero( gmp_complex * c, int digits )
778{
779  gmp_float eps,epsm;
780
781  if ( digits < 1 ) return true;
782
783  eps=pow(10.0,(int)digits);
784  //Print("eps: %s\n",floatToStr(eps,gmp_output_digits));
785  eps=(gmp_float)1.0/eps;
786  epsm=-eps;
787
788  //Print("eps: %s\n",floatToStr(eps,gmp_output_digits));
789
790  if ( c->real().sign() > 0 ) // +
791    return (c->real() < eps && (c->imag() < eps && c->imag() > epsm));
792  else // -
793    return (c->real() > epsm && (c->imag() < eps && c->imag() > epsm));
794}
795
796void gmp_complex::SmallToZero()
797{
798  gmp_float ar=this->real();
799  gmp_float ai=this->imag();
800  if (ar.isZero() || ai.isZero()) return;
801  mpf_abs(*ar._mpfp(), *ar._mpfp());
802  mpf_abs(*ai._mpfp(), *ai._mpfp());
803  mpf_set_prec(*ar._mpfp(), 32);
804  mpf_set_prec(*ai._mpfp(), 32);
805  if (ar > ai)
806  {
807    mpf_div(*ai._mpfp(), *ai._mpfp(), *ar._mpfp());
808    if (ai < *gmpRel) this->imag(0.0);
809  }
810  else
811  {
812    mpf_div(*ar._mpfp(), *ar._mpfp(), *ai._mpfp());
813    if (ar < *gmpRel) this->real(0.0);
814  }
815}
816
817//%e
818
819//#endif // HAVE_MPR
820
821// local Variables: ***
822// folded-file: t ***
823// compile-command-1: "make installg" ***
824// compile-command-2: "make install" ***
825// End: ***
Note: See TracBrowser for help on using the repository browser.