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

spielwiese
Last change on this file since 4c6e420 was 4c6e420, checked in by Oleksandr Motsak <motsak@…>, 13 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
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[341696]4/* $Id$ */
[35aab3]5/*
6* ABSTRACT: computations with GMP complex floating-point numbers
7*
8* ngc == number gnu complex
9*/
10
[691dba]11#include "config.h"
[c3d175]12
[2d805a]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>
[31213a4]20#include <reporter/reporter.h>
21#include <omalloc/omalloc.h>
[35aab3]22
23
[2d805a]24#include <coeffs/shortfl.h>
[3aae0e]25
[51d835]26/// Our Type!
27static const n_coeffType ID = n_long_C;
28
[3aae0e]29
[94b759]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)
[35aab3]42{
[94b759]43  assume( getCoeffType(r) == ID );
44
[35aab3]45  gmp_complex* n= new gmp_complex( (long)0, (long)1 );
46  return (number)n;
47}
48
49/*2
50* n := i
51*/
[7d90aa]52number ngcInit (int i, const coeffs r)
[35aab3]53{
[94b759]54  assume( getCoeffType(r) == ID );
55 
[78e67e]56  gmp_complex* n= new gmp_complex( (long)i, (long)0 );
[94b759]57 
[35aab3]58  return (number)n;
59}
60
61/*2
62* convert number to int
63*/
[7d90aa]64int ngcInt(number &i, const coeffs r)
[35aab3]65{
[94b759]66  assume( getCoeffType(r) == ID );
67 
[35aab3]68  return (int)((gmp_complex*)i)->real();
69}
70
[95d8df]71int ngcSize(number n, const coeffs R)
[12cca3]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) */
[95d8df]82  if ((oneNorm == 0.0) & (ngcIsZero(n,R) == FALSE)) oneNorm = 1;
[12cca3]83  return oneNorm;
84}
85
[35aab3]86/*2
87* delete a
88*/
[7d90aa]89void ngcDelete (number * a, const coeffs r)
[35aab3]90{
[94b759]91  assume( getCoeffType(r) == ID );
92
[7c961ba]93  if ( *a != NULL )
94  {
[35aab3]95    delete *(gmp_complex**)a;
96    *a=NULL;
97  }
98}
99
100/*2
[8cb8e1]101 * copy a to b
[35aab3]102*/
[94b759]103number ngcCopy(number a, const coeffs r)
[35aab3]104{
[94b759]105  assume( getCoeffType(r) == ID );
106 
[78e67e]107  gmp_complex* b= new gmp_complex( *(gmp_complex*)a );
[35aab3]108  return (number)b;
109}
[94b759]110
[35aab3]111
112/*2
113* za:= - za
114*/
[94b759]115number ngcNeg (number a, const coeffs R)
[35aab3]116{
[94b759]117  assume( getCoeffType(R) == ID );
118
[0f4db3]119  gmp_complex* r=(gmp_complex*)a;
[95d8df]120  (*r).neg();
[35aab3]121  return (number)a;
122}
123
124/*
125* 1/a
126*/
[94b759]127number ngcInvers(number a, const coeffs R)
[35aab3]128{
[94b759]129  assume( getCoeffType(R) == ID );
130
[b7e838]131  gmp_complex* r = NULL;
[78e67e]132  if (((gmp_complex*)a)->isZero())
[35aab3]133  {
[b7e838]134    WerrorS(nDivBy0);
[35aab3]135  }
136  else
137  {
[95d8df]138    r = new gmp_complex( (gmp_complex)1 / (*(gmp_complex*)a) );
[35aab3]139  }
[95d8df]140  return (number)r;
[35aab3]141}
142
143/*2
144* u:= a + b
145*/
[94b759]146number ngcAdd (number a, number b, const coeffs R)
[35aab3]147{
[94b759]148  assume( getCoeffType(R) == ID );
149
[78e67e]150  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) + (*(gmp_complex*)b) );
[35aab3]151  return (number)r;
152}
153
154/*2
155* u:= a - b
156*/
[8cb8e1]157number ngcSub (number a, number b, const coeffs R)
[35aab3]158{
[94b759]159  assume( getCoeffType(R) == ID );
160
[78e67e]161  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) - (*(gmp_complex*)b) );
[35aab3]162  return (number)r;
163}
164
165/*2
166* u := a * b
167*/
[94b759]168number ngcMult (number a, number b, const coeffs R)
[35aab3]169{
[94b759]170  assume( getCoeffType(R) == ID );
171 
[78e67e]172  gmp_complex* r= new gmp_complex( (*(gmp_complex*)a) * (*(gmp_complex*)b) );
[35aab3]173  return (number)r;
174}
175
176/*2
177* u := a / b
178*/
[94b759]179number ngcDiv (number a, number b, const coeffs r)
[35aab3]180{
[94b759]181  assume( getCoeffType(r) == ID );
182
[78e67e]183  if (((gmp_complex*)b)->isZero())
[35aab3]184  {
[b7e838]185    // a/0 = error
186    WerrorS(nDivBy0);
[35aab3]187    return NULL;
188  }
[94b759]189  gmp_complex* res = new gmp_complex( (*(gmp_complex*)a) / (*(gmp_complex*)b) );
190  return (number)res;
[35aab3]191}
192
193/*2
194* u:= x ^ exp
195*/
[94b759]196void ngcPower ( number x, int exp, number * u, const coeffs r)
[35aab3]197{
[94b759]198  assume( getCoeffType(r) == ID );
199
[35aab3]200  if ( exp == 0 )
201  {
202    gmp_complex* n = new gmp_complex(1);
203    *u=(number)n;
204    return;
205  }
[5fe545]206  else if ( exp == 1 )
[35aab3]207  {
[94b759]208    n_New(u, r);
[78e67e]209    gmp_complex* n = new gmp_complex();
210    *n= *(gmp_complex*)x;
211    *u=(number)n;
[35aab3]212    return;
213  }
[5fe545]214  else if (exp == 2)
215  {
[94b759]216    n_New(u, r);
[78e67e]217    gmp_complex* n = new gmp_complex();
218    *n= *(gmp_complex*)x;
219    *u=(number)n;
220    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
[5fe545]221    return;
222  }
[039016]223  if ( (exp & 1) == 1 )
[5fe545]224  {
[94b759]225    ngcPower(x,exp-1,u, r);
226    gmp_complex *n = new gmp_complex();
[5fe545]227    *n=*(gmp_complex*)x;
228    *(gmp_complex*)(*u) *= *(gmp_complex*)n;
229    delete n;
230  }
231  else
232  {
233    number w;
[94b759]234    n_New(&w, r);
235    ngcPower(x,exp/2,&w, r);
236    ngcPower(w,2,u, r);
237    n_Delete(&w, r);
[5fe545]238  }
[35aab3]239}
240
[94b759]241BOOLEAN ngcIsZero (number a, const coeffs r)
[35aab3]242{
[94b759]243  assume( getCoeffType(r) == ID );
244
[35aab3]245  return ( ((gmp_complex*)a)->real().isZero() && ((gmp_complex*)a)->imag().isZero());
246}
247
[94b759]248number ngcRePart(number a, const coeffs r)
[35aab3]249{
[94b759]250  assume( getCoeffType(r) == ID );
251
[35aab3]252  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->real());
253  return (number)n;
254}
255
[94b759]256number ngcImPart(number a, const coeffs r)
[35aab3]257{
[94b759]258  assume( getCoeffType(r) == ID );
259
[35aab3]260  gmp_complex* n = new gmp_complex(((gmp_complex*)a)->imag());
261  return (number)n;
262}
263
264/*2
265* za >= 0 ?
266*/
[94b759]267BOOLEAN ngcGreaterZero (number a, const coeffs r)
[35aab3]268{
[94b759]269  assume( getCoeffType(r) == ID );
270
[35aab3]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*/
[94b759]280BOOLEAN ngcGreater (number a, number b, const coeffs r)
[35aab3]281{
[94b759]282  assume( getCoeffType(r) == ID );
283
[890d63b]284  gmp_complex *aa=(gmp_complex*)a;
285  gmp_complex *bb=(gmp_complex*)b;
286  return (*aa) > (*bb);
[35aab3]287}
288
289/*2
290* a = b ?
291*/
[94b759]292BOOLEAN ngcEqual (number a, number b, const coeffs r)
[35aab3]293{
[94b759]294  assume( getCoeffType(r) == ID );
295
[890d63b]296  gmp_complex *aa=(gmp_complex*)a;
297  gmp_complex *bb=(gmp_complex*)b;
298  return (*aa) == (*bb);
[35aab3]299}
300
301/*2
302* a == 1 ?
303*/
[94b759]304BOOLEAN ngcIsOne (number a, const coeffs r)
[35aab3]305{
[94b759]306  assume( getCoeffType(r) == ID );
307
[78e67e]308  return (((gmp_complex*)a)->real().isOne() && ((gmp_complex*)a)->imag().isZero());
309  //return (((gmp_complex*)a)->real().isOne());
[35aab3]310}
311
312/*2
313* a == -1 ?
314*/
[94b759]315BOOLEAN ngcIsMOne (number a, const coeffs r)
[35aab3]316{
[94b759]317  assume( getCoeffType(r) == ID );
318
[78e67e]319  return (((gmp_complex*)a)->real().isMOne() && ((gmp_complex*)a)->imag().isZero());
320  //return (((gmp_complex*)a)->real().isMOne());
[35aab3]321}
322
323/*2
324* extracts the number a from s, returns the rest
325*/
[94b759]326const char * ngcRead (const char * s, number * a, const coeffs r)
[35aab3]327{
[94b759]328  assume( getCoeffType(r) == ID );
[4c6e420]329  assume( r->compex_parameter != NULL );
[35aab3]330  if ((*s >= '0') && (*s <= '9'))
331  {
332    gmp_float *re=NULL;
[94b759]333    s=ngfRead(s,(number *)&re, r);
[35aab3]334    gmp_complex *aa=new gmp_complex(*re);
335    *a=(number)aa;
336    delete re;
337  }
[4c6e420]338  else if (strncmp(s, r->compex_parameter,strlen(r->compex_parameter))==0)
[35aab3]339  {
[4c6e420]340    s+=strlen(r->compex_parameter);
[35aab3]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
[94b759]351
352
[35aab3]353/*2
354* write a floating point number
355*/
[7d90aa]356void ngcWrite (number &a, const coeffs r)
[35aab3]357{
[94b759]358  assume( getCoeffType(r) == ID );
359
360  extern size_t gmp_output_digits; /// comes from mpr_complex.cc
361
[35aab3]362  if (a==NULL)
[e53182]363    StringAppendS("0");
[35aab3]364  else
365  {
366    char *out;
[ac5686]367    out= complexToStr(*(gmp_complex*)a, gmp_output_digits, r);
[e53182]368    StringAppendS(out);
[7d90aa]369    //    omFreeSize((void *)out, (strlen(out)+1)* sizeof(char) );
370    omFree( (void *)out );
[35aab3]371  }
372}
373
[51d835]374
375
[039016]376/// test, whether r is an instance of nInitCoeffs(n, parameter)
[2b957a]377static BOOLEAN ngcCoeffsEqual(const coeffs r, n_coeffType n, void*)
[51d835]378{
379  assume( getCoeffType(r) == ID );
380 
381  return (n == ID);
[039016]382}
[51d835]383
[4c6e420]384BOOLEAN ngcInitChar(coeffs n, void* p)
[51d835]385{
386  assume( getCoeffType(n) == ID );
387
388  n->cfDelete  = ngcDelete;
[7bbbef]389  n->cfNormalize=ndNormalize;
[51d835]390  n->cfInit   = ngcInit;
[7bbbef]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;
[51d835]399  n->cfCopy   = ngcCopy;
[7bbbef]400  n->cfGreater = ngcGreater;
401  n->cfEqual   = ngcEqual;
402  n->cfIsZero  = ngcIsZero;
403  n->cfIsOne   = ngcIsOne;
404  n->cfIsMOne  = ngcIsMOne;
405  n->cfGreaterZero = ngcGreaterZero;
[51d835]406  n->cfWrite  = ngcWrite;
[7bbbef]407  n->cfRead    = ngcRead;
408  n->cfPower   = ngcPower;
[51d835]409  n->cfSetMap = ngcSetMap;
[7bbbef]410  n->cfPar     = ngcPar;
411  n->cfRePart  = ngcRePart;
412  n->cfImPart  = ngcImPart;
[7a8011]413  n->cfCoeffWrite = ngcCoeffWrite;
[7bbbef]414    // cfSize  = ndSize;
[51d835]415#ifdef LDEBUG
[7bbbef]416  n->cfDBTest  = ndDBTest; // not yet implemented: ngcDBTest
[51d835]417#endif
418
[039016]419  n->nCoeffIsEqual = ngcCoeffsEqual;
420
[51d835]421
422 
423/* 
424  //r->cfInitChar=nlInitChar;
425  r->cfKillChar=NULL;
426  r->cfSetChar=NULL;
427  r->nCoeffIsEqual=nlCoeffsEqual;
428
[7bbbef]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;
[51d835]436  r->cfInit = nlInit;
[7bbbef]437  r->cfPar = ndPar;
438  r->cfParDeg = ndParDeg;
439  r->cfSize  = nlSize;
440  r->cfInt  = nlInt;
[51d835]441#ifdef HAVE_RINGS
[7bbbef]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
[51d835]446#endif
[7bbbef]447  r->cfNeg   = nlNeg;
448  r->cfInvers= nlInvers;
[51d835]449  r->cfCopy  = nl_Copy;
[7bbbef]450  r->cfRePart = nl_Copy;
451  r->cfImPart = ndReturn0;
[51d835]452  r->cfWrite = nlWrite;
[7bbbef]453  r->cfRead = nlRead;
454  r->cfNormalize=nlNormalize;
455  r->cfGreater = nlGreater;
[51d835]456#ifdef HAVE_RINGS
[7bbbef]457  r->cfDivBy = NULL; // only for ring stuff
[51d835]458#endif
[7bbbef]459  r->cfEqual = nlEqual;
460  r->cfIsZero = nlIsZero;
461  r->cfIsOne = nlIsOne;
462  r->cfIsMOne = nlIsMOne;
463  r->cfGreaterZero = nlGreaterZero;
464  r->cfPower = nlPower;
[51d835]465  r->cfGetDenom = nlGetDenom;
466  r->cfGetNumerator = nlGetNumerator;
[7bbbef]467  r->cfGcd  = nlGcd;
468  r->cfLcm  = nlLcm;
[51d835]469  r->cfDelete= nlDelete;
470  r->cfSetMap = nlSetMap;
[7bbbef]471  r->cfName = ndName;
472  r->cfInpMult=nlInpMult;
473  r->cfInit_bigint=nlCopyMap;
[51d835]474#ifdef LDEBUG
475  // debug stuff
[7bbbef]476  r->cfDBTest=nlDBTest;
[51d835]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?
[4c6e420]488  if( p == NULL )
489    n->compex_parameter = "i"; //??
490  else
491    n->compex_parameter = omStrDup( (char*) p );
492   
[5d594a9]493  return FALSE;
[51d835]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
[210852]547  if ( from != NULL )
[51d835]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
[1cce47]571  if (nCoeff_is_Q(src))
[51d835]572  {
573    return ngcMapQ;
574  }
[1cce47]575  if (nCoeff_is_long_R(src))
[51d835]576  {
577    return ngcMapLongR;
578  }
[1cce47]579  if (nCoeff_is_long_C(src))
[51d835]580  {
581    return ngcCopyMap;
582  }
[1cce47]583  if (nCoeff_is_R(src))
[51d835]584  {
585    return ngcMapR;
586  }
[1cce47]587  if (nCoeff_is_Zp(src))
[51d835]588  {
589    return ngcMapP;
590  }
591  return NULL;
592}
593
[7a8011]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.