source: git/kernel/gnumpc.cc @ 899741

spielwiese
Last change on this file since 899741 was 85e68dd, checked in by Hans Schönemann <hannes@…>, 16 years ago
*hannes: gcc 4.2 git-svn-id: file:///usr/local/Singular/svn/trunk@10634 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: gnumpc.cc,v 1.7 2008-03-19 17:44:08 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
25number 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  {
137    delete *(gmp_complex**)a;
138    *a=NULL;
139  }
140}
141
142/*2
143* copy a to b
144*/
145number ngcCopy(number a)
146{
147  gmp_complex* b= NULL;
148  if ( a !=  NULL )
149  {
150    b= new gmp_complex( *(gmp_complex*)a );
151  }
152  return (number)b;
153}
154number ngc_Copy(number a, ring r)
155{
156  gmp_complex* b= NULL;
157  if ( a !=  NULL )
158  {
159    b= new gmp_complex( *(gmp_complex*)a );
160  }
161  return (number)b;
162}
163
164/*2
165* za:= - za
166*/
167gmp_complex ngc_m1(-1);
168
169number ngcNeg (number a)
170{
171  if ( a == NULL ) return NULL;
172  gmp_complex* r=(gmp_complex*)a;
173  (*r) *= ngc_m1;
174  return (number)a;
175}
176
177/*
178* 1/a
179*/
180number ngcInvers(number a)
181{
182  gmp_complex* r = NULL;
183  if ( (a==NULL)
184  || (((gmp_complex*)a)->isZero()))
185  {
186    WerrorS(nDivBy0);
187  }
188  else
189  {
190    r= new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
191  }
192  return (number)r;
193}
194
195/*2
196* u:= a + b
197*/
198number ngcAdd (number a, number b)
199{
200  gmp_complex* r= NULL;
201  if ( a==NULL && b==NULL )
202  {
203    return NULL;
204  }
205  else if ( a == NULL )
206  {
207    r= new gmp_complex( *(gmp_complex*)b );
208  }
209  else if ( b == NULL )
210  {
211    r= new gmp_complex( *(gmp_complex*)a );
212  }
213  else
214  {
215    r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
216  }
217  return (number)r;
218}
219
220/*2
221* u:= a - b
222*/
223number ngcSub (number a, number b)
224{
225  gmp_complex* r= NULL;
226  if ( a==NULL && b==NULL )
227  {
228    return NULL;
229  }
230  else if ( a == NULL )
231  {
232    r= new gmp_complex( (*(gmp_complex*)b) );
233    r= (gmp_complex *)ngcNeg((number)r);
234  }
235  else if ( b == NULL )
236  {
237    r= new gmp_complex( *(gmp_complex*)a );
238  }
239  else
240  {
241    r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
242  }
243  return (number)r;
244}
245
246/*2
247* u := a * b
248*/
249number ngcMult (number a, number b)
250{
251  gmp_complex* r= NULL;
252  if ( a==NULL || b==NULL )
253  {
254    return NULL;
255  }
256  else
257  {
258    r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
259  }
260  return (number)r;
261}
262
263/*2
264* u := a / b
265*/
266number ngcDiv (number a, number b)
267{
268  if ( a==NULL )
269  {
270    // 0/b = 0
271    return NULL;
272  }
273  else if (( b==NULL )
274  || (((gmp_complex*)b)->isZero()))
275  {
276    // a/0 = error
277    WerrorS(nDivBy0);
278    return NULL;
279  }
280  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
281  return (number)r;
282}
283
284/*2
285* u:= x ^ exp
286*/
287void ngcPower ( number x, int exp, number * u )
288{
289  if ( exp == 0 )
290  {
291    gmp_complex* n = new gmp_complex(1);
292    *u=(number)n;
293    return;
294  }
295  else if ( exp == 1 )
296  {
297    nNew(u);
298    if ( x == NULL )
299    {
300      gmp_complex* n = new gmp_complex();
301      *u=(number)n;
302    }
303    else
304    {
305      gmp_complex* n = new gmp_complex();
306      *n= *(gmp_complex*)x;
307      *u=(number)n;
308    }
309    return;
310  }
311  else if (exp == 2)
312  {
313    nNew(u);
314    if ( x == NULL )
315    {
316      gmp_complex* n = new gmp_complex();
317      *u=(number)n;
318    }
319    else
320    {
321      gmp_complex* n = new gmp_complex();
322      *n= *(gmp_complex*)x;
323      *u=(number)n;
324      *(gmp_complex*)(*u) *= *(gmp_complex*)n;
325    }
326    return;
327  }
328  if (exp&1==1)
329  {
330    ngcPower(x,exp-1,u);
331    gmp_complex *n=new gmp_complex();
332    *n=*(gmp_complex*)x;
333    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
334    delete n;
335  }
336  else
337  {
338    number w;
339    nNew(&w);
340    ngcPower(x,exp/2,&w);
341    ngcPower(w,2,u);
342    nDelete(&w);
343  }
344}
345
346BOOLEAN ngcIsZero (number a)
347{
348  if ( a == NULL ) return TRUE;
349  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
350}
351
352number ngcRePart(number a)
353{
354  if ((a==NULL) || ((gmp_complex*)a)->real().isZero()) return NULL;
355  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
356  return (number)n;
357}
358
359number ngcImPart(number a)
360{
361  if ((a==NULL) || ((gmp_complex*)a)->imag().isZero()) return NULL;
362  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
363  return (number)n;
364}
365
366/*2
367* za >= 0 ?
368*/
369BOOLEAN ngcGreaterZero (number a)
370{
371  if ( a == NULL ) return TRUE;
372  if ( ! ((gmp_complex*)a)->imag().isZero() )
373    return ( abs( *(gmp_complex*)a).sign() >= 0 );
374  else
375    return ( ((gmp_complex*)a)->real().sign() >= 0 );
376}
377
378/*2
379* a > b ?
380*/
381BOOLEAN ngcGreater (number a, number b)
382{
383  if ( a==NULL )
384  {
385    return (((gmp_complex*)b)->real().sign() < 0);
386  }
387  if ( b==NULL )
388  {
389    return (((gmp_complex*)a)->real().sign() < 0);
390  }
391  return FALSE;
392}
393
394/*2
395* a = b ?
396*/
397BOOLEAN ngcEqual (number a, number b)
398{
399  if ( a == NULL && b == NULL )
400  {
401    return TRUE;
402  }
403  else if ( a == NULL || b == NULL )
404  {
405    return FALSE;
406  }
407  return ( (*(gmp_complex*)a) == (*(gmp_complex*)b) );
408}
409
410/*2
411* a == 1 ?
412*/
413BOOLEAN ngcIsOne (number a)
414{
415  if ( a == NULL ) return FALSE;
416  //return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
417  return (((gmp_complex*)a)->real().isOne());
418}
419
420/*2
421* a == -1 ?
422*/
423BOOLEAN ngcIsMOne (number a)
424{
425  if ( a == NULL ) return FALSE;
426  //  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
427  return (((gmp_complex*)a)->real().isMOne());
428}
429
430/*2
431* extracts the number a from s, returns the rest
432*/
433const char * ngcRead (const char * s, number * a)
434{
435  const char *start= s;
436  if ((*s >= '0') && (*s <= '9'))
437  {
438    gmp_float *re=NULL;
439    s=ngfRead(s,(number *)&re);
440    gmp_complex *aa=new gmp_complex(*re);
441    *a=(number)aa;
442    delete re;
443  }
444  else if (strncmp(s,currRing->parameter[0],strlen(currRing->parameter[0]))==0)
445  {
446    s+=strlen(currRing->parameter[0]);
447    gmp_complex *aa=new gmp_complex((long)0,(long)1);
448    *a=(number)aa;
449  }
450  else
451  {
452    *a=(number) new gmp_complex((long)1);
453  }
454  return s;
455}
456
457/*2
458* write a floating point number
459*/
460void ngcWrite (number &a)
461{
462  if (a==NULL)
463    StringAppend("0");
464  else
465  {
466    char *out;
467    out= complexToStr(*(gmp_complex*)a,gmp_output_digits);
468    StringAppend(out);
469    //    omFreeSize((ADDRESS)out, (strlen(out)+1)* sizeof(char) );
470    omFree( (ADDRESS)out );
471  }
472}
473
474#ifdef LDEBUG
475// not yet implemented
476//BOOLEAN ngcDBTest(number a, const char *f, const int l)
477//{
478//  return TRUE;
479//}
480#endif
481
482// local Variables: ***
483// folded-file: t ***
484// compile-command: "make installg" ***
485// End: ***
Note: See TracBrowser for help on using the repository browser.