source: git/kernel/gnumpc.cc @ b7e838

spielwiese
Last change on this file since b7e838 was b7e838, checked in by Hans Schönemann <hannes@…>, 17 years ago
*hannes: test division by 0 git-svn-id: file:///usr/local/Singular/svn/trunk@10159 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 7.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: gnumpc.cc,v 1.4 2007-07-03 14:45:56 Singular Exp $ */
5/*
6* ABSTRACT: computations with GMP complex floating-point numbers
7*
8* ngc == number gnu complex
9*/
10
11#include "mod2.h"
12#include "structs.h"
13#include "febase.h"
14#include "omalloc.h"
15#include "numbers.h"
16#include "longrat.h"
17#include "modulop.h"
18#include "gnumpc.h"
19#include "gnumpfl.h"
20#include "mpr_complex.h"
21
22extern size_t gmp_output_digits;
23
24
25static number ngcMapQ(number from)
26{
27  if ( from != NULL )
28  {
29    gmp_complex *res=new gmp_complex(numberFieldToFloat(from,QTOF));
30    return (number)res;
31  }
32  else
33    return NULL;
34}
35union nf
36{
37  float _f;
38  number _n;
39  nf(float f) {_f = f;}
40  nf(number n) {_n = n;}
41  float F() const {return _f;}
42  number N() const {return _n;}
43};
44static number ngcMapLongR(number from)
45{
46  if ( from != NULL )
47  {
48    gmp_complex *res=new gmp_complex(*((gmp_float *)from));
49    return (number)res;
50  }
51  else
52    return NULL;
53}
54static number ngcMapR(number from)
55{
56  if ( from != NULL )
57  {
58    gmp_complex *res=new gmp_complex((double)nf(from).F());
59    return (number)res;
60  }
61  else
62    return NULL;
63}
64static number ngcMapP(number from)
65{
66  if ( from != NULL)
67    return ngcInit(npInt(from));
68  else
69    return NULL;
70}
71
72nMapFunc ngcSetMap(ring src,ring dst)
73{
74  if(rField_is_Q(src))
75  {
76    return ngcMapQ;
77  }
78  if (rField_is_long_R(src))
79  {
80    return ngcMapLongR;
81  }
82  if (rField_is_long_C(src))
83  {
84    return ngcCopy;
85  }
86  if(rField_is_R(src))
87  {
88    return ngcMapR;
89  }
90  if (rField_is_Zp(src))
91  {
92    return ngcMapP;
93  }
94  return NULL;
95}
96
97number   ngcPar(int i)
98{
99  gmp_complex* n= new gmp_complex( (long)0, (long)1 );
100  return (number)n;
101}
102
103void ngcNew (number * r)
104{
105  *r=NULL;
106}
107
108/*2
109* n := i
110*/
111number ngcInit (int i)
112{
113  gmp_complex* n= NULL;
114  if ( i != 0 )
115  {
116    n= new gmp_complex( (long)i, (long)0 );
117  }
118  return (number)n;
119}
120
121/*2
122* convert number to int
123*/
124int ngcInt(number &i)
125{
126  if ( i == NULL ) return 0;
127  return (int)((gmp_complex*)i)->real();
128}
129
130/*2
131* delete a
132*/
133void ngcDelete (number * a, const ring r)
134{
135  if ( *a != NULL ) {
136    delete *(gmp_complex**)a;
137    *a=NULL;
138  }
139}
140
141/*2
142* copy a to b
143*/
144number ngcCopy(number a)
145{
146  gmp_complex* b= NULL;
147  if ( a !=  NULL )
148  {
149    b= new gmp_complex( *(gmp_complex*)a );
150  }
151  return (number)b;
152}
153number ngc_Copy(number a, ring r)
154{
155  gmp_complex* b= NULL;
156  if ( a !=  NULL )
157  {
158    b= new gmp_complex( *(gmp_complex*)a );
159  }
160  return (number)b;
161}
162
163/*2
164* za:= - za
165*/
166gmp_complex ngc_m1(-1);
167
168number ngcNeg (number a)
169{
170  if ( a == NULL ) return NULL;
171  gmp_complex* r=(gmp_complex*)a;
172  (*r) *= ngc_m1;
173  return (number)a;
174}
175
176/*
177* 1/a
178*/
179number ngcInvers(number a)
180{
181  gmp_complex* r = NULL;
182  if ( (a==NULL)
183  || (((gmp_complex*)a)->isZero()))
184  {
185    WerrorS(nDivBy0);
186  }
187  else
188  {
189    r= new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
190  }
191  return (number)r;
192}
193
194/*2
195* u:= a + b
196*/
197number ngcAdd (number a, number b)
198{
199  gmp_complex* r= NULL;
200  if ( a==NULL && b==NULL )
201  {
202    return NULL;
203  }
204  else if ( a == NULL )
205  {
206    r= new gmp_complex( *(gmp_complex*)b );
207  }
208  else if ( b == NULL )
209  {
210    r= new gmp_complex( *(gmp_complex*)a );
211  }
212  else
213  {
214    r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
215  }
216  return (number)r;
217}
218
219/*2
220* u:= a - b
221*/
222number ngcSub (number a, number b)
223{
224  gmp_complex* r= NULL;
225  if ( a==NULL && b==NULL )
226  {
227    return NULL;
228  }
229  else if ( a == NULL )
230  {
231    r= new gmp_complex( (*(gmp_complex*)b) );
232    r= (gmp_complex *)ngcNeg((number)r);
233  }
234  else if ( b == NULL )
235  {
236    r= new gmp_complex( *(gmp_complex*)a );
237  }
238  else
239  {
240    r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
241  }
242  return (number)r;
243}
244
245/*2
246* u := a * b
247*/
248number ngcMult (number a, number b)
249{
250  gmp_complex* r= NULL;
251  if ( a==NULL || b==NULL )
252  {
253    return NULL;
254  }
255  else
256  {
257    r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
258  }
259  return (number)r;
260}
261
262/*2
263* u := a / b
264*/
265number ngcDiv (number a, number b)
266{
267  if ( a==NULL )
268  {
269    // 0/b = 0
270    return NULL;
271  }
272  else if (( b==NULL )
273  || (((gmp_complex*)b)->isZero()))
274  {
275    // a/0 = error
276    WerrorS(nDivBy0);
277    return NULL;
278  }
279  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
280  return (number)r;
281}
282
283/*2
284* u:= x ^ exp
285*/
286void ngcPower ( number x, int exp, number * u )
287{
288  if ( exp == 0 )
289  {
290    gmp_complex* n = new gmp_complex(1);
291    *u=(number)n;
292    return;
293  }
294  else if ( exp == 1 )
295  {
296    nNew(u);
297    if ( x == NULL )
298    {
299      gmp_complex* n = new gmp_complex();
300      *u=(number)n;
301    }
302    else
303    {
304      gmp_complex* n = new gmp_complex();
305      *n= *(gmp_complex*)x;
306      *u=(number)n;
307    }
308    return;
309  }
310  else if (exp == 2)
311  {
312    nNew(u);
313    if ( x == NULL )
314    {
315      gmp_complex* n = new gmp_complex();
316      *u=(number)n;
317    }
318    else
319    {
320      gmp_complex* n = new gmp_complex();
321      *n= *(gmp_complex*)x;
322      *u=(number)n;
323      *(gmp_complex*)(*u) *= *(gmp_complex*)n;
324    }
325    return;
326  }
327  if (exp&1==1)
328  {
329    ngcPower(x,exp-1,u);
330    gmp_complex *n=new gmp_complex();
331    *n=*(gmp_complex*)x;
332    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
333    delete n;
334  }
335  else
336  {
337    number w;
338    nNew(&w);
339    ngcPower(x,exp/2,&w);
340    ngcPower(w,2,u);
341    nDelete(&w);
342  }
343}
344
345BOOLEAN ngcIsZero (number a)
346{
347  if ( a == NULL ) return TRUE;
348  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
349}
350
351number ngcRePart(number a)
352{
353  if (((gmp_complex*)a)->real().isZero()) return NULL;
354  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
355  return (number)n;
356}
357
358number ngcImPart(number a)
359{
360  if (((gmp_complex*)a)->imag().isZero()) return NULL;
361  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
362  return (number)n;
363}
364
365/*2
366* za >= 0 ?
367*/
368BOOLEAN ngcGreaterZero (number a)
369{
370  if ( a == NULL ) return TRUE;
371  if ( ! ((gmp_complex*)a)->imag().isZero() )
372    return ( abs( *(gmp_complex*)a).sign() >= 0 );
373  else
374    return ( ((gmp_complex*)a)->real().sign() >= 0 );
375}
376
377/*2
378* a > b ?
379*/
380BOOLEAN ngcGreater (number a, number b)
381{
382  if ( a==NULL )
383  {
384    return (((gmp_complex*)b)->real().sign() < 0);
385  }
386  if ( b==NULL )
387  {
388    return (((gmp_complex*)a)->real().sign() < 0);
389  }
390  return FALSE;
391}
392
393/*2
394* a = b ?
395*/
396BOOLEAN ngcEqual (number a, number b)
397{
398  if ( a == NULL && b == NULL )
399  {
400    return TRUE;
401  }
402  else if ( a == NULL || b == NULL )
403  {
404    return FALSE;
405  }
406  return ( (*(gmp_complex*)a) == (*(gmp_complex*)b) );
407}
408
409/*2
410* a == 1 ?
411*/
412BOOLEAN ngcIsOne (number a)
413{
414  if ( a == NULL ) return FALSE;
415  //return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
416  return (((gmp_complex*)a)->real().isOne());
417}
418
419/*2
420* a == -1 ?
421*/
422BOOLEAN ngcIsMOne (number a)
423{
424  if ( a == NULL ) return FALSE;
425  //  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
426  return (((gmp_complex*)a)->real().isMOne());
427}
428
429/*2
430* extracts the number a from s, returns the rest
431*/
432char * ngcRead (char * s, number * a)
433{
434  char *start= s;
435  if ((*s >= '0') && (*s <= '9'))
436  {
437    gmp_float *re=NULL;
438    s=ngfRead(s,(number *)&re);
439    gmp_complex *aa=new gmp_complex(*re);
440    *a=(number)aa;
441    delete re;
442  }
443  else if (strncmp(s,currRing->parameter[0],strlen(currRing->parameter[0]))==0)
444  {
445    s+=strlen(currRing->parameter[0]);
446    gmp_complex *aa=new gmp_complex((long)0,(long)1);
447    *a=(number)aa;
448  }
449  else
450  {
451    *a=(number) new gmp_complex((long)1);
452  }
453  return s;
454}
455
456/*2
457* write a floating point number
458*/
459void ngcWrite (number &a)
460{
461  if (a==NULL)
462    StringAppend("0");
463  else
464  {
465    char *out;
466    out= complexToStr(*(gmp_complex*)a,gmp_output_digits);
467    StringAppend(out);
468    //    omFreeSize((ADDRESS)out, (strlen(out)+1)* sizeof(char) );
469    omFree( (ADDRESS)out );
470  }
471}
472
473#ifdef LDEBUG
474BOOLEAN ngcDBTest(number a, char *f, int l)
475{
476  return TRUE;
477}
478#endif
479
480// local Variables: ***
481// folded-file: t ***
482// compile-command: "make installg" ***
483// End: ***
Note: See TracBrowser for help on using the repository browser.