source: git/coeffs/gnumpc.cc @ 7bbbef

spielwiese
Last change on this file since 7bbbef was 7bbbef, checked in by Hans Schoenemann <hannes@…>, 14 years ago
access macros -> coeffs.h, internal proc renamed (n.. -> cf...)
  • Property mode set to 100644
File size: 11.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: computations with GMP complex floating-point numbers
7*
8* ngc == number gnu complex
9*/
10
11#include "coeffs.h"
12#include "numbers.h"
13#include "longrat.h"
14#include "modulop.h"
15#include "gnumpc.h"
16#include "gnumpfl.h"
17#include "mpr_complex.h"
18#include "output.h"
19#include "omalloc.h"
20
21
22#include "shortfl.h"
23
24/// Our Type!
25static const n_coeffType ID = n_long_C;
26
27
28#ifdef LDEBUG
29// not yet implemented
30BOOLEAN ngcDBTest(number a, const char *f, const int l, const coeffs r)
31{
32  assume( getCoeffType(r) == ID );
33
34  return TRUE;
35}
36#endif
37
38
39number   ngcPar(int i, const coeffs r)
40{
41  assume( getCoeffType(r) == ID );
42
43  gmp_complex* n= new gmp_complex( (long)0, (long)1 );
44  return (number)n;
45}
46
47/*2
48* n := i
49*/
50number ngcInit (int i, const coeffs r)
51{
52  assume( getCoeffType(r) == ID );
53 
54  gmp_complex* n= new gmp_complex( (long)i, (long)0 );
55 
56  return (number)n;
57}
58
59/*2
60* convert number to int
61*/
62int ngcInt(number &i, const coeffs r)
63{
64  assume( getCoeffType(r) == ID );
65 
66  return (int)((gmp_complex*)i)->real();
67}
68
69int ngcSize(number n)
70{
71  int r = (int)((gmp_complex*)n)->real();
72  if (r < 0) r = -r;
73  int i = (int)((gmp_complex*)n)->imag();
74  if (i < 0) i = -i;
75  int oneNorm = r + i;
76  /* basically return the 1-norm of n;
77     only if this happens to be zero although n != 0,
78     return 1;
79     (this code ensures that zero has the size zero) */
80  if ((oneNorm == 0.0) & (ngcIsZero(n) == FALSE)) oneNorm = 1;
81  return oneNorm;
82}
83
84/*2
85* delete a
86*/
87void ngcDelete (number * a, const coeffs r)
88{
89  assume( getCoeffType(r) == ID );
90
91  if ( *a != NULL )
92  {
93    delete *(gmp_complex**)a;
94    *a=NULL;
95  }
96}
97
98/*2
99 * copy a to b
100*/
101number ngcCopy(number a, const coeffs r)
102{
103  assume( getCoeffType(r) == ID );
104 
105  gmp_complex* b= new gmp_complex( *(gmp_complex*)a );
106  return (number)b;
107}
108
109
110/*2
111* za:= - za
112*/
113number ngcNeg (number a, const coeffs R)
114{
115  assume( getCoeffType(R) == ID );
116
117  gmp_complex* r=(gmp_complex*)a;
118  (*r) *= ngc_m1;
119  return (number)a;
120}
121
122/*
123* 1/a
124*/
125number ngcInvers(number a, const coeffs R)
126{
127  assume( getCoeffType(R) == ID );
128
129  gmp_complex* r = NULL;
130  if (((gmp_complex*)a)->isZero())
131  {
132    WerrorS(nDivBy0);
133  }
134  else
135  {
136    b = new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
137  }
138  return (number)b;
139}
140
141/*2
142* u:= a + b
143*/
144number ngcAdd (number a, number b, const coeffs R)
145{
146  assume( getCoeffType(R) == ID );
147
148  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
149  return (number)r;
150}
151
152/*2
153* u:= a - b
154*/
155number ngcSub (number a, number b, const coeffs R)
156{
157  assume( getCoeffType(R) == ID );
158
159  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
160  return (number)r;
161}
162
163/*2
164* u := a * b
165*/
166number ngcMult (number a, number b, const coeffs R)
167{
168  assume( getCoeffType(R) == ID );
169 
170  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
171  return (number)r;
172}
173
174/*2
175* u := a / b
176*/
177number ngcDiv (number a, number b, const coeffs r)
178{
179  assume( getCoeffType(r) == ID );
180
181  if (((gmp_complex*)b)->isZero())
182  {
183    // a/0 = error
184    WerrorS(nDivBy0);
185    return NULL;
186  }
187  gmp_complex* res = new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
188  return (number)res;
189}
190
191/*2
192* u:= x ^ exp
193*/
194void ngcPower ( number x, int exp, number * u, const coeffs r)
195{
196  assume( getCoeffType(r) == ID );
197
198  if ( exp == 0 )
199  {
200    gmp_complex* n = new gmp_complex(1);
201    *u=(number)n;
202    return;
203  }
204  else if ( exp == 1 )
205  {
206    n_New(u, r);
207    gmp_complex* n = new gmp_complex();
208    *n= *(gmp_complex*)x;
209    *u=(number)n;
210    return;
211  }
212  else if (exp == 2)
213  {
214    n_New(u, r);
215    gmp_complex* n = new gmp_complex();
216    *n= *(gmp_complex*)x;
217    *u=(number)n;
218    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
219    return;
220  }
221  if (exp&1==1)
222  {
223    ngcPower(x,exp-1,u, r);
224    gmp_complex *n = new gmp_complex();
225    *n=*(gmp_complex*)x;
226    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
227    delete n;
228  }
229  else
230  {
231    number w;
232    n_New(&w, r);
233    ngcPower(x,exp/2,&w, r);
234    ngcPower(w,2,u, r);
235    n_Delete(&w, r);
236  }
237}
238
239BOOLEAN ngcIsZero (number a, const coeffs r)
240{
241  assume( getCoeffType(r) == ID );
242
243  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
244}
245
246number ngcRePart(number a, const coeffs r)
247{
248  assume( getCoeffType(r) == ID );
249
250  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
251  return (number)n;
252}
253
254number ngcImPart(number a, const coeffs r)
255{
256  assume( getCoeffType(r) == ID );
257
258  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
259  return (number)n;
260}
261
262/*2
263* za >= 0 ?
264*/
265BOOLEAN ngcGreaterZero (number a, const coeffs r)
266{
267  assume( getCoeffType(r) == ID );
268
269  if ( ! ((gmp_complex*)a)->imag().isZero() )
270    return ( abs( *(gmp_complex*)a).sign() >= 0 );
271  else
272    return ( ((gmp_complex*)a)->real().sign() >= 0 );
273}
274
275/*2
276* a > b ?
277*/
278BOOLEAN ngcGreater (number a, number b, const coeffs r)
279{
280  assume( getCoeffType(r) == ID );
281
282  gmp_complex *aa=(gmp_complex*)a;
283  gmp_complex *bb=(gmp_complex*)b;
284  return (*aa) > (*bb);
285}
286
287/*2
288* a = b ?
289*/
290BOOLEAN ngcEqual (number a, number b, const coeffs r)
291{
292  assume( getCoeffType(r) == ID );
293
294  gmp_complex *aa=(gmp_complex*)a;
295  gmp_complex *bb=(gmp_complex*)b;
296  return (*aa) == (*bb);
297}
298
299/*2
300* a == 1 ?
301*/
302BOOLEAN ngcIsOne (number a, const coeffs r)
303{
304  assume( getCoeffType(r) == ID );
305
306  return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
307  //return (((gmp_complex*)a)->real().isOne());
308}
309
310/*2
311* a == -1 ?
312*/
313BOOLEAN ngcIsMOne (number a, const coeffs r)
314{
315  assume( getCoeffType(r) == ID );
316
317  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
318  //return (((gmp_complex*)a)->real().isMOne());
319}
320
321/*2
322* extracts the number a from s, returns the rest
323*/
324const char * ngcRead (const char * s, number * a, const coeffs r)
325{
326  assume( getCoeffType(r) == ID );
327 
328  if ((*s >= '0') && (*s <= '9'))
329  {
330    gmp_float *re=NULL;
331    s=ngfRead(s,(number *)&re, r);
332    gmp_complex *aa=new gmp_complex(*re);
333    *a=(number)aa;
334    delete re;
335  }
336  else if (strncmp(s, r->parameter[0],strlen(r->parameter[0]))==0)
337  {
338    s+=strlen(r->parameter[0]);
339    gmp_complex *aa=new gmp_complex((long)0,(long)1);
340    *a=(number)aa;
341  }
342  else
343  {
344    *a=(number) new gmp_complex((long)1);
345  }
346  return s;
347}
348
349
350
351/*2
352* write a floating point number
353*/
354void ngcWrite (number &a, const coeffs r)
355{
356  assume( getCoeffType(r) == ID );
357
358  extern size_t gmp_output_digits; /// comes from mpr_complex.cc
359
360  if (a==NULL)
361    StringAppendS("0");
362  else
363  {
364    char *out;
365    out= complexToStr(*(gmp_complex*)a, gmp_output_digits, r);
366    StringAppendS(out);
367    //    omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
368    omFree( (void *)out );
369  }
370}
371
372
373
374
375static BOOLEAN ngcCoeffsEqual(const coeffs r, n_coeffType n, int)
376{
377  assume( getCoeffType(r) == ID );
378 
379  return (n == ID);
380};
381
382void ngcInitChar(coeffs n, int)
383{
384  assume( getCoeffType(n) == ID );
385
386  n->cfDelete  = ngcDelete;
387  n->cfNormalize=ndNormalize;
388  n->cfInit   = ngcInit;
389  n->cfInt    = ngcInt;
390  n->cfAdd     = ngcAdd;
391  n->cfSub     = ngcSub;
392  n->cfMult    = ngcMult;
393  n->cfDiv     = ngcDiv;
394  n->cfExactDiv= ngcDiv;
395  n->cfNeg     = ngcNeg;
396  n->cfInvers  = ngcInvers;
397  n->cfCopy   = ngcCopy;
398  n->cfGreater = ngcGreater;
399  n->cfEqual   = ngcEqual;
400  n->cfIsZero  = ngcIsZero;
401  n->cfIsOne   = ngcIsOne;
402  n->cfIsMOne  = ngcIsMOne;
403  n->cfGreaterZero = ngcGreaterZero;
404  n->cfWrite  = ngcWrite;
405  n->cfRead    = ngcRead;
406  n->cfPower   = ngcPower;
407  n->cfSetMap = ngcSetMap;
408  n->cfPar     = ngcPar;
409  n->cfRePart  = ngcRePart;
410  n->cfImPart  = ngcImPart;
411    // cfSize  = ndSize;
412#ifdef LDEBUG
413  n->cfDBTest  = ndDBTest; // not yet implemented: ngcDBTest
414#endif
415
416
417 
418/* 
419  //r->cfInitChar=nlInitChar;
420  r->cfKillChar=NULL;
421  r->cfSetChar=NULL;
422  r->nCoeffIsEqual=nlCoeffsEqual;
423
424  r->cfMult  = nlMult;
425  r->cfSub   = nlSub;
426  r->cfAdd   = nlAdd;
427  r->cfDiv   = nlDiv;
428  r->cfIntDiv= nlIntDiv;
429  r->cfIntMod= nlIntMod;
430  r->cfExactDiv= nlExactDiv;
431  r->cfInit = nlInit;
432  r->cfPar = ndPar;
433  r->cfParDeg = ndParDeg;
434  r->cfSize  = nlSize;
435  r->cfInt  = nlInt;
436#ifdef HAVE_RINGS
437  r->cfDivComp = NULL; // only for ring stuff
438  r->cfIsUnit = NULL; // only for ring stuff
439  r->cfGetUnit = NULL; // only for ring stuff
440  r->cfExtGcd = NULL; // only for ring stuff
441#endif
442  r->cfNeg   = nlNeg;
443  r->cfInvers= nlInvers;
444  r->cfCopy  = nl_Copy;
445  r->cfRePart = nl_Copy;
446  r->cfImPart = ndReturn0;
447  r->cfWrite = nlWrite;
448  r->cfRead = nlRead;
449  r->cfNormalize=nlNormalize;
450  r->cfGreater = nlGreater;
451#ifdef HAVE_RINGS
452  r->cfDivBy = NULL; // only for ring stuff
453#endif
454  r->cfEqual = nlEqual;
455  r->cfIsZero = nlIsZero;
456  r->cfIsOne = nlIsOne;
457  r->cfIsMOne = nlIsMOne;
458  r->cfGreaterZero = nlGreaterZero;
459  r->cfPower = nlPower;
460  r->cfGetDenom = nlGetDenom;
461  r->cfGetNumerator = nlGetNumerator;
462  r->cfGcd  = nlGcd;
463  r->cfLcm  = nlLcm;
464  r->cfDelete= nlDelete;
465  r->cfSetMap = nlSetMap;
466  r->cfName = ndName;
467  r->cfInpMult=nlInpMult;
468  r->cfInit_bigint=nlCopyMap;
469#ifdef LDEBUG
470  // debug stuff
471  r->cfDBTest=nlDBTest;
472#endif
473
474  // the variables:
475  r->nNULL = INT_TO_SR(0);
476  r->type = n_Q;
477  r->ch = 0;
478  r->has_simple_Alloc=FALSE;
479  r->has_simple_Inverse=FALSE;
480*/
481
482/// TODO: Any variables?
483 
484}
485
486
487
488
489
490number ngcMapQ(number from, const coeffs aRing, const coeffs r)
491{
492  assume( getCoeffType(r) == ID );
493  assume( getCoeffType(aRing) == n_Q );
494
495  if ( from != NULL )
496  {
497    gmp_complex *res=new gmp_complex(numberFieldToFloat(from,QTOF,aRing));
498    return (number)res;
499  }
500  else
501    return NULL;
502}
503
504static number ngcMapLongR(number from, const coeffs aRing, const coeffs r)
505{
506  assume( getCoeffType(r) == ID );
507  assume( getCoeffType(aRing) == n_long_R );
508
509  if ( from != NULL )
510  {
511    gmp_complex *res=new gmp_complex(*((gmp_float *)from));
512    return (number)res;
513  }
514  else
515    return NULL;
516}
517
518static number ngcMapR(number from, const coeffs aRing, const coeffs r)
519{
520  assume( getCoeffType(r) == ID );
521  assume( getCoeffType(aRing) == n_R );
522
523  if ( from != NULL )
524  {
525    gmp_complex *res=new gmp_complex((double)nrFloat(from));
526    return (number)res;
527  }
528  else
529    return NULL;
530}
531
532static number ngcMapP(number from, const coeffs aRing, const coeffs r)
533{
534  assume( getCoeffType(r) == ID );
535  assume( getCoeffType(aRing) ==  n_Zp );
536
537  if ( from != NULL )
538    return ngcInit(npInt(from, aRing), r);
539  else
540    return NULL;
541}
542
543static number ngcCopyMap(number from, const coeffs aRing, const coeffs r)
544{
545  assume( getCoeffType(r) == ID );
546  assume( getCoeffType(aRing) ==  ID );
547
548  gmp_complex* b = NULL;
549
550  if ( from !=  NULL )
551  { 
552    b = new gmp_complex( *(gmp_complex*)from );
553  }
554  return (number)b; 
555}
556
557nMapFunc ngcSetMap(const coeffs src, const coeffs dst)
558{
559  assume( getCoeffType(dst) == ID );
560
561  if (nField_is_Q(src))
562  {
563    return ngcMapQ;
564  }
565  if (nField_is_long_R(src))
566  {
567    return ngcMapLongR;
568  }
569  if (nField_is_long_C(src))
570  {
571    return ngcCopyMap;
572  }
573  if (nField_is_R(src))
574  {
575    return ngcMapR;
576  }
577  if (nField_is_Zp(src))
578  {
579    return ngcMapP;
580  }
581  return NULL;
582}
583
Note: See TracBrowser for help on using the repository browser.