source: git/libpolys/coeffs/gnumpc.cc @ 4c6e420

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