source: git/kernel/gnumpc.cc @ f3a8c2e

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